PhantomJS for Web Automation

PhantomJS for Web Automation

Presented at O'Reilly Fluent Conference 2015: http://fluentconf.com/javascript-html-2015/public/schedule/detail/39450

PhantomJS, the scriptable headless WebKit-based automation tool, has gained a lot of traction in its first 4 years of existence. With >11,000 GitHub stars and ~10M downloads, it becomes the de-facto tool for web application continuous integration, whether to run basic tests or to catch rendering regressions. Many JavaScript test frameworks work well with PhantomJS. In addition, because PhantomJS permits the inspection of network traffic, it is suitable to run various analysis on the network behavior and performance. This talk will highlight the basic usages of PhantomJS and explore various PhantomJS-tools for web applications testing, screen capture, performance analysis, and other page automation tasks.

0284b8950e0f4a57bcc092d4dbb98d97?s=128

Ariya Hidayat

April 21, 2015
Tweet

Transcript

  1. 1.
  2. 2.
  3. 5.
  4. 6.

    Understands HTTP/1.1 Supports cookies, redirect, TLS, ... No JavaScript No

    DOM Supports JavaScript Simulates DOM No layout No rendering
  5. 7.
  6. 8.
  7. 10.
  8. 11.
  9. 14.

    var page = require('webpage').create(); page.open('http://fluentconf.com', function (status) { if (status

    !== 'success') { console.log('FAIL to load the address'); } else { var title = page.evaluate(function () { return document.title; }); console.log('Page title is', title); } phantom.exit(); });
  10. 15.
  11. 17.
  12. 18.
  13. 19.

    Set and change cookies Customize User-Agent string Execute JavaScript Open

    a web page Inject jQuery Intercept network requests
  14. 20.
  15. 21.

    var page = require('webpage').create(); page.open('http://example.com', function (status) { if (status

    !== 'success') { console.log('FAIL to load the address'); } else { console.log('Page is loaded'); } phantom.exit(); });
  16. 25.
  17. 26.

    var casper = require('casper').create(); casper.start('http://duckduckgo.com', function() { this.echo(this.getTitle()); }); casper.then(function()

    { this.fill('form', { q: 'Fluent Conference' }, true); }); casper.then(function() { var snippet = this.evaluate(function() { return document.querySelector('div#links > div').textContent; }); this.echo(snippet); }); casper.run();
  18. 27.

    https://speakerdeck.com/detronizator/boston Ghost Driver is a pure JavaScript implementation of the

    WebDriver Wire Protocol for PhantomJS. It's a Remote WebDriver that uses PhantomJS as back-end.
  19. 28.

    var wd = require('wd'); var driver = wd.remote('localhost', 9134); driver.init(function()

    { driver.get("http://casperjs.org", function() { driver.title(function(err, title) { console.log(title); }); }); }); npm install wd
  20. 31.
  21. 32.
  22. 33.

    npm install --save-dev grunt-contrib-jasmine $ grunt jasmine Running "jasmine:src" (jasmine)

    task Testing jasmine specs via phantom ..... 5 specs in 0.11s. >> 0 failures Done, without errors.
  23. 34.

    npm install --save-dev grunt-template-jasmine-istanbul $ grunt test:coverage Running "jasmine:coverage" (jasmine)

    task Testing jasmine specs via phantom . =============================== Coverage summary ============== Statements : 100% ( 2/2 ) Branches : 100% ( 0/0 ) Functions : 100% ( 1/1 ) Lines : 100% ( 2/2 ) =============================================================== = 1 spec in 0.082s. >> 0 failures Done, without errors.
  24. 35.
  25. 37.
  26. 38.

    var page = require('webpage').create(); page.open(title, function (status) { if (status

    !== 'success') { console.log('FAIL to load the address'); } else { page.render(filename); } phantom.exit(); });
  27. 39.

    → var svg2png = require('gulp-svg2png'); gulp.task('svg2png', function () { gulp.src('./specs/assets/**/*.svg')

    .pipe(svg2png()) .pipe(gulp.dest('./build')); }); npm install --save-dev gulp-svg2png
  28. 40.
  29. 41.
  30. 42.
  31. 43.
  32. 44.
  33. 45.

    page.onResourceRequested = function(requestData, request) { if ((/http:\/\/.+?\.css$/gi).test(requestData['url'])) { console.log('Skipping', requestData['url']);

    request.abort(); } }; Skipping http://static.bbci.co.uk/frameworks/barlesque/2.45.9/mobile/3.5/style/main.css Skipping http://static.bbci.co.uk/bbcdotcom/0.3.184/style/mobile/bbccom.css Skipping http://static.bbci.co.uk/news/1.7.1-259/stylesheets/core.css Skipping http://static.bbci.co.uk/news/1.7.1-259/stylesheets/compact.css
  34. 46.
  35. 47.
  36. 48.

    var page = require('webpage').create(); page.onResourceRequested = function(request) { console.log('Request '

    + JSON.stringify(request, undefined, 4)); }; page.onResourceReceived = function(response) { console.log('Receive ' + JSON.stringify(response, undefined, 4)); }; page.open(url);
  37. 49.
  38. 51.
  39. 52.
  40. 54.
  41. 55.
  42. 58.