Replacing JSDOM: Exploring Browser-Native Component Testing Solutions #3453
tamara-corbalt
announced in
RFCs
Replies: 2 comments
-
Great write up @tamara-corbalt ! Two comments:
|
Beta Was this translation helpful? Give feedback.
0 replies
-
Noting from a discussion in engineering pairing today (4/23/2025) we are shelving Playwright component testing in favor of using Storybook testing. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Our goal is to replace JSDOM with a more reliable and browser-native component testing solution. Below, we outline the challenges and trade-offs of the alternatives we could potentially adopt.
Some key considerations include:
Since we already rely on a tool called Playwright for our integration and visual regression testing, this write-up places extra emphasis on how we might extend Playwright to test component functionality in real browsers. This document is a starting point for discussions, and further exploration of the tools mentioned below is warranted.
Playwright and Playwright Component Testing
Unlike Jest with JSDOM, Playwright Component Testing runs tests in real browsers (Chromium, Firefox, and WebKit), providing more accurate rendering and event behavior for components. A big plus is that Playwright’s core testing framework,
@playwright/test
, is already integrated into our testing workflow for VRTs.Playwright's Component Testing (
@playwright/experimental-ct
) extends this by introducing a dedicated API for mounting and interacting with individual components in the browser. It includes sub-packages for React, Vue, and Svelte, allowing teams to write component tests that closely resemble real-world usage.For our React-based components, Playwright Component Testing seems to align well with our existing patterns. However, the key question is: how well does it align with our Preact-rendered Web Components?
Compatibility with Our Web Components
✅ Pros:
<ds-alert>
.variation="error"
andvariation="success"
.expect(component).toContainText(...)
One challenge in migrating our Web Component tests to Playwright is how event listeners are configured. In our current Jest setup, we manually attach event listeners after rendering the component using addEventListener('ds-click', callback). This allows us to capture custom events fired from Web Components.
However, Playwright Component Testing follows a different pattern—React event handlers are passed at mount, whereas Web Components require manual event listener attachment post-render, which
@playwright/experimental-ct
does not appear to support natively. To work around this, we may need to leverage Playwright's underlying Page API and use page.evaluate() to manually attach event listeners inside the test environment.At this stage, a working implementation of this workaround has not been established, and further exploration is needed to determine the best approach.
Experimental Branch
To inspect our test branch locally, pull down this branch and run:
npm install
npm run test-ct
Conclusion
Playwright Component Testing offers a promising path for testing our components in real browsers, aligning well with our existing usage of Playwright for visual regression testing. While it supports key rendering behaviors for specifically web components, event listener handling remains a challenge that requires further investigation.
Vitest
Another option we considered is the Vitest testing framework. Vitest supports unit, integration, and component testing with a Jest-compatible API, built-in mocking, and TypeScript support.
It's known for its speed and efficiency, leveraging Vite for rapid test execution. While it can be used with
jsdom
for DOM simulation, it also supports alternatives likehappy-dom
as well as testing in browser mode, which is what we're interested in. Vitest's experimental browser mode can be configured with providers like Playwright or WebDriverIO, enabling tests to run in real browsers, providing a more accurate environment for browser-specific behaviors.After setting up Vitest in our codebase, we confirmed that basic React components appear to render correctly in browser mode. However, Web Components that rely on Shadow DOM or template-based rendering do not:
Experimental Branch
To inspect this test branch locally, clone and pull down this branch, run:
npm install
npm run test:vitest
Final Thoughts
At this stage, Playwright Component Testing appears to be the strongest candidate due to our existing Playwright usage and its ability to effectively test React components in real browsers. However, Web Component event handling may require additional research and adaptation.
Vitest, while promising for browser-based testing of our React components, does not seem well-suited for our Preact-rendered Web Components, whether they rely on the Shadow DOM or template-based rendering.
As an alternative to both of these options, we could explore Storybook Component Testing in a follow-up ticket. While Storybook is already part of our workflow for component documentation, it operates within an iframe, meaning interactions are still simulated rather than truly occurring in a standalone browser environment. This could be useful for some cases but may not fully replace Playwright or other browser-based testing solutions.
Beta Was this translation helpful? Give feedback.
All reactions