Utilizando Async/Await com Protractor

Lucas Fraga
assert(QA)
Published in
4 min readJul 4, 2018
ilustração com códigos

Após o excelente post do Cássio Alves (Primeiros passos do Protractor), somados ao entendimento dos guias criados por ele mesmo, resolvi avançar um pouco para ver o que conseguiria alcançar usando o Protractor integrado ao CucumberJS, com o padrão Page-Objects e a lib de asserts do Chai.

Entendimento básico em chamadas assíncronas e síncronas

Sem entrar muito nesse assunto, as chamadas assíncronas são aquelas que quando feitas não impedem que outros processos sejam executados. Isso possibilita que o usuário continue a interagir com a aplicação enquanto o processo é executado em paralelo e, quando o mesmo é finalizado, o usuário verifica o resultado.

Já nas chamadas síncronas, o processo enviado é bloqueado até que ocorra uma resposta, ou seja, não é possível enviar novas requisições até que a atual seja finalizada. Enfim, existe um sincronismo nas requisições.

Mudando o nosso mundo com async/await

As funções assíncronas do JS quando são chamadas retornam uma Promises. Logo, quando a função assíncrona retorna um valor, a Promise vai ser resolvida com o valor retornado (ou rejeitada com um valor lançado).

A expressão ‘await’ pausa a execução da função assíncrona e espera pela resolução da Promise passada. Após isso, ela retoma a execução e segue o fluxo.

Então, a função async/await é para simplificar o uso de forma síncrona das Promises e executar alguns procedimentos em um grupo de Promises. Agora, em vez de usarmos o fluxo de controle, podemos sincronizar nossas funções com o async/await.

Quer ver as notas sobre async-await? Entre aqui.

Como utilizar async/await?

Ao perceber que os steps estavam dando um falso positivo — mesmo com o .then(callback) e os asserts.equals, comumente usados, que não foram aceitos por retornar um objeto (ao usar getText) –, coloquei na cabeça o seguinte raciocínio:

“Promises nada mais é do que a certeza do que você diz fazer, vai de fato acontecer.”

Então o que fazer para esperar e validar minha execução corretamente? Muito mais simples do que imaginávamos. Vamos lá…

Hands On

Não falaremos sobre a estrutura do projeto em si e tão pouco sobre o passo a passo, apenas focaremos no await e no resultado final disso. Só precisamos lembrar que vamos utilizar a dependência “chai-as-promised”: “⁷.1.1” para os asserts.

Vamos utilizar uma aplicação simples em AngularJS, a famosa Super Calculadora. As funcionalidades vão ser basicamente duas: somar e subtrair. O repositório com o código para rodar localmente está aqui.

ARQUIVO PAGE-OBJECTS

Nosso Page-Objects é bem simples, nada diferente do que costumamos ver.

Linha 4 — Classe Calculadora
Linha 5 — Constructor com os elementos mapeados
Linha 15 — Método para acessar a página (baseUrl que se encontra no arquivo de conf)
Linha 19 — Método de soma
Linha 27 — Método de subtração
Linha 37 — Módulo para exportar o Page

UTILIZANDO OS ASYNC/AWAIT

Vamos à explicação das linhas:

Linha 3 — Gancho para o caminho e utilização do CucumberJS
Linha 4 — Utilização do chai/chai-as-promised nos asserts
Linha 7/8 — Puxando o nosso Page para acessarmos através dos steps
Linha 10 em diante — Steps com async function() e awaits

Conclusão e explicação dos awaits no step

O framework CucumberJS utiliza chamadas assíncronas para ler e executar as features. O uso do async é para podermos utilizar o await, fazendo com que a execução seja forçada a aguardar que a linha seja executada antes de seguir com o fluxo. Assim, garantimos a ordem da execução além de percebermos uma melhoria no código.

No código abaixo, inclusive, o await está pausado, aguardando para seguir ao próximo step quando realizar a adição e/ou esperar por um tempo colocado como default [caso não ache algo].

steps when com método para adicionar na calculadora

Ao utilizamos o .to.eventually estamos expressando o que realmente queremos dizer. Por isso, não é preciso o uso do .then(), apesar que isso vai muito da preferência de cada um, mas para se ter mais controle das promises ele se faz necessário. Por exemplo, caso precise tratar algo no retorno da promises antes de usar o expect, o modo que funcionaria seria com o uso do .then().

steps then com método para validar o resultado

Por fim, vamos rodar o projeto para visualizarmos o resultado no terminal e logo em seguida o report do cucumber-html:

--

--