Как правильно настроить неявное / явное ожидание и pageLoadTimeout через Selenium?
В настоящее время у меня есть следующая настройка, но я не уверен, что мои ожидания (Implicit и pageLoadTimeout) работают. Это правильная реализация? Помещая его в @Before("@setup"), он работает для каждого запуска сценария или определения шага? Будет ли водитель ждать соответственно, каждый раз, когда я вызываю @Given, @When..etc?
@Before("@setup")
public void setUp() {
driver.manage().deleteAllCookies();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
}
Почему необходимо назначить WebElement для следующего ожидания, что получает элемент WebElement? Это правильная реализация? -
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
boolean status = element.isDisplayed();
3 ответа
implicitlyWait()
implicitlyWait()
должен сказать экземпляру WebDriver, то есть драйверу, опрашивать HTML DOM в течение определенного времени при попытке найти элемент или элементы, если они не доступны сразу. Конфигурация ожидания по умолчанию установлена в 0. После установки неявное ожидание устанавливается на весь срок службы экземпляра объекта WebDriver.
Ваша пробная версия кода просто идеальна, как в:
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
Здесь вы найдете подробное обсуждение в разделе Использование неявного ожидания в селене.
pageLoadTimeout()
pageLoadTimeout()
устанавливает интервал ожидания для завершения загрузки страницы, прежде чем выдать ошибку.
Ваша пробная версия кода просто идеальна, как в:
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
Здесь вы можете найти подробное обсуждение в pageLoadTimeout в Selenium не работает
Примечание. Старайтесь избегать настройки
pageLoadTimeout()
до тех пор, пока в Спецификации теста не будет явно указано то же самое.
Почему WebDriverWait?
Современные браузеры используют JavaScript, AJAX и React Native, где элементы внутри веб-страницы загружаются динамически. Таким образом, дождаться выполнения определенного условия, прежде чем переходить к следующей строке кода Explicit Waits, т.е. WebDriverWait - это путь для продвижения вперед.
Примечание. Согласно официальной документации явных и неявных ожиданий, не смешивайте неявные и явные ожидания. Это может привести к непредсказуемому времени ожидания.
Ваша пробная версия кода идеально подходит для ожидания видимости элемента, как в:
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
Здесь вы можете найти подробное обсуждение замены неявного ожидания явным ожиданием (selenium webdriver & java)
Ваши конкретные вопросы
Почему необходимо присвоить WebElement следующему ожиданию: WebDriverWait в сочетании с ExpectedConditions не только возвращает WebElement, но в зависимости от ExpectedConditions может также возвращать void, Boolean, List.
Что получает элемент WebElement?: Согласно вашему блоку кода, где вы использовали ExpectedConditions как
visibilityOfElementLocated()
, WebElement будет возвращен, как только элемент появится в дереве DOM веб-страницы и станет видимым. Видимость означает, что элементы не только отображаются, но также имеют высоту и ширину, превышающие 0.Это правильная реализация?: Ваша реализация была почти идеальной, но последняя строка кода, т.е.
boolean status = element.isDisplayed();
избыточен какvisibilityOfElementLocated()
возвращает элемент, как только элемент виден (то есть элементы не только отображаются, но также имеют высоту и ширину, которые больше 0).
Если вы только начали использовать селен, это законный вопрос. Я всегда предлагаю взглянуть на официальный документ.
Неявное ожидание - указать WebDriver опросить DOM в течение определенного времени при попытке найти элемент или элементы, если они не доступны сразу. Значение по умолчанию равно 0. После установки устанавливается неявное ожидание в течение срока службы экземпляра объекта WebDriver.
Пример:
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
В этом случае, если веб-элемент с идентификатором myDynamicElement отсутствует в DOM, когда вы пытаетесь найти его, вы говорите, что повторите попытку до 10 секунд. Время опроса зависит от используемого вами веб-драйвера. Вы должны знать, что он попытается найти элемент за 10 секунд. Конечно, если элемент находится до конца этого времени, код будет продолжаться. В противном случае выдается исключение.
Явное ожидание - это код, который вы определили для ожидания определенного условия, прежде чем продолжить работу в коде. В худшем случае это Thread.sleep(), который устанавливает условие для точного периода ожидания. Существует несколько удобных методов, которые помогут вам написать код, который будет ждать столько времени, сколько потребуется. WebDriverWait в сочетании с ExpectedCondition - это один из способов достижения этой цели.
Пример:
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
Это ожидает до 10 секунд, прежде чем выдать TimeoutException или если он обнаружит, что элемент вернет его через 0 - 10 секунд. По умолчанию WebDriverWait вызывает ExpectedCondition каждые 500 миллисекунд, пока не завершится успешно. Успешное возвращаемое значение для типа функции ExpectedCondition является логическим значением true или ненулевым объектом.
И, в конце, написано: Этот пример также функционально эквивалентен первому примеру неявного ожидания.
Таким образом, если вы используете senceOfElementLocated в качестве ожидаемого условия (для каждого элемента, который вы пытаетесь найти), то точно так же, чтобы использовать неявное ожидание. Но это не только условие. Как вы можете видеть из ExpectedConditions, вы можете указать другие условия (пример: elementToBeClickable, stalenessOf и т. Д.).
Итак, возвращаясь к вашему вопросу:
С
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
Вы говорите подождать, когда вы пытаетесь найти элемент, присутствие (помните, что это похоже на senceOfElementLocated) до 30 секунд.
С
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
Вы устанавливаете на 30 секунд время загрузки веб-страницы.
С:
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
boolean status = element.isDisplayed();
Вы говорите, что хотите подождать visibilityOfElementLocated веб-элемента с id:"id" до 30 секунд.
В заключение:
Почему необходимо назначить WebElement для следующего ожидания, что получает элемент WebElement? Это правильная реализация?
Что получает элемент WebElement? что еще, если не webelement с id:"id"? Конечно, если это видно. В противном случае будет выдано исключение.
Вам нужно только дождаться загрузки страницы в вашем случае, и ваша реализация в порядке. @ Before - один из крючков огурца, и это означает, что ваш метод будет запускаться перед каждым сценарием. Я предлагаю использовать свободное ожидание вместо webdriverwait, и вот почему:
При использовании экземпляра FluentWait:
- Вы можете проверить определенные условия (видимость, невидимость...)
- Игнорируйте определенные типы ожидающих исключений, такие как NoSuchElementExceptions или StaleElementException, при поиске элемента на странице.
- Вы можете указать опрос и время ожидания для каждого условия.
Например:
// Waiting 30 seconds for an element to be present on the page, checking for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(30, SECONDS) .pollingEvery(5, SECONDS).ignoring(NoSuchElementException.class);
Надеюсь, я помог.