Skip to main content

Architecture

The diagram below shows how the key pieces of Atomic Testing fit together. It's the same interactive diagram as the one in Core Concepts — one canonical picture, shown wherever it's useful.

Which branch actually runs?

declarative / interface — not a runtime instance test environment concrete class that runs

Atomic Testing follows a layered design so that your test code stays the same no matter which rendering library or test runner you use. The main pieces from the diagram are described below.

Test Engine​

The test engine renders a scene and wires up every component defined in a ScenePart. It exposes these parts through a typed API so tests can interact with them. Engines exist for React, Vue and other frameworks—see the Setup and Core Concepts sections for examples.

Component Drivers​

Drivers encapsulate how to operate a component. Rather than querying the DOM in every test, you call methods such as click() or setValue() on the driver. Drivers may also contain child parts, allowing complex widgets to be composed from simpler ones. The engine instantiates drivers based on the ScenePart definition. Learn how to build your own drivers in Build Component Driver.

Two specializations extend ComponentDriver for shapes many UIs share: ContainerDriver for a component whose content is a caller-supplied scene (e.g. a dialog body), and ListComponentDriver for a repeated collection of items (e.g. a menu). See Driver Types in Core Concepts for both, with shipped examples.

ScenePart​

ScenePart acts as a blueprint describing the parts a scene exposes—their locators and which driver class to use. Scene parts can be nested so larger scenes reuse smaller ones. Refer to the Core Concepts page for an in-depth look.

Interactor​

Interactors perform the low level actions requested by drivers. DOMInteractor works with @testing-library utilities for unit/DOM tests, and is extended by ReactInteractor (which wraps every interaction in React's act()), VueInteractor (which calls Vue's nextTick()), AngularInteractor (which awaits ApplicationRef.whenStable()), and StorybookInteractor (which drives a real browser via @storybook/addon-vitest rather than jsdom) so state settles before the next assertion. PlaywrightInteractor targets a real browser for end-to-end scenarios directly, without extending DOMInteractor. Because drivers talk only to the Interactor interface, the same driver code can operate in any of these environments. See the Interactor guide for details on the full set of available interactors and on creating custom ones.

Putting it all together​

When a test calls engine.parts.button.click(), the call flows through the driver into the interactor, which then manipulates the actual UI element. This indirection keeps tests declarative and portable across environments while still letting you reuse driver code and scene definitions.