Skip to Content
DocumentationAnnotationsOverview

@lytics/playwright-annotations

Generic annotation framework for Playwright tests with type-safe helpers and validation.

Installation

npm install @lytics/playwright-annotations

What 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 / testCaseId pattern
  • βœ… 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

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 test

This 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

IssueCauseSolution
testSuiteName must be setbeforeEach not running or missing testInfoEnsure pushSuiteAnnotation is in beforeEach with testInfo parameter
Validation errorsNaming hierarchy not followedCheck that testCaseId starts with journeyId
Annotations not appearingWrong testInfo scopeUse beforeEach (not beforeAll) for suite annotations

Next Steps

Last updated on