Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Ariya Hidayat

April 21, 2015
Tweet

More Decks by Ariya Hidayat

Other Decks in Programming

Transcript

  1. View Slide

  2. View Slide

  3. http://phantomjs.org/users.html

    View Slide

  4. http://phantomjs.org/releases.html

    View Slide

  5. View Slide

  6. Understands HTTP/1.1
    Supports cookies, redirect, TLS, ...
    No JavaScript
    No DOM
    Supports JavaScript
    Simulates DOM
    No layout
    No rendering

    View Slide

  7. View Slide

  8. View Slide

  9. Geolocation
    CSS 3-D
    Java
    Audio
    Video
    Speech

    View Slide

  10. View Slide

  11. View Slide

  12. console.log('Hello, world!');
    phantom.exit();

    View Slide

  13. var page = require('webpage').create();
    page.open('http://google.com', function (status) {
    page.render('google.png');
    phantom.exit();
    });

    View Slide

  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();
    });

    View Slide

  15. View Slide

  16. http://ariya.ofilabs.com/2011/06/your-webkit-port-is-special-just-like-every-other-port.html

    View Slide

  17. View Slide

  18. View Slide

  19. Set and change cookies
    Customize User-Agent string
    Execute JavaScript
    Open a web page
    Inject jQuery
    Intercept network requests

    View Slide

  20. View Slide

  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();
    });

    View Slide

  22. var title = page.evaluate(function () {
    return document.title;
    });
    console.log('Page title is', title);

    View Slide

  23. get_title.js
    page.open(...)
    page.evaluate(...)
    function () {
    return document.title;
    }

    View Slide

  24. page.evaluate(function () {
    document.querySelector('input[name=q]').value = 'PhantomJS';
    document.querySelector('form').submit();
    });

    View Slide

  25. View Slide

  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();

    View Slide

  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.

    View Slide

  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

    View Slide

  29. from selenium import webdriver
    driver = webdriver.PhantomJS('phantomjs')
    driver.get('http://www.phantomjs.org')
    print driver.title
    driver.quit()
    pip install selenium

    View Slide

  30. phantomjs --webdriver=9134

    View Slide

  31. View Slide

  32. View Slide

  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.

    View Slide

  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.

    View Slide

  35. View Slide

  36. “YOU SHALL NOT PASS!”
    — Darth Vader

    View Slide

  37. View Slide

  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();
    });

    View Slide


  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

    View Slide

  40. View Slide

  41. View Slide

  42. View Slide

  43. View Slide

  44. View Slide

  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

    View Slide

  46. View Slide

  47. View Slide

  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);

    View Slide

  49. View Slide

  50. http://yslow.org/phantomjs/

    View Slide

  51. View Slide

  52. View Slide

  53. “High Performance WebSocket”
    Wed 1.30pm

    View Slide

  54. View Slide

  55. View Slide

  56. http://www.trollquotes.org/619-super-spider-bat-troll-quote/

    View Slide

  57. * with caveat emptor
    2016

    View Slide

  58. View Slide