bennyhat / protractor-istanbul-plugin

Protractor plugin that collects istanbul coverage results from a page and dumps them to coverage.json files (one per spec).
MIT License
15 stars 7 forks source link

Help with save coverage #5

Closed bearjaws closed 8 years ago

bearjaws commented 8 years ago

I have made a saveCoverage function identical the example in the readme.md and added it to my config.

Unfortunately after running a few tests that appear to not save any coverage information (we know the code is being hit via console.log) and running saveCoverage it still is not writing the coverage information to disk. Does the saveCoverage function need to return anything or is it just an empty function? Any ideas why my function is not working?

bennyhat commented 8 years ago

Hello, I can try and get you a better example in the next few days. I'll probably put it in the example project.

Until then, however, I can try and clarify. In short, you don't need to make your own saveCoverage function. Instead you need to tell the plugin to wrap the function that is doing the server side navigation. This assumes that you have some way of getting a reference to it.

Otherwise, as for why it may not be working: this plugin was built for a much older version of protractor, so there is a possibility that it simply doesn't work with the newer plugin specifications. In that case, I apologize for any inconvenience. If you're interested, the example project has the recommended version of protractor set and should give you a baseline to work from.

As for saveCoverage:

Let's say you have a test utility function that does some server side navigation (for some reason). Additionally, you call that test utility function after every spec, like so: testUtilities.js

...
var navigate = function navigate(url) {
  // browser calls for navigation go here
}
...

mySpec.js

...
describe('my spec', function () {
  afterEach(function() {
      testUtils.navigate('/somewhere.html');
   });
  ...
}
...

Unfortunately, when testUtils.navigate is called, the client side objects, including the __coverage__ variable get wiped out (assuming it's a true server side navigation, and not a push state that gets picked up by angular locally).

In this case, you can tell the coverage plugin to wrap that navigate function in one that stores the __coverage__ variable in memory and then restores it after that function. That is, the navigate function does what it was already doing: no need for modification. The actual function doing the saveCoverage is already written out in the plugin and effectively amounts to this:

var coverage = // read __coverage__ from browser using webdriver browser call
wrappedFunction.apply(this, arguments); // navigate, clear cookies or whatever it actually does
// write __coverage__ to browser using webdrive browser call

To actually set up the navigate function to be the wrappedFunction shown above, we must set an extra property for it and then tell the plugin to wrap it, as shown below. Once again, this assumes that you can get a reference to the navigate function.

protractor.conf.js

// set up a bound object (has to be this way due to the way ES5 assigns references)
// in this case, I magically have already loaded in the testUtils object to the global scope earlier in the file)
...
testUtils.clearHistory.boundParent = testUtils;
testUtils.clearHistory.boundName = 'navigate';
...
  plugins : [{
    path: 'node_modules/protractor-istanbul-plugin',
    functions: [ testUtils.navigate ]
  }],
...
bearjaws commented 8 years ago

Thank you for the response, this helped me make sense of it. I can now see the coverage variable being saved in selenium's output.

Thanks again.