Automate Shadow DOM with WebDriver & Playwright
Locate elements in Shadow DOM of Web Components directly through the CSS query engine.
This document shows how to use the simpler CSS/xPaths that calls through document.querySelector
to locate elements within #shadow-root
of your Web Components or Salesforce LWC Applications. This solution can be extended to LitElements, Lighting Fast Templates etc.
The wish is to locate your #shadow-root
elements directly through CSS query engine (whic you cannot do it with current WebDriver implementation) e.g,
🔎 If you’re building your app with the Web Components or Salesforce’s LWC, and if you try to use document.querySelector
(in the console), it will not find anything in the document though you see the element in the Browser DOM. The reason is that the elements of Web Component are not in the Main DOM but rather in the Shadow DOM.
“The Shadow DOM shield becomes the pain for developers in writing integration/component/E2E automated tests for Web Components.”
⚠️ THE PROBLEM
Shadow DOM prevents your components from easily being e2e tested because normal Selenium commands fail, due to the element actually not being in the main document. Rather, they are encapsulated under Shadow DOM.
Selenium uses querySelector to find an element; Shadow DOMs prevent this.
The selector engines like css/xpath
do not work on the shadow DOM by default.
Example
Let’s take a look at chrome://download
page. It implements the Shadow DOM. As you see, the #searchInput
is a scoped element under #shadow-root (open)
, and so the document.querySelector
command fails to locate the #searchInput
element,
The below query fails to return the element because #searchInput
is encapsulated under Shadow Dom,
and as a result the below Selenium WebDriver Command will also fail to find an element ❎
So what is needed is a very complex nested CSS [not recommended] ↓
🤔 now imagine, you add one more element in the nested route. Then, you are unknowingly breaking the automation tests. You will need to track and update all the existing nested CSS — which is a pain!!
Can I get the support from WebDriver?
Yes. Codeceptjs-BDD Framework provides out-of-the-box support to locate Shadow DOM elements at ease. Though, there is an existing feature request to have the support in W3C/Webdriver, but thru Codeceptjs-BDD Framework, you can locate elements like, document.query,
I.click('.any-shadow-elements-in-dom'); // no dom hierarchy
[..] most end-to-end testing frameworks rely on [..] calls to querySelector through CSS/xPaths. Elements in Shadow DOM are selectable by neither. But, we have a Solution at framework level.
🚀 THE SOLUTION
The solution is Codeceptjs-BDD Webdriver implementations 🎉 🎉 🎉, which provides automatic support for the Shadow DOM , and Playwright already has in-built support.
Let’s talk about the real scenarios built with framework CodeceptJS!
Example: As you see in line #6 in below gif, the CSS is pretty simplified in test.
✅ As you see in a below example, you would just define a very simple CSS #searchInput
. The Playwright driver will find an element(s) for you. No need to mention about any of the hierachy of #shadow-roots
!
🙌 No Nested/Complex CSS required!
Simply inspect the element in DOM, and grab the unique attribute. It is as simple as that with Playwright because Playwright does rest of the plumbing work for us.
❣️ WebDriver Exclusive Support for Shadow Dom ⬇
✅ The Framework Documentations: https://gkushang.github.io/
Demo Time
Let’s take a look some real examples with scenarios
The examples in this doc are built with Codeceptjs-BDD framework with Playwright!
A Complete Example Test
As you see in above example, the #searchInput
is a scoped element (#shadow-root) but it does not require you to have nested CSS of #shadowRoots
to locate the element but it still finds an element!
Salesforce’s LWC Page Object, the Another Example
The Salesforce Lighting Web Components (LWC) is another great example of Shadow DOM elements. LWC Recipes is build with LWC. Below is the Page Object on how to query Shadow DOM elements with simple CSS.
A complete E2E automation Example of Salesforce’s Lighting Web Components Application is available here:
🎉 The Codeceptjs-BDD makes it easy to Automate Web Components in any of the below mentioned automation test layers:
- Component Tests
- Integration Tests
- Functional Tests
- E2E Tests
⭐️ Don’t forget to checkout more docs on Codeceptjs-BDD framework WebSite and the CodeceptJS library for great additional features🌈!
Thanks for reading, I hope you discovered something new and useful. Stay curious, and happy coding!