Configuration
This page is a reference for all configuration files generated by the tool and used in experiment projects.
playwright.config.js
The root Playwright configuration file. Controls test execution, browser projects, and reporting.
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
reporter: 'html',
use: {
trace: 'on-first-retry',
screenshot: 'on',
video: 'off',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});Key Options
| Option | Default | Description |
|---|---|---|
testDir | './tests' | Directory containing test files |
fullyParallel | true | Run all tests in parallel |
reporter | 'html' | Output format (see Running Tests) |
trace | 'on-first-retry' | When to record traces |
screenshot | 'on' | When to capture screenshots |
video | 'off' | When to record video |
projects | chromium, firefox, webkit | Browsers to test against |
Common Customizations
Add timeouts:
export default defineConfig({
timeout: 60000, // Per-test timeout (default: 30s)
expect: {
timeout: 10000, // Per-assertion timeout (default: 5s)
},
});Add viewport size:
use: {
viewport: { width: 1440, height: 900 },
},Add base URL:
use: {
baseURL: 'https://www.example.com',
},Grant permissions:
use: {
permissions: ['clipboard-read', 'clipboard-write'],
},tests/config/experiment.config.js
Contains experiment-specific settings used across all test files.
export const experimentConfig = {
name: 'My Experiment',
marketGroup: 'SEBN',
markets: [
{ code: 'BE', urlPath: 'be', name: 'Belgium (NL)' },
{ code: 'NL', urlPath: 'nl', name: 'Netherlands' },
],
baseUrl: 'https://www.example.com',
variants: {
control: 'control',
experiment: 'experiment',
},
timeouts: {
navigation: 30000,
element: 5000,
api: 10000,
},
environment: process.env.TEST_ENV || 'qa',
adobePreviewToken: process.env.ADOBE_PREVIEW_TOKEN || '',
getMarketCodes() {
return this.markets.map((m) => m.code);
},
getMarket(code) {
return this.markets.find((m) => m.code === code);
},
};Fields
| Field | Type | Description |
|---|---|---|
name | string | Experiment name |
marketGroup | string | Market group code (e.g., SEBN) |
markets | Array | Market objects with code, urlPath, name |
baseUrl | string | Base application URL |
variants | Object | Variant identifiers |
timeouts | Object | Timeout values in milliseconds |
environment | string | Test environment (qa, staging, production) |
adobePreviewToken | string | Adobe Target preview token from env var |
Methods
getMarketCodes()- returns array of market code stringsgetMarket(code)- finds a market object by code
tests/config/qa-links.config.js
Manages control and experiment URLs per market. This is the file you edit most after generation.
export const qaLinksConfig = {
baseUrl: 'https://www.example.com',
markets: [/* ... */],
getUrls(marketCode) {
const market = this.markets.find((m) => m.code === marketCode);
if (!market) {
throw new Error(`Unknown market code: ${marketCode}`);
}
return {
controlUrl:
process.env[`CONTROL_URL_${marketCode}`] ||
`${this.baseUrl}/${market.urlPath}/control-page/`,
experimentUrl:
process.env[`EXPERIMENT_URL_${marketCode}`] ||
`${this.baseUrl}/${market.urlPath}/experiment-page/`,
};
},
getAllUrls() { /* returns all markets with URLs */ },
getMarketCodes() { /* returns array of codes */ },
};
export function validateUrls() { /* warns about missing env vars */ }URL Resolution Priority
- Environment variable
CONTROL_URL_<CODE>/EXPERIMENT_URL_<CODE> - Default pattern:
${baseUrl}/${urlPath}/control-page/orexperiment-page/
Customizing URLs
For most experiments, you replace the default URL pattern with your actual QA URLs:
getUrls(marketCode) {
const market = this.markets.find((m) => m.code === marketCode);
return {
controlUrl: `${this.baseUrl}/${market.urlPath}/smartphones/?at_preview_token=ctrl_abc`,
experimentUrl: `${this.baseUrl}/${market.urlPath}/smartphones/?at_preview_token=exp_xyz`,
};
}tests/config/index.js
Barrel export file. All config is re-exported from here so tests import from a single location:
export { experimentConfig } from './experiment.config.js';
export { qaLinksConfig, validateUrls } from './qa-links.config.js';Usage in Tests
import { experimentConfig, qaLinksConfig, validateUrls } from '../../config/index.js';src/js/config.js (Experiment Source Config)
This file is not generated by the tool but exists in experiment projects. It contains:
- Selectors - CSS selectors for DOM elements the experiment targets
- Text content - Market-specific copy and translations
- Images - URLs for experiment assets
- Feature flags - Toggle individual experiment features
Example structure:
export const config = {
selectors: {
targetContainer: '.product-detail__overview',
ctaButton: '[data-cta="experiment"]',
},
content: {
NL: { headline: 'Speciale Aanbieding', cta: 'Nu Kopen' },
BE: { headline: 'Offre Speciale', cta: 'Acheter' },
},
features: {
showBadge: true,
animateEntry: false,
},
};Tests should reference this config rather than hardcoding expected values:
import { config } from '../../src/js/config.js';
test('should show correct headline', async ({ page }) => {
await expect(page.locator('.headline')).toHaveText(config.content.NL.headline);
});What's Next
- Test Structure - how the generated files are organized
- Architecture - how the generator builds these files
- Writing Tests - using the config in your tests