Is there a way to return the worker number in concurrent browser executions?

621 Views Asked by At

Each time I execute console.log(text); it is appended in the console with two digits separated by a dash. [n-n]

When running concurrent browsers, the 2nd number indicates the browser - or worker - number. Below is output from five concurrent browsers, where one has already completed.

[0-2] * Selected 'US Citizen' from 'Citizenship' list
[0-4] Clicked '- County -'
[0-6] Clicked 'District of Columbia' button
[0-2] Clicked 'Next' button
[0-3] Clicked 'Next' button
[0-5] * ... PageSync completed in 2.481 sec. *

I'd like to use the worker number to arrange browsers to five screen positions for demos with the MOD of 5 in WebdriverIO.

Is there a way to return the instance of the worker number?

Or is there an alternative way to accomplish this feat?

I'm thinking maybe reading and incrementing a system variable but then I wonder if this might cause a race condition?

1

There are 1 best solutions below

2
On

Without seeing your setup, I cannot give you a complete solution; however, I can provide some insight that may be helpful.

I assume you're running tests concurrently. If so, then you likely have more than one capability configured in wdio.conf.js, like so:

{
        //maxInstances: 1,
        browserName: 'chrome',
        // Set 1
        specs: './tests/set1/**/*.spec.js',
    },
    {
        //maxInstances: 1,
        browserName: 'chrome',
        // Set 2
        specs: './tests/set2/**/*.spec.js',
    },

There are two approaches you could take. In approach #1, we'll use a vendor prefix to add our own ID to each capability. In approach #2, we'll get a reference to the actual capability id, which is the ID you identified in brackets in your logs.

Approach 1

The capabilities are accessible via any one of your tests, as well as the wdio.conf.js hooks, using browser.options.capabilities. So we can assign each capability an index ID like so:

{
        //maxInstances: 1,
        browserName: 'chrome',
        // Set 1
        specs: './tests/set1/**/*.spec.js',
        'wdio:id': 1
    },
    {
        //maxInstances: 1,
        browserName: 'chrome',
        // Set 2
        specs: './tests/set2/**/*.spec.js',
        'wdio:id': 2
    },

In each test, as well as the wdio.conf.js hooks, we can tell which one of the 5 browsers the test is running on like so:

describe('Example Suite', () => {
    before(() => {
        console.log('Test is running on browser number ' + browser.options.capabilities['wdio:id']);
        // this outputs either 1, 2, 3, 4, or 5 depending on which browser the test is running on. You can use this to determine where you want to position the browser on the screen.
    });

Since you won't want to do this in every test, a better place to do this would be in the WebdriverIO beforeTest, beforeSuite, or before hook:

beforeTest: function (test, context) { 
        console.log('ID = ' + browser.options.capabilities['wdio:id']);
        // outputs either 1, 2, 3, 4, or 5 depending on which browser the test runs on
}

Approach 2

Approach 2 is similar to approach #1, except calculating the position may be more difficult since you don't control the actual ID's assigned to each browser. However, I'll show you how you can access the CID, just in case it proves to be a better option for you.

Like approach #1, we assume you have multiple capabilities as below:

{
        //maxInstances: 1,
        browserName: 'chrome',
        // Set 1
        specs: './tests/set1/**/*.spec.js',
    },
    {
        //maxInstances: 1,
        browserName: 'chrome',
        // Set 2
        specs: './tests/set2/**/*.spec.js',
    },

WebdriverIO has a hook called onWorkerStart, and WebdriverIO passes it the CID as one of the arguments. WebdriverIO also passes the capabilities to this function as an argument. Since we know we can access the capabilities from within the browser.options.capabilities object, we can intercept the CID in the wdio.conf.js onWorkerStart and assign it as a vendor-prefixed property on the capabilities object, like so:

    onWorkerStart: function (cid, caps, specs, args, execArgv) {
        console.log('onWorkerStart: cid = ' + cid)
        caps['wdio:cid'] = cid;
    },

Later, we can access it, either within the test, or within another hook, as follows:

    beforeTest: function (test, context) { 
        console.log('beforeTest: CID = ' + browser.options.capabilities['wdio:cid']);
        // do something here with the CID, since the browser object is available
    //...
    },

See my article, Identify which Worker is Running a WebdriverIO Test, for more information on other use cases for using capability IDs in WebdriverIO.