Skip to main content

Automation testing shadow DOM elements

Shadow DOM allows DOM elements to contain child nodes and CSS, which helps web developers by better encapsulating their code. But this creates challenges for automation testing, because elements inside a shadow root technically do not exist in the main DOM.

The Web Recorder and Spy in Katalon Studio allows you to:
  • Capture multi-level shadow DOM
  • Capture iframe in shadow DOM
  • Capture shadow DOM in iframe
This article will focus on how to capture multi-level shadow DOM elements using the Web Recorder and Spy.
  • To receive the desired result, we recommend setting the default selection method as Smart Locator. Go to Project Settings > Test Design > WebUI and select Smart Locator.

We will demo with the site Books: where all the elements are under a shadow root.

Understand shadow DOM elements

In the demo website, navigate to the search bar, right-click and choose Inspect. The Chrome Developer tool opens and highlights the selected element.

We'll look at two shadow DOM elements in the Chrome Developer tool:
  • Shadow host: the regular DOM node that the shadow DOM is attached to. In this example, book-app is the shadow host. In Katalon Studio, the shadow host acts as the parent object.
  • Shadow root: The root node of the shadow tree, indicated with #shadow-root. In this example, this element is nested in multi-level shadow DOM. The shadow root acts as the child object in Katalon Studio.

    You can learn more about object properties from the Mozilla developer documentation: Working with objects.

Create test cases with shadow DOM elements

This section guides you through creating a test case that includes shadow DOM elements using the Web Recorder. We'll use Smart Locator to capture the search bar element, which is a multi-level shadow DOM element.
  1. From the main toolbar, select Record Web to open the Web Recorder.
  2. In the Web Recorder dialog, input the demo site URL:, then click Show Captured Objects to expand the dialog.
  3. Click Record to start the session.
    The web page instance is launched automatically.
  4. Right-click the search bar to open the context menu > Katalon Studio > Verify Element Present.
    In the Captured Objects section you can see:
    • The book-app element is captured as the parent object
    • The input element is captured as the child object
  5. Click Stop recording to close the browser, then click Save Script.
  6. Save the test objects and test case as prompted.
You have successfully created a test with a shadow DOM element. When you view the test object, Katalon Studio shows that the element identifies book-app as a shadow root parent.

Known limitations

  • The default selection method settings is only applicable to CSS or Smart Locator. If you choose XPath or Attributes, the system will automatically generate CSS locators.
  • Recording in closed shadow DOMs is not supported. Only open shadow DOMs are supported.
  • When using the Record utility, some websites add dynamic CSS class attributes to selected elements, which the Recorder captures. However, when you run this test script, these attributes may not exist, causing WebElementNotFoundException. You need to manually adjust the XPath of the elements.
  • Katalon Studio does not support recording the click action on dynamic elements. Some elements in shadow DOM, iframe, or shadow DOM elements in iframe cannot be detected by Selenium 3, so they might be unclickable. The workaround for this issue is to manually replace the Click keyword with the Enhanced Click keyword. See [WebUI] Enhanced Click.
  • When using Record and Spy utilities, you cannot take screenshots of shadow DOM test objects. Katalon Studio does not support the XPath and Screenshot locator strategies for shadow DOM test objects. We recommend using the CSS locator strategy only.

Modify object properties at runtime

If you have multiple and similar objects you want to quickly interact with during test execution, and you really don't want to spend time writing duplicate steps to interact with them, the approach below will help you reduce the time and maintain cleaner codes.

Use CSS or XPath to locate your elements, and then you start changing the IDs. For example:

TestObject yourObject = WebUI.modifyObjectProperty(findTestObject('Object Repository/Some object'), 'css', 'equals', '#${i}', true)

where 'i' is the loop counter. You can put it all inside of a loop that will read your excel sheet:

for (def i=0; i <= fineTestData('Path to your excel').getRowNumbers(); i++) {}