Php-webdriver: дождитесь ответа браузера после отправки формы, используя click()

Помимо использования sleep() в моем тесте, мне интересно, знает ли кто-нибудь о лучшей стратегии, чтобы явно ждать завершения формы (POST), прежде чем продолжить мои утверждения. Здесь очень сжатая версия того, что мой тест выглядит, используя phpunit вместе php-webdriver от 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();
}

Ответ 1

php-webdriver из Facebook был переписан в июне 2013 года. Вы можете дождаться, когда URL-адрес будет легко подобен.

// 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';
})

Ответ 2

Хорошо, поэтому я знаю, что это очень старый вопрос, но когда я наткнулся на него через Google, я надеюсь, что это может быть полезно кому-то (возможно, даже OP?: -)).

После довольно некоторых статей по поиску и чтению в Google Code я нашел решение, которое, я думаю, довольно уродливое, но на самом деле нет хорошей альтернативы. Вы можете прочитать здесь, что WebDriver невозможно обнаружить при загрузке страницы. Итак, мы должны вернуться к ожиданию. Теперь OP использует Facebook PHP WebDriver, который не включает ожидающие утилиты AFAIK, но при использовании этого поддерживаемого клона вы получаете реализацию WebDriverWait.

Теперь вопрос: чего мы ждем? Вы можете дождаться изменения URL-адреса, но это никоим образом не является надежным подходом, поскольку страница, вероятно, еще не загружена, когда URL уже изменился. Следующая опция: дождитесь, пока элемент, который вы знаете, находится на загружаемой странице. Это будет работать, но что, если вы хотите иметь более общий подход? К счастью, я прочитал очень хорошую идею в потоке, о котором я упоминал выше. Вы можете дождаться исчезновения элемента, который находится на обеих страницах, и повторного появления, например нижнего колонтитула.

Я реализовал это сейчас и, похоже, работает. Функция ниже может быть передана $session и будет возвращаться только при загрузке новой страницы (или, по крайней мере, нижний колонтитул доступен снова).

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")));
            }
        );
}

Очевидно, вы можете изменить селектор или использовать какой-либо другой элемент, идея остается той же.

Надеюсь, это поможет! Ура!

Ответ 3

Вы можете использовать Implicit Wait and Explicit Wait для ожидания определенного веб-элемента, пока он не появится на странице. Период ожидания, который вы можете определить, и который зависит от приложения.

Явная Подождите:

Явным ожиданиям является код, который вы определяете, чтобы дождаться определенного условия, прежде чем продолжить код. Если достигнутое условие завершится, подождите и продолжите дальнейшие шаги.

код:

 WebDriverWait wait = new WebDriverWait(driver,30);
 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(strEdit)));

Или

 WebElement myDynamicElement = (new WebDriverWait(driver, 30))
 .until(new ExpectedCondition<WebElement>(){
@Override
public WebElement apply(WebDriver d) {
    return d.findElement(By.id("myDynamicElement"));
}});

Это ожидание до 30 секунд, прежде чем бросать исключение TimeoutException или если он найдет элемент, он вернет его через 0-30 секунд. WebDriverWait по умолчанию вызывает ExpectedCondition каждые 500 миллисекунд, пока он не вернется успешно. Успешный возврат для типа ExpectedCondition - это Boolean return true или not null возвращаемое значение для всех других типов ExpectedCondition.

Вы можете использовать класс ExpectedConditions так, как вам нужно для приложения.

Неявный Ожидание:

Неявным ожиданием является указание WebDriver опросить DOM в течение определенного времени при попытке найти элемент или элементы, если они не доступны сразу

код:

 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Одна вещь, о которой следует помнить, заключается в том, что после установки неявного ожидания - это останется для жизни экземпляра объекта WebDriver

Для получения дополнительной информации используйте эту ссылку http://seleniumhq.org/docs/04_webdriver_advanced.jsp

Ответ 4

Вместо click() следует использовать clickAndWait(), чтобы дождаться загрузки следующей страницы.