testing-library / dom-testing-library

🐙 Simple and complete DOM testing utilities that encourage good testing practices.
https://testing-library.com/dom
MIT License
3.26k stars 466 forks source link

prettyDOM should be able to serialize shadowRoots #1188

Open alexkrolick opened 1 year ago

alexkrolick commented 1 year ago

Splitting this out from #484

A ShadowRoot is a DocumentFragment node that should be able to be serialized by pretty-format & prettyDOM,

A few changes would be needed in pretty-dom, including removing or altering the check for outerHTML (shadowRoot has innerHTML only) and adding recursive traversal of the node.

eps1lon commented 1 year ago

This library is more of a helper and not a first-class citizen of the API. Could you explain what high-level use cases this change would serve?

alexkrolick commented 1 year ago
  1. Under the current implementation, if a query fails because the thing you are looking for is in a shadow root, you can't see it in prettyDOM output, which makes it hard to figure out what to do
  2. If we complete #413, we will need this anyways to allow failed tests to produce useful output

I'm envisioning printing something like what Playwright has in their documentation for ShadowDOM, which is basically what Chrome Devtools shows as well:

https://playwright.dev/docs/selectors#selecting-elements-in-shadow-dom

<article>
  <div>In the light dom</div>
  <div slot='myslot'>In the light dom, but goes into the shadow slot</div>
  #shadow-root
    <div class='in-the-shadow'>
      <span class='content'>
        In the shadow dom
        #shadow-root
          <li id='target'>Deep in the shadow</li>
      </span>
    </div>
    <slot name='myslot'></slot>
</article>
KonnorRogers commented 1 year ago

I have a PR to shadow-dom-testing-library that utilizes JSDOM serialization. Unfortunately it doesnt use the "#shadowRoot" conventions since its piping through JSDOM, but heres an example output:

<body>
  <div>
    <duplicate-buttons>
      <shadow-root>
        <slot
          name="start"
        />
        <button>
          Button One
        </button>
        <br />
        <slot />
        <br />
        <button>
          Button Two
        </button>
        <slot
          name="end"
        />
      </shadow-root>

      <div
        slot="start"
      >
        Start Slot
      </div>
      <div>
        Default Slot
      </div>
      <div
        slot="end"
      >
        End Slot
      </div>
    </duplicate-buttons>
  </div>
</body>
AriPerkkio commented 1 year ago

I have some kind of version of prettyDOM which supports ShadowRoots in output. I only added the parts I needed at the time so it likely does not fulfill all requirements. But hopefully this helps:

https://github.com/AriPerkkio/aria-live-capture/blob/85f1e4613bec443797097320ed5f2b9f733fc729/.storybook/pretty-dom-with-shadow-dom.ts

See it in action here by clicking the Next state button: https://ariperkkio.github.io/aria-live-capture/?path=/story/dom-api-support-shadowroot--live-region-inside-shadow-dom

KonnorRogers commented 1 year ago

Just updating here, I got a proper serializer working, Thanks @AriPerkkio for the assist.

https://github.com/KonnorRogers/shadow-dom-testing-library/pull/43

There is one problem where it seems to output a lot of extra whitespace, but at least its working!