RootsLabs

More than a tool ! GitHub Google+ LinkedIn RSS

Créer une miniature d’un site web adaptatif via PhantomJS et SlimerJS

Progi1984 - Commentaires (4)

Un site doit désormais s’adapter à différents phériphériques que ce soit un terminal mobile, un ordinateur, une tablette ou un écran de télévision. La technologie dite de Responsive Design est là pour cela. Afin de tester un site aux différents points de rupture, il me fallait trouver une technique et automatiser ces tests : PhantomJS (Chrome) et SlimerJS (Firefox) sont les solutions.

PhantomJS : Installation

  • Télécharger le package
$ wget https://phantomjs.googlecode.com/files/phantomjs-1.9.2-linux-x86_64.tar.bz2
--2013-09-23 19:46:15--  https://phantomjs.googlecode.com/files/phantomjs-1.9.2-linux-x86_64.tar.bz2
Résolution de phantomjs.googlecode.com (phantomjs.googlecode.com)... 173.194.66.82, 2a00:1450:400c:c03::52
Connexion vers phantomjs.googlecode.com (phantomjs.googlecode.com)|173.194.66.82|:443...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: 13279068 (13M) [application/x-bzip2]
Sauvegarde en : «phantomjs-1.9.2-linux-x86_64.tar.bz2»

100%[===========================================================================================================================================================================>] 13 279 068  1,39MB/s   ds 9,3s   

2013-09-23 19:46:25 (1,36 MB/s) - «phantomjs-1.9.2-linux-x86_64.tar.bz2» sauvegardé [13279068/13279068]
  • Décompresser le package
$ tar xf phantomjs-1.9.2-linux-x86_64.tar.bz2 phantomjs-1.9.2-linux-x86_64/
  • Copier le binaire vers /usr/local/bin/
$ cp phantomjs-1.9.2-linux-x86_64/bin/phantomjs /usr/local/bin/
cp: impossible de créer le fichier standard « /usr/local/bin/phantomjs »: Permission non accordée
$ sudo !!
sudo cp phantomjs-1.9.2-linux-x86_64/bin/phantomjs /usr/local/bin/
[sudo] password for franck:
  • Dés lors, trois cas peuvent apparaître :
    • Cela fonctionne parfaitement bien.
      $ phantomjs phantomjs-1.9.2-linux-x86_64/examples/hello.js
      Hello, world!
    • Il manque le package freetype
      $ phantomjs phantomjs-1.9.2-linux-x86_64/examples/hello.js
      phantomjs: error while loading shared libraries: libfreetype.so.6: cannot open shared object file: No such file or directory
      
      $ sudo yum install freetype
    • Il manque le package fontconfig
      $ phantomjs phantomjs-1.9.2-linux-x86_64/examples/hello.js
      phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
      
      $sudo yum install fontconfig

PhantomJS : Script

Voici un script de base qui va vous permettre de faire un screenshot d’une site en 1024*768 et de l’exporter vers un fichier PNG.

/*
    requires: phantomjs
    usage: phantomjs screenshot.js
*/
var page = new WebPage(),
    url, filename;

if (phantom.args.length < 2) {
    console.log('Usage: screenshot.js URL filename');
    phantom.exit();
} else {
    url = phantom.args[0];
    filename = phantom.args[1];

    page.viewportSize = { width: 1024, height: 768 };

    page.open(url, function (status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
        } else {
            window.setTimeout(function () {PhantomJS
                page.render(page.viewportSize.width + 'x' + page.viewportSize.height +'_'+ filename);
                phantom.exit();
            }, 2000);
        }
    });
}

Malheureusement, on a qu’une seule taille de viewport, il en faudrait plusieurs afin de tout tester.
Modifions ce script pour gérer plusieurs viewports.

/*
    requires: phantomjs
    usage: phantomjs screenshot.js URL
*/
var sizes = [
        [320, 480],
        [320, 568],
        [600, 1024],
        [1024, 768],
        [1280, 800],
        [1440, 900]
    ],
    count, url, filename;

if (phantom.args.length < 1) {
    console.log('Usage: screenshot.js URL');
    phantom.exit();
} else {
   url = phantom.args[0];
   var filename = url.replace('http://','');
   filename = filename.replace('www.','');
   filename = filename.replace(/\./g,'_');
   filename = filename.replace(/\//g,'_');
   count = 0;
   sizes.forEach(function(vpSize){
    count++;
    var page = new WebPage();
    page.viewportSize = { width: vpSize[0], height: vpSize[1] };
    page.open(url, function (status) {
      if (status !== 'success') {
        console.log('Unable to load the address!');
      } else {

        window.setTimeout(function () {
          page.render(filename+'_'+page.viewportSize.width+ 'x' + page.viewportSize.height +'.png');
          page.close();
          count--;
          if(count == 0){
            phantom.exit();
          }
        }, 2000);
      }
    });
  });
}

PhantomJS : Exemple

Pour l’utiliser, la commande est simple :

$ phantomjs screenshot.js http://rootslabs.net/blog/

Et hop, cela vous génère vos 6 screenshots de votre site :
PhantomJS : Screenshot RootsLabs

Il reste un souci ; PhantomJS permet le rendu sous le moteur de Chrome. Mais comment faire pour le moteur de Firefox ?
La solution s’appelle SlimerJS.

SlimerJS : Installation

  • Télécharger le package https://download.slimerjs.org/releases/0.8.3/slimerjs-0.8.3.zip
  • Ajouter dans votre fichier bashrc l’emplacement de Firefox via un export
    export SLIMERJSLAUNCHER=/usr/bin/firefox
  • Extraire le contenu du zip
  • Installer xvfb pour lancer SlimerJS en mode headless
    # yum install xorg-x11-server-Xvfb

SlimerJS : Script

Ensuite, je teste mon précédent script pour l’adapter à SlimerJS.

Je remplace

var page = new WebPage();

par

var page = require("webpage").create();

Pourquoi ? L’objet Webpage est marqué « deprecated » dans PhantomJS (Merci LaurentJ).
Le code devient ainsi fonctionnel et valide sur PhantomJS et SlimerJS.

Et j’adapte le code pour détecter le moteur utilisé :

/*
    requires: phantomjs
    usage: phantomjs screenshot.js URL
*/
var sizes = [
        [320, 480],
        [320, 568],
        [600, 1024],
        [1024, 768],
        [1280, 800],
        [1440, 900]
    ],
    count, url, filename;
if(typeof(slimer) != 'undefined'){
  var sEngine = 'slimerjs';
} else {
  var sEngine = 'phantomjs';
}
if (phantom.args.length < 1) {
    console.log('Usage: screenshot.js URL');
    phantom.exit();
} else {
   url = phantom.args[0];
   var filename = url.replace('http://','');
   filename = filename.replace('www.','');
   filename = filename.replace(/\./g,'_');
   filename = filename.replace(/\//g,'_');
   count = 0;
   sizes.forEach(function(vpSize){
    count++;
    //var page = new WebPage();
    var page = require("webpage").create();
    page.viewportSize = { width: vpSize[0], height: vpSize[1] };
    page.open(url, function (status) {
      if (status !== 'success') {
        console.log('Unable to load the address!');
      } else {

        window.setTimeout(function () {
          page.render(filename+'_'+page.viewportSize.width+ 'x' + page.viewportSize.height + '_' + sEngine +'.png');
          page.close();
          count--;
          if(count == 0){
            phantom.exit();
          }
        }, 2000);
      }
    });
  });
}

SlimerJS : Exemple

Pour l’utiliser, la commande est simple :

$ xvfb-run ./slimerjs screenshot.js http://rootslabs.net/blog/

Conclusion

Dorénavant, via les deux commandes suivantes, il vous est possible de tester votre responsive design en ligne de commande et ainsi voir les anomalies sur un navigateur ou un autre rapidement.
PhantomJS (moteur de Chrome) :

$ phantomjs screenshot.js http://rootslabs.net/blog/

SlimerJS (moteur de Firefox) :

$ xvfb-run ./slimerjs screenshot.js http://rootslabs.net/blog/

Commentaires

1. i M@N, le 30 septembre 2013 à 13:18

Bravo, excellent article.
Je viens de tester ça fonctionne super bien.
Merci beaucoup ça va m’être très utile. : )

2. Laurentj, le 2 octobre 2013 à 12:06

Ceci:

var page = require("webpage").create();

ça fonctionne dans PhantomJS, et c’est même la façon de faire recommandée. l’objet Webpage est marqué « deprecated » dans PhantomJS 😉

3. Progi1984, le 2 octobre 2013 à 12:29

@LaurentJ : Merci de ta contribution. J’ai mis à jour l’article pour préciser ce point.

4. Benjamin, le 8 octobre 2013 à 17:48

Bonjour,

Si le site est en HTTPS le script ne fonctionne pas à moins de modifier le code dans les sources :

var filename = url.replace(‘http://’, »);
par
var filename = url.replace(‘https://’, »);

Ajouter un commentaire

Commentaire :