Nightwatch JS doesn’t provide any out-of-the-box solution to handle shadow doms, hence we will use the document.queryselector and shadowroot web APIs.

Let’s automate a simple scenario where will use these api’s against shadow dom elements:

1. Go to https://shop.polymer-project.org/list/mens_outerwear
2. Validate the Title of the first product in the list to be Men’s Tech Shell Full-Zip

Next, we will look into our HTML DOM. To get the title of the first product we will have to traverse through 6 different elements (marked below):

For elements that have the shadow root, we will write:

1
document.querySelector('shop-app').shadowRoot //1

 
For elements that don’t have the shadow root, we will simply write:

1
document.querySelector('iron-pages') //2

 
So, to reach step-6, we have to traverse through some elements with shadow dom and some without. Hence, the final script will look like:

1
2
3
4
5
6
document.querySelector('shop-app').shadowRoot //1
.querySelector('iron-pages') //2
.querySelector('shop-list').shadowRoot //3
.querySelector('ul > li:nth-child(1)') //4
.querySelector('shop-list-item').shadowRoot //5
.querySelector('.title').innerText //6

 
We will then verify this script in the browser console. It should give us the text Men’s Tech Shell Full-Zip.

shadow dom browser console output
 
Now to write the above script inside a Nightwatch test, we will use the .execute() method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module.exports = {
    before: function (browser) {

        //Declaring Global Timeout
        browser.globals.waitForConditionTimeout = 7000
    },

    'Shadow DOM in Nightwatch JS': function (browser) {
        browser
            .url('https://shop.polymer-project.org/list/mens_outerwear')
            .waitForElementVisible('body')
            .execute(function () {
                return document.querySelector('shop-app').shadowRoot //1
                    .querySelector('iron-pages') //2
                    .querySelector('shop-list').shadowRoot //3
                    .querySelector('ul > li:nth-child(1)') //4
                    .querySelector('shop-list-item').shadowRoot //5
                    .querySelector('.title').innerText //6
            }, [], function (result) {
                this.assert.equal(result.value, 'Men\'s Tech Shell Full-Zip')
            })
    },

    after: function (browser) {
        browser.end()
    }
}

nightwatch js shadow dom test script

We are validating the item title as Men’s Tech Shell Full-Zip in the callback function using the command this.assert.equal(result.value, ‘Men\’s Tech Shell Full-Zip’)

After Execution:

nightwatch js shadow dom execution output on terminal

Do check out 🙂

Github: https://github.com/alapanme/NightwatchJS
All Nightwatch JS Articles: https://testersdock.com/nightwatch-js-tutorial/