playwright-sniff
v1.1.1
Published
Monitoring library for Playwright that measures action times, catches showstoppers and generates reports
Maintainers
Readme
playwright-sniff
A monitoring library for Playwright that measures action times, catches showstoppers, and generates comprehensive reports. By default, it collects showstoppers throughout test execution rather than failing immediately, displaying all issues in a consolidated report at the end.
Features
- 📊 Performance Monitoring: Track execution time for Playwright actions
- 🚨 Showstopper Detection: Identify and log critical issues during the test execution
- 📝 Report Generation: Create detailed reports of test execution performance
- 🔄 Low Overhead: Minimal impact on your existing Playwright tests
- 🌐 Network Monitoring: Track HTTP requests and detect slow or failed requests
Installation
npm install playwright-sniffBasic Usage
import { test } from '@playwright/test';
import { PlaywrightSniff } from 'playwright-sniff';
test('Monitor performance', async ({ page }) => {
// Initialize the monitoring
const sniff = new PlaywrightSniff({ page });
// Start monitoring
sniff.setTestName(test.info().title)
await sniff.start();
// Measure specific actions
await sniff.measureAction(
async () => { await page.goto('https://example.com') },
'Navigation to home page'
);
await sniff.measureAction(
async () => {
await page.getByRole('button').click(),
await expect(page.getByRole('heading', { name: 'Welcome!' })).toBeVisible()
},
'Login to application'
);
// Capture and save final stats
sniff.stop();
});Integration with Playwright Test (Recommended)
import { test as base } from '@playwright/test';
import { PlaywrightSniff } from 'playwright-sniff';
export const test = base.extend<{
sniffOptions: Required<SniffOptions>;
sniff: PlaywrightSniff;
}>({
// First fixture: provides the merged options
sniffOptions: async ({}, use, testInfo) => {
// Get default options from PlaywrightSniff class
const defaultOptions = PlaywrightSniff.DEFAULT_OPTIONS;
// Get options from playwright.config if available
const configOptions = testInfo.project.use?.sniffOptions || {};
// Combine defaults with config options
const options = {
...defaultOptions,
...configOptions
};
// Provide the combined options to the test
await use(options);
},
// Second fixture: provides a preconfigured PlaywrightSniff instance
sniff: async ({ page, sniffOptions }, use, testInfo) => {
// Create a PlaywrightSniff instance with the merged options
const sniff = new PlaywrightSniff({
page,
options: sniffOptions // Use the options from the sniffOptions fixture
});
// Start monitoring
sniff.setTestName(testInfo.title)
await sniff.start();
// Use the sniff instance in the test
await use(sniff);
// Capture and save final stats
sniff.stop();
}
});
// Use in tests
test('Example test with sniffing', async ({ page, sniff }) => {
await sniff.measureAction(
async () => { await page.goto('https://example.com') },
'Open page'
);
// You can add custom failures
sniff.addFailure('Example custom failure', 'custom');
// You can add custom showstoppers
await sniff.addShowStopper('Manual check', 'Found an issue during manual verification');
// Rest of your test...
});Global configuration
// Using fixture, you can set global configuration for all tests in playwright.config in the use: {} section
sniffOptions: {
slowThreshold: 2000,
outputFile: 'sniffing-results.json',
outputHTML: 'sniffing-report.html',
captureScreenshots: false,
}
Configuration Options
const sniff = new PlaywrightSniff({
page,
options: {
slowThreshold: 2000, // Flag actions taking longer than 2000ms (default)
captureScreenshots: true, // Take screenshots on showstoppers (default)
screenshotDir: './screenshots', // Where to save screenshots (default)
outputFile: 'sniffing-results.json', // Report filename (default)
outputHTML: 'sniffing-report.html', // HTML report (default)
logger: customLoggerFunction // Custom logging function (optional)
}
});API Reference
PlaywrightSniff
The main class that provides monitoring functionality.
Constructor
new PlaywrightSniff({ page, options? })Methods
start(): Start monitoring Playwright actionsstop(): Stop monitoring and generate reportmeasureAction(action: () => Promise<void>, label: string): Measure the execution time of actionsaddFailure(error: string, type?: 'console' | 'request' | 'custom', metadata?: Record<string, any>): Add a custom failureaddShowStopper(label: string, criticalError: string): Add a custom showstoppergetResults(): Get the current monitoring resultssaveReport(outputFile?: string): Generate and save a report to a filegenerateHTMLReport(outputFile?: string): Generate html report based on test resultshasShowStoppers(): Check if there are any showstoppersgetShowStoppers(): Get the list of showstopperssetupAlertHandler(locator: Locator): Setup handler for unwanted locator, e.g alert box
Data Types
ActionTiming
Information about a measured action's performance.
interface ActionTiming {
label: string; // Identifier for the action
duration: number; // Time taken in ms
slow: boolean; // Whether it exceeded the slow threshold
}ShowStopper
Critical errors. (5xx responses, failed actions inside measureAction())
interface ShowStopper {
label: string; // Where the error occurred
criticalError: string; // Error description
screenshot?: string; // Path to screenshot if captured
}Failures
Non-critical fails like console error or 4xx response.
interface Failure {
error: string | undefined; // Error description
type: 'console' | 'request' | 'custom'; // Type of failure
requestUrl?: string; // URL of the request
requestStatus?: number | null; // Status code of the request
requestMethod?: string; // HTTP method of the request
}SniffReport
Complete report structure returned by getResults().
interface SniffReport {
timestamp: string;
passed: boolean;
showStoppers: ShowStopper[];
slowThreshold: number;
pageLoadSteps: ActionTiming[];
avgLoadTime: string | null;
avgRequestTime: string | null;
slowRequests: RequestDetails[];
failures: Failure[];
}HTML Report
Issues
you can raise any issue here
License
- Copyright © 2025- Patryk Dobrzyński
