Hoe u AJAX-oproepen kunt afhandelen Selenium Webstuurprogramma

⚡ Slimme samenvatting

AJAX-aanroepen werken een deel van een pagina bij zonder dat de pagina opnieuw geladen hoeft te worden. Selenium WebDriver moet wachten op de nieuwe inhoud in plaats van ervan uit te gaan dat deze aanwezig is, en de wachtstrategie bepaalt of de test betrouwbaar slaagt.

  • 🔘 Definitie: AJAX haalt asynchroon kleine hoeveelheden data op en vernieuwt slechts een deel van de pagina.
  • ☑️ Kernprobleem: De reactietijd van de server is onbekend, dus het element bestaat mogelijk niet wanneer WebDriver ernaar zoekt.
  • Wachtopties: Thread.sleep, impliciet wachten, expliciet wachten, WebDriverWait en FluentWait gedragen zich elk anders.
  • 🧪 Aanbevolen: WebDriverWait met een ExpectedCondition wacht tot het AJAX-resultaat verschijnt en gaat dan direct verder.
  • FluentWait: Het voegt een pollinginterval toe en kan bepaalde uitzonderingen tussen pogingen negeren.
  • ⚠️ Selenium 4: Timeouts hebben nu een bepaalde duur, en Selenium De manager verwijdert het handmatige chauffeurspad.

Hoe om te gaan met AJAX-aanroepen in Selenium webdriver

Wat is AJAX?

AJAX staat voor Asynchronous JavaHet maakt gebruik van scripts en XML, waardoor de webpagina kleine hoeveelheden data van de server kan ophalen zonder de hele pagina opnieuw te laden.

AJAX is een techniek voor het bouwen van snelle, dynamische webpagina's. Het is asynchroon en combineert verschillende functies. JavaScript met een gegevensformaat, en werkt delen van een pagina bij in plaats van de hele pagina. Gmail, Google Kaarten, Facebook en YouTube Iedereen gebruikt het.

Hoe werkt AJAX?

Bijvoorbeeld, wanneer je op een verzendknop klikt, JavaHet script stuurt een verzoek naar de server, interpreteert het resultaat en werkt het huidige scherm bij zonder de pagina opnieuw te laden. Het onderstaande diagram illustreert deze uitwisseling.

Diagram van een AJAX-oproep tussen browser en server zonder volledige paginaverversing.

  • Een AJAX-oproep is een asynchroon verzoek van de browser dat geen paginaovergang veroorzaakt. De gebruiker kan doorwerken in de applicatie terwijl het verzoek op een reactie wacht.
  • AJAX verstuurt HTTP-verzoeken naar de server en verwerkt het antwoord zonder de pagina opnieuw te laden. Je kunt dus niet voorspellen hoe lang het duurt voordat de server antwoordt.

Vanuit het perspectief van een tester betekent het controleren van content of een element wachten tot het antwoord binnenkomt. De payload was oorspronkelijk XML, zoals de naam al aangeeft; de meeste API's retourneren tegenwoordig JSON.

Hoe u AJAX-oproepen kunt afhandelen Selenium webdriver

De grootste uitdaging bij het afhandelen van een AJAX-aanroep is het kennen van de laadtijd. Omdat de update een fractie van een seconde duurt, is de applicatie moeilijk te testen met een automatiseringstool. Selenium WebDriver moet een wachtmethode toepassen op de aanroep.

Het uitvoeren van dat wachtcommando onderbreekt de huidige procedure. Testgeval totdat de verwachte of nieuwe waarde verschijnt; Selenium WebDriver hervat vervolgens de onderbroken stappen.

Hieronder staan ​​de wachtmethoden die Selenium WebDriver kan gebruikmaken van

Draad.slaap()

  • Thread.sleep() is geen verstandige keuze, omdat het de huidige thread voor de opgegeven tijd opschort.
  • Bij AJAX is de exacte wachttijd nooit zeker, dus de test mislukt als het element niet binnen die tijd verschijnt. Het zorgt ook voor extra overhead, omdat Thread.sleep(t) de huidige thread van de actieve wachtrij naar de wachtwachtrij verplaatst.
  • Na een bepaalde tijd 't' verplaatst de thread zich naar de wachtrij en wacht vervolgens opnieuw tot de CPU hem oppakt.

Let op: the Java methode is Draad.slaap() in kleine letters; de versie met hoofdletters wordt niet gecompileerd.

Impliciet wachten()

  • Deze methode geeft WebDriver de opdracht om te wachten wanneer een element niet direct beschikbaar is, en deze instelling blijft van kracht gedurende de hele browsersessie. Elke elementzoekactie kan daarom zo lang duren als de impliciete wachttijd toelaat.

Expliciet wachten()

  • Expliciet wachten wordt gebruikt om de testuitvoering te bevriezen tot het moment dat aan een bepaalde voorwaarde is voldaan of de maximale tijd is verstreken.

WebDriverWacht

  • Het kan voor elke situatie worden gebruikt door WebDriverWait te combineren met een ExpectedCondition.
  • De beste aanpak is om elke seconde de voorwaarde te controleren en door te gaan naar de volgende opdracht zodra eraan voldaan is.

Maar het probleem met al dit wachten is dat je de time-out-eenheid moet vermelden. Wat als het element binnen de tijd nog steeds niet aanwezig is? Er is dus nog een wachttijd genaamd Vloeiend wachten.

Vloeiend wachten

  • Dit is een implementatie van de Wait-interface met een eigen time-out en polling-interval. Elke FluentWait-instantie stelt de maximale wachttijd voor een bepaalde voorwaarde in en bepaalt hoe vaak deze moet worden gecontroleerd.

Uitdagingen bij het afhandelen van AJAX-aanroepen in Selenium webdriver

  • Het gebruik van het commando "pauze" is niet betrouwbaar. Een lange pauze maakt de test onacceptabel traag en verhoogt de vertraging. Testen tijd, daarom werd "waitforcondition" aanbevolen voor AJAX-toepassingen.
  • Het is lastig om het risico in te schatten dat verbonden is aan specifieke AJAX-toepassingen.
  • Het geven van ontwikkelaars volledige vrijheid om een ​​AJAX-applicatie aan te passen, maakt het testproces lastig.
  • Het creëren van een geautomatiseerd testverzoek kan lastig zijn voor testtools, omdat AJAX-applicaties vaak een andere coderings- of serialisatietechniek gebruiken om POST-gegevens te verzenden.

Let op: “pauze” en “wachten op voorwaarde” zijn Selenese commando's verwijderd in Selenium 3; het WebDriver-equivalent is een expliciete wachtactie.

Code Voorbeeld van AJAX-afhandeling met behulp van Selenium webdriver

De TestNG De onderstaande klasse leest de tekst, klikt op het keuzerondje, wacht op het AJAX-antwoord en controleert of de tekst is gewijzigd.

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();
	}
	
}

Let op: on Selenium 4 pas Duur.vanSeconden(5) naar WebDriverWait en verwijder de regel System.setProperty, omdat Selenium Manager lost chromedriver-probleem op.

Veelgestelde vragen

Nee. De constructors voor int en long zijn verwijderd. Geef in plaats daarvan Duration.ofSeconds(5) door en gebruik Duration voor implicitlyWait, pageLoadTimeout en alle FluentWait-instellingen.

Gebruik ExpectedConditions.invisibilityOfElementLocated met de spinner-locator. Wachten op het doelelement alleen zorgt er vaak voor dat de laadindicator te vroeg verschijnt, terwijl de overlay de klik nog blokkeert.

Voer het script `return jQuery.active == 0` uit binnen een `wait until`-blok. Het retourneert alleen nul als er geen jQuery-verzoek meer openstaat.

De AJAX-respons heeft het DOM-element waarnaar uw WebElement verwees, vervangen. Zoek het element na de wachttijd opnieuw op in plaats van de eerdere verwijzing te hergebruiken.

AI-modellen leren typische reactietijden om de wachttijden per element te optimaliseren, intermitterende in plaats van echte storingen te signaleren en deze te groeperen, zodat één hoofdoorzaak in één keer wordt aangepakt.

Ja. GitHub-copiloot De concepten WebDriverWait- en FluentWait-blokken zijn afkomstig uit een opmerking, maar bevestigen dat de ExpectedCondition overeenkomt met het daadwerkelijke gedrag van de pagina.

Nee. Selenium De documentatie waarschuwt dat het combineren ervan tot onvoorspelbare time-outs kan leiden. Houd de impliciete wachttijd op nul en vertrouw op expliciete wachttijden.

Niet Sinds Selenium 4.6. Selenium De manager downloadt en configureert een bijbehorend stuurprogramma, dus de regel is alleen nodig om een ​​lokaal stuurprogramma-binair bestand vast te zetten.

Vat dit bericht samen met: