Як обробляти виклики AJAX Selenium Веб-драйвер

⚡ Розумний підсумок

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

  • 🔘 Визначення: AJAX асинхронно отримує невеликі обсяги даних та оновлює лише частину сторінки.
  • ☑️ Основна проблема: Час відповіді сервера невідомий, тому елемент може не існувати, коли WebDriver його перевіряє.
  • ✅ Варіанти очікування: Thread.sleep, неявне очікування, явне очікування, WebDriverWait та FluentWait поводяться по-різному.
  • 🧪 Рекомендується: WebDriverWait з ExpectedCondition опитує, доки не з'явиться результат AJAX, а потім негайно продовжує роботу.
  • 🛠️ FluentWait: Він додає інтервал опитування та може ігнорувати вибрані винятки між спробами.
  • ⚠️ Selenium 4: Тайм-аути тепер вимірюють тривалість, і Selenium Менеджер видаляє шлях до ручного драйвера.

Як обробляти AJAX-виклики в Selenium веб-драйвер

Що таке AJAX?

AJAX означає асинхронний JavaСкрипт та XML, що дозволяє веб-сторінці отримувати невеликі обсяги даних із сервера без перезавантаження всієї сторінки.

AJAX — це техніка для створення швидких, динамічних веб-сторінок. Вона є асинхронною, поєднує JavaScript з форматом даних та оновлює частини сторінки, а не всю сторінку. Gmail, Google Карти, Facebook та YouTube всі ним користуються.

Як працює AJAX?

Наприклад, коли ви натискаєте кнопку «Надіслати», JavaСкрипт надсилає запит на сервер, інтерпретує результат та оновлює поточний екран без перезавантаження. Діаграма нижче показує цей обмін.

Схема виклику AJAX між браузером та сервером без повного перезавантаження сторінки

  • AJAX-виклик – це асинхронний запит від браузера, який не призводить до переходу між сторінками. Користувач може продовжувати працювати над програмою, поки запит очікує відповіді.
  • AJAX надсилає HTTP-запити на сервер та обробляє відповідь без перезавантаження сторінки, тому ви не можете передбачити, скільки часу знадобиться серверу для відповіді.

З точки зору тестувальника, перевірка контенту або елемента означає очікування відповіді. Корисне навантаження спочатку було XML, як випливає з назви; більшість API зараз повертають JSON.

Як обробляти виклики AJAX Selenium веб-драйвер

Найбільшою проблемою обробки викликів AJAX є знання часу завантаження. Оскільки оновлення триває частки секунди, програму важко протестувати за допомогою інструменту автоматизації, тому Selenium WebDriver повинен застосувати метод очікування до виклику.

Виконання цієї команди очікування призупиняє поточну Тестовий випадок до появи очікуваного або нового значення; Selenium Потім WebDriver відновлює призупинені кроки.

Нижче наведено методи очікування Selenium WebDriver може використовувати

Thread.sleep ()

  • Thread.sleep() – не найкращий вибір, оскільки він призупиняє поточний потік на заданий час.
  • В AJAX ніколи не можна бути впевненим у точному часі очікування, тому тест завершується невдачею, якщо елемент не з'являється в ньому. Це також додає накладних витрат, оскільки Thread.sleep(t) переміщує поточний потік з черги виконання до черги очікування.
  • Після часу 't' потік переходить до черги готовності, а потім знову чекає на виконання процесором.

Примітка: Java метод є Thread.sleep () у нижньому регістрі; форма з великої літери не компілюється.

Неявне очікування ()

  • Цей метод повідомляє WebDriver про необхідність очікування, коли елемент недоступний негайно, і це налаштування залишається чинним протягом усього сеансу браузера. Таким чином, кожен пошук елемента може тривати стільки, скільки дозволяє неявне очікування.

Явне очікування ()

  • Явне очікування використовується для заморожування виконання тесту до моменту виконання певної умови або закінчення максимального часу.

WebDriverWait

  • Його можна використовувати для будь-якої умови, поєднуючи WebDriverWait з ExpectedCondition.
  • Найкращий підхід — перевіряти умову щосекунди та переходити до наступної команди, щойно вона виконана.

Але проблема з усіма цими очікуваннями полягає в тому, що ви повинні згадати одиницю тайм-ауту. Що робити, якщо елемент все ще відсутній протягом певного часу? Отже, є ще одне очікування під назвою Fluent wait.

Вільно зачекайте

  • Це реалізація інтерфейсу Wait з власним тайм-аутом та інтервалом опитування. Кожен екземпляр FluentWait встановлює максимальний час очікування умови та частоту її перевірки.

Проблеми обробки викликів AJAX Selenium веб-драйвер

  • Використання команди «пауза» не є надійним. Тривала пауза робить тест неприйнятно повільним і збільшує Тестування час, тому для AJAX-застосунків рекомендувалося використовувати «waitforcondition».
  • Важко оцінити ризик, пов'язаний з певними AJAX-додатками
  • Надання розробникам повної свободи змінювати AJAX-додаток ускладнює процес тестування.
  • Створення автоматизованого тестового запиту може бути складним для інструментів тестування, оскільки AJAX-додатки часто використовують різні методи кодування або серіалізації для надсилання POST-даних.

Примітка: «пауза» та «очікування умови» є Селенська команди видалені в Selenium 3; еквівалентом WebDriver є явне очікування.

Code Приклад обробки AJAX за допомогою Selenium веб-драйвер

Команда TestNG Клас нижче зчитує текст, натискає радіокнопку, очікує на відповідь AJAX та стверджує, що текст змінився.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class Ajaxdemo {
	
	private String URL = "https://demo.guru99.com/test/ajax.html";
	
	WebDriver driver;
	WebDriverWait wait;
	
	@BeforeClass
	public void setUp() {
		System.setProperty("webdriver.chrome.driver",".\\chromedriver.exe");
		//create chrome instance
		driver = new ChromeDriver();
		driver.manage().window().maximize();
		driver.navigate().to(URL);
	}
	
	@Test
	public void test_AjaxExample() {

		By container = By.cssSelector(".container");
		wait = new WebDriverWait(driver, 5);
		wait.until(ExpectedConditions.presenceOfElementLocated(container));
		
		//Get the text before performing an ajax call
		WebElement noTextElement = driver.findElement(By.className("radiobutton"));
		String textBefore = noTextElement.getText().trim();
		
		//Click on the radio button
		driver.findElement(By.id("yes")).click();
	
		//Click on Check Button
		driver.findElement(By.id("buttoncheck")).click();
		
		/*Get the text after ajax call*/
		WebElement TextElement = driver.findElement(By.className("radiobutton"));
		wait.until(ExpectedConditions.visibilityOf(TextElement));
		String textAfter = TextElement.getText().trim();
		
		/*Verify both texts before ajax call and after ajax call text.*/
		Assert.assertNotEquals(textBefore, textAfter);
		System.out.println("Ajax Call Performed");
		
		String expectedText = "Radio button is checked and it's value is Yes";
		
		/*Verify expected text with text updated after ajax call*/
		Assert.assertEquals(textAfter, expectedText);
		driver.close();
	}
	
}

Примітка: on Selenium 4 пас Тривалість.секунд(5) до WebDriverWait та видалення рядка System.setProperty, оскільки Selenium Менеджер вирішує проблему з chromedriver.

Поширені запитання

Ні. Конструктори int та long було видалено. Замість цього передайте Duration.ofSeconds(5) та використовуйте Duration для implicitlyWait, pageLoadTimeout та кожного параметра FluentWait.

Використовуйте ExpectedConditions.invisibilityOfElementLocated разом із локатором спінеру. Очікування лише цільового елемента часто закінчується занадто рано, тоді як накладання все ще блокує клік.

Виконайте скрипт return jQuery.active == 0 всередині блоку wait until. Він повертає нуль лише тоді, коли жодного jQuery-запиту ще не відкрито.

Відповідь AJAX замінила вузол DOM, на який вказував ваш WebElement. Знайдіть елемент знову після очікування замість повторного використання попереднього посилання.

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

Так. Копілот GitHub створює блоки WebDriverWait та FluentWait з коментаря, але перевіряє, чи ExpectedCondition відповідає фактичній поведінці сторінки.

Ні. Selenium Документація попереджає, що їх змішування призводить до непередбачуваних тайм-аутів. Зберігайте неявне очікування на нулі та покладайтеся на явне очікування.

Не з тих пір Selenium 4.6. Selenium Менеджер завантажує та налаштовує відповідний драйвер, тому рядок потрібен лише для закріплення локального бінарного файлу драйвера.

Підсумуйте цей пост за допомогою: