I'd like to capture the network requests made by my application during a Protractor test suite run.
BrowserMob Proxy looks like a great tool for this.
I'd like to integrate BrowserMob Proxy into Protractor using the browsermob-node node.js binding as follows:
onPrepare
: Create a new proxy and start it
beforeEach
: start a new HAR
afterEach
: write the HAR to file
onComplete
: stop the proxy
However, browsermob-node's API requires that I pass callbacks to each of the methods and onPrepare
, onComplete
are assumed to be synchronous. There is no done
callback that I could pass.
My tests run on Firefox and iOS and Android (via Appium).
You need to denodeify callbacks, i.e. turn them into Promises so Protractor will wait for them.
Alternative 1: Using already included protractor.promise
//...
onPrepare: function() {
var deferred = protractor.promise.defer();
proxy.doHAR('http://yahoo.com', function(err, data) {
if (err) {
deferred.reject('ERROR: ' + err);
} else {
deferred.fulfill(data);
}
});
return deferred.promise;
}
Alternative 2: Using Q library
var Q = require('q');
//...
onPrepare: function() {
var proxy_doHAR = Q.nfbind(proxy.doHAR);
return proxy_doHAR('http://yahoo.com');
}
More info here and here.
Protractor easily provides active wait for certain conditions. After starting the proxy on 8887. I used browser.driver.wait
for this solution:
// protractor.conf.js
var browsermob = require('browsermob-proxy').Proxy;
var webdriver = require('selenium-webdriver');
var fs = require('fs');
// ...
var proxy;
var conf = {
// Typical protractor configuration
// ...
beforeLaunch: function(){
proxy = new browsermob({
port : 8887
});
},
onPrepare: function (){
browser.driver.get('http://localhost:8080/index.html');
var proxyReady = false;
proxy.start(8888, function(err, data){
if (!err) {
proxy.startHAR(8888, 'test', true, true, function(){
proxyReady = true;
});
} else {
console.error(err);
}
});
browser.driver.wait(function(){
return proxyReady;
});
},
onComplete: function () {
var proxyDone = false;
proxy.getHAR(8888, function(err, resp) {
if (!err) {
console.log('har saved at output.har');
fs.writeFileSync('test/diagnostics/output.har', resp, 'utf8');
} else {
console.err('Error getting HAR file: ' + err);
}
proxy.stop(8888, function() {
proxyDone = true;
});
});
return browser.driver.wait(function(){
return proxyDone;
});
},
}