Screenshoty webů pomocí PhantomJS

posted 31.07.2013

Chystám článek o testování v Seleniu a jedna z užitečných funkcí je zachycení obrazovky při chybě (případně screenshoty několika poslední kroků). Dá se tak rychle poznat, jestli test opravdu padá na chybě, a hlavně lokalizovat přesněji příčinu. Jedna z nových možností, jak rychleji testovat v Seleniu je nový projekt jménem PhantomJS, headless verze webkitu, která se dá ovládat Javascriptem. O testování se rozepíšu jindy, podělím se ale o drobný tip, jak dělat screenshoty stránek, právě pomocí Phantomu. Nikdy se mi nepodařilo najít spolehlivou službu na vytváření screenshotů. Chvíli spolehlivě (ale ne moc pěkně) fungoval WebSnapr, dokonce jsem zachytával výstup z VNC, výsledky ale nebyly ideální ani v jednom případě.

Jak na to

PhantomJS se nemusí složitě instalovat, jen si stáhněte předkompilované binárky (zkompilovat webkit trvá věky) a přidejte si ho někam do cesty (jako PATH). Soubory ukládám jako md5 URL stránky s příponou. Příkazy Phantomu předám vlastním Javascriptem, nejde ani o front-endový JS a není to ani NodeJS. Proto bude potřeba specificky naincludovat knihovnu pro tvorbu hashů (používám md5.js).
var page = require('webpage').create(),
    system = require('system'),
    address, output, size;

phantom.injectJs('md5.js');

if (system.args.length < 2) {
    console.log('Usage: webshutter.js URL');
    phantom.exit(1);
} else {
    address = system.args[1];
    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
            phantom.exit();
        } else {
            window.setTimeout(function () {
                console.log('Rendering ' + address);
                page.render(CryptoJS.MD5(address) + '.png');
                phantom.exit();
            }, 200);
        }
    });
}
Spuštění už je pak jednoduché:
$ phantomjs webshutter.js "http://www.seznam.cz"

Výsledek

Screenshot Seznamu

Je libo měnší obrázek?

Funguje tenhle blog responzivně? Jednoduše to zjistím, když do callbacku pro úspěšné načtení stránky přidám resize viewportu:
page.viewportSize = { width: 320, height: 480 };
Responzivní blog