Vamos a repasar una serie de consejos y funcionalidades para hacer nuestros tests de e2e con Protractor más fáciles de mantener y debuggear.
Queries específicas de e2e
No es bueno usar las mismas clases para tus estilos y tu js que para tus test e2e. Es muy fácil que cuando estamos modificando el html borremos alguna clase que sea clave para que nuestros test e2e se ejecuten. Una forma de prevenirlo es añadir clases que solo se usen en los test e2e con un prefijo específico.
1 | <button class="btn-submit e2e-submit" (click)="onSubmit()">Enviar</button> |
Estas clases podemos borrarlas al generar el código de producción, por ejemplo con webpack podemos hacerlo con string-replace-loader
.
1 | module.exports = { |
Usar async/await
A veces en nuestros test queremos esperar a tener un resultado específico, antes de continuar podemos esperar a que se resuelva la promesa con .then
, pero nuestros test van a ser difíciles de entender o leer.
1 | browser.getCurrentUrl().then((url) => { |
Con async/await es mucho más legible.
1 | const url = await browser.getCurrentUrl(); |
Si empezamos a usar async/await podemos desactivar Selenium promise manager en nuestro protractor.conf.js
1 | exports.config = { |
Añadir mensajes de error en browser.wait
Si tenemos muchos browser.wait
puede llegar a ser difícil identificar cuál falla pero si le indicamos en su tercer parámetro un mensaje si ese wait expira sin cumplir la condición nos dará el mensaje anterior.
1 | browser.wait(() => { |
1 | browser.wait(() => { |
Expected conditions
Con protractor y selenium tenemos una serie de condiciones muy útiles por las que podemos esperar en nuestros browser.wait
. Veamos algunos ejemplos.
1 | // Esperando que el botón sea clickable |
1 | const button = element(by.css('.e2e-button')); |
1 | // podemos combinar expected conditions |
1 | const button = element(by.css('.e2e-button')) |
Component Objects
Lo mejor que podemos hacer por la legibilidad de nuestros test es crear objetos que manejen partes específicas de la página. Estos objetos podrian manejar un componente muy concreto o una página entera. Veamos primero un ejemplo escrito sin objetos.
1 | describe('Posts', () => { |
Este test sin los comentarios sin ser un test complejo no es muy fácil de leer, además si un query selector cambia es muy posible que tengamos que cambiarlo en varios tests. Veamos ahora el mismo ejemplo usando una clase para manejar nuestra página de enviar posts.
1 | describe('Posts', () => { |
Es exactamente lo mismo que lo anterior pero mucho más legible ¿verdad?, vemos ahora el código de nuestras dos clases PostPage y PostForm.
1 | export class PostPage { |
Ahora tenemos toda la funcionalidad en pequeñas funciones que indican claramente a qué se dedican y además hemos añadido algo que no teníamos antes, en el constructor de cada objeto nos aseguramos que el componente con el que queremos interactuar está listo.
Hightlight clicks
Empezamos con el debugging, a veces si estamos debuggeando un test e2e queremos saber al detalle qué está pasando, por ejemplo queremos ir viendo donde está protractor haciendo click, para ello simplemente tenemos que activarlo en nuestro protractor.conf y ahora nos resaltará el elemento justo antes de hacer click en él.
1 | exports.config = { |
Para hacerlo funcionar tenemos que deshabilitar antes el directConnect
y activar useBlockingProxy
, entonces podremos poner en highlightDelay
cuanto queremos que esté el elemento seleccionado antes de hacer click.

Como vemos en el gif antes de hacer click en el element vemos el foco.
Logs
También podemos almacenar logs de todo lo que hace protractor.
1 | exports.config = { |

En la imagen podemos ver qué elementos ha buscado y donde ha hecho click, muy útil si queremos averiguar dónde está fallando nuestro test.
Debugging con chrome
Podemos ejecutar el debugger de chrome como en cualquier otra parte de nuestra app, para ello ponemos debugger;
donde queremos que pare. Ahora lanzamos nuestros test de una forma algo distinta.
1 | node --inspect-brk node_modules/.bin/protractor protractor.conf.js |
Veremos este mensaje de confirmación.

A continuación abrimos chrome y entramos en chrome://inspect/#devices
y le damos a Inspect.

Ahora nuestro test avanzará hasta que encuentre el debugger;
y ya podemos usar toda la potencia de devtools en nuestro test.

Node 8+
Los siguientes métodos de debug no pueden ser usados por Node 8+
Pause
Podemos poner en nuestro test browser.pause()
para que el navegador se pare en ese punto. Al ejecutar nuestro test e2e protractor se parará en la línea donde pongamos el pause y el terminal nos pedirá instrucciones.

Ahora podemos continuar el test con normalidad con Ctrl+c
o que avance una tarea escribiendo c
.

Explore
El browser.explore()
nos pausa el navegador en el punto elegido y al igual que antes en pause el terminal nos pedirá instrucciones, salvo que aquí en vez de continuar a la siguiente tarea podemos interactuar con protractor al igual que haríamos en nuestro test.

Debugger
browser.debugger()
es similar a debugger;
la diferencia es que con uno interactuamos con el terminal y con el otro con devtools. También se comportan algo distinto browser.debugger()
pausa el navegador después de que la acción anterior haya sido completada en cambio debugger
lo pausa cuando la acción ha sido programada.
Para lanzarlos ejecutamos el siguiente comando protractor debug protractor.conf.js
. Ahora en el terminal podemos escribir c
para que avance hasta el siguiente breakpoint o n
para ir al siguiente comando.
En el navegador además disponemos de algunas quereis especiales de protractor en window.clientSideScripts
.