Você está na página 1de 62

Assine o DeepL Pro para traduzir arquivos maiores.

Mais informações em www.DeepL.com/pro.


Índice
Introdução A
p
Parte 1: Fundamentos ê
n
Capítulo 1: Primeiros passos d
i
Capítulo 2: Localizando elementos em uma c
página Capítulo 3: Interagindo com elementos e
A
em uma página Capítulo 4: Examinando uma :
G
página r
a
Capítulo 4: Como fazer testes de fácil manutenção usando o padrão d
Page Object Capítulo 6: O que fazer quando algo dá errado e
d
Parte 2: APIs do WebDriver em e
s
detalhes Capítulo 7: Gerenciando o e
l
WebDriver ê
Capítulo 8: Janelas, pop-ups e quadros n
i
Capítulo 9: Unicórnios e outros animais: recursos exóticos das o

páginas da Web Capítulo 10: Execução de JavaScript usando a


interface JavascriptExecutor Capítulo 11: O que você precisa saber
sobre os diferentes navegadores
Capítulo 12: Envolvendo o WebDriver e o
WebElement Parte 3: Estrutura de automação
baseada em páginas Capítulo 13: Formando uma
estrutura
Capítulo 14: Encapsulamento e agrupamento de
elementos Capítulo 15: Automatização de um
fluxo de página
Capítulo 16: Examinando tabelas HTML
Capítulo 17: Automatizando o jQuery
datepicker Capítulo 18: Estrutura do
datepicker Apêndices

2
1.1 1.13

1.2 1.14

1.3 1.15

1.4 1.16

1.5 1.17

1.6 1.18

1.7 1.19

1.8 1.20

1.9 1.21

1.10 1.22

1.11 1.23

1.12 1.23.1

3
Introdução

Introdução
Este livro é um guia prático para dezenas de maneiras específicas que você pode usar
para obter o máximo do WebDriver em seu desenvolvimento de automação de
testes. Este manual prático oferece soluções instantaneamente úteis para áreas
importantes, como a interação e o teste de aplicativos da Web e o uso das APIs do
WebDriver. Durante a leitura, você passará dos fundamentos do WebDriver às
práticas obrigatórias, desde como interagir, controlar e verificar páginas da Web e
tratamento de exceções até interações mais complexas, como objetos de página,
alertas e JavaScript, além de testes em dispositivos móveis e muito mais.
Por fim, você aprenderá a criar sua própria estrutura. Ao final do livro, você estará
confiante e capacitado para testar seus aplicativos Web com o WebDriver.

Sobre a tecnologia
Os aplicativos da Web são difíceis de testar porque muito depende da maneira
como o usuário interage com páginas individuais. A estrutura de teste da Web do
Selenium WebDriver ajuda a criar automação de teste confiável e de fácil
manutenção para seus aplicativos da Web em vários navegadores, sistemas
operacionais e linguagens de programação. Assim como um ser humano, ele pode
clicar em links, preencher formulários e ler as páginas da Web e, ao contrário de
um ser humano, não fica entediado. O WebDriver pode fazer quase tudo o que
você pedir - o truque é criar uma abordagem unificada para os testes. Felizmente,
é nesse ponto que este livro realmente se destaca.

O que há dentro
Técnicas específicas e práticas do WebDriver

Interagir com, controlar e testar aplicativos da Web

Usando as APIs do WebDriver

Como fazer testes de manutenção

Técnicas de testes automatizados

4
Introdução

Depoimentos

5
Introdução

Citações de nossos revisores de acesso antecipado:

Excelente cobertura de uma tecnologia importante no espaço de testes da Web.

Um livro essencial para qualquer pessoa interessada em fazer testes de


integração do WebDriver. Você deve ter alguma familiaridade com o
desenvolvimento Java (incluindo o uso básico do Maven). Ele começa com o uso
básico do Selenium WebDriver, mas há muito mais. Fica claro que os autores
vêm usando essa tecnologia em um ambiente profissional há bastante tempo,
pois o livro está repleto de uma técnica após a outra que pode ser usada para
resolver problemas que se pode esperar ao testar aplicativos da Web do
mundo real.

Este livro é um guia muito prático do Selenium WebDriver. O livro está


repleto de exemplos práticos com suas soluções. Já utilizei as técnicas para
resolver problemas no trabalho.

É uma introdução muito boa à estrutura e gosto da maneira como os autores


tentaram fornecer soluções práticas para os problemas que enfrentamos ao
tentar automatizar determinados tipos de testes.

Agradecimentos
Agradecemos aos seguintes colaboradores:

entropicrune

Edko24

PulwerJR

Errata e discussão
Se você encontrar algum erro ou problema neste livro, ou se quiser falar sobre o
conteúdo:

https://github.com/selenium-webdriver-book/manuscript/issues

Sobre o leitor

4
Introdução

Este livro pressupõe que você se sinta à vontade para ler códigos em Java ou em uma
linguagem semelhante e que conheça os conceitos básicos de criação e teste de
aplicativos. Não é necessário ter experiência com o WebDriver.

Sobre os autores

Yujun Liang é um Technical Agile Coach que ensina tecnologias de


desenvolvimento de software ágil, incluindo automação de testes usando o Selenium
WebDriver. Ele trabalhava para a ThoughtWorks e ajudava os clientes a criar testes
de automação para aplicativos da Web com interação rica com o usuário e lógica de
negócios complexa.

Alex Collins é arquiteto técnico no Reino Unido, blogueiro de


tecnologia, palestrante público e colaborador de OSS. Alex tem trabalhado com o
Selenium WebDriver desde 2011.

Direitos autorais © 2016 Yujun Liang e Alex Collins

5
Parte 1:
Fundamentos

Parte 1: Fundamentos
Nesta seção, apresentaremos o Selenium WebDriver. Ensinaremos técnicas comuns
que são úteis para escrever testes, como localizar, interagir e verificar elementos.
Também mostraremos como tornar seu código mais fácil de manter usando Page
Objects e como lidar com erros* Ao final desta seção, você será capaz de escrever
código para muitas páginas da Web comuns.

6
Capítulo 1: Primeiros
passos

Capítulo 1: Primeiros passos


Este capítulo abrange

O que é o WebDriver?

Por que escolher o WebDriver?

"Olá, WebDriver!"

Atualmente, cada vez mais transações comerciais são realizadas na Internet por
meio de páginas da Web criadas por pessoas. Alguns sites são simples o suficiente
para serem configurados por uma ou duas pessoas, mas outros são tão complexos
que são criados por centenas ou até milhares de desenvolvedores. Antes de cada
lançamento, o site deve ser testado para garantir que esteja livre de bugs críticos. É
demorado testar todo o site manualmente e, à medida que o site cresce, o custo
dos testes também aumenta. Mais do que isso, com o passar do tempo, um novo
recurso que foi bem testado quando foi disponibilizado pela primeira vez pode ser
esquecido mais tarde - corremos o risco de perder a consistência e a qualidade e,
como resultado, surgem bugs no que pensávamos ser peças sólidas de
funcionalidade.

No setor têxtil, o trabalho manual dominou o processo de confecção de roupas por


muito tempo. Quando as máquinas de tecelagem foram inventadas, a produtividade
melhorou muito.

O mesmo está acontecendo com os testes de software. Assim como as máquinas de


tecelagem mudaram o setor têxtil, agora estamos construindo "máquinas de teste
automáticas" para substituir o teste manual e melhorar a produtividade, a
qualidade e a consistência do software.

Desde sua criação em 2008, o Selenium WebDriver (também conhecido como


Selenium 2) se estabeleceu como a biblioteca de automação da Web de fato.

Antes do Selenium WebDriver, havia o Selenium 1.0, que permitia a automação por
meio da injeção de JavaScript em páginas da Web. O WebDriver é uma
reinvenção dessa ideia, mas é mais confiável, mais poderoso e mais
dimensionável.

O Selenium evoluiu, assim como a World Wide Web. HTML5 e CSS3 agora são padrão;
os aplicativos da Web ricos em AJAX não são mais nem mesmo de ponta. Isso significa
que a automação da Web é agora um tópico mais complexo e interessante.

7
Capítulo 1: Primeiros
passos
Este capítulo abordará rapidamente os conceitos básicos, garantindo que, ao final dele,
você compreenda a arquitetura básica e possa escrever código básico.

8
Capítulo 1: Primeiros
passos
Neste capítulo, apresentaremos o WebDriver, o que ele é, como funciona e os
motivos para escolhê-lo. Também falaremos brevemente sobre algumas ferramentas
que usamos neste livro, as quais recomendamos a todos os desenvolvedores.
Também falaremos brevemente sobre algumas das ferramentas que usamos neste
livro, as q u a i s recomendamos a todos os desenvolvedores.

O que é o WebDriver?
O Selenium WebDriver automatiza os navegadores da Web. Ele fica no lugar da pessoa
que está usando um navegador da Web. Como um usuário, ele pode abrir um site,
clicar em links, preencher formulários e navegar. Ele também pode examinar a página,
observando os elementos nela contidos e fazendo escolhas com base no que vê.

O caso de uso mais comum do WebDriver é o teste automatizado. Até pouco tempo
atrás, para executar um teste de regressão em seu site, era necessário ter um
conjunto de scripts que deveriam ser executados manualmente por desenvolvedores
ou QAs. Todos os relatórios também precisariam ser agrupados manualmente. Isso
pode ser demorado e caro. Em vez disso, o WebDriver pode ser usado para
executar esses scripts e reunir automaticamente relatórios sobre o sucesso deles,
bastando pressionar um botão. Cada execução subsequente não será mais cara do
que a primeira.

9
Capítulo 1: Primeiros
passos

Figura 1. Antes do WebDriver

10
Capítulo 1: Primeiros
passos
Já se foi o tempo em que você precisava criar uma versão do seu site para o Internet
Explorer 6, um navegador difundido e notoriamente não compatível com os padrões, e
outra para outros navegadores. Embora a maioria dos navegadores modernos seja
muito mais consistente em seu comportamento, a aparência ou o comportamento
de uma página da Web ainda pode variar muito, pois o número de diferentes
navegadores, sistemas operacionais e plataformas de uso comum aumentou. Um
cliente de alto valor ainda pode reclamar que não consegue acessar seu site.
Historicamente, a única maneira de mitigar isso era ter um exército de QAs testando
manualmente em uma variedade de configurações diferentes, um processo demorado e
caro. O WebDriver pode executar testes em diferentes sistemas operacionais e
configurações de navegadores, e em uma fração do tempo de um ser humano.
Além disso, você pode usá-lo para executá-los de forma muito mais consistente e
confiável do que um testador manual.

Aplicativos e sites oferecem serviços úteis, mas, às vezes, eles só podem ser
acessados por páginas da Web. Outro caso de uso do WebDriver é tornar essas
páginas acessíveis aos aplicativos por meio do WebDriver. Talvez você tenha um
aplicativo de administração escrito há vários anos e um cliente ou proprietário de
produto tenha solicitado a automatização de algumas ações nele. Mas talvez
ninguém saiba onde está o código-fonte. Pode ser muito mais fácil usar o
WebDriver para automatizar essa tarefa.

Como o WebDriver funciona


O WebDriver funciona em todos os principais navegadores e com todas as principais
linguagens de programação. Como isso é possível? Bem, o WebDriver tem vários
componentes que interagem entre si:

1. Um navegador da Web.

2. Um plug-in ou extensão do navegador que fica dentro do navegador e que,


por sua vez, contém um servidor que implementa a API JSON do WebDriver.

3. Uma vinculação de linguagem (no nosso caso, Java) que faz solicitações HTTP
para essa API.

11
Capítulo 1: Primeiros
passos

Figura 2. Diagrama do driver da Web


Quando você inicia um código que usa o WebDriver, ele abre o navegador, que, por
sua vez, inicia o plug-in. Você pode então enviar solicitações para executar as ações
desejadas, como clicar em links ou digitar texto. Como um plug-in só precisa
implementar a API JSON, as pessoas escreveram plug-ins para todos os principais
navegadores. Para usar um navegador que tenha um plug-in, você só precisa
implementar um cliente para o protocolo JSON.

Isso significa que todos os principais navegadores e todas as principais linguagens de


programação são compatíveis com o WebDriver.

O plug-in geralmente pode ser visto nas preferências do navegador, como na figura 1.3.

12
Capítulo 1: Primeiros
passos

Figura 3. Painel Extensões do Safari

Por que escolher o WebDriver?


Há vários motivos excelentes para escolher o WebDriver:

O WebDriver pode executar navegadores local e remotamente com alterações


mínimas de configuração.

O WebDriver é compatível com os principais fornecedores de navegadores:


tanto o Firefox quanto o Chrome participam ativamente do desenvolvimento do
WebDriver.

O WebDriver imita mais de perto um usuário. Sempre que possível, ele usa eventos
nativos para operar, a fim de torná-lo preciso e estável.

O WebDriver é um software de código aberto (OSS). Isso significa que ele é


gratuito e tem o suporte de uma excelente comunidade.

O WebDriver é compatível com todos os principais sistemas operacionais, como OS


X, Windows e
Linux. Ele também tem suporte para Android e iOS.

O WebDriver se tornará um padrão W3C, portanto, você pode esperar que ele
seja suportado por um longo tempo.

O WebDriver não apresenta alguns dos problemas que o Selenium 1.0


apresentava, como o upload de arquivos ou a manipulação de pop-ups.

O WebDriver tem uma sintaxe mais concisa do que o Selenium 1.0, o que torna
mais rápido escrever código.

13
Capítulo 1: Primeiros
passos
O que o WebDriver não pode fazer

14
Capítulo 1: Primeiros
passos
O WebDriver fornece uma maneira de controlar um navegador da Web, mas isso é
tudo. Quando você compra um carro novo, recebe um manual que informa como
operar o rádio e como trocar o óleo. Mas esse manual não informa o melhor lugar
para fazer a manutenção do carro nem ensina a dirigir. Assim como dirigir um
carro, há coisas que você deve fazer por si mesmo. Aqui estão algumas coisas que
o WebDriver não faz:

O WebDriver não tem o controle do momento em que os elementos aparecem


na página da Web. Alguns podem aparecer mais tarde, e você mesmo
precisará lidar com isso.

O WebDriver não sabe quando as coisas foram alteradas na página, portanto, você
não pode pedir que ele informe quando as coisas foram alteradas.

O WebDriver não fornece muitos utilitários para escrever seu código. Você precisa
escrevê-los por conta própria.

O WebDriver não oferece suporte integrado para elementos de página que são
compostos de vários elementos, como calendários JavaScript.

O WebDriver não fornece uma estrutura para escrever seu código. O JUnit é
uma escolha natural.

O WebDriver não gerencia o navegador. Por exemplo, você precisa fazer a limpeza
depois de usá-lo.

O WebDriver não instala nem mantém seus navegadores. Você precisa fazer isso

sozinho. Cobriremos todas essas tarefas importantes neste livro.

A história do selênio
O Selenium é um conjunto de ferramentas de teste da Web, incluindo o Selenium
IDE, o Selenium RC, o Selenium WebDriver e o Selenium Grid. O primeiro Selenium
é chamado Selenium Core, que saiu do escritório da ThoughtWorks em Chicago e foi
desenvolvido por Jason Huggins. Ele foi escrito para simular a ação de um usuário
humano com o Internet Explorer. Ele era diferente dos tipos de ferramentas
Record/Replay de outros fornecedores, pois não exigia uma ferramenta GUI
adicional para suportar sua operação. Precisava apenas do Java, que a maioria dos
desenvolvedores já tinha instalado em seus computadores.

Posteriormente, Shinya Kasatani desenvolveu um plug-in para Firefox chamado


Selenium IDE sobre o Selenium Core. O Selenium IDE é uma interface gráfica que

15
Capítulo 1: Primeiros
passos
permite aos usuários gravar uma sessão de navegação no navegador, que pode ser
reproduzida posteriormente. O Selenium IDE foi integrado ao Firefox e forneceu a
mesma função de registro/reprodução que as outras ferramentas proprietárias.

16
Capítulo 1: Primeiros
passos
Como o Selenium IDE é uma ferramenta gratuita, ele logo conquistou uma grande fatia
do mercado entre os QAs e analistas de negócios que não tinham as habilidades de
programação necessárias para usar o Selenium Core. Mais tarde, o Selenium Core
evoluiu para o Selenium RC ("RC" significa "Controle Remoto"), juntamente com o
Selenium Grid, que permitia que os testes fossem executados em várias máquinas
ao mesmo tempo.

O Selenium WebDriver foi originalmente criado por Simon Stewart, da Thoughtworks.


Ele foi originalmente apresentado na Conferência de Automação de Testes do
Google, e ainda pode ser visto on-line em
https://www.youtube.com/watch?v=tGu1ud7hk5I.

Em 2008, o Selenium incorporou a API do WebDriver e formou o Selenium 2.0. O


Selenium WebDriver tornou-se a escolha mais popular entre o conjunto de ferramentas
Selenium, pois oferece operação padronizada para vários navegadores por meio de
uma interface comum, o WebDriver. Em favor dessa nova API simplificada do
WebDriver, o Selenium RC foi descontinuado e seu uso não é mais incentivado. Os
desenvolvedores que mantêm o Selenium também forneceram um guia de migração
que ajuda os usuários do Selenium RC a migrar do Selenium RC para o WebDriver.

Hoje, quando as pessoas falam sobre "Selenium", geralmente estão falando sobre
o Selenium WebDriver.

Por que ele é chamado de selênio?


Jason Huggins brincou com um concorrente chamado Mercury em um e-mail,
dizendo que é possível curar o envenenamento por mercúrio tomando suplementos
de selênio. Foi daí que surgiu o nome Selenium.

As ferramentas de que você precisa para


começar
Além de um computador, acesso à Internet e um ambiente de desenvolvimento,
você precisará de alguns softwares adicionais para começar.

Por que usamos Java neste livro


Embora estejamos cientes de que muitos desenvolvedores não usarão o Java como
linguagem principal. Nós a escolhemos como linguagem para este livro porque
queríamos escrever para o maior número possível de pessoas, e Java é a
linguagem de programação mais popular.

A API do WebDriver é semelhante em todos os idiomas. As linguagens da Web -

17
Capítulo 1: Primeiros
passos
JavaScript, CSS e HTML - são as mesmas, independentemente da linguagem em que
você está escrevendo seus testes. Se você estiver usando uma das muitas linguagens
compatíveis com o WebDriver, como

18
Capítulo 1: Primeiros
passos
como C#, Ruby ou Python, você deve ser capaz de replicar muitas das técnicas deste
livro.

Kit de desenvolvimento Java (JDK)


Como o Java está entre as linguagens de desenvolvimento mais populares e
amplamente utilizadas, nós o usaremos ao longo deste livro. O Java 8 apresenta vários
recursos, como fluxos e expressões lambda, que tornam o trabalho com o WebDriver
mais rápido e eficiente.

Você pode verificar se (e qual versão de) o JDK já está instalado em um terminal
usando o comando javac:

$ javac -versão
javac 1.8.0_20

Observe que é comum se referir a uma versão do Java pelo dígito do meio do
número completo da versão, portanto, "Java 1.8" é normalmente conhecido como
"Java 8".

Os usuários do Linux podem instalar o Java usando os gerenciadores de pacotes yum


ou apt. Os usuários do Windows e do OS X podem fazer o download no site da
Oracle: http://www.oracle.com/technetwork/java/javase/downloads/index.html.

Apache Maven
Ao longo deste livro, usaremos a ferramenta de compilação Apache Maven para
gerenciar nosso código. O principal motivo disso é que o Maven pode gerenciar as
muitas dependências de que precisamos para criar um aplicativo. Você pode verificar
se tem o Maven instalado no terminal:

$ mvn -version
Apache Maven 3.3.1

Caso não o tenha instalado, os usuários do Linux podem instalá-lo usando seu
gerenciador de pacotes (por exemplo, Apt ou Yum), e os usuários do OS X podem
instalá-lo usando o gerenciador de pacotes Homebrew (http://brew.sh)

Por exemplo (no OS-X usando o Brew):

brew install maven

19
Capítulo 1: Primeiros
passos
Ou (no Ubuntu Linux):

sudo apt-get install maven

Os usuários do Windows podem fazer o download no site do Apache Maven em


https://maven.apache.org.

Google Chrome
O navegador Chrome é o navegador com o melhor suporte. Ao contrário de outros
navegadores, ele está disponível em todas as plataformas, é compatível com os
padrões e tem uma integração simples e pronta para uso com o WebDriver.

Como de costume, os usuários do Linux podem instalar o Chrome usando seu


gerenciador de pacotes; caso contrário, você pode fazer o download do Chrome no
site do Chrome.

Mais adiante no livro, examinaremos outros navegadores, como o Firefox, mas ter o
Chrome instalado agora o ajudará a passar pelos primeiros capítulos.

Git
Você precisará instalar o Git se quiser conferir o código-fonte deste livro. No
OS-X usando o Brew:

brew install git

Ou no Ubuntu Linux usando o Apt:

sudo apt-get install git

Se você usa o Windows, pode fazer o download em https://git-scm.com/ .

O projeto de teste
Como parte desse projeto, colocamos todo o código-fonte no sistema de
controle de versão Git. Ele contém todo o código de amostra, bem como um
pequeno site no qual o código é executado.

20
Capítulo 1: Primeiros
passos
Você pode obter isso executando estes comandos:

git clone https://github.com/selenium-webdriver-book/source.git


fonte de cd

O projeto tem um servidor da Web integrado que pode ser iniciado digitando o
seguinte:

mvn jetty:run

Você pode visualizar o site que ele cria em http://localhost:8080/hello-


webdriver.html. Você deverá ver uma página semelhante à figura Hello WebDriver.
Isso forma a base de muitos dos testes do projeto, portanto, você provavelmente
desejará mantê-lo em execução o tempo todo.

Figura 4. Olá, WebDriver


Quando terminar, pressione Ctrl+C para sair do servidor.

Se você quiser encontrar exemplos do livro no código, procure o pacote com o


nome do capítulo. Por exemplo, se estiver procurando os exemplos do capítulo um,
eles podem ser encontrados em src/test/java/swb/ch01intro .

Para executar todos os testes com o livro, execute o seguinte:

mvn verify

Instruções sobre como executar com diferentes navegadores podem ser


encontradas no arquivo README.md.

"Olá, WebDriver!"
Vamos dar uma olhada em um exemplo de uso do WebDriver para automatizar
uma tarefa básica e terminar com um exemplo funcional. Um script de automação
do WebDriver geralmente consiste em várias operações:

1. Crie um novo WebDriver, com o apoio de um navegador local ou remoto.

21
Capítulo 1: Primeiros
passos
2. Abra uma página da Web.

3. Interagir com essa página, por exemplo, clicando em links ou inserindo texto.

4. Verifique se a página foi alterada conforme o esperado.

5. Instrua o WebDriver a sair.

Crie um diretório com esse p o m .xml:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>


<projeto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>hello-webdriver</groupId>
<artifactId>hello-webdriver</artifactId>
<versão>1.0.0-SNAPSHOT</versão>

<dependências>
<dependência>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId> (1)
<versão>LATEST</versão> (2)
<escopo>teste</scope>
</dependência>
<dependência>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<versão>4.12</versão>
<escopo>teste</scope>
</dependência>
</dependências>

<construção>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<versão>3.3</versão>
<configuração>
<fonte>1,8</fonte> (3)
<target>1.8</target>
</configuração>
</plugin>
<plugin>

22
Capítulo 1: Primeiros
passos
<artifactId>maven-failsafe-plugin</artifactId>
<versão>2.18.1</versão>
<execuções>
<execução>
<objetivos>
<objetivo>teste de integração</objetivo> (4)
<objetivo>verificar</objetivo>
</goals>
</execução>
</execuções>
</plugin>
</plugins>
</build>

</projeto>

1. Você pode escolher um navegador diferente, por exemplo, o selenium-

firefox-driver é para o navegador Firefox.

2. Sempre use a versão mais recente disponível.

3. Compile usando a versão mais recente do Java - Java 1.8.

4. Certifique-se de que os testes sejam executados usando o plug-in à prova de falhas


do Maven.

Para iniciar o driver, você precisará de um programa binário especial para iniciá-lo. Para
o Chrome, ele se chama chromedriver e pode ser encontrado em
https://sites.google.com/a/chromium.org/chromedriver/downloads. Faça o download e
salve-o na raiz do projeto.

Criar src/test/java/swb/intro/HelloWebDriverIT.java :

HelloWebDriverIT.java

23
Capítulo 1: Primeiros
passos

pacote swb.ch01intro;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By; (1)
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import static org.junit.Assert.assertEquals; public

class HelloWebDriverIT { (2)

driver WebDriver privado;

@Antes
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "chromedriver"); (3)
driver = new ChromeDriver(); (4)
}

@Após
public void tearDown() throws Exception {
driver.quit(); (5)
}

@Teste
public void helloWebDriver() throws Exception {

driver.get("http://localhost:8080/hello-webdriver.html"); (6)

WebElement pageHeading
= driver.findElement(By.tagName("h1")); (7)

assertEquals("Hello WebDriver!",
pageHeading.getText()); (8)
}
}

1. Importações Java padrão para o WebDriver.

2. Usamos o sufixo IT para teste neste livro; essa é a convenção do Maven


para testes de integração que são executados usando o plug-in
Failsafe [1].

3. Informe ao driver da Web, por meio dessa propriedade do sistema, o local do binário
do driver.

24
Capítulo 1: Primeiros
passos
4. Crie um novo driver que se conecte a uma instância do navegador Chrome.

25
Capítulo 1: Primeiros
passos
5. Certifique-se de que o navegador seja encerrado quando o teste for concluído.

6. Abra uma página da Web no navegador.

7. Localiza um elemento na página atual, nesse caso, o cabeçalho da página.

8. Verifique se o cabeçalho é o valor que você espera.

Você precisará iniciar o projeto de teste conforme mostrado na seção anterior antes
de executar o teste. Em seguida, ao executar o teste, você deverá ver o navegador
abrir uma página semelhante à figura Hello WebDriver.

Resumo
Você pode usar o WebDriver para economizar tempo e dinheiro automatizando as
tarefas do navegador.

Ele é especialmente adequado para testes automatizados de navegadores.

O WebDriver foi desenvolvido com base em um protocolo JSON padrão, o que


significa que todos os principais navegadores e linguagens são compatíveis com
ele.

Há alguns ótimos motivos para usar o WebDriver em vez de testes manuais. Por
exemplo, você pode economizar custos e melhorar a qualidade ao mesmo
tempo.

Você precisa de algumas ferramentas para começar. Neste livro, usaremos o Maven
e o Java.

No próximo capítulo, começaremos nossa jornada examinando a primeira parte de


qualquer script de automação - localizar elementos nas páginas.

1. https://maven.apache.org/surefire/maven-failsafe-plugin/

26
Capítulo 2: Localização de elementos
em uma página

Capítulo 2: Localização de elementos em


uma página
Este capítulo abrange

Localização de elementos usando os localizadores By

Escrevendo suas próprias fábricas de localizadores

Práticas recomendadas para escolher e organizar localizadores

Como usuário, a primeira coisa que você faz ao abrir uma página da Web é tentar
encontrar a parte da página em que está interessado. Se for a nossa rede social,
pode ser o ícone de novas mensagens; se for o nosso banco on-line, pode ser o
nosso saldo. Em seguida, você usa essas informações para considerar suas ações.
Da mesma forma, o WebDriver oferece uma ampla variedade de métodos para
localizar elementos em uma página. Isso nos permite examinar a página e verificar
se estamos vendo o que esperamos.

Sem a capacidade de encontrar esses elementos, não é possível fazer nenhuma


interação com a página. Isso faz com que as técnicas necessárias para isso sejam
incrivelmente importantes.

Neste capítulo, abordaremos todos os principais métodos de localização de elementos


nas páginas. Também veremos como compor esses blocos de construção básicos em
localizadores mais complicados. A localização de elementos é apenas a metade da
história. Também abordaremos maneiras de gerenciar as diferentes estratégias de
localização que você pode querer usar para tornar seu código amigável e fácil de
trabalhar.

Ao contrário da percepção humana, os métodos do WebDriver são muito rigorosos.


Se você estiver procurando o ícone de novas mensagens, talvez esteja procurando
algo que se pareça com um envelope, mas se esse envelope for um dia maior ou
menor, ou tiver uma cor diferente da que você se lembra, você se adaptará. O
WebDriver não tem essa inteligência. Se o ícone mudar de um envelope para outra
coisa, a maioria dos usuários perceberá rapidamente a mudança, mas nem todas as
invocações do WebDriver perceberão. Examinaremos os padrões que você pode
usar para garantir que o seu código permaneça robusto às alterações na página
que, de outra forma, poderiam quebrar o código e criar um problema de
manutenção.

27
Capítulo 2: Localização de elementos
em uma página
Não apenas apresentaremos todos os principais métodos de localização de
elementos, mas também abordaremos para que cada um deles é mais adequado,
bem como as práticas de organização. Por fim, veremos como tornar o site que você
está automatizando fácil de automatizar.

28
Capítulo 2: Localização de elementos
em uma página
Ao final do capítulo, você terá uma excelente caixa de ferramentas com estratégias
robustas para localizar elementos de todos os tipos.

Localização de um ou mais elementos com


base em ID, classe ou nome
O WebDriver oferece várias maneiras de localizar elementos. Veremos como isso
funciona e as principais maneiras de fazer isso.

O que é um contexto de pesquisa?


A localização de elementos em qualquer página ocorre dentro do que o WebDriver
chama de contexto de pesquisa. Vamos dar uma olhada rápida na interface
SearchContext:

interface pública SearchContext {


List<WebElement> findElements(By by);

WebElement findElement(By by);


}

Essa interface fornece dois métodos: um que encontra todos os elementos que
correspondem a uma instância do que é conhecido como localizador e um segundo que
encontra o primeiro elemento que corresponde ou lança uma NoSuchElementException se
ele não for encontrado. Isso significa que o
O método findElements é útil para localizar elementos quando você não tem
certeza se eles estarão na página ou se deseja ter certeza de que eles não estão
na página.

As interfaces WebElement e WebDriver estendem o SearchContext, portanto, todos os


drivers e elementos terão esses métodos.

O que é um localizador?
Um localizador descreve o que você deseja encontrar, e há um zoológico deles. Em
Java, você cria um localizador usando a classe By. Vamos dar uma olhada em um
exemplo de localização de um elemento de título h1 na página atual:

WebElement heading1Element = driver.findElement(By.tagName("h1"));

E, para completar, encontrar todos os elementos de parágrafo na página atual:

29
Capítulo 2: Localização de elementos
em uma página

List<WebElement> paragraphElement = driver.findElements(By.tagName("p"));

Conforme discutido, há vários localizadores de núcleo que podem ser usados para
localizar elementos em uma página.

Localizador Uso

Localiza elementos pelo valor do


Nome da classe
atributo "class".

Localiza elementos por meio do


mecanismo W3 CSS Selector
subjacente do driver. Se o navegador
Seletor CSS não implementar a API do seletor,
será feito um esforço máximo para
emular a API. Nesse caso, ele se
esforça para oferecer pelo menos
suporte a CSS2, mas não oferece
garantias.
Localiza elementos pelo valor de seus
ID
atributo id.

Localiza elementos pelo texto exato que


Texto do link
ele exibe

Localiza elementos pelo valor de seus


Nome
atributo name.

Localiza elementos que contêm o


Texto de link parcial
texto do link fornecido

Nome da etiqueta Localiza elementos por seu nome de tag

XPath Localiza elementos via XPath

Localização por texto de link


O texto do link é o localizador preferencial para links. Figura Formulário de login
http://localhost:8080/login.html mostra o link na página de login do aplicativo de teste
para senhas esquecidas:

30
Capítulo 2: Localização de elementos
em uma página

Figura 1. Formulário de login


http://localhost:8080/login.html Isso é representado pelo
seguinte HTML:

<a href="#" id="change-password" class="btn">Forgotten Password</a>

E isso pode ser localizado usando o seguinte:

driver.findElement(By.linkText("Forgotten Password"));

Qualquer parte da cadeia de caracteres "Forgotten Password" pode ser usada como
parâmetro para esse método:

driver.findElement(By.partialLinkText("Forgotten Password"));
driver.findElement(By.partialLinkText("Forgotten "));
driver.findElement(By.partialLinkText("en Passwo"));

Você deve ser cauteloso ao usar findElement com esse localizador. Você pode
encontrar outros elementos que contenham o mesmo texto parcial, portanto, ele não
deve ser usado para localizar um único elemento isoladamente. Naturalmente, você
pode usá-lo para localizar um grupo de elementos usando o método findElements.

Localização por atributo de classe


Localiza elementos pelo valor do atributo class. Isso pode ser usado somente para os
elementos que têm um atributo class, mas não é um bom seletor para ser usado com o
seletor
método findElement. A classe é usada para estilizar páginas e, como resultado, é
provável que muitos elementos tenham a mesma classe. Como findElement sempre
retorna o primeiro elemento encontrado, se o elemento desejado não estiver em
primeiro lugar, você não poderá usá-lo para localizá-lo. Mesmo que seja o primeiro
elemento agora, se um desenvolvedor adicionar um novo elemento com a
mesma classe no início da página, ele retornará o elemento recém-adicionado, em vez
do elemento que você está tentando localizar. Isso torna o código frágil.

Na página de login da figura Formulário de login http://localhost:8080/login.html, o link


"Forgotten Password" tem uma classe CSS: btn; você pode usar o nome da classe btn

31
Capítulo 2: Localização de elementos
em uma página
para localizá-lo:

32
Capítulo 2: Localização de elementos
em uma página

driver.findElement(By.className("btn"))

Localização por ID
A localização de um elemento por seu atributo id pode ser expressa da seguinte
forma:

driver.findElement(By.id("change-password"))

Se o site for criado usando JavaScript, a ID normalmente é aplicada a elementos


importantes. As IDs devem ser exclusivas, portanto, se um e l e m e n t o tiver uma ID,
essa geralmente é a maneira mais precisa de identificá-lo. Embora os IDs possam
aparecer acidentalmente várias vezes em uma página (por exemplo, devido a um erro
de programação), isso é raro. Como eles geralmente são adicionados para facilitar o
código JavaScript, se esse erro ocorrer, o JavaScript geralmente também estará com
defeito e, portanto, isso será detectado no início do desenvolvimento.

Se a ID estiver disponível, faça dela sua primeira opção.

Localização por nome de entrada


Esse é um localizador que localiza elementos pelo valor do atributo name.
Normalmente, ele só pode ser usado para localizar elementos de formulário criados
usando: <input> , <button> ,
<select> , e <textarea> . Lembre-se de que, se o mesmo nome for usado para vários
elementos na mesma página, somente o primeiro elemento encontrado será
retornado. Portanto, antes de usar esse localizador, você precisa verificar se o nome
é exclusivo na página. Se for, ele poderá ser usado; caso contrário, será
necessário usar outros localizadores (ou uma combinação deles).

Na página de login, há uma entrada de e-mail:

<input name="email" class="form-control" placeholder="Email"/>

Portanto, o código de que você precisaria seria o seguinte:

driver.findElement(By.name("email"));

Localização por nome de tag de elemento

33
Capítulo 2: Localização de elementos
em uma página
Esse localizador localiza elementos pelo nome da tag HTML. Como muitas vezes há
muitos usos repetidos da maioria das tags, nem sempre é possível usar esse método
para localizar um único elemento. Mas ele pode ser combinado com outros
localizadores para localizar elementos de forma eficaz. Uma das vezes em que ele
será útil é para localizar o cabeçalho da página, pois geralmente há apenas um
deles:

<h1>Bem-vindo ao WebDriver!</h1>

driver.findElement(By.tagName("h1"));

Localização usando seletores CSS


Juntamente com os localizadores XPath, o localizador de seletor CSS é eficiente. Você
pode usar a abordagem do seletor CSS para localizar por ID, por exemplo:

#change-password

Os seletores CSS podem ser usados para localizar a maioria dos outros seletores.
Você pode deduzir que, se não conseguir localizar o elemento usando um seletor
CSS, não conseguirá localizar o elemento usando qualquer localizador de
atributo id, nome de classe ou nome.

Localizador Seletor CSS equivalente

Por nome de classe "the-class" .a - c l a s s e

Por ID "the-id" #oid

Por nome de tag "h1" h1

Por nome "the-name" (o nome) *[name='the-name']

A finalidade de um seletor CSS é marcar parte de uma página para formatação,


não para automação. É razoável que um desenvolvedor altere todos os seletores de
CSS em uma página, especialmente quando um site recebe uma nova camada de
tinta na forma de uma nova aparência. Isso significa que os seletores CSS, embora
poderosos, podem ser um tanto frágeis.

34
Capítulo 2: Localização de elementos
em uma página
Os seletores CSS podem ser mais lentos do que outros localizadores, e vale a pena
ter isso em mente se estiver pensando em usá-los. Este livro está focado no ensino
do WebDriver, não no ensino de CSS, portanto, você pode obter mais informações
sobre CSS no site da Mozilla: https://developer.mozilla.org/en-
US/docs/Web/CSS/Tutorials.

O CSS é uma boa opção se você não conseguir localizar um elemento pelo nome ou ID.

Localização usando XPath


Os localizadores XPath são o seletor mais complexo de usar. Ele requer conhecimento
da linguagem de consulta XPath, portanto, se você não for fluente nessa linguagem de
consulta, terá d i f i c u l d a d e e m encontrar elementos usando consultas XPath.

Vamos dar uma olhada em um exemplo de uso de um XPath para esse HTML:

<a href="#" id="change-password">Alterar senha</a>

driver.findElement(By.xpath("//a[@id='change-password']"));

Você pode usar o Web Developer Tools no Chrome para descobrir os XPaths e os
seletores CSS. O XPath que você obtém da ferramenta é //*[@id="change-password"]
, que pode ser usado diretamente, como na figura Copiando um XPath.

Figura 2. Cópia de um XPath


Isso encontra qualquer tag com um atributo ID de "change-password". Como você
sabe que se trata de um link, você pode alterá-lo para //a[@id='change-password'] e
ele ainda funcionará; isso também é mais seguro, pois restringe os elementos à tag
<a> .

Os seletores XPath e CSS podem atender a alguns dos mesmos objetivos.

35
Capítulo 2: Localização de elementos
em uma página

Localizador Equivalente ao seletor XPath


//*[contains(concat(' ',normalize-
Por nome de classe "the-class" space(@class),' '),' the-class ')]

Por id "the-id" //*[@id='the-id']"

Por nome de tag "h1" //h1

Por nome "the-name" (o nome) //*[@name='the-name']

Espero que você possa perceber que tem o mesmo poder que os seletores CSS, mas a
complexidade é muito maior.

Vamos dar uma olhada em alguns XPaths úteis, que são difíceis de fazer usando
outros localizadores.

normalize-space(.) versus text(.)


text(.) faz a correspondência apenas com o texto do elemento, enquanto normalize-
space(.)

retorna o texto do elemento e de todos os elementos que ele contém. Isso é útil se você
quiser localizar um parágrafo de texto que contenha algum estilo:

<p>Um parágrafo com <b>este texto em negrito</b>.</p>

Isso não será correspondido pelo XPath a seguir:

//*[contains(text(), 'Um parágrafo com esse texto em negrito')]

Considerando que esse XPath corresponderá:

//*[contains(normalize-space(.), 'A paragraph with this text in bold')]

Aqui combinamos normalize-space com contains . Você pode usar isso para
localizar um elemento dentro de um elemento pai.

//div[contains(., 'A visible paragraph')]/a

36
Capítulo 2: Localização de elementos
em uma página
Essa é uma expressão poderosa. Ela encontra um link em um parágrafo que
contém a frase "A visible paragraph" (Um parágrafo visível). O principal desafio das
expressões XPath é sua complexidade. Elas demoram um pouco para serem
aprendidas e, como não há segurança de tipo ou suporte completo automático na
maioria dos IDEs, pode ser caro trabalhar com elas e mantê-las.

Deve-se observar que o XPath é o mais lento de todos os localizadores. Se você


quiser saber mais sobre o XPath, pode fazê-lo no site da Mozilla
https://developer.mozilla.org/en-US/docs/Web/XPath.

Muitos navegadores modernos oferecem uma ferramenta para encontrar o seletor


XPath ou CSS de um elemento. Tenha cuidado ao copiar isso literalmente em seus
testes. Eles costumam ser bastante específicos e podem mudar facilmente na
próxima vez que a página for carregada.

O XPath é uma boa opção, mas geralmente é melhor tentar resolver os problemas
de localização usando primeiro os localizadores de CSS, nome ou ID, pois eles são
mais fáceis de entender para você e sua equipe.

Essa é uma grande variedade de localizadores! Todos eles são orientados em


torno do conhecimento da cadeia de caracteres que você precisa passar para criá-los.
Para localizadores XPath e CSS, eles podem ser longos e complexos. Podemos
reduzir a complexidade do nosso código encapsulando os localizadores mais
usados em pequenas fábricas que podem ser reutilizadas. Por exemplo, em vez de
ter um localizador para localizar entradas usando um XPath, pode ser mais fácil
criar um localizador especificamente para a tarefa de localizar entradas.

Criação de uma fábrica de localizadores para localizadores


complexos
É possível que você crie localizadores semelhantes uns aos outros. Para esses
locais comuns, você pode reduzir a verbosidade do seu código tendo fábricas para
criá-los.

Os XPaths são complicados de escrever e caros de manter.

Crie fábricas de localizadores, semelhantes aos Por pois métodos


métodos dos localizadores. Minha recomendação é Por complicados não são
que, como específicos da classe
um elemento, crie um factory genérico para localização sem um nome de tag,
chamado
ElementBy e, em seguida, crie um para cada tag que você deseja localizar. Por exemplo,
para localizar elementos de entrada pelo texto do rótulo com o qual estão

37
Capítulo 2: Localização de elementos
em uma página

anotados:

InputBy.java

38
Capítulo 2: Localização de elementos
em uma página

classe final pública InputBy {


private InputBy() {
}

public static By label(String labelText) {


return By.xpath("//label[contains(., '" + labelText + "')]/input");
}
}

Você notará que o construtor é privado para evitar a instanciação da classe. Para

localizar qualquer elemento pelo texto que ele contém:

ElementBy.java

classe final pública ElementBy {


private ElementBy() {
}

public static By partialText(String text) {


return By.xpath("//*[contains(normalize-space(.), '" + text + "')]");
}
}

As classes de fábrica anteriores permitem encapsular localizadores complexos em uma


classe e reutilizá-los à vontade. Ao seguir um esquema de nomenclatura e um estilo
semelhante ao da classe
De fábrica, você pode garantir que outros desenvolvedores os considerem fáceis de
usar e que a adoção seja mais fácil.

Mais adiante, falaremos sobre estratégias para agrupar localizadores.

Direcionamento refinado usando


seletores CSS complexos
Falamos anteriormente sobre o uso de seletores CSS. Assim como as consultas XPath,
os seletores CSS são muito mais avançados do que os localizadores básicos. Vamos
dar uma olhada em algumas maneiras de localizar elementos usando seletores CSS.

Você pode refinar um localizador usando um atributo:

<input name="email">

39
Capítulo 2: Localização de elementos
em uma página

input[name='email']

Ou vários atributos:

<input name="email" type="text">

input[type='text'][name='email']

Observe que se o atributo for seu valor padrão, como o tipo poderia ser neste exemplo,
então seus valores serão indefinidos. Você não conseguirá localizá-lo dessa
forma.

Você também pode refinar um localizador pelo prefixo dos atributos:

<input name="password">

input[name^='passw']

Pelo sufixo:

<input name="password">

input[name$='sword']

Ao conter uma cadeia de caracteres com infixo:

<input name="password">

input[name*='sswor']

Pelo próximo elemento da página:

<input name="password">
<input type="submit">

input[name='password'] + input[type='submit']

40
Capítulo 2: Localização de elementos
em uma página
Ou, mais livremente, por qualquer elemento irmão:

input[name='email'] ~ input[type='submit']

Por um descendente direto:

<div>
<input name="email">
</div>

div > input[name='email']

Ou por qualquer descendente:

<form>
<div>
<input name="email">
</div>
</form>

entrada de formulário[name='email']

Você perceberá que a maioria dos exemplos aqui não contém mais do que dois
elementos. Isso é intencional. Pense nesse seletor longo:

div > #login > div > input.btn.btn-primary

Se você removesse uma dessas divs, o seletor se tornaria inválido. Considere este,
sugerido pelo Chrome:

#login > div:nth-child(1) > input.btn.btn-primary

Se as divs fossem reordenadas, isso não seria mais válido. Seletores ideais e
fáceis de manter são concisos e precisos.

Localização de células de tabela usando seletores CSS

41
Capítulo 2: Localização de elementos
em uma página
As tabelas HTML são uma forma comum de layout de dados em uma página da
Web. Como você pode querer localizar células pelo título da coluna da célula, é
necessário fazer uma série de pesquisas. Vamos ver uma técnica para tornar o
acesso a elas menos complexo.

Você deseja localizar elementos de forma robusta em uma tabela, mas as tabelas
podem mudar e as colunas podem ser reordenadas.

Localizar células de tabela usando seletores CSS. Você pode acessar as células de
uma tabela HTML usando seletores CSS. Considere a tabela de usuários na figura
Tabela de usuários http://localhost:8080/users-table.html.

Figura 3. Tabela de usuários http://localhost:8080/users-


table.html Isso é criado pelo seguinte HTML:

users-table.html - http://localhost:8080/users-table.html

42
Capítulo 2: Localização de elementos
em uma página

<table class="table table-striped" id="users-table">


<caption>Usuários</caption>
<thead>
<tr>
<th>#</th>
<th>Email</th>
<th>Nome</th>
</tr>
</thead>
<tbody> (1)
<tr> (2)
<td>1</td>
<td>john@doe.com</td>
<td>John Doe</td> (3)
</tr>
<tr>
<td>2</td>
<td>jane@smith.com</td>
<td>Jane Smith</td>
</tr>
</tbody>
</table>

1. No tbody da tabela

2. 1ª linha

3. 3ª coluna

Aqui está um seletor que encontrará "John Doe" na tabela da figura Tabela de
usuários http://localhost:8080/users-table.html:

table#users-table tbody tr:nth-child(1) td:nth-child(3)

Driver de unidade CSS3 e HTML


Se você estiver usando o HTML Unit Driver, poderá descobrir que os exemplos que
usam a sintaxe de seletor CSS3 (como :nth-child) não funcionam.

Esse seletor localiza a terceira célula da primeira linha da tabela com o ID users-
table body. Isso é típico do acesso à tabela: localizar a célula nas coordenadas x/y.
Observe que a indexação é de 1 para N em vez de 0 para N-1. Esse seletor tem
uma consulta XPath equivalente:

//table[@id='users-table']/tbody/tr[1]/td[3]

43
Capítulo 2: Localização de elementos
em uma página
Nossa primeira tarefa é encontrar o índice da coluna que você deseja. Como você
deseja obter uma célula pelo título da coluna, pode fazer o seguinte:

TableIT.java

int columnNumber = 1;
while (!driver
.findElement(By.cssSelector(String.format("table#users-table th:nth-c
hild(%d)", columnNumber)))
.getText().equals("Name")) {
columnNumber++;
}

Esse loop será interrompido quando encontrar o cabeçalho; caso contrário, ele será
encerrado com um
NoSuchElementException se não conseguir encontrá-lo. Você pode encontrar a linha com
base no número retornado.

Por.cssSelector(
String.format("table#users-table tbody tr:nth-child(1) td:nth-child(%d)",
columnNumber))

Esse é um bom primeiro exemplo de como trabalhar com uma seção do DOM
de uma página, e não com um único elemento. Certas estruturas de página,
como formulários e tabelas, são razoavelmente complexas, e as relações entre
os elementos dentro delas são importantes para localizar o elemento específico
no qual você está interessado.

Essa também é uma ótima oportunidade para criar uma fábrica de localizadores:

TdBy.java

classe final pública TdBy {


private TdBy() {
}

public static By cellLocation(int rowNumber, int columnNumber) {


return By.cssSelector(String.format("tbody tr:nth-child(%d) td:nth-child(%d)",
rowNumber, columnNumber));
}
}

Você perceberá que pode usar localizadores baseados em XPath e CSS de forma
intercambiável. Mas quando você deve usar o XPath e quando deve usar o seletor CSS?
Não há regras rígidas e rápidas, mas como os XPaths são orientados pela estrutura do
documento que você está usando, é possível usar o seletor CSS.

44
Capítulo 2: Localização de elementos
em uma página
observando e CSS em torno do estilo, você pode se perguntar: "Estou localizando
com base na estrutura ou com base no estilo?"

A seguir, vamos ver um exemplo de encadeamento de contexto de pesquisa.

Limitando a localização em contextos de pesquisa


encadeados
Você pode combinar contextos de pesquisa. Por exemplo, se você conseguir localizar
um formulário em uma página, poderá encontrar facilmente o botão de envio desse
formulário usando o contexto de pesquisa
método findElement do formulário. Mas se você precisar pesquisar a página inteira,
poderá ter muitos botões. Nesta técnica, veremos como podemos encadear
pesquisas para localizar um elemento com facilidade e precisão.

Você tem um elemento que é difícil de encontrar com um único localizador.

WebElement implementa SearchContext . Isso significa que você pode encadear chamadas
para restringir o contexto até encontrar o elemento. Vamos dar uma olhada no HTML
bruto da página de login:

login.html - http://localhost:8080/login.html

<div class="container">
<h1>Login</h1>

<form class="form-inline" id="login">


<div class="form-group">
<input name="email" class="form-control" placeholder="Email"/>
<input type="password" name="password" class="form-control"
placeholder="Password"/>
<input type="submit" value="Login" class="btn btn-primary"/>
</div>
<div class="form-group forgotten-password">
<a href="#" id="change-password" class="btn">
Esqueci minha senha</a>
</div>
</form>
</div>

A classe btn é usada duas vezes aqui. Para localizar o link "Forgotten Password", você
pode encadear duas chamadas findElement para encontrar exatamente o que deseja:

ChainedLocatorsIT.java

45
Capítulo 2: Localização de elementos
em uma página

motorista
.findElement(By.className("forgotten-password")) (1)
.findElement(By.tagName("a")); (2)

1. Encontre um grupo de formulários para a senha esquecida.

2. Encontre um link nesse grupo.

Você tem várias maneiras de pesquisar elementos comuns. Se o elemento for mais
difícil de encontrar, você poderá usar uma cadeia de invocações de findElement
para restringir o contexto da pesquisa até obter o elemento desejado. Isso é
realmente eficaz quando se trabalha com formulários. Você pode localizar o
formulário com um localizador cuidadosamente criado e, em seguida, ser um pouco
mais solto para encontrar os elementos que deseja dentro do formulário:

ChainedLocatorsIT.java

WebElement loginForm = driver.findElement(By.id("login")); (1)


WebElement emailInput = loginForm.findElement(By.name("email")); (2)
WebElement passwordInput = loginForm.findElement(By.name("password"));
WebElement submit = loginForm.findElement(By.className("btn-primary"));

1. Localize o próprio formulário.

2. Limite cada elemento.

Isso pode resolver vários problemas com códigos de localização frágeis.

Composição do localizador
Você viu que realizamos repetidamente a mesma operação: encontrar um elemento
em uma página e, em seguida, restringir o escopo para encontrar outro elemento.
Você já viu isso com formulários e tabelas. O que você deve tentar fazer é manter
os localizadores simples: localizar uma célula em uma tabela ou uma entrada em
um formulário. Você pode combiná-los para fornecer uma localização mais
complexa.

O WebDriver não fornece isso de imediato, mas a biblioteca de suporte tem vários
localizadores úteis.

Biblioteca de suporte do WebDriver


O WebDriver fornece uma pequena biblioteca de suporte. Ela contém várias classes
úteis que não fazem parte da biblioteca principal. Essas classes incluem suporte
para (entre outras coisas) listas de seleção e objetos de página. Vale a pena incluí-

46
Capítulo 2: Localização de elementos
em uma página
las em seu

47
Capítulo 2: Localização de elementos
em uma página
projeto.

Localização por ID ou nome


Esse localizador localiza pelo valor do atributo ID ou nome. Isso é útil para situações
em que você espera que uma página seja alterada e deseja ser robusto em relação
a essa alteração. Isso é especialmente útil se o código de automação não convive
com o código de produção, e você não pode garantir que eles serão atualizados em
sintonia um com o outro. É um exemplo de compatibilidade retroativa/anterior. Isso
significa que você pode atualizar o teste antes que a alteração seja feita, e ele ainda
será aprovado antes e depois da alteração.

Considere esta entrada de senha:

<input type="password" name="password" class="form-control"/>

Pode ser que os desenvolvedores precisem alterar o nome para j_password . Você pode
negociar com eles para adicionar um ID a ele:

<input type="password" name="password" id="password" class="form-control"/>

Em seguida, você pode usar o seguinte localizador:

driver.findElement(new ByIdOrName("password"));

Isso funcionará antes e depois de a alteração ter sido feita. Um aspecto a ser
observado é que, se você usar ByIdOrName com findElements (plural), obterá o
superconjunto de elementos que correspondem: todos os elementos que têm o ID e
o nome.

Localizadores encadeados
Esse localizador executa uma sequência de correspondências, pesquisando no DOM
para encontrar o elemento. Provavelmente, a melhor explicação é usar um exemplo de
localização da entrada de e-mail no formulário de registro, mas sem usar nenhum
atributo principal da entrada de e-mail:

48
Capítulo 2: Localização de elementos
em uma página

<form role="form" id="registration-form"> (1)


<div class="form-group">
<label> (2)
E-mail
<input type="email" name="email" class="form-control"
placeholder="E.g. john.doe@swb.com"/> (3)
</label>
</div>
<!--- ... --->
</form>

1. Localizar formulário por ID "registration-form"

2. Encontre um rótulo com o texto "Email"

3. encontrar uma e n t r a d a

LocalizadorComposiçãoIT.java

driver.findElement(
novo ByChained(
By.id("registration-form"),
By.xpath("//label[contains(.,'Email')]"),
By.tagName("input")
)
);

O exemplo na listagem LocatorCompositionIT.java primeiro localizará o formulário de


registro pelo seu ID, depois localizará o rótulo dentro desse formulário e, por
fim, a entrada dentro desse localizador. Cada localizador é executado com o
WebElement retornado pelo elemento anterior. O código anterior é equivalente a isso:

driver.findElement(By.id("registration-form"))
.findElement(By.xpath("//label[contains(.,'Email')]"))
.findElement(By.tagName("input"));

Os localizadores encadeados são úteis quando você deseja misturar e combinar


diferentes localizadores.

Criação de compositores de localizadores para oferecer


compatibilidade retroativa/anterior

49
Capítulo 2: Localização de elementos
em uma página
Imagine que uma nova versão do seu site será lançada. Mas o HTML foi alterado de
modo que seus localizadores não funcionam mais - frustrante! Você pode atualizar
o localizador para a nova versão, mas isso pode não estar concluído ainda, ou pode
deixar seus testes "vermelhos" e garantir que todos saibam que eles precisam ser
atualizados em algum momento no futuro. Ou você pode garantir que seu teste seja
aprovado tanto com o código antigo quanto com o novo.
Esta técnica lhe mostrará como.

Você deseja localizar os elementos de forma confiável e flexível.

Crie uma fábrica de localizadores que componha localizadores usando operações de


correspondência, como
all , any e none . Por exemplo, você pode criar um localizador "all" da seguinte
forma:

AllBy.java

classe pública AllBy extends By {

By[] bys final privado;

private AllBy(By... bys) {


this.bys = bys;
}

público estático AllBy all(By... bys) { (1)


return new AllBy(bys);
}

@Override
public List<WebElement> findElements(SearchContext context) {
List<WebElement> elements = null;
para (By by : bys) {
List<WebElement> newElements = context.findElements(by);
Se (elementos == nulo) {
elements = newElements; (2)
} else {
elements.retainAll(newElements); (3)
}
}
retornar elementos;
}
}

1. Método estático de fábrica.

2. Se você tiver o primeiro conjunto de elementos, inicialize a lista.

3. Caso contrário, mantenha apenas os novos elementos.

50
Capítulo 2: Localização de elementos
em uma página
Você pode usá-lo da

seguinte forma:

LocatorCompositionIT.java

driver.findElement(AllBy.all(By.tagName("input"), By.name("password")))

Você pode emular o localizador IdOrName com um AnyBy :

AnyBy.java

classe pública AnyBy extends By {


By[] bys final privado;

private AnyBy(By... bys) {


this.bys = bys;
}

público estático By any(By... bys) {


return new AnyBy(bys);
}

@Override
public List<WebElement> findElements(SearchContext context) {
List<WebElement> elements = new ArrayList<>();
for (By by : bys) {
elements.addAll(context.findElements(by)); (1)
}
retornar elementos;
}
}

1. Adicione todos os elementos que você encontrar.

Isso pode ser usado da

seguinte forma:

LocatorCompositionIT.java

driver.findElement(AnyBy.any(By.id("email"), By.name("email")))

Se você quiser excluir correspondências, o código é simples:

NotBy.java

51
Capítulo 2: Localização de elementos
em uma página

classe pública NotBy extends By {

final privado By by;

private NotBy(By by) {


this.by = by;
}

público estático By not(By by) {


return new NotBy(by);
}

@Override
public List<WebElement> findElements(SearchContext context) {
List<WebElement> elements =
context.findElements(By.cssSelector("*")); (1)
elements.removeAll(context.findElements(by));
return elements;
}
}

1. Obtenha todos os elementos da página.

Por exemplo, para localizar todas as caixas de seleção de contato na página de


registro, mas excluindo a caixa de e-mail:

LocalizadorComposiçãoIT.java

driver.findElements(
AllBy.all(
By.name("contact"),
NotBy.not(By.cssSelector("*[value='email']"))
)
);

Os mais atentos já devem ter notado a semelhança com os matchers da Hamcrest.


Isso é intencional, pois facilitará o aprendizado. A pergunta que você talvez queira
fazer é: "Por que o WebDriver não vem com isso incluído?" Desempenho? Talvez. O
NotBy precisará retornar todos os elementos da página, o que pode ser bastante
lento, especialmente quando se trabalha com uma grade do Selenium ou em páginas
com grande número de elementos.

Essa é apenas uma maneira de combinar elementos de localização de

uma forma complexa. A seguir, veremos uma maneira de facilitar o

trabalho com as páginas.

52
Capítulo 2: Localização de elementos
em uma página

Tornar as páginas mais fáceis de localizar


elementos
Um dos desafios interessantes da automação de páginas é que estamos automatizando
um aplicativo que não foi escrito por nós mesmos. Acho que minha maior
recomendação para a automação é: se puder, obtenha acesso de gravação ao código-
fonte do aplicativo que está automatizando. Se você descobrir que há um elemento que
não pode ser localizado sem um seletor complexo, poderá modificá-lo para facilitar
o trabalho.

Item Uso

Atributo ID JavaScript e CSS.

Atributo de nome Parâmetros do formulário.

Atributo de classe Página de estilo.

CSS Estilizar a página.

Qualquer um deles pode ser legitimamente alterado por seu autor. Em nenhum
lugar da lista está escrito "usado para automação".

Uso de um prefixo de classe CSS comum para criar


seu próprio namespace de automação
O HTML do site é projetado para que o site tenha boa aparência e os clientes fiquem
satisfeitos. Mas e quanto à nossa automação de testes? Podemos agradar a todos!
Essa técnica mostrará como marcar o HTML de tal forma que as alterações no
HTML necessárias para o estilo ou qualquer outra coisa não afetem seus testes.

As páginas são alteradas, causando a quebra do código de automação.

Obter acesso de gravação ao código-fonte da página. Adicione dados de automação a


ela. Revisar o HTML do carrinho de compras:

carrinho de compras.html

<input type="text"
name="cartDS.shoppingcart_ROW0_m_orderItemVector_ROW0_m_quantity"
class="form-control input-sm" value="1" size="2"/>

53
Capítulo 2: Localização de elementos
em uma página
O único aspecto que podemos alterar sem afetar o comportamento da página é o
nome da classe. Podemos acrescentar uma nova classe especial a ela, neste caso
wd-cart-item-0 :

<input type="text"
name="cartDS.shoppingcart_ROW0_m_orderItemVector_ROW0_m_quantity"
class="form-control input-sm wd-cart-item-0" value="1" size="2"/>

Para dividir isso em suas partes:

wd

Um prefixo de automação ("wd" para WebDriver, mas você pode querer auto
para automação).

i t e m do carrinho-0

Uma ID de automação para acessarmos.

Podemos usar isso da seguinte forma:

driver.findElement(By.className(String.format("wd-cart-item-%d", 0)))

Essa técnica depende do acesso ao código-fonte e de um acordo claro e bem


conhecido de que as classes prefixadas com seu prefixo de automação são apenas
para automação e não podem ser usadas para programação ou outros motivos. Seria
fácil para um novo desenvolvedor acidentalmente prejudicar essa técnica se não a
conhecesse, por isso é muito importante que todos estejam cientes dela.

Em vez de ter o prefixo comum espalhado pelo seu código, essa técnica pode ser
combinada com fábricas de localizadores para produzir um código mais conciso,
por exemplo:

ElementBy.java

classe final pública ElementBy {


...

public static By automationId(String id) {


return By.className("wd-" + id);
}
}

Usado da seguinte forma:

driver.findElement(ElementBy.automationId(String.format("cart-item-%d", 0)))

54
Capítulo 2: Localização de elementos
em uma página

Quando usar cada localizador?


Abordamos tanto os localizadores integrados quanto alguns personalizados. Mas
quando usar cada um deles? Aqui está uma folha de dicas útil para ajudá-lo!

Localizador Quando usá-lo

ID Quando seu elemento tem uma ID


exclusiva
Quando você está testando um
Nome
formulário e o nome do input é
exclusivo
Quando o elemento tem um nome de
Nome da classe
classe exclusivo

Quando você quiser localizar um


Nome da etiqueta
título de página

Quando você precisa localizar um link


Texto do link
e só se importa com um idioma

Quando você precisa de um


CSS
localizador complexo ou tem um
prefixo de automação
Quando você precisa de um
XPath
localizador complexo e o CSS não
funciona
Quando você precisa de um
Acorrentado localizador complexo, mas deseja
misturar diferentes tipos de
localizador

Resumo
SearchContext é a interface principal para localizar elementos, os métodos
findElement e findElements são os métodos principais.

Você tem vários métodos diferentes para localizar elementos. Eles incluem ID,
nome, classe, CSS e XPath.

55
Capítulo 2: Localização de elementos
em uma página
Os localizadores XPath e CSS são poderosos. Esse poder pode gerar
complexidade e, portanto, o uso de padrões, como a composição e o padrão de
estratégia, pode ajudar muito a simplificar seu uso.

A criação de fábricas de localizadores pode tornar segura a criação de localizadores


complexos.

Você pode encapsular estruturas de página complexas, como tabelas, em classes


auxiliares. O padrão Decorator é útil quando você está fazendo isso.

Os elementos difíceis de encontrar podem ser localizados usando o padrão de


navegação.

Se você tiver acesso ao site que está automatizando, um prefixo de automação


pode reduzir a complexidade da automação de páginas.

Agora que você já sabe como localizar elementos em uma página, chegou a hora
de abordar os vários métodos de interação com esses elementos. O foco do
próximo capítulo será trabalhar com os vários métodos que o WebDriver eo
WebElement fornecem para interagir com a página.

56
Capítulo 3: Interagindo com elementos em
uma página

Capítulo 3: Interagindo com elementos


em uma página
Este capítulo abrange

Inserção de texto em campos de entrada, áreas de texto

Trabalhar com o mouse para clicar em botões e links

Trabalhando com o toque

Ao automatizar as interações com uma página, você está assumindo a função do


usuário. Isso significa que você desejará ser capaz de fazer tudo o que o usuário
pode fazer, inclusive inserir texto do teclado e selecionar e interagir com elementos
individuais na página. O WebDriver oferece várias maneiras de fazer isso, mas, na
maioria dos casos, você só precisará usar um subconjunto delas, portanto, neste
capítulo, abordaremos primeiro os métodos mais comuns e, portanto, mais úteis.

Neste capítulo, você aprenderá a:

Inserir texto usando as classes WebElement e Keyboard

Controle o mouse usando as classes WebElement e Mouse.

Executar técnicas específicas para trabalhar com formulários.

Seja o usuário
Ao elaborar um teste para simular o comportamento de um usuário, vale a pena
colocar-se no lugar do usuário e, em seguida, detalhar as etapas que você
executaria. Gosto de considerar a meta que o usuário deseja atingir e quais
operações eu realizaria para atingir essa meta. Por exemplo:

Meu objetivo seria fazer login em um site para poder enviar

um e-mail. As operações poderiam ser:

1. Clique na entrada denominada "Username" (Nome de usuário).

2. Digite o nome de usuário.

57
Capítulo 3: Interagindo com elementos em
uma página
3. Clique ou faça tabulação na entrada denominada "Password" (Senha).

4. Digite a senha.

5. Clique no botão Login ou pressione Return.

Figura 1. Formulário de login http://localhost:8080/login.html


Vale a pena observar que o usuário pode estar fazendo algumas coisas que não
são imediatamente claras. Por exemplo, ao digitar uma senha, ele pode verificar se o
texto da senha está oculto ou se a página é segura. Abordaremos as verificações
que um usuário pode fazer no capítulo 7.

Uma das principais ações de um usuário, ao preencher formulários, é inserir texto


nos elementos do formulário.

Inserção de texto
A inserção de texto é fundamental para várias tarefas comuns ao testar páginas da
Web. A mais comum seria o preenchimento de um formulário. Pense nas tarefas
que o usuário pode querer realizar:

Faça login ou registre-se em um site.

Enviar uma atualização de rede social.

Concluir a compra de um item com um cartão de crédito.

Escreva um e-mail.

Atualizar uma postagem de blog.

58
Capítulo 3: Interagindo com elementos em
uma página
O texto que você precisa digitar pode ser texto simples, mas talvez seja necessário
digitar texto rico, texto que pode conter negrito ou itálico, por exemplo.

O WebDriver oferece duas maneiras de inserir texto. O primeiro método é enviar


diretamente as teclas para um elemento na página. Isso é conveniente, pois está
disponível como um método da classe
classe WebElement. O segundo método, para drivers que implementam a classe
A interface HasInputDevices serve para controlar o objeto de teclado. Isso é mais
avançado e permite que você faça mais coisas, mas também é mais complexo.

Vamos dar uma olhada nos dois principais métodos que o WebDriver fornece para a
interação com o teclado.

WebElement.java

interface pública WebElement extends SearchContext {

void sendKeys(CharSequence... keysToSend);

void clear();

...
}

E podemos usar esse teste para entender como funcionam o sendKey e o clear. Sem
limpar o texto primeiro, sendKey simplesmente anexará o texto ao final do texto
original,

LoginIT.java

@Teste
public void login() throws Exception {
driver.get("/login.html");

WebElement email = driver.findElement(By.name("email")); (1)


email.clear(); (2)
email.sendKeys("john@doe.com"); (3)

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


password.clear();
password.sendKeys("secret");

driver.findElement(By.cssSelector("input[type='submit']"))
.click();
}

1. Localizamos o elemento primeiro

59
Capítulo 3: Interagindo com elementos em
uma página
2. Precisamos limpar o texto dentro da entrada, caso contrário, o texto será
anexado ao texto original

3. Defina a string "john@doe.com" para o campo "email"

O envio de teclas diretamente usando o método WebElement tem a vantagem de ser


conciso e, portanto, é uma boa opção padrão para inserir texto na maioria dos
casos. No entanto, ele não tem a precisão da classe Keyboard. Por exemplo, não é
possível controlar quando uma tecla é pressionada e liberada.

Você usa uma técnica de localização de elementos para encontrar o elemento


desejado, e o WebDriver enviará o texto desejado diretamente para ele, como se
você tivesse selecionado o elemento com um clique do mouse e começado a
digitar. Infelizmente, não é possível fazer tudo o que um usuário pode fazer com o
teclado usando as teclas de envio.

Você também pode obter um identificador para o teclado usando o método


getKeyboard dos drivers que implementam a interface HasInputDevices:

Keyboard.java

interface pública Keyboard {

void sendKeys(CharSequence... keysToSend);

void pressKey(CharSequence keyToPress);

void releaseKey(CharSequence keyToRelease);

A interface do teclado permite simular as ações exatas do usuário, até as teclas


exatas pressionadas. O uso da interface do teclado tem as vantagens do controle e da
precisão. Você pode fazer tudo o que o usuário pode fazer. Ao contrário do método
sendKeys, você não envia as teclas pressionadas a um elemento específico. Em vez
disso, elas serão digitadas no elemento ativo. Você pode digitar facilmente caracteres
não imprimíveis, inclusive teclas modificadoras (Alt, Ctrl, Command e a japonesa
Zeukauk-Hankaku), teclas de função (F1 a F12), Backspace e teclas de seta
(esquerda, direita, para cima e para baixo). Se você tiver um aplicativo complicado,
como um jogo baseado na Web, talvez seja necessário usar essas teclas. Se quiser
obter mais informações sobre caracteres imprimíveis e não imprimíveis:
http://en.wikipedia.org/wiki/ASCII. As interfaces de teclado não oferecem suporte para
localização de elementos; o texto digitado é enviado para o elemento ativo no
momento, o que significa que você precisará focalizar o elemento.

60

Você também pode gostar