6

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

afternoon
  • 1,235
  • 16
  • 25
  • onPrepare functions can return a promise: https://github.com/angular/protractor/blob/master/spec/onPreparePromiseConf.js – afternoon Sep 01 '14 at 16:34
  • Related? http://stackoverflow.com/questions/21689089/how-can-i-make-a-post-request-from-a-protractor-test – afternoon Sep 01 '14 at 16:35

2 Answers2

3

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.

Leo Gallucci
  • 15,165
  • 11
  • 66
  • 103
  • 4
    Thanks. You're exactly right. I've created a simple demo (using `Q.ninvoke`) here: https://github.com/afternoon/protractor-browsermob-test – afternoon Sep 01 '14 at 21:43
  • Hi, I stumbled upon this article while was looking for a way to add headers to my protractor tests. Do you think I can use the browsermob proxy library in an async/await fashion. I couldn't find an example online. – Monnie_tester Feb 28 '19 at 05:16
1

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;
    });
  },
}
miguelr
  • 1,294
  • 13
  • 21
  • Hi, I am behind a corporate proxy. Do you know how I can set that up. Few online articles suggested, i do proxy chaining but there is no proper example of that here : https://github.com/zzo/browsermob-node could you pls shed some light as to how I can implement this? – Monnie_tester Mar 13 '19 at 06:50