3

Hi I am a facebook Webdriver newbie. I need help on getting HTML source of an AJAX page.

Here is my expected results:

$first == HTML source of the 1st page.
$second == HTML source of the 2nd page.
$third == HTML source of the 3rd page.

But my Output:

$first == HTML source of the 1st page.
$second == $first
$third == HTML source of the 2nd page.

However, I could get the HTML source of the 2nd page when I landed on the 3rd page. I don't know why I can not get the current HTML on Current page.

Please Help!

Here is my code:

<?php 
$host = 'http://localhost:4444/wd/hub'; 
$capabilities = DesiredCapabilities::firefox();
$driver = RemoteWebDriver::create($host, $capabilities, 5000);

// Openning page
$driver->get('https://careers.yahoo.com/?global=1');

// Click 'Search' 
$driver->findElement(WebDriverBy::className('yellow-submit'))->click();

// Wait until Ajax part loaded
$driver->wait(40)->until(
 WebDriverExpectedCondition::presenceOfAllElementsLocatedBy(
 WebDriverBy::className('actions-container')
));

// Print HTML of the 1st page
$first = $driver->getPageSource();
print_r($first);

// go to 2nd page
$driver->findElement(WebDriverBy::id('next'))->click();

// Wait until the 2nd page is loaded
$driver->wait(40)->until(
 WebDriverExpectedCondition::presenceOfAllElementsLocatedBy(
 WebDriverBy::className('actions-container')
));

// Print HTML of the 2nd page
$second = $driver->getPageSource();
print_r($second);

// go to 3rd page
$driver->findElement(WebDriverBy::id('next'))->click();

// Wait until the 3rd page is loaded
$driver->wait(40)->until(
 WebDriverExpectedCondition::presenceOfAllElementsLocatedBy(
 WebDriverBy::className('actions-container')
));

// Print HTML of the 3rd page
$second = $driver->getPageSource();
print_r($third);

$driver->quit();
CBroe
  • 91,630
  • 14
  • 92
  • 150
tcode
  • 39
  • 1
  • 4
  • 1
    Are you sure that wait actually works? If I was you, I would better wait till some contents of first page to become stale to be sure they were unloaded – Furious Duck Feb 28 '15 at 01:24
  • You mean I have to wait longer to getPageSource() for $second? I'm on the 2nd page (physically seeing - so I just assumed that 2nd page is loaded already) on my browser when I print_r($second); Am I wrong? – tcode Feb 28 '15 at 01:32
  • no, adding longer time to wait does not solve this, because your wait is over when the expected condition is satisfied. What I'm trying to say is that you should wait until contents of the first table are unloaded and after that wait for the new one to load – Furious Duck Mar 01 '15 at 12:23
  • Thank you very much for your response to my question! I appreciate your time and effort in responding. By any chance, could you suggest any links to examples? – tcode Mar 02 '15 at 03:39
  • `satlenessOf` condition is [here](https://github.com/facebook/php-webdriver/blob/master/lib/WebDriverExpectedCondition.php#L290). It returns true when element is no longer attached to DOM. So, you can try waiting until some table element is unloaded and after that - until the new one is loaded – Furious Duck Mar 02 '15 at 09:03
  • Did you guys find the solution of the issue? – Anil Chandna Mar 05 '15 at 12:16
  • I'm not sure how to properly rewrite the wait() function. so I added 10 second sleep command just before the $second then it works. – tcode Mar 06 '15 at 07:14

2 Answers2

0

"...If the page has been modified after loading (for example, by Javascript) there is no guarantee that the returned text is that of the modified page..." (getPageSource part)

Eventually it means that selenium does not necessarily hold the latest source! at a given time.

For your result: Looping is good, try to sleep for a short break in between searches for the element. it will save the tests unneeded sleep time but still will not break,

Avishay
  • 305
  • 1
  • 11
0

in JQuery, there is a flag such that JQuery.active = 0 once all Ajax has finished. Whether this is true in non-JQuery AJAX I don't know.

The following code I stole from someone on here and I can't for the life of me remember where, but it's handy (in the context of JQuery + Selenium2 + PHPUnit)

public function waitForAjax()
{
    while(true)
    {
        $ajaxIsComplete = array(
            'script' => 'return jQuery.active == 0',
            'args' => array()
        );
        $ajaxIsComplete = $this->execute($ajaxIsComplete);
        if ($ajaxIsComplete) {
            break;
        }
        sleep(1);
    }
}

rather than just sticking "sleep(n)" on everything where n is an arbitrary number, after all it's nice not to HAVE to wait that long every time...

Simon Brown
  • 127
  • 1
  • 6
  • "Whether this is true in non-JQuery AJAX I don't know." It is not true for any AJAX that is not initiated through jQuery. – Louis May 21 '15 at 16:36
  • added sleep(1) to put a 1 second pause in there. Otherwise it could hog server resources / write massive log files unnecessarily. – Simon Brown Jun 03 '15 at 12:21
  • "The following code I stole from someone on here and I can't for the life of me remember where" Let's solve a 6 year old mystery: https://stackoverflow.com/a/30069368/4306828 Found using following google search; site:stackoverflow.com "$ajaxIsComplete = array(" Where "site:site.com" limits the search to the given site, and double quotes on the following term makes an EXACT search. Only results matching exactly the characters between the quotes are returned. For this particular search, there are only two results, yours, and an answer 15 days before yours ) Hope this helps haha – Umur Karagöz Nov 04 '21 at 14:57