Nightwatch Shadow DOM support is here. This has been a long pending item on the Nightwatch roadmap. You can now write tests including shadow DOMs using Nightwatch.
The use case that we will address is around how to do a text assertion within a shadow DOM. Let’s start with understanding of Shadow DOMs. A shadow DOM allows a way to hide DOM elements but still allows it to be attached to the main DOM tree. A developer cannot access a shadow DOM element normally but a browser can render it as if it is any other nested DOM element.
The following demo app contains a page that has shadow DOMs.
Use Case
If you inspect the HTML on the page, you fill find the shadow DOM that we want to validate as shown in the screenshot below.

We will do a text assertion by getting the Shadow DOM root and then finding the slot element within that.
Nightwatch Shadow DOM – Implementation
Nightwatch has documented how to use Shadow DOMs in this API reference page. The .getShadowRoot() api has to be used to get the Shadow Root element. You can then search for the child elements for further interaction.
Let’s see how we can utilize this API to make our text assertion. Here is the test code.
describe('Shadow DOM', function () {
it('Text assertion on an element in a shadow DOM', async function (browser) {
await browser
.navigateTo('http://the-internet.herokuapp.com/shadowdom')
.waitForElementVisible('body');
const shadowRootEl = await browser.getShadowRoot('#content > my-paragraph:nth-child(4)');
const slotElement = await shadowRootEl.find('slot');
await expect(slotElement.property('innerHTML')).to.equal('My default text');
});
});
Let us try to break this down step by step
- First, we navigate to the page that contains the html having shadow DOMs and wait for the body to be visible.
- We then use the selector ‘#content > my-paragraph:nth-child(4)’ to get the shadow root element.
- Once we have the shadow root, we search for the required slot element
- We write our assertion and run the test
Conclusion
Nightwatch does support Shadow DOM. However, it is not as straightforward as it is in Playwright. While Playwright pierces through the shadow DOM making the child elements directly available as normal selectors, Nightwatch needs a special treatment to handle them.