Como lidar com chamadas AJAX em Selenium Driver da Web

⚡ Resumo Inteligente

As chamadas AJAX atualizam parte de uma página sem recarregá-la, portanto Selenium O WebDriver precisa aguardar o novo conteúdo em vez de presumir que ele esteja presente, e a estratégia de espera decide se o teste é aprovado de forma confiável.

  • 🔘 Definição: AJAX busca pequenas quantidades de dados de forma assíncrona e atualiza apenas parte da página.
  • ☑️ Problema central: O tempo de resposta do servidor é desconhecido, portanto o elemento pode não existir quando o WebDriver o procurar.
  • ✅ Opções de espera: Thread.sleep, espera implícita, espera explícita, WebDriverWait e FluentWait comportam-se de maneira diferente.
  • 🧪 Recomendado: O WebDriverWait com uma ExpectedCondition verifica repetidamente até que o resultado do AJAX apareça e, em seguida, continua imediatamente.
  • 🛠️ FluentWait: Isso adiciona um intervalo de sondagem e pode ignorar exceções selecionadas entre as tentativas.
  • ⚠️ Selenium 4: Os tempos limite agora levam em consideração a duração, e Selenium O gerenciador remove o caminho do driver manual.

Como lidar com chamadas AJAX em Selenium webdriver

O que é AJAX?

AJAX significa Assíncrono JavaScript e XML permitem que a página da Web recupere pequenas quantidades de dados do servidor sem recarregar a página inteira.

AJAX é uma técnica para construir páginas web rápidas e dinâmicas. É assíncrona e combina... JavaScript com um formato de dados, e atualiza partes de uma página em vez da página inteira. Gmail, Google Mapas, Facebook e YouTube Todos o utilizam.

Como funciona o AJAX?

Por exemplo, quando você clica em um botão de envio, JavaO script envia uma solicitação ao servidor, interpreta o resultado e atualiza a tela atual sem recarregar a página. O diagrama abaixo mostra essa troca de informações.

Diagrama de uma chamada AJAX entre o navegador e o servidor sem recarregamento completo da página.

  • Uma chamada AJAX é uma solicitação assíncrona do navegador que não causa uma transição de página. O usuário pode continuar trabalhando no aplicativo enquanto a solicitação aguarda uma resposta.
  • O AJAX envia solicitações HTTP para o servidor e processa a resposta sem recarregar a página, portanto, não é possível prever quanto tempo o servidor levará para responder.

Do ponto de vista de um testador, verificar o conteúdo ou um elemento significa esperar até que a resposta chegue. A carga útil era originalmente XML, como o nome indica; a maioria das APIs agora retorna JSON.

Como lidar com chamadas AJAX em Selenium webdriver

O maior desafio ao lidar com uma chamada AJAX é conhecer o tempo de carregamento. Como a atualização dura uma fração de segundo, o aplicativo é difícil de testar por meio de uma ferramenta de automação. Selenium O WebDriver deve aplicar um método de espera à chamada.

Executar esse comando de espera suspende o processo atual. Caso de teste até que o valor esperado ou o novo valor apareça; Selenium Em seguida, o WebDriver retoma as etapas suspensas.

A seguir estão os métodos de espera que Selenium O WebDriver pode usar

Thread.sleep ()

  • Thread.sleep() não é uma escolha sábia, pois suspende a thread atual pelo período de tempo especificado.
  • Em AJAX, você nunca pode ter certeza do tempo de espera exato, então o teste falha se o elemento não aparecer dentro desse período. Isso também adiciona sobrecarga, porque Thread.sleep(t) move a thread atual da fila de execução para a fila de espera.
  • Após o tempo 't', o thread passa para a fila de prontos e, em seguida, aguarda novamente para ser selecionado pela CPU.

Observação: da Java método é Thread.sleep () Em minúsculas; a forma com maiúsculas não compila.

Espera Implícita()

  • Este método instrui o WebDriver a aguardar quando um elemento não estiver disponível imediatamente, e essa configuração permanece ativa durante toda a sessão do navegador. Portanto, cada busca por elemento pode levar o tempo que a espera implícita permitir.

Espera explícita()

  • Espera explícita é usado para congelar a execução do teste até o momento em que uma condição específica seja atendida ou o tempo máximo decorrido.

WebDriverEspere

  • Ele pode ser usado para qualquer condição, combinando WebDriverWait com um ExpectedCondition.
  • A melhor abordagem é verificar a condição a cada segundo e passar para o próximo comando assim que ela for atendida.

Mas o problema com todas essas esperas é que você precisa mencionar a unidade de tempo limite. E se o elemento ainda não estiver presente dentro do prazo? Portanto, há mais uma espera chamada espera fluente.

Espera Fluente

  • Esta é uma implementação da interface Wait com seu próprio tempo limite e intervalo de verificação. Cada instância de FluentWait define o tempo máximo de espera por uma condição e a frequência com que ela deve ser verificada.

Desafios no tratamento de chamadas AJAX Selenium webdriver

  • O uso do comando “pause” não é confiável. Uma pausa longa torna o teste inaceitavelmente lento e aumenta o tempo de execução do teste. Testes tempo, então “waitforcondition” foi recomendado para aplicações AJAX.
  • É difícil avaliar o risco associado a aplicações AJAX específicas.
  • Dar aos desenvolvedores total liberdade para modificar uma aplicação AJAX torna o processo de teste desafiador.
  • Criar uma solicitação de teste automatizada pode ser difícil para ferramentas de teste, porque os aplicativos AJAX geralmente usam uma técnica de codificação ou serialização diferente para enviar dados POST.

Observação: “pause” e “waitforcondition” são Selenese comandos removidos em Selenium 3; o equivalente no WebDriver é uma espera explícita.

Code Exemplo de manipulação de AJAX usando Selenium webdriver

O TestNG A classe abaixo lê o texto, clica no botão de opção, aguarda a resposta AJAX e verifica se o texto foi alterado.

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

Observação: on Selenium passe 4 Duração.deSegundos(5) para WebDriverWait e remova a linha System.setProperty, porque Selenium O gerenciador resolve o problema do chromedriver.

Perguntas Frequentes

Não. Os construtores int e long foram removidos. Passe Duration.ofSeconds(5) em vez disso e use Duration para implicitlyWait, pageLoadTimeout e todas as configurações de FluentWait.

Use `ExpectedConditions.invisibilityOfElementLocated` com o localizador do spinner. Aguardar apenas o elemento alvo geralmente passa muito cedo, enquanto a sobreposição ainda bloqueia o clique.

Execute o script `return jQuery.active == 0` dentro de um bloco `wait until`. Ele retornará zero somente quando nenhuma requisição jQuery estiver aberta.

A resposta AJAX substituiu o nó DOM para o qual seu WebElement apontava. Localize o elemento novamente após a espera, em vez de reutilizar a referência anterior.

Os modelos de IA aprendem os tempos de resposta típicos para ajustar as esperas por elemento, sinalizar falhas intermitentes em vez de falhas genuínas e agrupá-las para que a causa raiz seja corrigida de uma só vez.

Sim. Travas deslizantes portáteis Copiloto do GitHub Rascunhos de blocos WebDriverWait e FluentWait a partir de um comentário, mas confirme se a ExpectedCondition corresponde ao comportamento real da página.

Não. Selenium A documentação alerta que a mistura dos dois métodos causa timeouts imprevisíveis. Mantenha a espera implícita em zero e confie nas esperas explícitas.

Não Desde Selenium 4.6. Selenium O gerenciador baixa e configura um driver compatível, portanto, essa linha é necessária apenas para fixar um binário de driver local.

Resuma esta postagem com: