Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use BrowserMob Proxy with Protractor?

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

like image 797
afternoon Avatar asked Sep 01 '14 16:09

afternoon


People also ask

How does BrowserMob proxy work?

What is BrowserMob Proxy? On that page its definition is as follows: BrowserMob Proxy allows you to manipulate HTTP requests and responses, capture HTTP content, and export performance data as a HAR file. BMP works well as a standalone proxy server, but it is especially useful when embedded in Selenium tests.

What is BrowserMob?

BrowserMob Proxy is an open source tools which is used to capture performance data for a web applications in an HAR format. It also allows to manipulate browser behavior and traffic, such as simulating network traffic, rewriting HTTP requests and responses etc.


2 Answers

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.

like image 83
Leo Gallucci Avatar answered Oct 13 '22 17:10

Leo Gallucci


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;
    });
  },
}
like image 44
miguelr Avatar answered Oct 13 '22 17:10

miguelr