Явные ожидания selenide java

Теория большого вейта

Тема ожиданий вызывает много обсуждений и споров.
Современные веб-сайты создают проблемы для написателей автотестов. Возникает много ситуаций, в которых стандартные методы Selenium неэффективны.

Если вы читали документацию Selenide, вы уже знаете, что классические явные ожидания типа

element = (new WebDriverWait(driver, timeOutForElement>)) .until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector>))); 
element = (new WebDriverWait(driver, timeOutForElement>)) .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(cssSelector>))); 

были заменены в Selenide более коротким конструкциями типа

element = $(cssSelector>).should(exist); element = $(cssSelector>).shouldBe(visible); 

Как известно, ассерты в Selenide — это новая версия явных ожиданий, что хорошо описано в документации.

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

Современные проблемы требуют современных решений

1. Thread.sleep()

Это самое ужасное, что может случиться с нашими тестами на Selenium.

В некоторых ситуациях мы были вынуждены использовать слипы. У нас просто не было другого решения, чтобы обойти проблему и двигаться дальше. Например, слипы используют, чтобы дождаться окончания загрузки страницы. Иногда — чтобы дождаться какого-то элемента, когда другие ожидания не помогли. Увы, таким образом мы можем терять много времени при запуске теста.

Если поставить один слип — это ещё ничего. Вы потеряете, скажем, 4 секунды — не смертельно.
Но если вы используете слип в 150 тестах, время их выполнения увеличится заметно.
Нет смысла объяснять, почему это плохо.

Хотя команда sleep() есть и в Selenide, вышеупомянутые “умные ожидания” делают слипы почти ненужными для ожидания появления чего-то либо на странице.
Смотри следующие пункты.

2. Как дождаться окончания загрузки страницы?

Самый простой способ — выбрать какой-то элемент на странице, который редко меняется (скажем, заголовок), и использовать метод Selenide:

$(cssSelector).shouldBe(visible); 

Selenide сначала попытается найти элемент, а потом проверить, что он видимый.
Если это не удалось за 4 секунды, вы можете сделать вывод, что страница не загрузилась.

Ещё вы можете выбрать какой-то элемент на предыдущей странице и дождаться, пока он исчезнет:

Таким образом мы создаём двойную проверку, что мы перешли с одной страницы на другую. И это будет работать, даже если загрузка страницы занимает значительное время. Как видите, обошлись без всяких Thread.sleep() .

3. Изменение состояния элемента

Иногда нам нужно проверить, что состояние элемента поменялось в результате действий пользователя.
Например, элемент может содержать текст, сигнализирующий об успешной или неуспешной загрузке файла.
Допустим, загрузка файла занимает какое-то время, потому что файл большой, или сервер должен запустить какую-то сложную обработку этого файла.

Обычно мы в тесте загружаем файл и проверяем состояние элемента (скажем, текст “файл загружен”).
Но как узнать, когда именно состояние элемента должно поменяться? Загрузка-то происходит не мгновенно.
В этой ситуации многие используют Thread.sleep() .

А в Selenide у нас есть умный инструмент для “отложенной” проверки состояния элемента:

$(cssSelector).shouldHave(exactText(expectedText>)); 

В этом случае Selenide сам дождётся, пока состояние элемента изменится, и в нём появится нужный текст.
Нам не нужно писать лишних строк для ожиданий, и мы можем быть уверены, что Selenide точно дождётся.

Что теперь?

Мы рассмотрели всего лишь несколько простых идей, как можно “ждать” с помощью Selenide.
В реальности ситуаций намного больше. И здорово, что теперь у нас есть хороший инструмент, позволяющий нам обходится без слипов и не терять драгоценное время.
Используйте умные инструменты и не теряйте время — время ценно. 🙂

Maciej Grymuza (figrym@gmail.com)

Источник

Способы ожидания в Java и Selenium

Ожидания — не самый приятный процесс, где бы он ни происходил. Ожидания в автотестах — отдельная боль. Избавиться от них невозможно, но есть способы организовать их работу в более удобной форме, нежели Thread.sleep() .

Чтобы собрать вместе и систематизировать информацию по этой теме, рассмотрю все варианты написания ожиданий для автоматизированного тестирования UI посредством Java и Selenium, с которыми мне приходилось работать, а именно ожидания, предоставляемые Selenium, возможность написания собственных ожиданий и библиотека Awaitility.

Selenium waiting methods

Implicit Wait

Implicit Wait, или неявное ожидание, — пожалуй, самый популярный способ ожидания в Selenium благодаря своей легкости в использовании.

Чтобы использовать Implicit Wait в автотестестах, достаточно:

После того, как команда исполнится, Implicit Wait будет действовать на протяжении всего пробега автотестов и ожидать указанное время прежде, чем выбросить NoSuchElementException (или не выбрасывать, если необходимый элемент на странице найден). Не устанавливать Implicit Wait равносильно нулевому лимиту времени, и исключение пробросится сразу.

Чтобы установить Implicit Wait, необходимо написать всего одну строку после установки драйвера, и таким образом мы установим лимит ожидания 10 секунд:

Implicit Wait можно использовать для:

  • ожидания полной загрузки страницы — pageLoadTimeout() ;
  • ожидания появления элемента на странице — implicitlyWait() ;
  • ожидания выполнения асинхронного запроса — setScriptTimeout() ;

Установка использования неявного ожидания будет выглядеть следующим образом:

@BeforeMethod (alwaysRun = true) public void setUpDriver() < //Set up driver ChromeOptions options = new ChromeOptions(); WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(options); //Set implicit wait: //wait for WebElement driver.manage().timeouts().implicitlyWait(5000, TimeUnit.MILLISECONDS); //wait for loading page driver.manage().timeouts().pageLoadTimeout(10000, TimeUnit.MILLISECONDS); //wait for an asynchronous script to finish execution driver.manage().timeouts().setScriptTimeout(5000, TimeUnit.MILLISECONDS); >@Test (description = "Open url") public void openUrl() < //Open browser driver.manage().window().setSize(new Dimension(1280, 970)); //Get url driver.get("https://some_site.com"); //Search an element WebElement element = driver.findElement(By.id("some-id")); Assert.assertTrue(element.isDisplayed()); >@AfterMethod (alwaysRun = true) public void closeBrowser() < //Close browser driver.quit(); >

Explicit Wait

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

Какие инструменты и подходы использовать для тестирования фронтенда — рассказывают эксперты

О явном ожидании стоит помнить следующие вещи:

  • ожидание сработает именно там, где оно указано;
  • как и неявному ожиданию, ему необходимо указать лимит времени;
  • ожидает выполнения необходимого условия;
  • ждет завершения Ajax request.

Использовать явное ожидание можно через WebDriverWait . Инициализация будет происходить следующим образом:

WebDriverWait wait = new WebDriverWait(driver,10);

где driver является референсом к нашему используемому WebDriver , а число 10 — TimeOut в секундах.

В тесте само ожидание уже будет выглядеть примерно так:

wait.until(ExpectedConditions.invisibilityOfElementLocated (By.cssSelector("element"));

Класс ExpectedConditions предоставляет нам ряд вещей, которых мы можем дожидаться во время пробега теста. Они все достаточно легко читаемы, что облегчит жизнь как вам, так и людям, которым, возможно, придется поддерживать ваши автотесты.

Вот полный список всего, что вам предлагает подождать ExpectedConditions :

  • alertIsPresent()
  • elementSelectionStateToBe()
  • elementToBeClickable()
  • elementToBeSelected()
  • frameToBeAvaliableAndSwitchToIt()
  • invisibilityOfTheElementLocated()
  • invisibilityOfElementWithText()
  • presenceOfAllElementsLocatedBy()
  • presenceOfElementLocated()
  • textToBePresentInElement()
  • textToBePresentInElementLocated()
  • textToBePresentInElementValue()
  • titleIs()
  • titleContains()
  • visibilityOf()
  • visibilityOfAllElements()
  • visibilityOfAllElementsLocatedBy()
  • visibilityOfElementLocated()

В тесте создание и использование неявного ожидания будут выглядеть следующим образом:

private WebDriver driver; private WebDriverWait wait; private WebElement exampleElement; @BeforeMethod(alwaysRun = true) public void setUpDriver() < //Set up driver ChromeOptions options = new ChromeOptions(); WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(options); //Set explicit wait wait = new WebDriverWait(driver, 10); >@Test(description = "Open url") public void openUrl() < //Open browser driver.manage().window().setSize(new Dimension(1280, 970)); //Get url driver.get("https://some-site.com"); //Wait until blockUI disappear wait.until(ExpectedConditions.invisibilityOfElementLocated (By.cssSelector("element"))); wait.until(ExpectedConditions.invisibilityOf(exampleElement)); //Search an element WebElement element = driver.findElement(By.id("some-id")); Assert.assertTrue(element.isDisplayed()); //Click element element.click(); //Wait until alert is present wait.until(ExpectedConditions.alertIsPresent()); driver.switchTo().alert().accept(); >@AfterMethod(alwaysRun = true) public void closeBrowser() < //Close browser driver.quit(); >

Разница между Implicit и Explicit Wait

Написание собственных ожиданий

Ожидания Selenium не всегда способны удовлетворить потребности тестировщика. В таких случаях мы можем сами написать методы, которые удержат автотесты от падения. Работать кастомные ожидания будут по тому же принципу, что и Explicit Wait, т.е. срабатывать в той части теста, в которой указаны, а условие, которого необходимо дождаться, нужно написать самим как некий аналог класса ExpectedConditions . Хранить ли свои условия в отдельном классе или в том же, где и написанный способ ожидания, и нужно ли разделять метод ожидания и условие или достаточно будет оставить их прописанными в едином методе, зависит от условий проекта и предпочтений тестировщика.

Чтобы написать ожидание самим, потребуется не так много: старый добрый цикл while и System.currentTimeMillis() .

Выглядеть это может примерно таким образом:

public static void waitForInvisibilityOfElement(WebElement element) < float waitingTime = 0; //Start loading time of waiting for invisibility of element startLoadingTime = System.currentTimeMillis(); while (element.isDisplayed())< //If element is still presented, verify if the //maximum of waiting time is reached if(waitingTime else < System.out.println("Condition wasn't executed with time limit"); break; >> //If the element disappeared, log the loading time of the if(!element.isDisplayed()) < System.out.println("Condition was executed in " + waitingTime + " seconds"); >>

Условие, которое мы ждем в этом примере — element.isDisplayed() , его можно вынести в отдельный метод, возвращающий boolean , и таким образом сам метод ожидания можно прописать единожды и просто передавать туда разные условия в формате boolean .

Awaitility library

Пожалуй, лучшее, ну или, по крайней мере, мое любимое, решение проблемы ожиданий. Awaitility применима не только в автоматизации тестирования, однако я ограничусь рассмотрением ее использования на примерах тестов. Эта библиотека упростит вам жизнь при написании собственных ожиданий; все, что сказано про аналог кастомных ожиданий с Explicit Wait и ExpectedConditions , будет справедливо и здесь. То же касается и того, как вы предпочтете прописать условия, которых хотите дождаться. В рамках этой статьи рассмотрена только часть возможностей данной библиотеки. Если вам интересно почитать обо всех возможностях, можете ознакомиться с официальной документацией. Здесь я хочу обратить внимание на те моменты, которые мне показались максимально полезными, и просто поделиться тем, что есть такая замечательная штука, которая помогает стабилизировать автотесты.

Awaitility library позволит:

  • дождаться выполнения асинхронных запросов;
  • установить как максимум, так и минимум ожидаемого времени;
  • проигнорировать выпадающие исключения (в таком случае по истечению лимита времени будет выброшен ConditionTimeoutException );
  • использовать Assertion в качестве ожидаемого условия;
  • использовать polling.

Синтаксис довольно читабельный; Awaitility позволяет понять, что и куда вызывается для определения лимита времени, игнорирования исключений, где устанавливаем polling и чего ожидаем в финале нашего метода. Внутреннее написание ожидания может выглядеть так — остается только вызвать его в тесте. Хранить подобные методы стоит все же отдельно от тестов.

public static void waitVisibleElement(WebElement we)

Отдельным примером хочу показать ожидание Assertion, именно этот метод кажется мне особенно удобным, так как убивает сразу двух зайцев и позволяет не прописывать лишних строк кода:

/** * Wait until two lists became equal * @param actualValues - actual values * @param requiredValues - expected values */ public static void waitOfAssertionForLists(List actualValues, List requiredValues) < given().ignoreExceptions().await().atMost(10, TimeUnit.SECONDS) .untilAsserted(() ->Assert.assertEquals (getValuesFromDropDown(actualValues), requiredValues)); > //Get text values from list of WebElements private static List getValuesFromDropDown(List wes)< List actualValuesInDropDown = new ArrayList<>(); for (WebElement we : wes) < if(we.isDisplayed() && we.getText().trim().length() >0) < actualValuesInDropDown.add(we.getText().trim()); >> return actualValuesInDropDown; >

Это та информация, которой я хотела поделиться об ожиданиях.

Более подробно вы можете ознакомиться с Awaitility по ссылке.

Источник

Читайте также:  Del в питоне словарь
Оцените статью