What is DOM ?
The Document Object Model (DOM) is a programming interface that allows developers to manipulate web pages by representing them as objects and nodes. The DOM is a fundamental concept in web development, and is essential for creating dynamic and interactive web pages.
What is Shadow DOM ?
Shadow DOM is a web standard that allows developers to isolate a section of a web page's HTML document from the rest of the page. It's a part of the Web Components standard, which also includes HTML templates, Custom Elements, and HTML imports.
There are some bits of shadow DOM terminology to be aware of:
Shadow host: The regular DOM node that the shadow DOM is attached to.
Shadow tree: The DOM tree inside the shadow DOM.
Shadow boundary: the place where the shadow DOM ends, and the regular DOM begins.
Shadow root: The root node of the shadow tree.
Shadow DOM works by allowing you to attach a hidden, separate Document Object Model (DOM) to an element. This hidden DOM is known as the ‘Shadow DOM’, and the element it’s attached to is referred to as the ‘Shadow Host’. The Selenium IDE cannot directly reach the elements in a shadow tree. However, If the shadow root is
open It is possible to access such elements via a piece of Javascript.
Benefits of Using Shadow DOM
Encapsulation, Independence, Reusability
The Problem with Shadow DOM in Automation:
Standard queries like getElementById or cy.get will not penetrate the Shadow DOM. Normally, if we locate the element by finding the Element method (driver.findElement()) , then it will throw a NosuchElement Exception.
This means we need to pierce through the shadow boundary and access those elements manually.
In Selenium, in order to overcome this situation, we have to use Javascript two methods:
a) querySelector()
In the example given below, If we try to locate the Username element in this website. We can inspect using selectorshub and we can use sendkeys method to give the Username.
The querySelector method is called on the document object and takes in an argument that represents the CSS selector of the element you want to select.document.querySelector(selector); If the selector matches an element within the document, the method will return the first matching element.
b) shadowRoot property.
To access the shadow DOM elements using JavaScript you first need to query the shadow host element and then can access its shadowRoot property. Once you have access to the shadowRoot , you can query the rest of the DOM like regular JavaScript.
We cannot query if the elements are 'outside' from a shadow root. The mode specified should also be like { mode: "open" } to attachShadow(). With mode set to "open" only, the JavaScript in the page is able to access the internals of your shadow DOM through the shadowRoot property of the shadow host.
Playwright
There are various locator strategies you can apply for interacting with any regular web element in Playwright, but you must use CSS selectors to traverse into ShadowRoot. Playwright can easily traverse an 'open' shadow-root like any regular web element but remember XPath won't work.
For Instance, I used 'books' website to work with the shadow DOM.
This is the shadow root that we need to pierce through when we inspect the search books element. We can run the code by giving the id and for printing the specific text , we can select the class name to locate the text content.
or we can try with the code below, if we want to interact with elements in the shadow DOM under an iframe:
Cypress:
Cypress provides a way to traverse into the Shadow DOM of an element for testing purposes. To interact with elements inside the Shadow DOM in Cypress, you can use the . shadow() command.
The Syntax includes:
.shadow(selector)
.shadow(selector, options)
For Instance,
The line cy.get('.shadow-xyz').shadow().find() uses command to locate the Shadow DOM element with the respective tag name “shadow-xyz”.
The .shadow() method is used to interact with elements inside the Shadow DOM, and we can use find(‘input[name=”username”]’) is used to find the input field in case of the name “username”.
When working with cy.click(), it sometimes won't click the right element in Chrome. It's happening because of the ambiguity in spec.
In this case, pass the syntax as { position: 'top' } to cy.click().
Conclusion:
Shadow DOM is a web standard that offers a way to encapsulate style and markup in web components. It is a part of the Web Components standard, which also includes HTML templates, Custom Elements, and HTML imports.The great synergy between shadow DOM, custom elements and CSS variables is worth exploring.