π Native Playwright integration for UI element coverage analysis. Discover interactive elements during test execution and generate comprehensive coverage reports.
Playwright Coverage Reporter helps you ensure your E2E tests are thoroughly testing all interactive elements on your web pages. It integrates directly with Playwright's test runner to analyze coverage during actual test execution.
- π Cross-Test Coverage Aggregation: Track which elements are covered by ANY test across your entire test suite
- π Persistent Coverage Data: Coverage data persists across test runs to build comprehensive coverage maps
- π― Smart Recommendations: Get prioritized suggestions for uncovered elements with generated test code
- π Multiple Report Formats: Console, JSON, HTML, and LCOV coverage reports with detailed insights
- π Runtime Element Discovery: Automatically discover interactive elements during test execution
- π― Istanbul Integration: Export coverage data in LCOV format for CI/CD integration
- πΈ Screenshot Capture: Capture screenshots of uncovered elements for visual debugging
- β‘ Performance Optimization: Batch processing, concurrency control, and memory management for large test suites
- π‘οΈ Advanced Error Handling: Intelligent error recovery with detailed guidance and troubleshooting steps
- π§ Configuration Validation: Comprehensive validation with actionable recommendations and debug mode
- π― Element Filtering: Advanced filtering system with presets for comprehensive, essential, and minimal coverage
- π Performance Monitoring: Built-in performance metrics and optimization recommendations
- π Zero Configuration: β¨ NEW! Works out of the box with automatic element discovery from test files
- ποΈ TypeScript Support: Full TypeScript support with comprehensive type definitions
npm install -D playwright-coverage-reporterv3.0.0+ - Works out of the box! The reporter now automatically discovers elements from your test files and requires zero configuration:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
reporter: [
['list'], // Keep your existing reporters
['playwright-coverage-reporter'] // Just add this line!
],
});That's it! π The reporter will automatically:
- β Analyze your test files to discover selectors
- β Create synthetic elements for coverage tracking
- β Generate meaningful coverage reports
- β Work with any existing Playwright tests
- β Use a 0% threshold by default for mixed test suites (no configuration needed!)
If you want to customize the behavior, you can add options:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
reporter: [
['list'], // Keep your existing reporters
['playwright-coverage-reporter', {
outputPath: './coverage-report',
threshold: 80,
verbose: true,
elementDiscovery: true // Enable cross-test coverage aggregation
}]
],
});Alternative: Class-based Configuration
import { defineConfig } from '@playwright/test';
import { PlaywrightCoverageReporter } from 'playwright-coverage-reporter';
export default defineConfig({
testDir: './tests',
reporter: [
['list'], // Keep your existing reporters
[PlaywrightCoverageReporter, {
outputPath: './coverage-report',
threshold: 80,
verbose: true,
elementDiscovery: true // Enable cross-test coverage aggregation
}]
],
});Note: The string-based approach is recommended as it's more robust and avoids potential module resolution issues in some environments.
- Run your tests:
npx playwright test- View the coverage report:
# Console output appears automatically during test execution
# For HTML report: open coverage-report/index.htmlThat's it! No separate configuration files needed - everything is configured directly in your Playwright config.
The most powerful feature of this reporter is cross-test coverage aggregation. Unlike traditional coverage tools that only look at individual test runs, this system tracks coverage across your entire test suite and persists data between test runs.
- Persistent Storage: Coverage data is saved to
.coverage-data.jsonin your output directory - Cross-Test Analysis: Elements are considered "covered" if ANY test in your suite interacts with them
- Smart Recommendations: Get prioritized suggestions for elements that no test covers
π CROSS-TEST COVERAGE REPORT
ββββββββββββββββββββββββββββββββββββββββββββββββββ
π SUMMARY:
Total Interactive Elements: 45
Covered Elements: 38
Uncovered Elements: 7
Coverage Percentage: 84%
Test Files: 12
π COVERAGE BY TYPE:
button: 84% ββββββββββββββββ (16/19)
input: 90% ββββββββββββββββ (9/10)
link: 75% βββββββββββββββ (9/12)
select: 100% ββββββββββββββββ (2/2)
π¨ HIGH PRIORITY UNCOVERED ELEMENTS:
β #delete-account (button): Critical delete button is not tested. This could lead to major functionality issues.
β #export-data (button): Important export functionality is not covered by any tests.
- Identify Gaps: Find elements that NO test in your entire suite covers
- Prioritize Testing: Get high-priority recommendations for critical elements
- Track Progress: See coverage improve across multiple test runs
- Team Collaboration: Shared coverage data works for entire development teams
All configuration is done directly in your playwright.config.ts reporter section:
| Option | Type | Default | Description |
|---|---|---|---|
| Core Options | |||
outputPath |
string | ./coverage-report |
Directory for coverage reports |
format |
string | console |
Report format: console, html, json, lcov, all |
threshold |
number | 0 |
Coverage threshold percentage (0-100) |
verbose |
boolean | false |
Enable detailed logging |
elementDiscovery |
boolean | true |
Auto-discover elements on page load |
runtimeDiscovery |
boolean | false |
Track interactions during tests |
pageUrls |
string[] | [] |
Specific pages to analyze |
captureScreenshots |
boolean | false |
Enable screenshots for debugging |
| Enterprise Features | |||
validateConfig |
boolean | true |
Enable comprehensive configuration validation |
debugMode |
boolean | false |
Enable debug information and performance analysis |
performanceProfile |
string | 'development' |
Performance preset: development, ci, large, minimal |
elementFilter |
object/string | undefined |
Element filtering configuration or preset name |
enableErrorRecovery |
boolean | true |
Enable automatic error recovery with degraded mode |
cacheResults |
boolean | true |
Enable result caching for better performance |
maxConcurrency |
number | profile-dependent |
Maximum concurrent operations |
timeoutMs |
number | 30000 |
Operation timeout in milliseconds |
The coverage threshold determines when the reporter will fail your test run based on coverage percentage:
// No threshold enforcement (good for mixed test suites with CLI tests)
export default defineConfig({
reporter: [['playwright-coverage-reporter', { threshold: 0 }]]
});
// Standard coverage enforcement (good for pure UI test suites)
export default defineConfig({
reporter: [['playwright-coverage-reporter', { threshold: 80 }]]
});
// Dogfooding setup (ensure your own code has good coverage)
export default defineConfig({
reporter: [['playwright-coverage-reporter', { threshold: 85 }]]
});Recommended Thresholds:
- 0%: Mixed test suites (CLI + UI tests), development environments
- 70-80%: Standard UI test suites, good balance of coverage vs. practicality
- 85-95%: Dogfooding, critical applications, high-quality standards
- 100%: Not recommended (can be counterproductive and brittle)
Choose from pre-configured setups:
// Development setup with detailed HTML reports
import { PlaywrightCoverageReporter, CoveragePresets } from 'playwright-coverage-reporter';
export default defineConfig({
reporter: [
[PlaywrightCoverageReporter, CoveragePresets.development()]
]
});
// CI/CD setup with JSON reports
export default defineConfig({
reporter: [
[PlaywrightCoverageReporter, CoveragePresets.ci()]
]
});
// Comprehensive setup with all features
export default defineConfig({
reporter: [
[PlaywrightCoverageReporter, CoveragePresets.comprehensive()]
]
});You can also configure options via environment variables:
PLAYWRIGHT_COVERAGE_OUTPUT=./custom-coverage
PLAYWRIGHT_COVERAGE_FORMAT=html
PLAYWRIGHT_COVERAGE_THRESHOLD=90
PLAYWRIGHT_COVERAGE_VERBOSE=true
PLAYWRIGHT_COVERAGE_RUNTIME_DISCOVERY=trueπ CROSS-TEST COVERAGE REPORT
ββββββββββββββββββββββββββββββββββββββββββββββββββ
π SUMMARY:
Total Interactive Elements: 45
Covered Elements: 38
Uncovered Elements: 7
Coverage Percentage: 84%
Test Files: 12
π COVERAGE BY TYPE:
button: 84% ββββββββββββββββ (16/19)
input: 90% ββββββββββββββββ (9/10)
link: 75% βββββββββββββββ (9/12)
select: 100% ββββββββββββββββ (2/2)
π COVERAGE BY PAGE:
http://localhost:3000/login: 90% (18/20 elements)
http://localhost:3000/dashboard: 75% (15/20 elements)
http://localhost:3000/profile: 85% (11/13 elements)
π¨ HIGH PRIORITY UNCOVERED ELEMENTS:
β #delete-account (button): Critical delete button is not tested. This could lead to major functionality issues.
β #export-data (button): Important export functionality is not covered by any tests.
β .notification-settings (checkbox): User preference settings are not tested.
ββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Features of the Cross-Test Report:
- Persistent Data: Shows coverage across ALL test runs, not just the current one
- Smart Prioritization: High-priority warnings for critical elements (submit buttons, delete actions, etc.)
- Coverage by Type: Breakdown by element type (buttons, inputs, links, etc.)
- Page-Level Insights: See which pages have the best/worst coverage
Generate an interactive HTML report with detailed element information and coverage breakdowns.
Export coverage data in standard LCOV format for CI/CD integration with tools like Codecov, Coveralls, or GitHub's coverage visualization.
For large test suites, use performance profiles to optimize execution:
import { defineConfig } from '@playwright/test';
import { PlaywrightCoverageReporter } from 'playwright-coverage-reporter';
export default defineConfig({
reporter: [
[PlaywrightCoverageReporter, {
performanceProfile: 'ci', // Optimized for CI/CD
maxConcurrency: 2, // Limit concurrent operations
cacheResults: true, // Enable caching
timeoutMs: 60000 // Longer timeout for large suites
}]
],
});Available Performance Profiles:
development: Optimized for local development with detailed loggingci: Optimized for CI/CD with minimal resource usagelarge: Optimized for large test suites with aggressive batchingminimal: Minimal resource usage for constrained environments
Filter which elements to include in coverage analysis:
export default defineConfig({
reporter: [
[PlaywrightCoverageReporter, {
// Use preset
elementFilter: 'essential',
// Or custom configuration
elementFilter: {
includeTypes: ['button', 'input', 'link'],
excludeTypes: ['div', 'span'],
includeSelectors: ['[data-testid]', '[role="button"]'],
excludeSelectors: ['.hidden', '[aria-hidden="true"]'],
minVisibility: 0.5,
includeHidden: false
}
}]
],
});Filter Presets:
comprehensive: Include all interactive elementsessential: Only critical elements (buttons, inputs, links)minimal: Bare minimum elements for basic coverageforms: Form-related elements onlynavigation: Navigation elements only
Enable comprehensive debugging for troubleshooting:
export default defineConfig({
reporter: [
[PlaywrightCoverageReporter, {
debugMode: true,
validateConfig: true,
verbose: true
}]
],
});name: Tests with Coverage
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests with coverage
run: npm test
env:
PLAYWRIGHT_COVERAGE_FORMAT: json
PLAYWRIGHT_COVERAGE_THRESHOLD: 80
PLAYWRIGHT_COVERAGE_VERBOSE: true
- name: Upload coverage reports
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage-report/
- name: Comment PR with coverage
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
if (fs.existsSync('coverage-report/coverage-summary.json')) {
const coverage = JSON.parse(fs.readFileSync('coverage-report/coverage-summary.json', 'utf8'));
const comment = `
## π Playwright Coverage Report
| Metric | Value |
|--------|-------|
| Coverage | ${coverage.coveragePercentage}% |
| Elements | ${coverage.coveredElements}/${coverage.totalElements} |
| Tests | ${coverage.testFiles} |
${coverage.coveragePercentage < 80 ? 'β οΈ Coverage below threshold!' : 'β
Coverage threshold met'}
`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
}Issue: Configuration validation failed during initialization Solution:
- Enable
debugMode: truein configuration for more details - Check for invalid option values or missing required fields
- Verify your playwright.config.ts syntax
Issue: Coverage analysis is too slow or consumes too much memory Solution:
- Use
performanceProfile: 'ci'or'minimal'for better performance - Set
maxConcurrencyto limit concurrent operations - Enable
cacheResults: truefor better performance on subsequent runs - Use element filtering to reduce the number of elements analyzed
Issue: Getting 0% or very low coverage despite having tests Solution:
- Ensure
elementDiscovery: trueis set in your configuration - Check that tests are actually interacting with elements
- Verify selectors in tests match actual page elements
- Use
debugMode: trueto see detailed discovery logs
Issue: No coverage reports are created after running tests Solution:
- Ensure PlaywrightCoverageReporter is properly configured in your playwright.config.ts
- Check that tests are passing (failed tests are excluded from coverage)
- Verify the output directory permissions
- Check for initialization errors in console output
Issue: Reporter falls back to degraded mode Solution:
- Check console for specific error messages and guidance
- Enable
debugMode: trueto identify configuration issues - Fix underlying configuration problems and restart tests
- Some errors are recoverable and will provide specific guidance
Issue: TypeScript errors when importing the reporter Solution:
- Ensure you're using TypeScript files (
.ts) - Check that the package is properly installed:
npm install -D playwright-coverage-reporter - Make sure your tsconfig.json includes the node_modules type resolution
Issue: Out of memory errors with large test suites Solution:
- Use
performanceProfile: 'large'orperformanceProfile: 'minimal' - Reduce
maxConcurrencyto limit parallel processing - Enable element filtering to reduce scope
- Increase system memory or run tests in smaller batches
Contributions are welcome! Please read our Contributing Guide for details on:
- Code style and standards
- Pull request process
- Issue reporting
- Development setup
# Clone the repository
git clone https://github.com/DoomedRamen/playwright-coverage-reporter.git
cd playwright-coverage-reporter
# Install dependencies (this also sets up Git hooks automatically)
npm install
# Build the project
npm run build
# Run tests
npm testThis project is licensed under the MIT License - see the LICENSE file for details.
- Built with Playwright for reliable browser automation
- Inspired by the need for better E2E test coverage visibility
- Coverage reporting compatible with Istanbul ecosystem
- π Documentation
- π Report Issues
- π¬ Discussions
Made with β€οΈ by Martin Page