Handling of element in shadow dom

I am working with load tests for frontend using xk6-browser and facing issue to handle a link inside shadow dom. I can run same code from playwright but its not working with xk6. I am using Page object model and sharing code here:

export class Homepage {
    constructor(page) {
        this.page = page
        this.verifyDeviceLink = page.locator('.messenger-web-component h4.title')

    }
   async verifyDeviceIfRequired(){
     this.verifyDeviceLink.click();
     await Promise.all([this.verifyDeviceLink.click()]);
    }

and here we have code for test case.

  const page = browser.newPage();
    const loginpage = new Loginpage(page);
    const homepage = new Homepage(page);
 
    await loginpage.goto();
    await loginpage.doLogin(" ", "");
    await homepage.verifyDeviceIfRequired();
    await Promise.all([page.waitForNavigation()]);
    page.close();
  } 

Kindly help me with this issue.

Hi @mujamil90. Welcome to the forum.

Is there a specific reason you’re calling click as follows as it clicks on the element twice:

     this.verifyDeviceLink.click();
     await Promise.all([this.verifyDeviceLink.click()]);

Also, we should put click and waitForNavigation in the same promise to prevent race conditions. Here’s an example:

export class Homepage {
    constructor(page) {
        this.page = page
        this.verifyDeviceLink = page.locator('.messenger-web-component h4.title')

    }
   async verifyDeviceIfRequired() {
     return this.verifyDeviceLink.click;
    }
    ...

  const page = browser.newPage();
    ...
    await Promise.all([
        page.waitForNavigation(),
        homepage.verifyDeviceIfRequired(),
    ]);
    ...
  } 

Thank you for letting me know this and I have made the changes. I am getting problem while clicking on “Device link” as it is in Shadow dom. I am getting below error.

ERRO[0035] Uncaught (in promise) clicking on “.messenger-web-component h4.title”: timed out after 30s executor=per-vu-iterations scenario=ui

Hi @mujamil90,

You’re welcome. Can you send an example HTML page snippet that contains this component that the script can’t find?

Thanks.

I have attached image for HTML code. Please have a look.

Hi @maideypl,

I’ve tried querying shadow DOM, and it seems to be working. If possible, we would like to help further by receiving a script and an HTML snippet from you in text form (instead of a screenshot) to try to reproduce and solve the issue.

Here’s a working example:

export default async function() {
  const page = browser.newPage();
  page.setContent("<html><head><style></style></head><body>hello!</body></html>")
  await page.evaluate(() => {
    const shadowRoot = document.createElement('div');
    shadowRoot.id = 'shadow-root';
    shadowRoot.attachShadow({mode: 'open'});
    shadowRoot.shadowRoot.innerHTML = '<p id="find">Shadow DOM</p>';
    document.body.appendChild(shadowRoot);
  });
  const shadowEl = page.$("#find");
  check(shadowEl, {
    "shadow element exists": (e) => e !== null,
    "shadow element text is correct": (e) => e.innerText() === "Shadow DOM",
  });
  page.close();
}

Thanks.