Automação de Navegadores em Java com Selenium

O Selenium é um conjunto de ferramentas e bibliotecas voltado para automação de navegadores, permitindo simular o comportamento de um usuário real. Com ele, é possível escrever scripts em várias linguagens, incluindo Java, para controlar navegadores como Chrome e Firefox, interagir com o DOM, capturar informações, clicar em elementos e preencher formulários. Essas funcionalidades tornam o Selenium uma base sólida tanto para criar bots, web scrapers quanto, para automatizar testes de aplicações web.

A comunicação entre o código e o navegador acontece por meio do WebDriver, uma API padronizada pelo W3C e implementada pelos próprios navegadores através de seus drivers oficiais. O seu programa conversa com esse driver, que por sua vez executa as ações dentro do navegador. Para utilizar o Selenium na prática, é necessário baixar o driver correspondente ao navegador escolhido, como ChromeDriver ou GeckoDriver, além da biblioteca do Selenium na linguagem em que você está trabalhando.

Para começar, precisamos obter o driver do navegador que será utilizado. No caso do Google Chrome, isso significa baixar o ChromeDriver(chromedriver-win64.zip) e extrair o arquivo executável (chromedriver.exe). Depois, o Java precisa saber onde esse driver está localizado. Isso pode ser feito de duas formas: configurando o caminho diretamente no código com System.setProperty("webdriver.chrome.driver", "..."), ou adicionando o executável ao PATH do sistema operacional.

System.setProperty("webdriver.chrome.driver", "chromedriver.exe");

Observação: Nas versões mais recentes do Selenium, o ecossistema passou a incluir o Selenium Manager, um utilitário interno responsável por localizar ou baixar automaticamente o driver necessário para o navegador configurado no seu código. Quando nenhum caminho é informado manualmente, o Selenium Manager baixa o driver correspondente e o armazena em ~/.cache/selenium, evitando a necessidade de configurar o System.setProperty ou fazer download manual.

Além do driver, também precisamos adicionar a biblioteca Java do Selenium ao projeto. A forma mais simples de fazer isso é incluindo a dependência oficial do Selenium no arquivo pom.xml do Maven.

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.38.0</version>
</dependency>

Agora que o ambiente está configurado, vamos ver um exemplo simples de código que acessa uma página e retorna o título exibido no navegador.

public class App 
{
    public static void main( String[] args )
    {
        //System.setProperty("webdriver.chrome.driver", "chromedriver.exe");

        WebDriver driver = new ChromeDriver();

        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

        driver.get("https://www.botecodigital.dev.br");

        String title = driver.getTitle();

        System.out.println("Título: "+title);

        driver.quit();
    }
}

Na linha 7, criamos uma instância de ChromeDriver, o que inicia uma nova sessão do Selenium e abre automaticamente uma janela do navegador. É dentro dessa janela que todas as interações configuradas no código serão executadas. Já na linha 11, utilizamos o método get() para navegar até a página desejada.

Com a página carregada, utilizamos o método getTitle() do driver para recuperar o título exibido pelo navegador e, em seguida, mostramos esse valor no console. Por fim, chamamos o método quit(), que encerra a sessão do WebDriver e fecha a janela do navegador.

O construtor do driver também permite receber um objeto de configurações, no qual podemos definir diversas opções de inicialização do navegador. Entre elas, é possível ajustar o nome e a versão do browser, definir estratégias de carregamento da página e incluir argumentos específicos para controlar o comportamento do navegador durante a execução.

ChromeOptions options = new ChromeOptions();
options.setPlatformName("Windows");
options.setBrowserVersion("140");
options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
options.setAcceptInsecureCerts(true);
options.addArguments("--headless=new --start-maximized"); 

WebDriver driver = new ChromeDriver(options);

Nesse exemplo, criamos um objeto ChromeOptions para configurar o comportamento do navegador antes da inicialização. Definimos o sistema operacional, a versão desejada do Chrome, estas opções normalmente são utilizadas se estivermos utilizando Selenium Grid, RemoteWebDriver que não abordaremos aqui. Definimos a estratégia de carregamento da página e permitimos certificados inseguros. Também adicionamos argumentos de inicialização, como o modo headless (--headless=new) que irá fazer o navegador não abrir uma nova janela ao iniciar uma sessão, mas rodar em segundo plano. Por fim, essas opções são repassadas ao construtor do ChromeDriver, que inicia o navegador já com todas as configurações aplicadas.

A opção setPageLoadStrategy define a estratégia de carregamento da página. Em outras palavras, ao chamar get(), o WebDriver aguarda até que o readyState do navegador atinja o status complete. Porém, é importante destacar que esse estado não garante que todo o conteúdo esteja disponível, já que elementos carregados dinamicamente via Javascript podem continuar sendo processados após o carregamento inicial.

StrategyReady StateDescrição
normalcompleteEstratégia padrão. O WebDriver aguarda todo o carregamento da página, incluindo recursos externos, e o evento load ser disparado.
eagerinteractiveO DOM está disponível para interação, mas recursos adicionais, como imagens e scripts secundários, podem ainda estar sendo carregados.
noneAnyO WebDriver não espera o carregamento da página. A navegação retorna imediatamente após o comando get().

Obtendo valores da página com o Selenium

Após o carregamento completo da página, o Selenium WebDriver disponibiliza uma série de métodos que permitem extrair informações diretamente do navegador. Entre os mais utilizados estão:

  • driver.getTitle(): Retorna o conteúdo da tag <title>, ou seja, o título da página exibido pelo navegador. Esse método é útil para validações simples, como confirmar se o usuário foi redirecionado para a página correta.
  • driver.getPageSource(): Fornece o código fonte da página, o conteúdo retornado pode não refletir o estado final renderizado.
  • driver.getCurrentUrl(): Retorna a URL atual exibida no navegador. Esse método é fundamental para verificar redirecionamentos e fluxos de navegação.

Para obter valores de elementos em uma página, o primeiro passo é localizá-los. No Selenium, isso é feito pelo método findElement, que recebe um objeto da classe By como parâmetro. Esse objeto funciona como um mecanismo de localização, semelhante a um seletor, que pode usar ID, name, CSS selector, e outros critérios. O método retorna uma instância de WebElement, que representa o elemento encontrado e permite interagir com ele.

driver.get("https://www.botecodigital.dev.br");

WebElement element = driver.findElement( By.cssSelector(".excerpt h1"));
String texto = element.getText();
String classe = element.getAttribute("class");
String tag = element.getTagName();

O objeto By disponibiliza vários métodos para localizar elementos dentro da página, permitindo que o WebDriver utilize diferentes estratégias de seleção conforme a necessidade do código.

  • By.id(String): localiza um elemento a partir do valor do atributo id
  • By.name(String): busca elementos utilizando o atributo name.
  • By.tagName(String): encontra elementos pelo nome da tag HTML.
  • By.className(String): seleciona elementos que possuem o nome de classe informado. Somente aceita um nome de classe.
  • By.cssSelector(String): permite localizar elementos utilizando qualquer seletor CSS válido, por exemplo: #content .autor .nome ou .input[type='submit'].
  • By.linkText(String): seleciona um elemento <a> cujo texto visível corresponde exatamente ao texto informado.

Quando o Selenium não encontra nenhum elemento que corresponda ao seletor informado no By, ele lança a exceção org.openqa.selenium.NoSuchElementException, indicando que o elemento simplesmente não existe na árvore DOM naquele momento.

O método findElement sempre retorna apenas o primeiro elemento que corresponde ao seletor informado. Caso o seletor identifique vários elementos na página, devemos utilizar findElements, que retorna uma List<WebElement> contendo todos os elementos encontrados, ou uma lista vazia, caso nenhum corresponda ao critério.

driver.get("https://www.botecodigital.dev.br");

List<WebElement> elements = driver.findElements( By.cssSelector(".excerpt h1"));

for(WebElement e : elements){
    String titulo = e.getText();
    String link = e.findElement(By.tagName("a")).getAttribute("href");
    System.out.println("Titulo: "+ titulo);
    System.out.println("Link: "+ link);
    System.out.println("-----------------------------------");
} 

driver.quit();

Depois de obter um WebElement, podemos chamar vários métodos da API do Selenium para extrair informações do elemento, como texto, atributos, valores de CSS e até o nome da tag correspondente.

  • getText(): retorna o texto visível do elemento na página.
  • getAttribute(String): obtém o valor de um atributo HTML, como value, title, href, entre outros.
  • getTagName(): devolve o nome da tag HTML correspondente ao elemento.
  • getCssValue(String): retorna o valor computado de uma propriedade CSS.
  • isEnabled(): indica se o elemento está habilitado (retorna true quando não possui a propriedade disabled).
  • isSelected(): informa se o elemento está selecionado, aplicado principalmente a inputs do tipo radio e checkbox.
  • isDisplayed(): retorna true quando o elemento está visível na página. Por exemplo, caso o CSS defina display: none ou visibility: hidden, o método retornará false.
WebElement element = driver.findElement( By.cssSelector(".excerpt h1 a"));

String titulo = element.getText();
String link = element.getAttribute("href");
String tagname = element.getTagName();
String cssFont = element.getCssValue("font-family");

É importante lembrar que todos esses métodos retornam os valores atuais do elemento no DOM, refletindo exatamente o estado no momento da consulta. Se algum script Javascript modificar atributos, estilos ou o próprio conteúdo do elemento de forma dinâmica, o Selenium irá retornar esses valores atualizados. O mesmo vale para elementos criados ou removidos em tempo de execução, o WebDriver sempre interage com o DOM tal como ele existe no instante da busca.

Um objeto WebElement também possui os métodos findElement e findElements, permitindo localizar outros elementos dentro de sua própria subárvore do DOM. Isso é útil quando queremos navegar pela estrutura interna de um componente sem precisar realizar buscas a partir do documento inteiro.

Interagindo com a página

O Selenium oferece diversas formas de interagir com os elementos da página após o carregamento. As ações mais comuns envolvem cliques e envio de texto.

Para realizar um clique em um elemento, basta localizá-lo utilizando o método findElement, obtendo assim um objeto WebElement, e então chamar o método click() sobre ele.

WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(15));
driver.manage().window().maximize();

driver.get("https://www.botecodigital.dev.br");       

WebElement element = driver.findElement( By.cssSelector(".post-thumbnail"));
        
element.click();

String title = driver.getTitle();
String url = driver.getCurrentUrl();

System.out.println("Titulo: " + title);
System.out.println("Url: " + url);

driver.quit();

Para inserir texto em um campo da página, primeiro localizamos o elemento desejado usando findElement, exatamente como fazemos ao executar um clique. Em seguida, chamamos o método sendKeys(String), passando como argumento o texto que queremos digitar nesse elemento.

Vale lembrar que, caso o campo já contenha algum valor, o texto informado no sendKeys() será acrescentado ao existente. Por isso, uma prática recomendada é limpar o campo previamente utilizando o método clear() antes de inserir novos dados.

WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().window().maximize();

driver.get("https://www.botecodigital.dev.br/exemplos/selenium/login");
      
WebElement usernameEl = driver.findElement( By.name("username"));
WebElement passwordEl = driver.findElement( By.name("password"));
WebElement btSubmitEl = driver.findElement( By.cssSelector("button[type='submit']"));
        
usernameEl.sendKeys("rodrigo");
passwordEl.sendKeys("123456");
btSubmitEl.click();

String title = driver.getTitle();
String url = driver.getCurrentUrl();

System.out.println("Titulo: " + title);
System.out.println("Url: " + url);

driver.quit();

O método sendKeys() é utilizado principalmente em elementos do tipo input (text, password, email, etc) e textarea, ou seja, campos que aceitam entrada direta de texto. Para elementos como radio ou checkbox, o procedimento adequado é usar o método click(), que altera seu estado de seleção.

WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().window().maximize();
driver.get("https://www.botecodigital.dev.br/exemplos/selenium/check.php");

WebElement verdeEl = driver.findElement( By.id("azul"));
verdeEl.click();

Para selecionar uma opção dentro de um elemento <select>, utilizamos a classe Select, que recebe um WebElement correspondente ao próprio <select> em seu construtor. A partir desse objeto Select, temos acesso a vários métodos que facilitam a interação com o combobox, como selecionar opções pelo valor, texto visível ou índice.

  • selectByVisibleText(String): seleciona a opção pelo texto visível exibido no <option>.
  • selectByValue(String): seleciona a opção de acordo com o valor definido no atributo value do <option>.
  • selectByIndex(int): seleciona a opção com base em sua posição dentro do <select>, começando pelo índice 0.
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().window().maximize();
driver.get("https://www.botecodigital.dev.br/exemplos/selenium/select.php");

WebElement selectEl = driver.findElement( By.name("opcoes"));
        
Select select = new Select(selectEl);

select.selectByVisibleText("Opção 3");

Lidando com espera

Um dos principais desafios na automação de navegadores é garantir que a página esteja em um estado apropriado antes de executar uma ação. É comum que uma página carregue o DOM inicial e, em seguida, faça requisições assíncronas a APIs para obter novos dados, alterando a interface dinamicamente, como adicionando ou removendo elementos. Muitas vezes, o elemento com o qual desejamos interagir só é criado após algum evento, como um clique ou o retorno de uma requisição. Para o usuário, essas mudanças parecem instantâneas, mas em um script de automação elas podem ocorrer tarde demais, fazendo com que o Selenium tente acessar um elemento que ainda não existe no DOM, resultando em erros durante a execução.

Para lidar com esses cenários, o Selenium oferece duas abordagens principais de espera: esperas implícitas e esperas explícitas. Ambas permitem que o script aguarde determinadas condições antes de prosseguir. Vale destacar que o uso de Thread.sleep() não é recomendado, pois congela a execução por um tempo fixo, independente do estado real da página, tornando o teste mais lento e menos confiável.

A espera implícita define um tempo máximo para que o WebDriver tente localizar um elemento antes de lançar uma exceção. Trata-se de uma configuração global: após definida, ela passa a valer para todas as chamadas de findElement e findElements durante toda a sessão, sendo necessário configurá-la apenas uma vez. É importante frisar que a espera implícita não espera que o elemento esteja interagível, visível ou clicável — apenas que exista no DOM.

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

A espera explícita permite definir uma condição específica que o WebDriver deve aguardar até que seja satisfeita ou até que o tempo máximo configurado seja atingido. Para utilizá-la, é necessário instanciar um objeto de Wait<T>(como WebDriverWait), informando o WebDriver e o tempo limite desejado.

No objeto de espera utilizamos o método until, que recebe uma condição de espera fornecida pelos métodos estáticos da classe ExpectedConditions. Essa classe disponibiliza diversas condições prontas, entre elas:

  • visibilityOfElementLocated(By): aguarda até que o elemento identificado pelo seletor By esteja visível na página.
  • textToBePresentInElementLocated(By,String): aguarda até que um texto específico esteja presente no elemento localizado pelo seletor By.
  • invisibilityOfElementLocated(By): aguarda até que o elemento localizado pelo seletor By se torne invisível ou deixe de existir no DOM.
  • numberOfElementsToBe(By, int): aguarda até que a quantidade de elementos encontrados pelo seletor By corresponda ao número informado.
  • alertIsPresent(): aguarda até que um alert Javascript (popup nativo do navegador) esteja presente.
  • titleIs(String): aguarda até que o título da página seja exatamente igual ao texto informado.
  • elementToBeClickable(By): aguarda até que o elemento localizado pelo seletor By esteja visível e habilitado para clique.
driver.get("https://www.botecodigital.dev.br/exemplos/selenium/wait.php");

Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(50));
wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".content"))
 );
        
 WebElement element = driver.findElement( By.cssSelector(".content"));

 System.out.println("Texto: "+element.getText());

No exemplo apresentado, o elemento .content já existe no DOM, porém está oculto (com display: none) e só se tornará visível depois que o conteúdo for carregado via fetch(acesse a página pelo navegador). Se utilizássemos apenas a espera implícita, o Selenium consideraria que o elemento já foi encontrado, pois ele realmente está no DOM, e devolveria o elemento mesmo estando vazio e invisível. Já com a espera explícita, definimos uma condição que aguarda até que o elemento esteja visível, utilizando o método visibilityOfElementLocated.

Exemplo de cadastrado de produtos

Agora vamos reunir tudo o que vimos até aqui e criar um script capaz de cadastrar, em uma página web, os dados obtidos a partir de um arquivo CSV. A seguir, apresentamos os dados que serão utilizados:

Refrigerante Cola,6.50,Bebida,S
Suco de Laranja,4.20,Bebida,N
Camiseta Básica,39.90,Vestuário,S
Notebook Slim,3500.00,Eletrônico,N
Sanduíche Natural,12.00,Alimentação,N
Agua Mineral,2.50,Bebida,N
Fone de Ouvido,89.90,Eletrônico,S
Jaqueta Jeans,159.90,Vestuário,N
Chocolate Amargo,7.80,Alimentação,S
Smartphone X1,1899.00,Eletrônico,N
Calça Moletom,89.90,Vestuário,N
Pizza Congelada,19.99,Alimentação,N
Chá Gelado,5.50,Bebida,S
Tênis Esportivo,249.90,Vestuário,N
Monitor 24 Polegadas,699.90,Eletrônico,S
Queijo Mussarela,14.50,Alimentação,N
Blusa Feminina,59.90,Vestuário,S
Café Torrado,16.90,Alimentação,N
Mouse Gamer,129.90,Eletrônico,N
Água de Coco,6.30,Bebida,S

Vamos realizar os cadastros em uma aplicação de exemplo bem simples (https://www.botecodigital.dev.br/exemplos/selenium/produtos), que armazena as informações diretamente na sessão do navegador. Por esse motivo, não encerraremos o WebDriver ao final do script, permitindo visualizar os registros incluídos. Para acessar o sistema, utilizaremos o usuário admin e a senha 123456.

A seguir, é apresentado o código de exemplo:

WebDriver driver = new ChromeDriver();


driver.get("https://www.botecodigital.dev.br/exemplos/selenium/produtos");

WebElement usernameEl = driver.findElement(By.name("username"));
WebElement senhaEl = driver.findElement(By.name("password"));

usernameEl.clear();
senhaEl.clear();
usernameEl.sendKeys("admin");
senhaEl.sendKeys("123456");

WebElement btEntrar = driver.findElement(By.cssSelector("button[type='submit']"));
btEntrar.click();

try(Scanner scan = new Scanner(new FileInputStream("produtos.csv"))){
    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));

    while (scan.hasNext()) {
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Adicionar Produto")));

        WebElement linkAdd = driver.findElement(By.linkText("Adicionar Produto"));
        linkAdd.click();

        String[] line = scan.nextLine().split(",");
        String nome = line[0];
        String preco = line[1];
        String categoria = line[2];
        String destaque = line[3];
                
        driver.findElement(By.name("nome")).sendKeys(nome);
        driver.findElement(By.name("preco")).sendKeys(preco);

        Select selectCategoria = new Select(driver.findElement(By.name("categoria")));
        selectCategoria.selectByVisibleText(categoria);

        if(destaque.equals("S")){
            driver.findElement(By.cssSelector("label[for='destaque']")).click();
        }
                
        driver.findElement(By.cssSelector("button[type='submit']")).click();
    }
}catch(IOException e){
    e.printStackTrace();
}

No início do exemplo, a linha 4 realiza o acesso à página de login. Em seguida, nas linhas 6 e 7, recuperamos os elementos dos campos username e password. Nas linhas 9 e 10, esses campos são limpos para garantir que não haja dados pré-preenchidos, e logo depois, nas linhas 11 e 12, inserimos os valores necessários. Já na linha 14, selecionamos o botão de envio utilizando um seletor CSS, e na linha 15 executamos o comando de clique, que efetua o login e direciona o usuário para a página de listagem.

Em seguida, o arquivo produtos.csv é aberto para leitura por meio de um objeto Scanner (linha 17), e percorremos seu conteúdo utilizando um laço while (linha 20), que processa cada linha do arquivo. A cada iteração, aguardamos até que o botão “Adicionar Produto” esteja visível na página (linha 21), garantindo que a tela de listagem tenha sido carregada e que o link esteja pronto para interação. Após essa espera, localizamos o elemento correspondente ao botão de adicionar (linha 23) e executamos o clique (linha 24), o que nos direciona para a página do formulário de cadastro.

Na sequência, lemos uma linha do arquivo CSV (linha 26) e a dividimos utilizando a vírgula como separador, atribuindo cada parte às variáveis correspondentes (linhas 27 a 30). Em seguida, localizamos os campos de entrada nome e preço (linhas 32 e 33) e preenchemos seus valores usando o método sendKeys, com os dados obtidos do arquivo. Para o campo de seleção de categoria, criamos um objeto Select a partir do elemento <select> correspondente (linha 35) e utilizamos o método selectByVisibleText() para escolher a opção cujo texto coincide com o valor presente no arquivo CSV (linha 36).

Em seguida, verificamos se o valor do campo destaque lido do arquivo é igual a "S" (linha 38). Caso seja, localizamos o label associado ao checkbox e realizamos um clique nele (linha 39), marcando assim o campo correspondente no formulário.

Por fim, na linha 42, selecionamos o botão de envio do formulário e executamos a ação de click, o que submete os dados e grava o produto. Após o envio, a aplicação redireciona para a página de listagem de produtos. Em seguida, o loop reinicia, aguardando novamente a visibilidade do link “Adicionar Produto”, que será clicado para iniciar um novo cadastro, repetindo o processo até que todas as linhas do arquivo CSV sejam processadas.

Este é um exemplo simples, sem validações adicionais para garantir que todas as etapas ocorram corretamente, mas serve para ilustrar de forma como utilizar o Selenium para automatizar interações com páginas web.

Executando código JavaScript com o Selenium

Se precisarmos executar código Javascript diretamente na página, o Selenium permite fazer isso por meio do próprio WebDriver. Como ChromeDriver herda de ChromiumDriver, que por sua vez herda de RemoteWebDriver, classe que implementa a interface JavascriptExecutor, podemos usar o polimorfismo para “converter” (fazer cast) o driver para JavascriptExecutor e, assim, chamar o método executeScript, responsável por executar código Javascript no contexto da página carregada.

Podemos enviar parâmetros para o método executeScript() junto ao código JavaScript que será executado. Esses parâmetros são repassados ao script na forma do array especial arguments, permitindo acessar valores dinâmicos dentro do próprio JavaScript. Dessa forma, podemos manipular elementos ou definir propriedades diretamente pelo código Java.

WebDriver driver = new ChromeDriver();
        
driver.get("http://localhost:8000/js.php");
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));

WebElement element = driver.findElement( By.cssSelector("h1"));

JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;

String js = """
            arguments[0].innerHTML = 'Conteudo adicionado via JS!';
            """;

javascriptExecutor.executeScript(js, element);

Como podemos visualizar o objeto WebElement passado como segundo argumento para o método executeScript pode utilizado pelo código Javascript através do array arguments.

Lidando com janelas pop-up no Selenium

Em páginas web, podemos encontrar três tipos tradicionais de pop-ups gerados via Javascript: alert, confirm e prompt. No Selenium, todos eles são tratados de forma semelhante. Para interagir com qualquer um desses diálogos, utilizamos driver.switchTo().alert(), que retorna um objeto do tipo Alert. A partir dele, temos acesso aos métodos necessários para manipular o pop-up, como aceitar, rejeitar ou enviar texto, dependendo do tipo de diálogo apresentado. Os principais métodos são:

  • getText(): obtém o texto exibido no pop-up.
  • accept(): confirma o pop-up, clicando no botão equivalente a “OK”.
  • dismiss(): cancela o pop-up, acionando o botão correspondente a “Cancelar”.
  • sendKeys(String): envia texto para o pop-up, disponível apenas quando o diálogo é do tipo prompt.
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.botecodigital.dev.br/exemplos/selenium/alert.php");
        
var wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.alertIsPresent());

// alert
Alert alert = driver.switchTo().alert();
String textoAlert = alert.getText();
System.out.println("Texto alert: "+ textoAlert);
alert.accept();

wait.until(ExpectedConditions.alertIsPresent());

//confirm
Alert confirm = driver.switchTo().alert();
String textoConfirm = confirm.getText();
System.out.println("Texto confirm: "+ textoConfirm);
confirm.dismiss();

wait.until(ExpectedConditions.alertIsPresent());

// prompt
Alert prompt = driver.switchTo().alert();
String textoPrompt = prompt.getText();
System.out.println("Texto prompt: "+ textoPrompt);
prompt.sendKeys("Um texto de  teste");
prompt.accept();

Utilizando o Selenium para testar uma aplicação Spring

Um dos usos mais comuns do Selenium é a automação de testes de interface web. Ele pode ser integrado ao JUnit em uma aplicação desenvolvida com Spring Boot, por exemplo, para validar o comportamento da camada de apresentação e garantir que a interface esteja funcionando conforme o esperado.

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class HomeControllerTest {

    @LocalServerPort
    private int port;

    private ChromeDriver driver;

    @BeforeEach
    void setup(){
        this.driver = new ChromeDriver();
    }

    @AfterEach
    void tearDown(){
        this.driver.quit();
    }

    @Test
    void homePageTest() {
        driver.get("http://localhost:" + port+"/home");
    
        String title = driver.getTitle();
        assertEquals("Home Page", title);

        String h1 = driver.findElement(By.tagName("h1")).getText();
        assertEquals("Home", h1);

    }

    @Test
    void clickLinkTest() {
        driver.get("http://localhost:" + port+"/home");
    
        WebElement link = driver.findElement(By.linkText("Contato"));
        link.click();

        String h1Contato = driver.findElement(By.tagName("h1")).getText();
        assertEquals("Contato", h1Contato);

    }

}

Utilizamos a anotação @SpringBootTest configurada com webEnvironment = WebEnvironment.RANDOM_PORT para que a aplicação seja iniciada em uma porta aleatória durante a execução dos testes. Em seguida, aplicamos a anotação @LocalServerPort ao atributo responsável por armazenar essa porta, permitindo que o teste construa corretamente a URL de acesso. Já os métodos anotados com @BeforeEach e @AfterEach garantem, respectivamente, a criação de uma nova instância do WebDriver antes de cada teste e o encerramento dessa instância ao final, assegurando que cada execução ocorra em um ambiente limpo.

Acessamos a página que desejamos testar utilizando o método get() e, em seguida, localizamos os elementos necessários da mesma forma que fizemos nos exemplos anteriores. Depois disso, validamos os resultados esperados empregando métodos de asserção, como em qualquer outro teste JUnit. Simples assim!

Esta foi uma introdução ao uso do Selenium, uma ferramenta extremamente versátil que permite tanto criar bots e automações quanto realizar testes de interface de forma eficiente. No entanto, é importante lembrar que páginas web modernas costumam ser altamente dinâmicas devido ao uso intenso de Javascript. Por isso, é fundamental analisar cuidadosamente o comportamento da página e realizar testes abrangentes para garantir que a automação funcione conforme o esperado.

T++