@atomic-testing/vue-3
Vue 3 test adapter that extends Atomic Testing's component driver pattern to Vue applications. It enables testing Vue components using the same high-level semantic APIs used across React, Playwright, and DOM environments.
Overview​
The @atomic-testing/vue-3 package brings Atomic Testing's "component driver" abstraction to Vue 3, maintaining architectural consistency while respecting Vue's unique reactivity model. It provides reliable, framework-agnostic testing by automatically handling Vue's async reactivity system.
Key Features​
✅ Unified API: Vue components use identical component drivers as other frameworks
✅ Reactivity Safety: Properly handles Vue's async reactivity system using nextTick()
✅ Cross-Framework: Test patterns learned in React translate directly to Vue
✅ E2E Ready: Same drivers work in both DOM and Playwright environments
✅ Flexible Components: Supports both compiled Vue components and template-based definitions
Installation​
pnpm add @atomic-testing/vue-3
Architecture​
VueInteractor​
Extends the base DOMInteractor with Vue-specific reactivity handling:
- Automatically calls
nextTick()after each interaction - Ensures Vue's reactive updates complete before proceeding
- Provides reliable, predictable testing experience
Test Engine Factory​
Two main functions for different testing scenarios:
createTestEngine(): Renders and tests Vue componentscreateRenderedTestEngine(): Tests already-rendered components (e.g., Storybook)
Framework Integration​
- Uses
@testing-library/vuefor component rendering with fallback strategies - Maintains the same ComponentDriver API as React adapters
- Enables cross-framework driver reuse
Usage​
Basic Example​
import { HTMLButtonDriver } from '@atomic-testing/component-driver-html';
import { byDataTestId } from '@atomic-testing/core';
import { createTestEngine } from '@atomic-testing/vue-3';
import CounterComponent from './Counter.vue';
const engine = createTestEngine(CounterComponent, {
incrementButton: {
locator: byDataTestId('increment'),
driver: HTMLButtonDriver,
},
});
// Test interaction - automatically handles Vue reactivity
await engine.parts.incrementButton.click();
expect(await engine.parts.incrementButton.getText()).toBe('Count: 1');
SFC-Like Components​
For simplified testing, you can define components using template strings:
import { createTestEngine } from '@atomic-testing/vue-3';
const TestComponent = {
template: `
<div>
<button @click="increment" data-testid="counter">
Count: {{ count }}
</button>
</div>
`,
setup() {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
},
};
const engine = createTestEngine(TestComponent, {
button: { locator: byDataTestId('counter'), driver: HTMLButtonDriver },
});
Testing Rendered Components​
For components already rendered in the DOM (e.g., Storybook):
import { createRenderedTestEngine } from '@atomic-testing/vue-3';
const engine = createRenderedTestEngine({
button: { locator: byDataTestId('counter'), driver: HTMLButtonDriver },
});
// Test the already-rendered component
await engine.parts.button.click();
Cross-Framework Compatibility​
The same component drivers work across all Atomic Testing adapters:
// Works identically in React, Vue, and Playwright
const parts = {
emailInput: { locator: byDataTestId('email'), driver: TextFieldDriver },
submitButton: { locator: byDataTestId('submit'), driver: ButtonDriver }
};
// React
const reactEngine = createTestEngine(<LoginForm />, parts);
// Vue 3
const vueEngine = createTestEngine(LoginFormVue, parts);
// Playwright
const playwrightEngine = createTestEngine(page, parts);
Integration with Vue Ecosystem​
Vue Testing Library​
The adapter uses @testing-library/vue internally with intelligent fallback strategies for component rendering.
Vue Reactivity​
All interactions automatically wait for Vue's reactivity cycle to complete:
// This automatically calls nextTick() after the click
await engine.parts.button.click();
// Reactive state is guaranteed to be updated here
const updatedText = await engine.parts.button.getText();
TypeScript Support​
Full TypeScript support with proper Vue component typing:
import type { Component } from 'vue';
const engine = createTestEngine<Component>(MyVueComponent, sceneParts);
Why Use @atomic-testing/vue-3?​
- Consistent Testing Patterns: Learn once, test everywhere - same patterns work across React, Vue, and E2E
- Reliable Vue Integration: Proper handling of Vue's reactivity ensures tests aren't flaky
- High-Level APIs: Focus on user interactions, not DOM implementation details
- Framework Agnostic Drivers: Reuse component drivers across different frameworks and test environments
- Future-Proof: As your app grows or changes frameworks, your test patterns remain consistent