Introducción
Esta artículo pretende explicar cómo Phanjom.js puede ayudarnos a comprobar de manera automática, la adaptabilidad de nuestra aplicación web a diversas resoluciones de pantalla, generando capturas de las páginas HTML de nuestra aplicación.
¿Qué es Phantom.js?
PhantomJS es un navegador sin interfaz gráfica basado en Webkit, es decir, no nos sirve para testear nuestra aplicación con IE ni Firefox, y sólo podemos manejarlo con un terminal, o la consola MSDOS, usando un API Javascript.
¿Qué podemos hacer con Phantom.js?
- Lanzar test unitarios con Jasmine, QUnit, Mocha, y muchos otros.
- Simular acciones del usuario, antes de realizar la captura de pantalla: click, mouseover, keypress, etc...
- Podemos manejar el DOM con librerías con jQuery, si lo necesitamos para testear nuestras páginas.
- Automatizar la eficiencia de nuestras páginas con YSlow y Jenkins
Prepara el entorno
Lo único que necesitamos es un servidor web, ya sea Apache, Nginx o Node.js, con el que servir los estáticos de nuestra aplicación. Si usamos Grunt, podemos lanzar la tarea grunt-connect, o simplemente podemos crearnos un script para lanzar un servidor web bajo Node.js.
Añadir Express a package.json
Para que el anterior script funcione, será necesario que instaléis antes Express, como un módulo de Node.js. Para ello, simplemente editamos nuestro archivo package.json y añadimos la dependencia:
{ "name": "hello-world", "description": "hello world test app", "version": "0.0.1", "private": true, "dependencies": { "express": "3.x" } }
De este modo, una vez añadida, para instalarla ejecutamos:
npm install
Arrancar el servidor Node
El siguiente código de ejemplo, nos sirve para arrancar un servidor Node en el puerto 3000, y suponiendo que los estáticos que queremos testear están en el directorio /dev, y dentro de él, que nos redireccione a /html/index.html. Este código lo guardamos como web.js, por ejemplo:
var express = require( "express" ), app = express(), port = process.env.PORT || 3000; process.env.PWD = process.cwd() app.configure(function(){ // Directorio donde estará la raíz de nuestro servidor app.use(express.static( process.env.PWD + '/dev' )); app.use(express.bodyParser()); app.use(express.methodOverride()); //Error Handling app.use(express.logger()); app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); app.use(app.router); }); // Redireccionamos a /dev/html/index.html app.get('/', function(req, res){ res.redirect( "/html/index.html" ); }); app.listen(port, function() { console.log( "Listening on " + port ); });
Para hacerlo funcionar, lo ejecutamos desde la consola:
node web
Añadiendo Phantom.js al PATH
Lo primero que debemos hacer es, obviamente, descargarnos Phantom.js. Una vez descargado, lo guardamos en el directorio C:/phantomjs
Después editamos la variable de entorno PATH, y añadimos dicha ruta, para que phantomjs.exe, esté disponible desde la consola de MSDOS, o terminal. Es posible que tengas que reiniciar para que la variable de entorno la coja bien Windows.
Definiendo los test y capturas de pantalla a realizar con Phantom.js
Como Phantom.js se maneja sólo por comandos, si queremos simular la acción del usuario, o capturar pantallas, lo siguiente que debemos hacer es crearnos un archivo javascript con el que definir las acciones a realizar con dicho navegador. Este código lo guardamos con el nombre phantomtest.js (por ejemplo):
(function(){ "no strict"; var resourceWait = 300, maxRenderWait = 10000, forcedRenderTimeout, clickTimeout, renderTimeout, url = 'http://localhost:3000/html/index.html', page = require('webpage').create(); page.onConsoleMessage = function (msg, line, source) { console.log( 'console> ' + msg ); }; page.onAlert = function (msg) { console.log( 'alert!!> ' + msg ); }; page.onResourceRequested = function (req) { //console.log( 'request> ' + req.id + ' - ' + req.url ); clearTimeout(renderTimeout); }; page.onResourceReceived = function (res) { if (!res.stage || res.stage === 'end') { console.log( 'loaded> ' + res.id + ' ' + res.status + ' - ' + res.url); } }; page.open(url, function (status) { if (status !== 'success') { console.log('Error al cargar la URL: ' + url); } else { forcedRenderTimeout = setTimeout(function () { page.viewportSize = { width: 1024, height : 512 }; page.render( 'test-1024.png' ); page.viewportSize = { width: 768, height : 512 }; page.render( 'test-768.png' ); page.viewportSize = { width: 320, height : 512 }; page.render( 'test-320.png' ); phantom.exit(); }, maxRenderWait); } }); }());
Ejecutamos los test con Phantom.js
Una vez que tengamos nuestro servidor funcionando en el puerto 3000, sólo nos queda ejecutar phantomtest.js con el navegador. Para hacerlo funcionar, iniciamos otra consola nueva, y escribimos:
phantomjs phantomtest
Lo que sucede a continuación, es que Phantom.js va a ejecutar las acciones que le hayamos indicado en phantomtest.js: tendremos 3 capturas de pantalla, a diferentes resoluciones, de una de las páginas de nuestra aplicación. Si quisiésemos simular acciones de usuario, o modificar el DOM, podemos usar jQuery. En dicho caso, las acciones las debemos englobar dentro de page.evaluate. Nuestro page.open quedaría ahora así:
page.open(url, function (status) { if (status !== 'success') { console.log('Error al cargar la URL: ' + url); } else { forcedRenderTimeout = setTimeout(function () { page.viewportSize = { width: 1024, height : 512 }; page.evaluate(function () { var $elm = $("#test3"); if( $elm.length > 0 ) { $elm.trigger("click"); } }); page.render( 'test-1024-click.png' ); page.viewportSize = { width: 768, height : 512 }; page.render( 'test-768.png' ); page.viewportSize = { width: 320, height : 512 }; page.render( 'test-320.png' ); phantom.exit(); }, maxRenderWait); } });
De este modo hemos simulado, antes de hacer la captura de pantalla, que el usuario ha hecho click en el elemento cuyo id es #test3.
Ejemplo de código
Si quieres ver todo junto funcionando, puedes encontrar el código al que hago referencia en este artículo, aquí: https://github.com/alfonsomartinde/prettychecks.
No hay comentarios :
Publicar un comentario