Write once, test everywhere
The same driver and assertion code works across React, Vue and Playwright — plus Angular (async setup), Storybook, and plain DOM tests. Learn once, test any UI framework.
Stop rewriting your test suite every time you switch UI frameworks or upgrade a component library. Atomic Testing composes tiny, reusable component drivers into portable test scenes — so the same semantic test runs across frameworks, libraries, and environments. Learn once, test any UI.
pnpm add -D @atomic-testing/core @atomic-testing/react-19 @atomic-testing/component-driver-htmlSwitch the runtime tab — notice the scene definition and the test body never change. Only the import and mount line differ.
import { createTestEngine } from '@atomic-testing/react-19';
import { HTMLButtonDriver, HTMLElementDriver } from '@atomic-testing/component-driver-html';
import { byDataTestId } from '@atomic-testing/core';
// One scene definition — reused on every runtime
const scene = {
greeting: { locator: byDataTestId('greeting'), driver: HTMLElementDriver },
button: { locator: byDataTestId('welcome-btn'), driver: HTMLButtonDriver },
};
it('welcomes the user on click', async () => {
const engine = createTestEngine(<Welcome name="Alice" />, scene);
expect(await engine.parts.greeting.getText()).toBe('Hello Alice!');
await engine.parts.button.click();
expect(await engine.parts.button.getText()).toBe('Welcome!');
await engine.cleanUp();
});
Each primitive is tiny and replaceable: locators and drivers snap into scenes, scenes into engines, engines into suites that outlive any framework.
The same driver and assertion code works across React, Vue and Playwright — plus Angular (async setup), Storybook, and plain DOM tests. Learn once, test any UI framework.
select.selectByLabel('Option 2') instead of brittle DOM queries. Focus on behavior, not implementation.
Reuse component drivers across Material-UI, Radix, shadcn/ui and custom components. Component library changes don’t break your tests.
Framework migrations, library upgrades and environment changes become trivial. Your testing investment scales with your app.
✓ verifiableNot just a claim: this repo's own *.suite.ts test logic runs unmodified under Jest and across Chromium, Firefox & WebKit via Playwright — see package-tests/ in this monorepo.
Atomic Testing adds a driver layer on top of Testing Library and Playwright — that's a learning curve and a dependency, not a free lunch. It's a poor fit for a single throwaway component, a prototype you'll never maintain, or a team unwilling to invest in the pattern up front. Each driver call is a thin async wrapper around the same Testing Library/Playwright call you'd write by hand, so it adds a coordination step rather than real work — and lock-in risk is low: every driver bottoms out in those same portable primitives, so dropping the abstraction later means calling them directly, not rewriting your component tree.
Get your first portable test running in five minutes.