Better BrowserStack Builds in WebdriverIO

One of the benefits of using a Selenium Cloud service like BrowserStack or Sauce Labs is the ability to review your automated test runs. This is especially useful if you run your tests through a Continuous Integration (CICD) tool like Jenkins or TravisCI.

BrowserStack will show you a list of previous test runs when you visit your automation page. Here's what the default output looks like:

You can see that there's not much information in there, aside from the browser/OS details. This isn't much of an issue when it's only you running tests, but when you try scaling your test execution to your entire team, it can quickly become a mess of test runs.

Thankfully, BrowserStack allows us to pass in three bits of information that are helpful in organizing our tests:

  1. The project name
  2. The build name
  3. A name for the test

For example, if we had a collection of tests for a shopping cart and ran that test via Jenkins, our three values would look like:

Project: Shopping Cart
Build: Jenkins #42
Name: Remove an item

We can set these values via our capabilities object that gets passed to BrowserStack. Here's what that would look like:

capabilities: {
	browserName: "firefox",
	project: "Shopping Cart",
	build: "Jenkins #" + process.env.BUILD_TAG,
	name: "Remove an item"
}

I used the BUILD_TAG environment variable that's available via Jenkins to get the ID of the Jenkins job corresponding to the test. This makes it easy to find the relevant test recording when needed.

With those simple additions, we now have a much more detailed output:

In addition to the better detail provided, we also have improved our organization. Say we have another set of tests that validate the login/registration functionality. If we want to narrow down our results to just the shopping cart project, Browserstack now allows that via their Project dropdown:

There's one more improvement we can add to this. Since we don't always run our tests in Jenkins, we don't always have a build tag available. We should check if that environmental variable is available, and if not, provide some information from the local environment.

Here's some updated code that checks for the variable and if not present, uses the provided Browserstack username with an appended timestamp instead:

var buildName;

if (process.env.BUILD_TAG) {
	buildName = "Jenkins #" + process.env.BUILD_TAG;
} else {
	buildName = process.env.BROWSERSTACK_USERNAME + " " + Date.now();
}

exports.config = {
	capabilities: {
	  browserName: "firefox",
	  project: "Shopping Cart",
		build: buildName,
		name: "Remove an item"
	},
	// all your other WDIO configs
};

And here's what that output looks like:

Moving to a Service

One of the improvements with WebdriverIO 4.x is the implementation of services. Services are individual NPM modules that act to easily add extra functionality to WebdriverIO. There's currently a wdio-sauce-service module that does a lot of the work we described above, but for the Sauce Labs integration.

With a little bit of work, we could create a wdio-browserstack-service module, which would do the work we described above. If I get around to it, I'll definitely post about my experience writing the service.

More WebdriverIO!

If you're interested in learning more about WebdriverIO and all the ways you can take advantage of it, check out my Learn WebdriverIO Course, currently at a 50% early acccess discount.