简体   繁体   中英

Stenciljs E2E Testing: how to find a child of a child in the Shadow Dom

I have components arranged like so:

app-home
  shadow-root
    component1
      shadow-root
        div id=div1

In other words both my app-home and component1 have shadow doms.

I can find component1 easily in Stenciljs E2E Tests like so:

const page = await newE2EPage();
await page.setContent('<app-home></app-home>');
const component1 = await page.find('app-home >>> component1');

But, whatever I've tried I cannot get #div1 inside component1. It's important that I get back an E2EElement so I can use its methods such as click which trigger changes in the page.

Here's what I've tried:

  1. page.find('app-home >>> component1 >>> #div1')

    Returns null

  2. component1.find(':host >>> #div1') or component1.find(':root >>> #div1') or component1.find('>>> #div1') or component1.find('#div1') or component1.find('component1 >>> #div1')

    Returns null

  3. component1.shadowRoot.querySelector('#div1')

    This method gets an element but clicking on it or dispatching an event to it has no effect on app-root or component1 in the page.

Any suggestions then on how to find a child of a child when both elements have shadowDOMs?

Note: I'm assuming that component1 is in reality a valid custom element tag name (containing a dash).


page.find('app-home >>> component1 >>> #div1')

Using the >>> multiple times is currently not possible (see source ). >>> is not an official CSS selector, so its implementation is entirely up to Stencil.js.


component1.find(':host >>> #div1')

This or your similar approaches are also not possible because calling .find on an E2EElement can only find elements that are children of that element, but not the host element itself.


One solution is to switch entirely into the browser context:

await page.evaluate(() => {
  // this function will run in the browser context, not
  // in the Node.js context that the test is executed in.
  const appHome = document.querySelector('app-home');
  const comp1 = appHome.shadowRoot.querySelector('component1');
  const div1 = comp1.shadowRoot.querySelector('#div1');

  div1.click();
});

await page.waitForChanges();

You could refactor that into a helper, however I agree that it would be good if Stencil.js provided a proper API for this. Allowing the >>> selector multiple times would be a nice feature. I suggest you open a feature request in the Stencil.js repository.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM