Объединение неявного ожидания и явного ожидания вместе приводит к неожиданным временам ожидания

Два моих сценария -

1) Первый

@driver.manage.timeouts.implicit_wait = 30
@wait = Selenium::WebDriver::Wait.new(:timeout => 45) # Time greater than implicit
@wait.until {@driver.find_element(:tag_name => "body").text.include?("hey")}

Что дает драйверу 45 секунд для поиска текста (что ожидается)

2) Второй

@driver.manage.timeouts.implicit_wait = 30
@wait = Selenium::WebDriver::Wait.new(:timeout => 5) # Time less than implicit
@wait.until {@driver.find_element(:tag_name => "body").text.include?("hey")}

Теперь это дает драйверу 30 секунд для поиска текста (не ожидается)

Есть ли способ заставить селен ждать только время ожидания explicit, а не для большего из двух?

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

Использование Selenium версии 30, windows, ff

Ответ 1

Не смешивать неявные и явные ожидания. Частью проблемы является то, что неявные ожидания часто (но не всегда могут быть!) Реализованы на стороне "remote" системы WebDriver. Это означает, что они "испечены" в IEDriverServer.exe, chromedriver.exe, расширении WebDriver Firefox, которое устанавливается в анонимный профиль Firefox и на удаленный сервер Java WebDriver (selenium-server-standalone.jar). Явные ожидания выполняются исключительно в "локальных" языковых привязках. При использовании RemoteWebDriver все сложнее, поскольку вы можете использовать как локальную, так и удаленную стороны системы несколько раз.

Вот как это работает: локальный код → удаленный сервер Java → локальные привязки языка Java на удаленном сервере → "remote", такие как расширение Firefox, chromedriver.exe или IEDriverServer.exe. Это еще сложнее в случае сетки, поскольку между ними могут быть другие переходы.

Таким образом, когда вы пытаетесь смешивать неявные и явные ожидания, вы отклоняетесь в "поведение undefined". Возможно, вы сможете выяснить, каковы правила этого поведения, но они могут быть изменены, поскольку детали реализации драйверов меняются. Так что не делайте этого.

Вы не должны испытывать "зависания", когда элемент не может быть найден, если вы не используете неявные ожидания. Драйвер должен немедленно выбросить исключение NoSuchElement.

Ответ 2

Лучшей практикой является установка implicitlyWait() в начале каждого теста и использование WebDriverWait() для ожидания элемента или элемента AJAX для загрузки.

Однако, implicitlyWait() и WebDriverWait() не работают хорошо вместе в одном тесте. Вам нужно будет аннулировать implicitlyWait() перед вызовом WebDriverWait, потому что implicitlyWait() также устанавливает время ожидания "driver.findElement()".

Всякий раз, когда вы используете WebDriverWait(), с implicitlyWait() уже задали начальное значение, выполните следующие действия:

  • аннулирование неявноWait()
  • выполнение WebDriverWait() и возвращаемого элемента
  • reset implicitlyWait() снова

Пример кода Java -

driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait() 

WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); 
element = wait.until(ExpectedConditions.visibilityOfElementLocated(by));

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