Introdução ao Playwright e WebDriver para Testes E2E na JVM

Ao concluir esta lição, você será capaz de:

  • Saber o que são o Selenium WebDriver e o Microsoft Playwright e qual problema eles resolvem.
  • Identificar os componentes-chave da arquitetura dos nossos testes End-to-End e entender como eles interagem entre si.
  • Declarar as dependências necessárias no Maven e no Gradle 9 (Kotlin DSL).

1. O Que São Selenium WebDriver e Playwright?

Selenium WebDriver e Playwright são APIs de automação que nos permitem escrever testes automatizados para aplicações web executados dentro de um navegador web real (Chromium/Chrome, Firefox, WebKit/Safari). Em outras palavras, eles nos ajudam a verificar se a nossa aplicação funciona conforme o esperado sob a perspectiva de um usuário humano real interagindo com a interface gráfica, o DOM, o CSS e o JavaScript.

As principais características dessas ferramentas são:

  • Suportam diversas linguagens de programação populares, incluindo Java/Kotlin (JVM), TypeScript/JavaScript, Python e C#.
  • Suportam todos os principais motores de navegadores web modernos (Chromium/Google Chrome, Mozilla Firefox, WebKit/Apple Safari e Microsoft Edge).
  • Suportam execução tanto com janela visível (headed) quanto em modo headless (sem interface gráfica aberta na tela, ideal para servidores de CI/CD e containers Docker).

A Evolução do Selenium WebDriver para o Playwright na JVM:

No curso original, todas as aulas de testes End-to-End utilizavam a API do Selenium WebDriver 3. Na stack moderna com Kotlin 2.4 e Spring Boot 4.1, cobrimos tanto a arquitetura clássica do Selenium WebDriver quanto o Microsoft Playwright para JVM, pois o Playwright introduziu melhorias arquiteturais importantes para aplicações web modernas:

  • Auto-Waiting nativo: Aguarda automaticamente que elementos estejam visíveis, habilitados e estáveis antes de clicar ou preencher, eliminando 95% dos flaky tests causados por StaleElementReferenceException ou Thread.sleep().
  • BrowserContexts isolados em milissegundos: Permite criar uma sessão de navegador limpa (cookies e localStorage zerados) para cada método de teste em menos de 10ms sem precisar fechar e reabrir o processo do navegador.
  • Comunicação direta via WebSocket (CDP): Em vez de traduzir cada comando em uma requisição HTTP intermediária para um executável externo (chromedriver), comunica-se diretamente com o navegador via canal bidirecional persistente.

A seguir, examinaremos em detalhes os componentes-chave dos nossos testes End-to-End.


2. Os Componentes-Chave dos Nossos Testes End-to-End

Antes de escrevermos testes End-to-End, precisamos reconhecer os quatro componentes fundamentais que participam da execução de um teste E2E e entender como eles conversam entre si:

  1. A API de Controle (WebDriver no Selenium / Page e Browser no Playwright): Declara os métodos que invocamos ao escrever nossos testes End-to-End. Esses métodos nos permitem controlar o navegador (navegar para URLs, voltar, avançar) e localizar elementos na página HTML carregada.
  2. A Classe de Teste (e Page Objects): Controla o fluxo do teste, interage com a página através da API do driver/Playwright e escreve asserções (com AssertJ ou PlaywrightAssertions.assertThat) para validar os dados exibidos nos elementos HTML.
  3. O Driver Intermediário (chromedriver/geckodriver no W3C WebDriver ou o processo servidor do Playwright): Atua como uma ponte (proxy) entre o código Kotlin rodando na JVM e o navegador web. No Selenium WebDriver, esse executável implementa a especificação W3C WebDriver (ou o legado JSON Wire Protocol). No Playwright, o driver gerencia a conexão WebSocket de baixa latência com o motor do browser.
  4. O Navegador Web Real (Chrome/Chromium, Firefox, WebKit): Fornece suporte nativo à automação (via Chrome DevTools Protocol ou W3C BiDi), expondo uma API que permite controlar remotamente a interface do usuário da aplicação web testada.

O diagrama a seguir ilustra o relacionamento entre esses quatro componentes:

flowchart LR TestClass["Classe de Teste (JUnit 6 / Kotlin)"] --> API["API (Playwright Page / Selenium WebDriver)"] API --> Driver["Driver Bridge (Playwright Server / ChromeDriver W3C)"] Driver --> Browser["Navegador Real (Chromium / Chrome / Firefox)"] Browser --> App["Aplicação Spring Boot 4 (http://localhost:port)"]

Vamos descobrir como declarar as dependências necessárias no nosso script de build.


3. Obtendo as Dependências Necessárias

Opção A: Usando Microsoft Playwright (Recomendado na Stack Moderna)

Para utilizar o Playwright na JVM, declaramos a dependência com.microsoft.playwright:playwright no nosso script de build.

Se estivermos usando Gradle 9 (build.gradle.kts), adicionamos à configuração da suíte E2E:

1
2
3
dependencies {
    endToEndTestImplementation("com.microsoft.playwright:playwright:1.51.0")
}

Se estivermos usando Maven (pom.xml), adicionamos:

1
2
3
4
5
6
<dependency>
    <groupId>com.microsoft.playwright</groupId>
    <artifactId>playwright</artifactId>
    <version>1.51.0</version>
    <scope>test</scope>
</dependency>

Opção B: Usando Selenium WebDriver 4

Para utilizar o Selenium WebDriver, declaramos a dependência selenium-java no nosso script de build.

Se estivermos usando Gradle 9 (build.gradle.kts):

1
2
3
dependencies {
    endToEndTestImplementation("org.seleniumhq.selenium:selenium-java:4.29.0")
}

Se estivermos usando Maven (pom.xml):

1
2
3
4
5
6
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.29.0</version>
    <scope>test</scope>
</dependency>

Dica de Otimização de Dependências no Selenium:

O artefato guarda-chuva selenium-java traz os drivers para todos os navegadores (Chrome, Firefox, Edge, Safari, IE). Se você souber que sua suíte de testes End-to-End utilizará exclusivamente o Google Chrome (ChromeDriver), você não precisa depender de selenium-java inteiro: basta declarar apenas org.seleniumhq.selenium:selenium-chrome-driver:4.29.0, evitando dezenas de dependências transitivas desnecessárias no seu build!

Vamos resumir o que aprendemos nesta lição.


Resumo

Esta lição nos ensinou quatro pontos essenciais:

  • O Selenium WebDriver e o Playwright suportam as principais linguagens de programação (incluindo Kotlin/Java na JVM) e todos os navegadores web modernos em modo headed ou headless.
  • A implementação da interface WebDriver (ou Page/Browser do Playwright) em conjunto com o executável do driver permite que nossos testes automatizados controlem o navegador através de sua API nativa de automação.
  • Podemos obter todas as dependências necessárias declarando com.microsoft.playwright:playwright ou org.seleniumhq.selenium:selenium-java na configuração endToEndTestImplementation do nosso build.gradle.kts.
  • No Selenium, se formos utilizar apenas uma implementação específica de WebDriver (como ChromeDriver), podemos declarar apenas o módulo específico (selenium-chrome-driver) para enxugar as dependências transitivas.