Getting the spec name in Protractor for Sauce Labs

Say that you’re writing tests in Protractor, and say also that you’re running your tests on Sauce Labs.  You want to set your test name in Sauce Labs to match the spec.

You normally set the test name in Sauce Labs by sending “name” in the desired capabilities.

capabilities.name = "your test name"

But in Protractor, the browser is created before starting the test.  The order of execution is:

1) Setup environment
2) Create a browser and setup globals 
3) Setup plugins 
4) Execute test cases 
5) Wait for postTest plugins to finish 
6) Teardown plugins 
7) Teardown

(in runner.ts)

The configuration file(s) are read and capabilities set in step 1.  Then the browser is created.  And only in step 4 are the spec files read.

There is an afterEach() hook that allows you to restart the browser for each test (if your test runner supports it, e.g. jasmine, mocha), and when using Sauce Labs (or Browserstack) to update the test status:

this.sauceServer_.updateJob(session.getId(), update, (err: Error) => {

(in sauce.ts)

We could use this updateJob method to also set the test name before each spec, but that would require changing the source code — it’s not available to the conf file or before each.

However, this same method can be called on the client side by using the Javascript executor.  So, in the beforeEach() method you can call:

browser.executeScript("sauce:job-name=whatever you want");

and it will change the test name in Sauce Labs. There is only one thing left to do to make this functional, get the spec name to set in the Javascript Executor.

This can be accomplished by getting the spec as a return value to the spec definition:

var spec = it('should set the spec name in Sauce Labs', function() { 
    browser.executeScript("sauce:job-name=" + spec.getFullName()); 
}

Now your tests in Sauce Labs reflect the text in your carefully worded spec description.

There’s one thing that can make this better.  Instead of adding this step to each spec, set it in your protractor conf.js file using the onPrepare() hook.

If you’re using mocha, no problem, but if you’re using Jasmine (the default Protractor test runner), well, this is a problem:

https://github.com/jasmine/jasmine/issues/611

Let me just say here that often open source project maintainers pull the “because it is better” argument to mean “because I don’t know how”.  Ask Dostoyevsky about the mindset.

But, you could also use a custom reporter in Jasmine

onPrepare: function() {
    jasmine.getEnv().addReporter({
        specStarted: function(result) { 
            browser.executeScript("sauce:job-name=" + result.fullName);
        }
    });
} }

If you add this to your protractor conf.js your tests will update with the spec fullname in Sauce Labs.

Here’s a working example:

https://github.com/sauceaaron/protractor-saucelabs-testname-per-spec

Advertisements