@lytics/playwright-annotations
Generic annotation framework for Playwright tests with type-safe helpers and validation.
Installation
npm
npm install @lytics/playwright-annotationsWhat This Package Provides
For Everyone
A generic annotation framework that any team can use:
- β Type-safe annotation helpers
- β Flexible validation framework
- β Works with any annotation schema
- β Full TypeScript support
For Contentstack Teams
Pre-built conventions for journey-driven testing:
- β
testSuiteName/journeyId/testCaseIdpattern - β Validation rules for naming hierarchy
- β Convenience helpers
You can use the Contentstack conventions as-is, extend them, or define your own schema entirely.
Quick Start
Option A: Use Contentstack Conventions (Recommended)
import { test } from '@playwright/test';
import { pushSuiteAnnotation, pushTestAnnotations } from '@lytics/playwright-annotations';
test.describe('Account Security @smoke', () => {
test.beforeEach(async ({}, testInfo) => {
pushSuiteAnnotation(testInfo, 'ACCOUNT_SECURITY');
});
test('user can view access tokens', async ({}, testInfo) => {
pushTestAnnotations(testInfo, {
journeyId: 'ACCOUNT_SECURITY_VIEW-TOKENS',
testCaseId: 'ACCOUNT_SECURITY_VIEW-TOKENS_VALID',
});
// Your test implementation...
});
});Option B: Define Your Own Schema
import { pushAnnotations, createValidator } from '@lytics/playwright-annotations';
import type { TestAnnotations } from '@lytics/playwright-annotations';
// 1. Define your annotation schema
interface MyTeamAnnotations extends TestAnnotations {
featureArea: string;
ticketId: string;
priority: 'high' | 'medium' | 'low';
}
// 2. Create a validator
const validateMyAnnotations = createValidator<MyTeamAnnotations>({
rules: [
(annotations) => ({
valid: Boolean(annotations.featureArea),
errors: annotations.featureArea ? [] : ['featureArea is required'],
warnings: [],
}),
(annotations) => ({
valid: /^[A-Z]+-\d+$/.test(annotations.ticketId),
errors: /^[A-Z]+-\d+$/.test(annotations.ticketId)
? []
: ['ticketId must match pattern: PROJECT-123'],
warnings: [],
}),
]
});
// 3. Use in your tests
test('my feature', async ({}, testInfo) => {
const annotations: MyTeamAnnotations = {
featureArea: 'auth',
ticketId: 'JIRA-123',
priority: 'high'
};
const validation = validateMyAnnotations(annotations);
if (!validation.valid) {
throw new Error(`Invalid annotations: ${validation.errors.join(', ')}`);
}
pushAnnotations(testInfo, annotations);
});Why Annotations?
Annotations enable:
- π Observability β Centralized dashboards showing test health
- π Traceability β Link tests to user journeys and requirements
- π Trend Analysis β Track test stability over time
- π― Coverage Tracking β Identify gaps in test coverage
- π Querying β Find all tests for a journey or suite
Integration with Other Packages
With Reporter
Annotations are consumed by @lytics/playwright-reporter. Create a reporter file:
// reporter.ts
import { CoreReporter } from '@lytics/playwright-reporter';
import { FilesystemAdapter } from '@lytics/playwright-adapters/filesystem';
class CustomReporter extends CoreReporter {
constructor() {
super({
adapters: [
new FilesystemAdapter({ outputDir: './test-results' }),
],
});
}
}
export default CustomReporter;Then reference it in your config:
// playwright.config.ts
export default {
reporter: [['list'], ['./reporter.ts']]
};The reporter extracts annotations from tests and includes them in the output, enabling filtering, grouping, and analysis.
Troubleshooting
Debug Mode
If annotations arenβt working as expected, enable debug mode to see detailed logging:
PLAYWRIGHT_ANNOTATIONS_DEBUG=true npx playwright testThis outputs verbose logs showing:
- When each annotation helper is called
- What annotations exist at each step
- Validation results and any errors
Example output:
π [playwright-annotations] pushSuiteAnnotation called {
"testTitle": "user can view access tokens",
"testSuiteName": "ACCOUNT_SECURITY",
"existingAnnotations": []
}
π [playwright-annotations] pushTestAnnotations called {
"testTitle": "user can view access tokens",
"annotations": { "journeyId": "...", "testCaseId": "..." },
"existingAnnotations": [{ "type": "testSuiteName", "description": "ACCOUNT_SECURITY" }]
}Common Issues
| Issue | Cause | Solution |
|---|---|---|
testSuiteName must be set | beforeEach not running or missing testInfo | Ensure pushSuiteAnnotation is in beforeEach with testInfo parameter |
| Validation errors | Naming hierarchy not followed | Check that testCaseId starts with journeyId |
| Annotations not appearing | Wrong testInfo scope | Use beforeEach (not beforeAll) for suite annotations |
Next Steps
- Schema & Types β Type definitions and interfaces
- Helper Functions β API reference for helpers
- Validation β Validation framework and rules
Last updated on