Playwright Selecting elements in Shadow DOM

Playwright Selecting elements in Shadow DOM

  • Whenever we launch a page, we see the page's DOM inside the main page DOM. We know the shadow DOM.
  • Under this particular shadow dom, we have some elements.

  • We can see here that within the shadow root, we can see the elements.
  • We first need to go to the page DOM and then to the shadow DOM.
  • With playwright, it's pretty straightforward, and we don't need to write complex js selectors or query selectors like in selenium.
  • The playwright can pierce into the shadow DOM where it can handle anything automatically.

  • This is something that is done in selenium to handle a shadow DOM.
  • To pierce the shadow DOM, first, we need to search for the elements in the page's DOM in iteration order and recursively search inside the shadow DOM roots.
  • Note that shadow-root should be open to pierce and automate.

So for realtime, we will be automating on a site called https://books-pwakit.appspot.com/
We will type in something inside the search box.

  • This is the DOM of the search box, which, as we can witness, is inside the shadow root.

Let us check out the straightforward method of this.

const {test, expect} = require('@playwright/test');
const site = "https://books-pwakit.appspot.com/";

test('ElementHandle', async ({page})=> 
{

    
    await page.goto(site);
    await page.locator('#input').type('Playwright')

   

});
  • We can give in to the id, and the playwright pierces the shadow root and automates it.

Page DOM To Shadow DOM:

  • We can see here that the shadow roots parent is book-app which is the page DOM.
  • We can even pierce it with the help of this by writing a CSS selector followed by the id of the shadow root search box.
const {test, expect} = require('@playwright/test');
const site = "https://books-pwakit.appspot.com/";

test('ElementHandle', async ({page})=> 
{

    
    await page.goto(site);
    await page.locator("book-app[apptitle = 'BOOKS'] #input").type('Cypress')

   

});
  • This way, we can automate elements and handle shadow DOM more effectively using playwright.
  • Let us write another test to fetch the text, which is down below, using the page to shadow pierce method.
const {test, expect} = require('@playwright/test');
const site = "https://books-pwakit.appspot.com/";

test('ElementHandle', async ({page})=> 
{

    
    await page.goto(site);
    await page.locator("book-app[apptitle = 'BOOKS'] #input").type('Cypress')
    const text = await page.locator("book-app[apptitle = 'BOOKS'] .books-desc").textContent()
    console.log(text)

   

});

  • We can see that it has given us the text within the shadow root from the page DOM.
Standard (Image)