Test Structure
This page explains the generated file tree, the purpose of each directory, and when to add new files.
Generated File Tree
After running the generator, your project gains this structure:
your-project/
├── playwright.config.js # Playwright configuration
├── tests/
│ ├── config/ # Test configuration
│ │ ├── index.js # Barrel export
│ │ ├── experiment.config.js # Experiment settings
│ │ └── qa-links.config.js # Market URLs
│ ├── fixtures/ # Custom Playwright fixtures
│ │ └── test-fixtures.js # Experiment context, Adobe preview
│ ├── utils/ # Reusable test helpers
│ │ └── test-helpers.js # Wait, scroll, screenshot, retry
│ └── e2e/ # Test specs
│ └── <experiment-name>/
│ ├── <experiment-name>.spec.js # Live URL tests
│ └── experiment-test.spec.js # Bundle injection testDirectory Reference
tests/config/
All test configuration lives here. The barrel index.js re-exports everything so tests have a single import path.
| File | Purpose |
|---|---|
index.js | Barrel export - import everything from here |
experiment.config.js | Experiment name, markets, variants, timeouts, Adobe preview token |
qa-links.config.js | Control/experiment URL resolution per market |
When to add files: Add new config files here when your experiment needs additional configuration (e.g., feature flags, A/B platform tokens, content mappings). Always re-export from index.js.
tests/fixtures/
Custom Playwright fixtures that extend the base test object with experiment-specific context.
| File | Purpose |
|---|---|
test-fixtures.js | experimentContext fixture (config access, URL builder), adobePreview fixture |
When to add files: Add new fixtures when you need shared setup that multiple test files use. For example, a cookie-fixtures.js for tests that need consent cookies, or a mobile-fixtures.js for mobile viewport tests.
tests/utils/
Reusable helper functions that don't depend on Playwright's test runner. These are pure utility functions.
| File | Purpose |
|---|---|
test-helpers.js | waitForNetworkIdle, waitForStable, getComputedStyle, isInViewport, scrollIntoView, takeScreenshot, waitForText, retryWithBackoff |
When to add files: Add new utility files for domain-specific helpers. For example:
selector-helpers.js- functions that build complex selectors from configdata-helpers.js- functions that generate test dataassertion-helpers.js- custom assertion wrappers
tests/e2e/
Test spec files, organized by experiment name.
| File | Purpose |
|---|---|
<name>/<name>.spec.js | Live URL tests with control and experiment describe blocks |
<name>/experiment-test.spec.js | Bundle injection smoke test |
When to add files: Add new spec files within the experiment folder for additional test scenarios:
<name>/visual-regression.spec.js- screenshot comparison tests<name>/accessibility.spec.js- a11y checks on the experiment<name>/performance.spec.js- performance metrics collection
tests/performance/ (Optional)
Not generated by default. Create this directory for performance-focused tests.
tests/performance/
└── selector-performance.spec.js # Measure selector resolution timeImport Conventions
Config Imports
Always import config from the barrel file:
// Correct
import { experimentConfig, qaLinksConfig, validateUrls } from '../../config/index.js';
// Avoid importing individual config files directlyFixture Imports
Import the extended test and expect from your fixtures file instead of from @playwright/test:
// When using custom fixtures
import { test, expect } from '../fixtures/test-fixtures.js';
// When not using custom fixtures
import { test, expect } from '@playwright/test';Helper Imports
Import individual functions from utils:
import { waitForNetworkIdle, scrollIntoView } from '../utils/test-helpers.js';Scaling the Structure
As your experiment test suite grows, the structure scales naturally:
tests/
├── config/
│ ├── index.js
│ ├── experiment.config.js
│ ├── qa-links.config.js
│ └── content.config.js # Added: market-specific content expectations
├── fixtures/
│ ├── test-fixtures.js
│ └── consent-fixtures.js # Added: cookie consent setup
├── utils/
│ ├── test-helpers.js
│ └── selector-helpers.js # Added: dynamic selector builders
└── e2e/
└── my-experiment/
├── my-experiment.spec.js
├── experiment-test.spec.js
├── multi-market.spec.js # Added: cross-market sweep
└── mobile.spec.js # Added: mobile-specific testsWhat's Next
- Configuration - detailed reference for each config file
- Writing Tests - tutorial on filling in the generated specs
- Architecture - how the generator creates this structure