Slide 1

Slide 1 text

PhantomJS for Web Page Automation @ariyahidayat Mountain View Jan 8, 2014 South Bay Selenium Meetup

Slide 2

Slide 2 text

/usr/bin/whoami shapesecurity.com

Slide 3

Slide 3 text

“Software Provocateur” PhantomJS Esprima

Slide 4

Slide 4 text

11-Second Elevator Pitch Scriptable Simulate user interactions Headless Command-line, no GUI WebKit Layout and rendering

Slide 5

Slide 5 text

Important Traits Multi platforms Zero dependencies (*) Works with Other Tools

Slide 6

Slide 6 text

Who is Using PhantomJS http://phantomjs.org/users.html

Slide 7

Slide 7 text

Versions vs Downloads http://phantomjs.org/releases.html Announced Jan 23, 2011 WebDriver Winter 2012 Pure headless Linux Spring 2012

Slide 8

Slide 8 text

Web Page Processing Screen Capture Headless Testing Network Monitoring

Slide 9

Slide 9 text

5-Minute Primer

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

Get Page Title var page = require('webpage').create(); page.open('http://linkedin.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(); });

Slide 13

Slide 13 text

Use jQuery (or Other Libs) var page = require('webpage').create(); page.open('http://www.sample.com', function() { page.includeJs("http://code.jquery.com/jquery-1.10.2.js", function() { page.evaluate(function() { $("button").click(); }); phantom.exit() }); });

Slide 14

Slide 14 text

Behind the Scene C++ Framework Operating Systems WebKit PhantomJS Ghost Driver

Slide 15

Slide 15 text

Web Page Processing

Slide 16

Slide 16 text

Ghost Driver 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. https://github.com/detro/ghostdriver

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

PhantomJS (Remote) WebDriver phantomjs --webdriver=9134 Port

Slide 19

Slide 19 text

Ruby Example require "selenium-webdriver" driver = Selenium::WebDriver.for(:remote, :url => "http://localhost:9134") driver.navigate.to "http://google.com" element = driver.find_element(:name, 'q') element.send_keys "PhantomJS" element.submit puts driver.title driver.quit gem install selenium-webdriver

Slide 20

Slide 20 text

Node.js JavaScript Example 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

Slide 21

Slide 21 text

.NET and C# See http://michael-whelan.net/using-phantomjs-with-webdriver http://www.andykelk.net/tech/headless-browser-testing-with-phantomjs- selenium-webdriver-c-nunit-and-mono

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Using CasperJS var casper = require('casper').create(); casper.start('http://duckduckgo.com', function() { this.echo(this.getTitle()); }); casper.then(function() { this.fill('form', { q: 'Selenium San Jose' }, true); }); casper.then(function() { var snippet = this.evaluate(function() { return document.querySelector('div#links > div').textContent; }); this.echo(snippet); }); casper.run();

Slide 24

Slide 24 text

Headless Testing

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

On Being Defensive http://ariya.ofilabs.com/2012/12/quality-code-via-multiple-layers-of-defense.html

Slide 27

Slide 27 text

Pre-commit Hook http://ariya.ofilabs.com/2012/03/git-pre-commit-hook-and-smoke-testing.html if [ `date +%w` -eq 6 ]; then echo "Enjoy your life. Do not work on Sunday!" exit 1 fi exit 0 make test

Slide 28

Slide 28 text

Jasmine Mocha QUnit YUITest Capybara tapedeck Karma Testem Buster.JS Travis CI Grunt Laika

Slide 29

Slide 29 text

“YOU SHALL NOT PASS!” — Darth Vader

Slide 30

Slide 30 text

Screen Capture

Slide 31

Slide 31 text

HTML-to-Anything 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(); }); Outputs: external file, base64 string Formats: PNG, JPEG, GIF, PDF

Slide 32

Slide 32 text

Rendering Aspects Zoom Factor Scale the page up and down Viewport Size Simulates different window dimensions Clipping Rectangle Crop portions of the page

Slide 33

Slide 33 text

Media Queries, Responsive Design http://mediaqueri.es/

Slide 34

Slide 34 text

Dichromacy http://ariya.ofilabs.com/2012/10/web-page-screenshot-with-phantomjs.html

Slide 35

Slide 35 text

De-CSS-ify (No Stylesheets) http://ariya.ofilabs.com/2013/06/capturing-web-page-without-stylesheets.html

Slide 36

Slide 36 text

Resources Blocking 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

Slide 37

Slide 37 text

Visual Regression http://tldr.huddle.com/blog/css-testing/ https://github.com/Huddle/PhantomCSS https://github.com/facebook/huxley https://github.com/bslatkin/dpxdt

Slide 38

Slide 38 text

Network Monitoring

Slide 39

Slide 39 text

Requests + Responses Capture 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);

Slide 40

Slide 40 text

Network Waterfall

Slide 41

Slide 41 text

YSlow + PhantomJS http://yslow.org/phantomjs/

Slide 42

Slide 42 text

Future Outlook

Slide 43

Slide 43 text

Engine vs Browser Pratt & Whitney JT9D http://ariya.ofilabs.com/2011/06/your-webkit-port-is-special-just-like-every-other-port.html

Slide 44

Slide 44 text

Diversity = Better

Slide 45

Slide 45 text

Future (with Caveat Emptor) PhantomJS 2.x Fresher, multi-process QtWebKit PhantomJS 3.x Chromium-based

Slide 46

Slide 46 text

Thank You @ariyahidayat ariya.ofilabs.com/highlights speakerdeck.com/ariya Some artworks are from http://openclipart.org.