How can I use BrowserMob Proxy with Protractor?

2020-02-09 18:27发布

问题:

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

回答1:

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.



回答2:

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;
    });
  },
}