php-webdriver: wait for browser response after submitting form using click()

16,155

Solution 1

php-webdriver from Facebook has been rewritten in June 2013. You can wait for the URL easily like this.

// wait for at most 10 seconds until the URL is 'http://example.com/account'.
// check again 500ms after the previous attempt.
$driver->wait(10, 500)->until(function ($driver) {
  return $driver->getCurrentURL() === 'http://example.com/account';
})

Solution 2

Okay, so I know this is a very old question, but as I stumbled upon it through Google I hope that this can still be useful for someone (maybe even the OP? :-)).

After quite some searching and reading articles and messages on Google Code, I found a solution that I think is quite ugly, but there is not really a good alternative. You can read here that it is impossible for WebDriver to detect when the page has loaded. So, we have to revert to waiting. Now, the OP is using Facebook's PHP WebDriver, which does not include waiting utilities AFAIK, but when using this maintained clone, you get an implementation of WebDriverWait.

Now the question is: what do we wait for? You could wait for the URL to change, but this is in no way a reliable approach as the page probably is not loaded yet when the URL has changed already. Next option: wait for an element you know is on the page to be loaded to appear. That'll work, but what if you want to have a more generic approach? Luckily, I read a very good idea in the thread I mentioned above. You can wait for an element that is on both pages to disappear and the reappear, for example the footer.

I implemented this just now and it seems to work. Below function can be passed your $session and will only return when the new page is loaded (or at least, the footer is available again).

public static function waitForNextPage($pWDSession) {
    $aWait = new PHPWebDriver_WebDriverWait($pWDSession);
    // wait for footer to not be available anymore
    $aWait->until(
            function($pWDSession) {
                return (0 === count($pWDSession->elements(PHPWebDriver_WebDriverBy::CSS_SELECTOR, "#footer,#mx-footer")));
            }
        );
    // wait for footer to be available again
    $aWait->until(
            function($pWDSession) {
                return (0 < count($pWDSession->elements(PHPWebDriver_WebDriverBy::CSS_SELECTOR, "#footer,#mx-footer")));
            }
        );
}

You can obviously change the selector or use some other element, the idea remains the same.

I hope it helps! Cheers!

Share:
16,155
Justin Watt
Author by

Justin Watt

Updated on June 24, 2022

Comments

  • Justin Watt
    Justin Watt almost 2 years

    Aside from using sleep() in my test, I'm wondering if anyone knows of a better strategy to explicitly wait for a form submission (POST) to complete before continuing with my assertions. Here's a very condensed version of what my test looks like, using phpunit together php-webdriver from Facebook).

    function test_form_submission()
    {   
        // setup
        $web_driver = new WebDriver();
        $session = $web_driver->session();
        $session->open('http://example.com/login');
    
        // enter data
        $session->element('css selector', 'input[name=email]')->value(array('value' => str_split('[email protected]')));
        $session->element('css selector', 'input[name=password]')->value(array('value' => str_split('testpassword')));
    
        // click button to submit form
        $session->element('css selector', 'button[name=submit]')->click();
    
        // How do I wait here until the click() above submits the form
        // so I can check that we correctly arrives at the destination below
        // without resorting to sleep()?
    
        // Confirm that login was successful because we landed on account page
        $this->assertSame('http://example.com/account', $session->url());
    
        // teardown
        $session->close();
    }
    
  • Justin Watt
    Justin Watt over 11 years
    I was specifically asking for a PHP solution that uses php-webdriver.
  • Justin Watt
    Justin Watt over 11 years
    I'm not sure that works with php-webdriver. I get the following error: "Exception: clickAndWait is not a valid webdriver command."
  • Purefan
    Purefan about 10 years
    What if the url is dynamically created? for example: site.com/item?id=123&color=black&size=small
  • whhone
    whhone about 10 years
    Match the URL by regular expression.