PhantomJS is a headless browser based on WebKit. It is used for testing
web applications. It has fast and native support for various web standards:
DOM handling, CSS selector, JSON, Canvas, and SVG.
PhantomJS allows developers to access the browser’s DOM API. After all,
PhantomJS is still a browser even if it hasn’t a GUI. Developers can write
JavaScript code that will be evaluated against a specified page. Although this
may not seem very important, this allows us to automate any sort of interactions
with a web page without having to open a browser (operation that will save you a
tremendous amount of time).
//userAgent.js
var page = require('webpage').create();
console.log('The default user agent is ' + page.settings.userAgent);
page.settings.userAgent = 'SpecialAgent';
page.open('http://www.httpuseragent.org', function(status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var ua = page.evaluate(function() {
return document.getElementById('myagent').textContent;
});
console.log(ua);
}
phantom.exit();
});
The above code show us how we can change the user agent string, open a page
evaluate a function, or condition.
To run the above test:
phantomjs userAgent.js
By utilizing WebKit, PhantomJS provides the ability to render any content on a
web page and save it as an image. Therefore, it can be used to automate the
process of capturing screenshots of web pages that developers can analyse to
ensure that everything looks good. These images can be saved in several format
such as PNG, JPEG, PDF, and GIF.
var page = require('webpage').create();
page.open('http://github.com/', function() {
page.render('github.png');
phantom.exit();
});
PhantomJS also allows developers to adjust the size of these screenshots, and
specify the exact areas that we want to capture:
var page = require('webpage').create();
//viewportSize being the actual size of the headless browser
page.viewportSize = { width: 1024, height: 768 };
//the clipRect is the portion of the page you are taking a screenshot of
page.clipRect = { top: 0, left: 0, width: 1024, height: 768 };
//the rest of the code is the same as the previous example
page.open('http://example.com/', function() {
page.render('github.png');
phantom.exit();
});
Because PhantomJS permits the inspection of network traffic, it is suitable to
build various analysis on the network behavior and performance.
This means that PhantomJS can be programmed to collect different data about the
performance of a web page. When paired with PhantomJS, YSlow can output the
results from these tests using different formats (TAP, for example). When
implemented, TAP allows communication between unit tests, and a testing harness,
which in this case would be PhantomJS. Additionally, PhantomJS and YSlow make
use of TAP protocol in continuous integration systems, and monitor the
performance of new code being added to a project. In this way, developers can
be informed of any regression in performance before the code is pushed.
One major use case of PhantomJS is headless testing of web applications. It is
suitable for general command-line based testing, within a precommit hook, and
as part of a continuous integration system.
PhantomJS itself is not a test framework, it is only used to launch the tests
via a suitable test runner. In other words, PhantomJS is just a headless
browser. It can be integrated into other framework (other framework can take
advantage of PhantomJS). PhantomJS does not provide the test runner. The test
framework provides the test runner, or use a separate test runner.
As of version 1.6, you are also able to include jQuery into your page using a
page.includeJs as follows:
var page = require('webpage').create();
page.open('http://www.sample.com', function() {
page.includeJs(
"http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js",
function() {
page.evaluate(function() {
$("button").click();
});
phantom.exit()
});
});
The above snippet will open up a web page, include the jQuery library into the
page, and then click on all buttons using jQuery. It will then exit from the web
page. Make sure to put the exit statement within the page.includeJs or else it
may exit prematurely before the javascript code is included.
page.canGoForward -> boolean (based on the window.history object)
page.canGoBack -> boolean
page.content -> string (the whole HTML content of the page)
page.cookies -> object
page.customHeaders -> object
page.event -> object
page.libraryPath -> string
page.loading -> boolean
page.loadingProgress -> number
page.navigationLocked -> boolean
page.offlineStoragePath -> string (Where the sqlite3 localstorage and
other offline data are stored.)
page.offlineStorageQuota -> number
page.paperSize -> object
page.plainText -> string
page.scrollPosition -> object
page.settings -> object
page.title -> string
page.url -> string
page.viewportSize -> object
page.windowName -> string
page.zoomFactor -> number
Functions:
page.childFramesCount
page.childFramesName
page.close
page.currentFrameName
page.deleteLater
page.destroyed
page.evaluate
page.initialized
page.injectJs
page.javaScriptAlertSent
page.javaScriptConsoleMessageSent
page.loadFinished
page.loadStarted
page.openUrl
page.release
page.render
page.resourceError
page.resourceReceived
page.resourceRequested
page.uploadFile
page.sendEvent
page.setContent
page.switchToChildFrame
page.switchToMainFrame
page.switchToParentFrame
page.addCookie
page.deleteCookie
page.clearCookies
Events:
onInitialized
onLoadStarted
onLoadFinished
onUrlChanged
onNavigationRequested
onRepaintRequested
onResourceRequested
onResourceReceived
onResourceError
onResourceTimeout
onAlert
onConsoleMessage
onClosing