Primeiros passos com o Protractor — Parte 2
Este é o segundo post da série sobre Protractor. Se você ainda não leu o primeiro, veja aqui como dar os primeiros passos com Protractor. Hoje vamos conhecer os locators mais utilizados, saber em qual situação utilizar e quais as vantagens de cada um deles, além de entender como o Protractor trabalha com as promisses. Bora lá?
O Protractor exporta a função global element, que é responsável por encontrar um elemento no DOM. Caso você precise manipular múltiplos elementos, pode usar a função element.all, e com essas funções é possível utilizar os métodos das ações como click(), getText() e sendKeys().
O ElementFinder do Protractor executa as ações de forma assíncrona, ou seja, todas elas são enviadas para o browser, que vai gerenciá-las utilizando o Protocolo do WebDriver. O browser, então, executa essas ações como um usuário comum.
Além de todos os locators específicos do WebDriver nós temos a opção de utilizar locators específicos para aplicações AngularJS. Na minha opinião essa é uma das principais vantagens de usar Protractor para automatizar nossos testes. Veja abaixo os principais locators do Protractor e quando utilizar cada um deles:
by.addLocator
Acho que esse é um dos mais legais. Com ele nós podemos criar nosso locator customizado. Isso mesmo, podemos escolher como encontrar nossos elementos na tela. Top demais né? E como utilizar?
Primeiro, imagine que no seu html você pode ter um elemento que utiliza data attributes. Por exemplo:
Repare que temos um atributo data-test=”filtro”. Quando queremos manipular esse elemento via JS, podemos encontrá-lo dessa forma:
Beleza Cássio, você já falou sobre data-attributes, já falou como encontrar esse elemento usando JS, mas queremos utilizar o Protractor para encontrar esse elemento nos nossos testes.
Pois bem, agora acontece a “mágica”.
Primeiro, temos que ir ao nosso arquivo de configuração do Protractor e adicionar esse trecho de código dentro da nossa função onPrepare:
Pronto, feito isso você já pode utilizar o seu locator customizado dentro dos seus testes, da seguinte forma:
Legal, né? Isso pode ser uma ótima forma de deixar seus testes mais resilientes contra falhas, pois muitas vezes id’s e name’s acabam sendo alterados e quebram nossos testes. Pode até adotar como sendo um padrão dentro do seu projeto a utilização de data attributes para facilitar a manipulação dos elementos.
by.binding e by.exactBinding
Para elementos que contenham a diretiva ng-bind (do próprio AngularJS) podemos utilizar os locators by.binding ou by.exactBinding:
Ao utilizar o locator by.binding podemos passar como parâmetro apenas uma parte do valor da diretiva, como:
Já para o by.exactBinding temos que passar exatamente o valor que está declarado na diretiva.
by.model
Encontra um elemento no DOM que tenha a diretiva ng-model (do próprio AngularJS):
Encontramos esse elemento da seguinte forma no teste com Protractor:
by.buttonText e by.partialButtonText
Ambos encontram um elemento no DOM baseado pelo texto do botão:
Para localizar esse elemento usamos:
Ou, por apenas por uma parte do texto do botão, utilizamos o by.partialButtonText:
by.repeater e by.exactRepeater
Encontra elemento com a diretiva do AngularJS ng-repeat:
Esse locator é muito útil e ajuda muito quando precisamos lidar com uma lista de elementos. Com ele podemos extrair várias informações úteis como:
Quantidade de registros listados
Retornar um dado específico da listagem:
Retornar todos os valores de uma determinada coluna
Para usar o by.exactRepeater, como o próprio nome sugere, devemos passar por parâmetro o valor exatamente igual ao que está no valor da diretiva. Nesse caso fica assim:
Obs.: podemos continuar extraindo as informações da mesma forma que o by.repeater.
* Em breve teremos um post com algumas dicas de como trabalhar listas usando Protractor e alguns métodos auxiliares.
by.cssContainingText
Esse locator encontra elemento por CSS que contenha um determinado texto. Recebe dois parâmetros, o primeiro é o seletor css e o segundo é o texto que vai filtrar. Veja abaixo um exemplo:
Dado que tenha mais de um elemento html com a mesma class:
Para filtrar um específico usamos da seguinte maneira:
by.options
Encontra um elemento com a diretiva do AngularJS ng-opitons
Para encontrar esse elemento utilizando Protractor:
Como o Protractor trabalha com as Promisses?
Como já falei anteriormente, todos as ações do Protractor são assíncronas, isso significa que todos os métodos retornam uma promisse. Então, se quisermos saber o valor de um determinado elemento, precisamos fazer assim:
Se quisermos saber se um elemento está habilitado:
Se quisermos saber se um elemento está visível:
Obs.: Alguns locators do Protractor ainda não estão funcionando adequadamente com as novas versões do AngularJS. Tem uma issue aberta no github do Protractor sobre esse assunto, e se você quiser acompanhar é só clicar aqui.
O Protractor possui uma grande variedade de locators e saber qual podemos utilizar em cada situação é uma grande vantagem para melhorar nossos testes. Então, antes de sair utilizando XPATH e CSS Selector (só usem em último caso e ainda sim, saibam como utilizar com inteligência), tentem utilizar ao máximo os locators do Protractor. Fechado? Se tiver alguma dúvida ou tem algo a acrescentar, é só usar os campos abaixo. Até a próxima!
Quer saber mais? Acesse:
— Protractor API Docs
— Making your UI tests resilient to change (Kent Dodds)
— Promise Manager (Protractor — WebDriverJs)