Git Product home page Git Product logo

Comments (32)

mmun avatar mmun commented on August 22, 2024 9

Hey Percy folks!

Shadow DOM support is important for us at Addepar because our design system is based on Stencil which makes heavy use of shadow DOM.

We've developed a fork of @percy/cli (and to a smaller extent @percy/ember) that supports shadow DOM. They're publicly accessible at https://github.com/Addepar/percy-cli and https://github.com/Addepar/percy-ember. We've open sourced the forks as a proof of concept for the developers of Percy, as well as for other Percy users to use if they are in a similar situation as us.

Here are some details of the implementation. I'm happy to answer any questions.

Caveats

As discussed in the comments above, we're leaning on the experimental Declarative Shadow DOM available in Chrome. This means that:

  • 🚨 It only works in Chrome 🚨 Specifically Chrome 90+, or Chrome 85+ behind a flag. See https://chromestatus.com/feature/5191745052606464.
  • It may break at any time in the future if Chrome changes its API or drops support for the feature entirely.

Implementation notes

cloneNode

cloneNode(true) does not include shadow roots. We reimplement a recursive cloneNode that can handle this.

adoptedStylesheets

The adoptedStylesheets property is commonly used in component frameworks using shadow DOM because it lets you efficiently reuse stylesheet objects across multiple shadow roots (i.e. across multiple instances of a shadow DOM-based web component).

It's a known issue that adoptedStylesheets are not currently serialized by the APIs exposed in the Declarative Shadow DOM feature. See for example whatwg/dom#831 (comment), https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md#other-unanswered-questions and WICG/webcomponents#939.

We resolve this issue by inlining a <style> tag into each shadow root. There are more efficient ways to handle this serialization but it would require running a bit of setup code in the document on Percy's servers before snapshots are taken and that's not currently a feature Percy offers.

from cli.

itsjwala avatar itsjwala commented on August 22, 2024 9

Hey folks!

Percy now supports capturing Shadow DOM available in the Alpha release of CLI 🏗️. Please refer to this documentation for trying it out.

from cli.

wwilsman avatar wwilsman commented on August 22, 2024 5

That fork does look promising! We'll look into adopting this officially behind a config option in the coming weeks. Currently, the only option that gets forwarded to the DOM serialization script is enableJavaScript. A new option will likely follow a similar pattern, and we'll have to verify that all of our SDKs will correctly forward that option to the script.

from cli.

IgnasCi avatar IgnasCi commented on August 22, 2024 4

Strange that percy is not putting effort on this issue, since more and more products are moving on vue components... :)

from cli.

jeffchew avatar jeffchew commented on August 22, 2024 3

Just keeping this on the radar if possible. We are increasing our e2e test coverage on our end and so far can only test with React (which we plan to deprecate sometime in the future and only support web components).

from cli.

wachunga avatar wachunga commented on August 22, 2024 1

@Robdel12 That's great news. I have confirmed that Cypress supports this already with the following change (when using Chrome browser, but not yet Electron):

  on("before:browser:launch", (browser = {}, launchOptions) => {
    launchOptions.args.push("--enable-experimental-web-platform-features");
    return launchOptions;
  });

Can you confirm that doesn't help until percy-dom knows what to do with <template shadowroot="open\>?

Also, if you have ideas for workarounds, that would really help my team.

from cli.

Robdel12 avatar Robdel12 commented on August 22, 2024 1

Sadly there isn't anything that can be done until we do the work to update @percy/dom. We have to change how we clone the DOM -- Shadow DOM doesn't respect/work with cloning the full DOM tree (document.cloneNode(true)). We'll have to rewrite use element.getInnerHTML({includeShadowRoots: true}) which could have other ripple impacts on how the DOM is captured/serialized/persisted. Not a small change :)

from cli.

Robdel12 avatar Robdel12 commented on August 22, 2024 1

Hey @jeffchew! Based on @wwilsman's research (the comment right above) it doesn't look like this will be something we'll be able to implement for a while. The web APIs just aren't there and what is starting to come out only works/exists in Chrome (behind flags, depending on what version your tests are running in, default in Chrome 90).

We'd love to support this but it seems to be a case of Google running out in front of everyone (other browser vendors).

from cli.

Robdel12 avatar Robdel12 commented on August 22, 2024 1

For sure! I'd open a support discussion on the storybook SDK

from cli.

snake-py avatar snake-py commented on August 22, 2024 1

Is this on any roadmap? Can anyone give a rough estimate of when shadow doms will be supported? We are building vue web components and want to test the build component.

from cli.

wachunga avatar wachunga commented on August 22, 2024

Forgot to mention: there's a similar issue with Cypress snapshots (shown on hover) not including shadow-dom:
cypress-io/cypress#8843

There's a repo linked there that makes it easy to repro.

from cli.

Robdel12 avatar Robdel12 commented on August 22, 2024

Thanks for the issue! This is currently not supported across all of our SDKs. In the near future we'll be picking this up now that there's a method for capturing open shadowroots in the DOM: https://web.dev/declarative-shadow-dom/#serialization

But it does require a complete refactor to how @percy/dom works now.

from cli.

jeffchew avatar jeffchew commented on August 22, 2024

I'd like to +1 this too. We started out with percy-storybook which appears to be fine with at least the base snapshots, but we have recently started hooking into puppeteer to capture click states, etc. The only way any content appears to render is with enableJavascript set to true, which only renders the initial state of the page but does not capture any subsequent states/e2e tests like click states, form entering, etc.

from cli.

wwilsman avatar wwilsman commented on August 22, 2024

Did some preliminary research on this with Chrome 90 recently out with the declarative API enabled by default.

  1. Even with the new declarative API, the cloned document does not seem to contain shadow roots. While the document does contain the templates needed to create shadow roots, it seems the roots themselves aren't actually created unless the cloned templates are rendered. This makes it so we have the same current issue of not being able to serialize shadow root contents (such as nested input elements or canvases).

  2. It doesn't looks like these new template shadow roots will be able to be re-rendered trivially (without JS) unless the browser also supports the new declarative API. While chromium browsers have only recently shipped with support enabled by default, our other main rendering browser, FireFox, doesn't seem to have support on their roadmap quiet yet (that I can find).

Even when support is more widely available and that isn't an issue, we'll still have to figure out the first issue of how to properly serialize shadow root trees. Maybe that involves an even bigger refactor to walking the DOM tree and building the clone ourselves, but that's an even larger task than refactoring to use getInnerHTML.

from cli.

jeffchew avatar jeffchew commented on August 22, 2024

Just checking if there's been any progress here at all?

from cli.

jeffchew avatar jeffchew commented on August 22, 2024

Just another FYI, we tried upgrading @percy/storybook to v4, and it ended up breaking all of the snapshots since from what I understand uses @percy/cli under the hood in this version:

https://percy.io/538fc19a/Carbon-for-IBM.com-Web-Components/builds/14269858/changed/805810435?browser=chrome&browser_ids=18%2C20&subcategories=unreviewed%2Cchanges_requested&viewLayout=side-by-side&viewMode=new&width=1280&widths=375%2C1280

All snapshots are unstyled, and a number of them also just went missing.

from cli.

Robdel12 avatar Robdel12 commented on August 22, 2024

You'll want to re-enable JavaScript with Storybook & WC's. https://github.com/percy/percy-storybook#unexpected-diffs

Edit: FWIW, there won't be any progress on this until the Web's APIs for WC's matures (as described here.)

from cli.

IgnaceMaes avatar IgnaceMaes commented on August 22, 2024

@mmun That's amazing, thanks for looking into this.

At @OTA-Insight we're in the exact same situation as the design system is built with Stencil using Shadow DOM and the main application is written in Ember. Not having Shadow DOM available in the screenshot is blocking us from adopting Percy.

I've tested our setup using the forks you've linked and it fixes the issue 🙌

Right now the forks are built locally. When linking them directly in package.json in the following way it results in an error from the @percy/cli package: error Can't add "@percy/cli": invalid package version undefined.. Any idea if there is a way to fix this?

"@percy/cli": "https://github.com/Addepar/percy-cli.git#master",
"@percy/ember": "https://github.com/Addepar/percy-ember.git#master",

It would be great if this could make its way to the official package.

from cli.

mmun avatar mmun commented on August 22, 2024

@IgnaceMaes Yeah, we're still thinking about the best way to handle this. One option is to use something like https://gitpkg.vercel.app/.

As an aside, you'll probably run into a Stencil-specific bug ("Sharing constructed stylesheets in multiple documents is not allowed") with the current implementation. This will cause your tests to fail despite the screenshots uploading correctly. We'll add a workaround for that soon.

from cli.

Robdel12 avatar Robdel12 commented on August 22, 2024

👋🏼 Thanks for the info @mmun! We'll likely only be interested in accepting something like this behind a flag so it's opt-in. There's too many caveat's for us to go all in on this, the API will need to stabilize a lot more before we feel ready for that.

from cli.

mixonic avatar mixonic commented on August 22, 2024

There's too many caveat's for us to go all in on this

I mean, the caveat today is that Percy doesn't work with Web Components (w/ Shadow DOM) rendered by a JS framework (or maybe generally) at all, which seems like a pretty large caveat.

Regardless, your call over at Percy 👍. What does adding this functionality behind an opt-in flag look like? Is there prior art or an example? We would love to have this upstream even if it is opt-in so that we can get off our forks.

from cli.

mmun avatar mmun commented on August 22, 2024

@wwilsman Awesome. Thanks for taking a look. My team is available to collaborate if needed.

from cli.

jeffchew avatar jeffchew commented on August 22, 2024

Would love this as a config option! Thank you @mmun for the work you put into your project for this! This would hopefully unblock us on our end!

from cli.

Robdel12 avatar Robdel12 commented on August 22, 2024

@jeffchew with storybook you can enable JS safely and it will render the story from scratch in our browsers (so the shadow DOM will get built). It's the only SDK that this will work well with

from cli.

jeffchew avatar jeffchew commented on August 22, 2024

Thank you @Robdel12 , it turns out after digging into the storybook side there might be an unrelated issue to this that we are still blocked by, but we are also using percy with e2e testing in Cypress where we currently cannot do with web components (which relates more to this issue).

The unrelated bug with storybook seems to also affect our React based storybook, where most snapshots are not rendering (there is a timeout error of some kind) and I already reached out to our account executive and Lee V. about this (but not sure if there is an issue open for this).

from cli.

Robdel12 avatar Robdel12 commented on August 22, 2024

Ah! @jeffchew I remember debugging this and shipping a feature to help. I remember there were ad requests that were hanging asset discovery up (or maybe tracking pixels). You can exclude those requests from asset discovery and that should hopefully stop the timeouts from happening on your storybook builds https://docs.percy.io/docs/debugging-sdks#disallowing-requests

from cli.

jeffchew avatar jeffchew commented on August 22, 2024

Thanks @Robdel12 ! We did try that but still running into issues. Should I create a new issue to track this as this is different from the Shadow DOM support? I can share logs on what I'm seeing but looks like JS assets themselves are getting blocked in Percy.

from cli.

jeffchew avatar jeffchew commented on August 22, 2024

@Robdel12 issue opened! percy/percy-storybook#565

from cli.

andrei-musnikov avatar andrei-musnikov commented on August 22, 2024

Hi all, is there any progress on this?

from cli.

andreapigatto avatar andreapigatto commented on August 22, 2024

@mmun I'm in same situation having some web components developed with Preact.js. Wanted to add visual testing with Percy but shadow-dom is preventing me on doing this.
Will give a try of the forks you kindly shared.
Was thinking to bypass the issue doing visual testing as part of unit test instead of cypress e2e with jest and other libraries till this feature is not implemented.

from cli.

branislav-remen avatar branislav-remen commented on August 22, 2024

Any updates on this? My last info from browserstack support (April 2022):

Gladly, the feature of being able to take a screenshot of shadow DOM components is topmost on our roadmap. It is going to be rolled out within 6 months.

from cli.

itsjwala avatar itsjwala commented on August 22, 2024

Hey folks!

we've shadow DOM capturing in our roadmap. Due to some OKR reshuffling, it was delayed. Please expect beta by earlier Jan 2023.

To workaround this till then you may enable javascript in Percy's config and use https://github.com/percy/percy-storybook/ SDK.

from cli.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.