Друкарня від WE.UA

Implicit wait або неявне очікування та пошук елементів findElement

Даний матеріал вперше було опубліковано на сайті automation-qa.in.ua, втім з певних причин я вирішив не продовжувати його підтримку.

Implicit wait або неявне очікування є, мабуть, найпростішим типом очікування в Selenium Webdriver й однією з його властивостей є те, що період очікування встановлюється один раз для всіх наступних викликів й буде діяти допоки його не змінять або до завершення сесії. За замовчуванням його значення дорівнює нулю, тобто можна вважати, що таке очікування вимкнене, а щоб його змінити можна використати такий код мовою Java (приклади для інших мов, що підтримуються у Selenium WebDriver):

//Встановлення неявного очікування 5 секунд
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

В інших статтях також можна зустріти такий код, однак він вже буде застарілим і його використання у нових проектах є небажаним:

//Застарілий варіант
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Також варто додати, що використовуючи об’єкт timeouts очікування можна встановити не тільки для пошуку якогось елементу на сторнці ( findElement() ), а ще для часу очікування завантаження сторінки( pageLoadTimeout() ), та виконання асинхронного коду( scriptTimeout() ).

//Встановлює неявне очікування в 5 секунд для виконання асинхронного скрипта
driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(5)); 

//Встановлює неявне очікування в 5 секунд для завантаження сторінки
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(5));

А втім, в рамках цієї статті буде розглянуто тільки неявне очікування, тобто impliicitlyWait та його роботу разом з методами findElement та findElements, оскільки розглядати їх окремо одне від одного буде некоректно, зважаючи на те, що неявне очікування впливає на максимальну тривалість пошуку елементу чи елементів.

Згідно з https://w3c.github.io/webdriver/#element-retrieval час завершення пошуку елемента для findElement та findElements буде тоді, коли настане час виклику команди плюс час неявного очікування, тобто якщо умовний пошук елементу почнеться о 00:00:00 і неявне очікування матиме значення 10 секунд, то після 00:00:10 буде вкинуте NoSuchElementException, якщо елемент не знайдеться до цього.

Загалом, неявне очікування повідомляє веб-драйверу, що він має почекати певну кількість часу, перед тим як повернути NoSuchElementException, якщо такого елементу незнайдеться в період очікування. Тепер, коли розібралися із неявним очікування, можна перейти до самого пошуку елементів з його використанням. Розглянемо це на прикладі сторінки, яка симулює сторінку із контентом, який може завантажуватися із затримками або динамічно.

Приклад сторінки

Ця сторінка має такі елементи:

  • Заголовок, який завантажується із сторінкою

  • Один параграф, який завантажується також із сторінкою

  • Кнопку “ClickMe”, яка завантажується із сторінкою та при натисканні додасть ще один параграф через випадкову кількість часу в проміжку від 0 до 5 секунд

  • Один параграф, який додасться через 5 секунд після завантаження сторінки

  • Один параграф, який додасться через 11 секунд після завантаження сторінки

Отже, до перших трьох елементів можна отримати доступ одразу, без використання будь-яких очікувань, оскільки вони завантажаться разом із сторінкою та на момент їхнього пошуку будуть присутні в DOM-дереві.

Початкове DOM-дерево

А після того, як буде натиснути кнопка і пройде 11 секунд з моменту завантаження сторінки вона й DOM-дерево будуть мати такий вигляд:

DOM-дерево після появи всіх елементів через 11 секунд

Можна помітити, що в кінці додалося три раніше згаданих елементи і для того, щоб до них отримати доступ, потрібно використати очікування, оскільки вони додаються на сторінку із затримкою.

Допустимо, що є завдання вивести в консоль текст кожного елементу після того, як всі елемети будуть завантажені на сторінці. Тому для початку спробуємо застосувати такий код:

WebElement h1 = driver.findElement(By.tagName("h1"));
System.out.println("Header text: " + h1.getText()); //Header text: Implicit Wait Example

WebElement firstParagraph = driver.findElement(By.tagName("p"));
System.out.println("First paragraph text: " + firstParagraph.getText()); //First paragraph text: This loads with page

WebElement clickMe = driver.findElement(By.id("addNewContent"));
System.out.println("Button text: " + clickMe.getText()); //Button text: ClickMe

WebElement secondParagraph = driver.findElement(By.id("postponedForFiveSeconds"));//NoSuchElementException
System.out.println("Second paragraph text: " + secondParagraph.getText());

WebElement thirdParagraph = driver.findElement(By.id("postponedForElevenSeconds"));
System.out.println("Forth paragraph text: " + thirdParagraph.getText());

WebElement fourthParagraph = driver.findElement(By.id("dynamicElement"));
System.out.println("Fourth paragraph text: " + fourthParagraph.getText());

Очікувано, що на 10 рядку виконання перерветься через NoSuchElementException, оскільки в цьому місці є намагання отримати елемент, якого ще немає в DOM-дереві. Тому перед тим, як спробувати отримати доступ до цього елементу, потрібно встановити очікування, а точніше неявне очікування протягом 5 секунд.

WebElement h1 = driver.findElement(By.tagName("h1"));
System.out.println("Header text: " + h1.getText()); //Header text: Implicit Wait Example

WebElement firstParagraph = driver.findElement(By.tagName("p"));
System.out.println("First paragraph text: " + firstParagraph.getText()); //First paragraph text: This loads with page

WebElement clickMe = driver.findElement(By.id("addNewContent"));
System.out.println("Button text: " + clickMe.getText()); //Button text: ClickMe

//
// Додано неявне очікування 5 секунд перед пошуком елементу
//
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

WebElement secondParagraph = driver.findElement(By.id("postponedForFiveSeconds"));//Second paragraph text: Loaded after 5 seconds.
System.out.println("Second paragraph text: " + secondParagraph.getText());

WebElement thirdParagraph = driver.findElement(By.id("postponedForElevenSeconds"));//NoSuchElementException
System.out.println("Third paragraph text: " + thirdParagraph.getText());

clickMe.click();
WebElement fourthParagraph = driver.findElement(By.id("dynamicElement"));
System.out.println("Fourth paragraph text: " + fourthParagraph.getText());

Що ж, якщо з другим параграфом все зрозуміло і помилка виправлена, то з третім все трішки складніше, оскільки він завантажиться тільки після 11 секунди, а очікування зараз дорівнює 5 секунд, тому знову потрібно маніпулювати часом очікування, тобто збільшити його до 11 секунд. Зважаючи на те, що останній параграф завантажиться через 5 секунд після натискання на кнопку, то потім його знову потрібно буде зменшити до 5, оскільки елемент має завантажитися через 5 секунд і не пізніше. Тому фінальний варіант коду буде мати такий вигляд:

WebElement h1 = driver.findElement(By.tagName("h1"));
System.out.println("Header text: " + h1.getText()); //Header text: Implicit Wait Example

WebElement firstParagraph = driver.findElement(By.tagName("p"));
System.out.println("First paragraph text: " + firstParagraph.getText()); //First paragraph text: This loads with page

WebElement clickMe = driver.findElement(By.id("addNewContent"));
System.out.println("Button text: " + clickMe.getText()); //Button text: ClickMe

// Встановлено неявне очікування 5 секунд перед пошуком елементу
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

WebElement secondParagraph = driver.findElement(By.id("postponedForFiveSeconds"));
System.out.println("Second paragraph text: " + secondParagraph.getText());//Second paragraph text: Loaded after 5 seconds.


// Встановлено неявне очікування 11 секунд перед пошуком елементу
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(11));

WebElement thirdParagraph = driver.findElement(By.id("postponedForElevenSeconds"));
System.out.println("Third paragraph text: " + thirdParagraph.getText());//Third paragraph text: Loaded after 11 seconds.

clickMe.click();


// Встаглвлено неявне очікування 5 секунд перед пошуком елементу
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

WebElement fourthParagraph = driver.findElement(By.id("dynamicElement"));
System.out.println("Fourth paragraph text: " + fourthParagraph.getText());//Fourth paragraph text: Created at: 3:30:01 AM

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(0));//Вимикає неявні очікування

Також варто додати те, що методи findElement та findElements очікують на появу елемента в DOM-дереві, не зважаючи на інші його властивості, а неявне очікування не варто поєднувати з іншими типами очікуваннь, оскільки це може викликати небажані наслідки та неявно збільшити інтервал в інших типах очікувань(fluent та explicit).

Підсумовуючи написане можна виокремити наступне про неявне очікування:

  • Вимкнуте за замовчуванням

  • Встановлюється один раз та діє протягом всієї сесії або до його зміни

  • Може впливати на інші типи очікувань, тому їхнє поєднання — не рекомендоване

  • findElement та findElements лише шукають елемент в DOM-дереві ігноруючи його властивості

В наступних постах розгляну fluent wait та explicit wait і різницю між ними.

Статті про вітчизняний бізнес та цікавих людей:

  • Вітаємо з Різдвом Христовим!

    Друкарня та платформа WE.UA вітають всіх наших читачів та авторів зі світлим святом Різдва! Зичимо всім українцям довгожданого миру, міцного здоровʼя, злагоди, родинного затишку та втілення всього доброго і прекрасного, чого вам побажали колядники!

    Теми цього довгочиту:

    Різдво
  • Каблучки – прикраси, які варто купувати

    Ювелірні вироби – це не тільки спосіб витратити гроші, але і зробити вигідні інвестиції. Бо вартість ювелірних виробів з кожним роком тільки зростає. Тому купуючи стильні прикраси, ви вигідно вкладаєте кошти.

    Теми цього довгочиту:

    Як Вибрати Каблучку
  • П'ять помилок у виборі домашнього текстилю, які псують комфорт сну

    Навіть ідеальний матрац не компенсує дискомфорт, якщо текстиль підібрано неправильно. Постільна білизна безпосередньо впливає на терморегуляцію, стан шкіри та глибину сну. Більшість проблем виникає не через низьку якість виробів, а через вибір матеріалів та подальшу експлуатацію

    Теми цього довгочиту:

    Домашній Текстиль
  • Як знайти житло в Києві

    Переїжджаєте до Києва і шукаєте житло? Дізнайтеся, як орендувати чи купити квартиру, перевірити власника та знайти варіанти, про які зазвичай не говорять.

    Теми цього довгочиту:

    Агентство Нерухомості
  • Як заохотити дитину до читання?

    Як залучити до читання сучасну молодь - поради та факти. Користь читання для дітей - основні переваги. Розвиток дітей - це наше майбутнє.

    Теми цього довгочиту:

    Читання
Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Василь Побережник
Василь Побережник@VasylPoberezhnyk

AQA | Фотограф-ентузіаст

695Прочитань
0Автори
4Читачі
Підтримати
На Друкарні з 29 серпня

Більше від автора

  • Holga 120 або шматок пластику, який може знімати

    Колись давно я пообіцяв написати про Holga 120, тож намагаюся дотримати свою обіцянку і пишу писанину про відому, а може і не дуже камеру або шматок пластику.

    Теми цього довгочиту:

    Фотографія
  • Explicit wait: явне очікування або fluent wait швидкого приготування

    Що ж, в попередніх постах було описано imlicit wait(неявне очікування) та fluent wait(впевнене очікування, хоча такий переклад — це радше відсебеньки), а це означає, що настав час для останнього з трьох — явного очікування.

    Теми цього довгочиту:

    Qa
  • Fluent wait або впевнене очікування та як його їсти

    Цього разу буду розглядату впевнене очікування, хоча його називають ще інколи плаваючим, вільним або ще якось, втім називати в рамках цієї статті буду його впевненим.

    Теми цього довгочиту:

    It

Це також може зацікавити:

  • Чому __name__ == "__main__"?

    "name == "main"" - ключова фраза в Python. Визначає, чи є файл головним скриптом чи модулем. Це допомагає створювати зручні модулі, уникати ненавмисного виконання при імпорті та оптимізувати продуктивність.

    Теми цього довгочиту:

    Python
  • Як почати вивчення програмування

    Ця стаття надає огляд найважливіших ресурсів та порад для тих, хто починає вивчати програмування. Стаття підкреслює, що вивчення програмування - це довгий процес, який вимагає терпіння та послідовності.

    Теми цього довгочиту:

    Програмування
  • Що означають розміри файлів та папок у Windows?

    Коли ми переглядаємо властивості файлів та папок у Windows, часто помічаємо два значення: “Розмір” і “Розмір на диску”. Багато користувачів не задумуються над тим, чому ці числа відрізняються і що насправді означає кожне з них.

    Теми цього довгочиту:

    Ос Windows

Коментарі (2)

Досі дивуюся з того що хтось використовує застралій selenium(

Це також може зацікавити:

  • Чому __name__ == "__main__"?

    "name == "main"" - ключова фраза в Python. Визначає, чи є файл головним скриптом чи модулем. Це допомагає створювати зручні модулі, уникати ненавмисного виконання при імпорті та оптимізувати продуктивність.

    Теми цього довгочиту:

    Python
  • Як почати вивчення програмування

    Ця стаття надає огляд найважливіших ресурсів та порад для тих, хто починає вивчати програмування. Стаття підкреслює, що вивчення програмування - це довгий процес, який вимагає терпіння та послідовності.

    Теми цього довгочиту:

    Програмування
  • Що означають розміри файлів та папок у Windows?

    Коли ми переглядаємо властивості файлів та папок у Windows, часто помічаємо два значення: “Розмір” і “Розмір на диску”. Багато користувачів не задумуються над тим, чому ці числа відрізняються і що насправді означає кожне з них.

    Теми цього довгочиту:

    Ос Windows