Shadow DOM inspect

Inspecting elements within the Shadow DOM and generating XPath and CSS selectors can be challenging because Shadow DOM elements are encapsulated. Here’s how to inspect Shadow DOM elements and generate selectors using Google Chrome DevTools and relevant addons for XPath and CSS selectors.

Inspecting Shadow DOM Elements Using Google Chrome DevTools

Step-by-Step Guide

  • Open Chrome DevTools:
  • Right-click on the webpage and select Inspect or press Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (Mac) to open DevTools.
  • Locate the Shadow Host:
  • Find the element that hosts the Shadow DOM. It will typically have a #shadow-root indicator under it.
  • Expand the Shadow Root:

Click on the #shadow-root to expand it and see the Shadow DOM elements.

Inspect Elements within the Shadow DOM:

You can now inspect and interact with elements within the Shadow DOM as you would with regular DOM elements.

Using CSS Selectors in Shadow DOM

When dealing with Shadow DOM, you need to traverse from the shadow host to the shadow root and then to the desired element.

Example

html
Copy code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Shadow DOM Example</title>
</head>
<body>
    <div id="shadow-host"></div>

    <script>
        const shadowHost = document.getElementById('shadow-host');
        const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
        shadowRoot.innerHTML = `
            <style>
                .shadow-element {
                    color: blue;
                }
            </style>
            <div class="shadow-element">Inside Shadow DOM</div>
        `;
    </script>
</body>
</html>

Accessing Elements with CSS Selectors (JavaScript)

const shadowHost = document.querySelector('#shadow-host');
const shadowRoot = shadowHost.shadowRoot;
const shadowElement = shadowRoot.querySelector('.shadow-element');
console.log(shadowElement.textContent); // Outputs: Inside Shadow DOM

Using XPath in Shadow DOM

XPath is generally not used for querying within the Shadow DOM directly due to its encapsulation, but you can use JavaScript to access the shadow root and then work with elements inside it.

Example (JavaScript)

const shadowHost = document.querySelector('#shadow-host');
const shadowRoot = shadowHost.shadowRoot;
const shadowElement = shadowRoot.querySelector('.shadow-element');
const xpathResult = document.evaluate('.//div[@class="shadow-element"]', shadowRoot, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
console.log(xpathResult.textContent); // Outputs: Inside Shadow DOM

Using Add-ons to Generate Selectors

  1. ChroPath

ChroPath is a Chrome extension that helps generate, edit, and verify XPath and CSS selectors, including within Shadow DOM.

How to Use ChroPath

  • Install ChroPath:
    • Install ChroPath from the Chrome Web Store.
  • Open ChroPath:
    • Open DevTools and navigate to the ChroPath tab.
  • Generate Selectors:
    • Select an element within the Shadow DOM.

ChroPath will display the XPath and CSS selectors for the selected element.

  1. SelectorGadget

SelectorGadget is a Chrome extension that helps generate CSS selectors by clicking on elements on a webpage.

How to Use SelectorGadget

  • Install SelectorGadget:
    • Install from the Chrome Web Store.
  • Activate SelectorGadget:
    • Click the SelectorGadget icon in the browser toolbar.
  • Select Elements:
    • Click on elements within the Shadow DOM. SelectorGadget will highlight the elements and display the generated CSS selector.
  • Copy Selector:
    • Copy the generated CSS selector for use in your automation scripts.

Practical Usage in Automation Scripts

Using CSS Selectors in Selenium (Python)

from selenium import webdriver

# Access Shadow DOM
shadow_host = driver.find_element_by_css_selector('#shadow-host')
shadow_root = driver.execute_script('return arguments[0].shadowRoot', shadow_host)
shadow_element = shadow_root.find_element_by_css_selector('.shadow-element')
print(shadow_element.text)  # Outputs: Inside Shadow DOM

Using XPath in Selenium (Python)

from selenium import webdriver

# Access Shadow DOM
shadow_host = driver.find_element_by_css_selector('#shadow-host')
shadow_root = driver.execute_script('return arguments[0].shadowRoot', shadow_host)
shadow_element = driver.execute_script('return arguments[0].querySelector(".shadow-element")', shadow_root)
print(shadow_element.text)  # Outputs: Inside Shadow DOM

Using CSS Selectors in Playwright (JavaScript)

javascript


const { chromium } = require('playwright');

(async () => {
    const browser = await chromium.launch();
    const page = await browser.newPage();
    await page.goto('https://www.google.com');

    // Access Shadow DOM
    const shadowHost = await page.$('#shadow-host');
    const shadowRoot = await shadowHost.evaluateHandle(el => el.shadowRoot);
    const shadowElement = await shadowRoot.$('.shadow-element');
    console.log(await shadowElement.textContent());  // Outputs: Inside Shadow DOM

    await browser.close();
})();

One important thing USE XPATH ONLY with Salesforce shadowdom:

Salesforce uses Shadow DOM extensively in its Lightning components. This can make it challenging to interact with elements using traditional selectors. LWC uses a polyfill to implement shadow DOM rather than a native browser

implementation. This implementation restricts Selenium access by non-XPath

selectors, like By.cssSelector(), but still allows direct access with By.xpath().

The simplest fix is to convert your non-XPath locators to XPath. There are plans to change this but just make sure you are using XPATH for now.

Summary

Inspecting and Generating Selectors:

Chrome DevTools: Allows you to inspect elements within the Shadow DOM.

ChroPath: Generates and verifies XPath and CSS selectors, including for Shadow DOM elements.

SelectorGadget: Helps generate CSS selectors by clicking on elements.

Using Selectors in Automation:

Selenium: Use JavaScript to access Shadow DOM elements and then use CSS or XPath selectors.

Playwright: Provides methods to access Shadow DOM and use CSS or XPath selectors.