Test Fixtures for Playwright Test
Using Axe Watcher for organizations that already use Playwright Test fixtures
If your organization already uses Playwright Test fixtures in your test suites, you'll need to merge your existing fixtures with Axe Watcher's fixtures to enable accessibility testing. This guide walks you through the integration process.
Understanding the Challenge
Playwright Test allows you to create custom fixtures that extend the base test functionality. These fixtures might provide mock data, shared setup logic, or reusable test utilities. When you introduce Axe Watcher, which also uses fixtures for accessibility testing, you need to combine the two sets of fixtures using mergeTests to ensure they work together.
Without merging, your tests will fail because Playwright won't recognize your custom fixtures when using the Axe Watcher test configuration.
Basic Integration Steps
Step 1: Import Required Functions
Start by importing the necessary functions from Playwright Test and Axe Watcher:
import { test as base, mergeTests } from '@playwright/test'
import { playwrightTest } from '@axe-core/watcher/playwright-test'The mergeTests() function is the key to combining your custom fixtures with Axe Watcher's fixtures.
Step 2: Create Your Custom Fixtures
Define your existing custom fixtures as you normally would. For example, if you have a mock user fixture for authentication testing:
class MockUser {
#username = 'testuser'
#password = 'SecurePassword123!'
get username() {
return this.#username
}
get password() {
return this.#password
}
}
const customFixtures = base.extend<{ mockUser: MockUser }>({
mockUser: async ({}, use) => {
await use(new MockUser())
}
})Step 3: Configure Axe Watcher
Set up your Axe Watcher configuration with your API credentials:
const ACCESSIBILITY_API_KEY = process.env.ACCESSIBILITY_API_KEY
const PROJECT_ID = process.env.PROJECT_ID
const { test: watcherTest, expect } = playwrightTest({
axe: {
apiKey: ACCESSIBILITY_API_KEY,
projectId: PROJECT_ID
},
})Step 4: Merge the Fixtures
Use mergeTests to combine your custom fixtures with Axe Watcher's fixtures:
const test = mergeTests(customFixtures, watcherTest)
export { test, expect }Complete Example
Here's a comprehensive example showing the entire integration:
import { test as base, mergeTests } from '@playwright/test'
import { playwrightTest } from '@axe-core/watcher/playwright-test'
// Environment variables for Axe Developer Hub
const ACCESSIBILITY_API_KEY = process.env.ACCESSIBILITY_API_KEY
const PROJECT_ID = process.env.PROJECT_ID
// Custom fixture: Mock user for authentication
class MockUser {
#username = 'testuser'
#password = 'SecurePassword123!'
get username() {
return this.#username
}
get password() {
return this.#password
}
}
// Define custom fixtures
const customFixtures = base.extend<{ mockUser: MockUser }>({
mockUser: async ({}, use) => {
await use(new MockUser())
}
})
// Configure Axe Watcher
const { test: watcherTest, expect } = playwrightTest({
axe: {
apiKey: ACCESSIBILITY_API_KEY,
projectId: PROJECT_ID
},
headless: false
})
// Merge fixtures
const test = mergeTests(customFixtures, watcherTest)
// Export merged test and expect
export { test, expect }Using the Merged Fixtures in Tests
Once you've set up the merged fixtures, use them in your test files by importing from your fixtures file:
import { test, expect } from './fixtures'
test('should login with accessible form', async ({ page, mockUser }) => {
await page.goto('https://example.com/login')
// Use your custom fixture
await page.fill('#username', mockUser.username)
await page.fill('#password', mockUser.password)
await page.click('#login-button')
// Verify successful login
await expect(page.locator('.welcome-message')).toBeVisible()
// Accessibility testing happens automatically
})Multiple Custom Fixtures
If you have multiple custom fixtures, you can merge them all together:
// Define multiple fixture sets
const userFixtures = base.extend<{ mockUser: MockUser }>({
mockUser: async ({}, use) => {
await use(new MockUser())
}
})
const apiFixtures = base.extend<{ apiClient: ApiClient }>({
apiClient: async ({}, use) => {
await use(new ApiClient())
}
})
// Configure Axe Watcher
const { test: watcherTest, expect } = playwrightTest({
axe: {
apiKey: ACCESSIBILITY_API_KEY,
projectId: PROJECT_ID
}
})
// Merge all fixtures
const test = mergeTests(userFixtures, apiFixtures, watcherTest)
export { test, expect }Advanced Configuration Options
You can customize Axe Watcher's behavior while maintaining your custom fixtures:
const { test: watcherTest, expect } = playwrightTest({
axe: {
apiKey: ACCESSIBILITY_API_KEY,
projectId: PROJECT_ID,
autoAnalyze: true,
configurationOverrides: {
accessibilityStandard: 'WCAG 2.2 AA',
bestPractices: true,
experimentalRules: false
}
},
args: ['--headless=new']
})Troubleshooting
Fixture Not Available Error
If you see an error like Property 'mockUser' does not exist on type, ensure you've:
- Properly merged the fixtures using
mergeTests - Imported
testfrom your merged fixtures file, not directly from@playwright/test - Exported both
testandexpectfrom your fixtures file
Type Safety Issues
For TypeScript projects, ensure your custom fixture types are properly defined:
type CustomFixtures = {
mockUser: MockUser
apiClient: ApiClient
}
const customFixtures = base.extend<CustomFixtures>({
mockUser: async ({}, use) => {
await use(new MockUser())
},
apiClient: async ({}, use) => {
await use(new ApiClient())
}
})