Playwright's component testing architecture enables testing UI components in isolation within a real browser environment. Unlike traditional unit tests that use simulated DOMs (like JSDOM), Playwright renders components in actual browser engines (Chromium, Firefox, WebKit) docs/src/test-components-js.md173-175 This system is powered by Vite, which handles the on-the-fly compilation and bundling of components, allowing developers to leverage Playwright's full automation API (Locators, Assertions, Network Interception) to verify component behavior packages/playwright-ct-core/src/vitePlugin.ts159-161
The system supports multiple frameworks including React, React 17, Vue, Svelte, and Solid, all built upon a shared @playwright/experimental-ct-core infrastructure packages/playwright-ct-core/index.d.ts19-20
The component testing system bridges the Node.js test runner environment with a browser-side rendering environment. It uses a specialized transform to identify component imports in test files and replace them with serializable identifiers that can be sent to the browser.
The following diagram illustrates the lifecycle of a component test, from the initial mount() call to the final rendering in the browser.
Sources: packages/playwright-ct-core/src/tsxTransform.ts34-40 packages/playwright-ct-core/src/vitePlugin.ts54-70 packages/playwright-ct-react/registerSource.mjs67-97
ct-core)The @playwright/experimental-ct-core package provides the engine that powers all framework-specific adapters.
vitePlugin.ts)The playwright-vite-plugin manages the lifecycle of the Vite dev server and the bundling process. It performs a "pre-scan" of test files to populate a ComponentRegistry, ensuring that only components actually used in tests are bundled packages/playwright-ct-core/src/vitePlugin.ts142-145
Key responsibilities:
buildBundle: Orchestrates the Vite build, generating a metainfo.json that tracks component dependencies, Playwright versions, and source hashes packages/playwright-ct-core/src/vitePlugin.ts105-140clearCache: Removes the output directory (usually .cache) where Vite artifacts are stored packages/playwright-ct-core/src/vitePlugin.ts81-86populateComponentsFromTests: Scans test files to find all components imported by the test suite to prepare the registry packages/playwright-ct-core/src/viteUtils.ts26tsxTransform.ts)Because components cannot be directly serialized and sent to the browser as live functions/classes, the transform modifies test code at runtime. It intercepts imports and replaces them with a reference object containing the component's metadata.
Sources: packages/playwright-ct-core/src/tsxTransform.ts34-40 packages/playwright-ct-react/registerSource.mjs31-33
Each framework (React, Vue, etc.) provides a registerSource.mjs file. This file is injected into the browser page and defines how the framework-specific playwrightMount function behaves.
@playwright/experimental-ct-react)The React adapter uses react-dom/client to create roots and render JSX components. It supports beforeMount and afterMount hooks to wrap components or perform setup packages/playwright-ct-react/registerSource.mjs87-96
| Function | Implementation Detail |
|---|---|
playwrightMount | Uses __pwCreateRoot(rootElement).render() to initialize the component packages/playwright-ct-react/registerSource.mjs67-93 |
playwrightUpdate | Updates the state of the mounted component using a React useState hook packages/playwright-ct-react/registerSource.mjs108-116 |
playwrightUnmount | Calls root.unmount() and removes the entry from the internal registry packages/playwright-ct-react/registerSource.mjs99-106 |
@playwright/experimental-ct-vue)The Vue adapter handles both JSX and Object-based component definitions (Vue Test Utils style). It includes a specialized __pwCreateSlot function to compile string-based templates into render functions at runtime using @vue/compiler-dom packages/playwright-ct-vue/registerSource.mjs20-21
| Feature | Code Entity |
|---|---|
| Component Creation | __pwCreateComponent processes props, listeners, and slots packages/playwright-ct-vue/registerSource.mjs119-179 |
| Slot Compilation | __pwCreateSlot uses __pwCompile to turn HTML strings into render functions packages/playwright-ct-vue/registerSource.mjs70-89 |
| Event Interception | __pwSetDevTools hooks into Vue's internal component:emit event to track events in tests packages/playwright-ct-vue/registerSource.mjs208-220 |
Component tests differ from E2E tests by utilizing the mount fixture. The mount function returns a Locator extended with component-specific methods like unmount and update packages/playwright-ct-react/index.d.ts25-28
Sources: packages/playwright-ct-core/src/mount.ts63-82 packages/playwright-ct-react/registerSource.mjs67-93 docs/src/test-components-js.md84-91
MountOptions: Framework-specific options like props, slots, on (for Vue events), and hooksConfig packages/playwright-ct-vue/index.d.ts30-35MountResult: A Playwright Locator that also exposes unmount() and update() for lifecycle management packages/playwright-ct-vue/index.d.ts41-48Component: A union of serializable types including JsxComponent and ObjectComponent packages/playwright-ct-core/types/component.d.ts17-37Component testing requires a playwright-ct.config.ts file. This configuration extends the standard Playwright config with component-specific fields.
playwright/index.html: The mandatory entry point that must contain a <div id="root"></div> for mounting docs/src/test-components-js.md84-95playwright/index.ts: A script for global setup, such as applying themes or importing global stylesheets docs/src/test-components-js.md100-102metainfo.json: A file generated in the .cache directory that tracks the viteVersion, playwrightVersion, and all discovered components tests/playwright-test/playwright.ct-build.spec.ts40-45The mount fixture handles the underlying navigation to the Vite-served page and coordinates the playwrightMount call via page.evaluate packages/playwright-ct-core/src/mount.ts49-61
Sources: docs/src/test-components-js.md84-102 packages/playwright-ct-core/src/vitePlugin.ts114-139 tests/playwright-test/playwright.ct-build.spec.ts40-45
Refresh this wiki