100 lines
2.4 KiB
TypeScript
100 lines
2.4 KiB
TypeScript
import { Page } from '@playwright/test';
|
|
|
|
export interface CapturedError {
|
|
type: 'console' | 'page';
|
|
message: string;
|
|
stack?: string;
|
|
timestamp: number;
|
|
}
|
|
|
|
|
|
export class ConsoleErrorCapture {
|
|
private errors: CapturedError[] = [];
|
|
private allowlist: (string | RegExp)[] = [];
|
|
|
|
constructor(private page: Page) {
|
|
this.setupCapture();
|
|
}
|
|
|
|
public setAllowlist(patterns: (string | RegExp)[]): void {
|
|
this.allowlist = patterns;
|
|
}
|
|
|
|
private isAllowed(message: string): boolean {
|
|
return this.allowlist.some(pattern =>
|
|
typeof pattern === 'string' ? message.includes(pattern) : pattern.test(message)
|
|
);
|
|
}
|
|
|
|
private setupCapture(): void {
|
|
this.page.on('console', (msg) => {
|
|
if (msg.type() === 'error') {
|
|
this.errors.push({
|
|
type: 'console',
|
|
message: msg.text(),
|
|
timestamp: Date.now(),
|
|
});
|
|
}
|
|
});
|
|
|
|
this.page.on('pageerror', (error) => {
|
|
this.errors.push({
|
|
type: 'page',
|
|
message: error.message,
|
|
stack: error.stack ?? '',
|
|
timestamp: Date.now(),
|
|
});
|
|
});
|
|
}
|
|
|
|
public getErrors(): CapturedError[] {
|
|
return this.errors;
|
|
}
|
|
|
|
public getUnexpectedErrors(): CapturedError[] {
|
|
return this.errors.filter(e => !this.isAllowed(e.message));
|
|
}
|
|
|
|
public format(): string {
|
|
if (this.errors.length === 0) return 'No console errors captured.';
|
|
|
|
const unexpected = this.getUnexpectedErrors();
|
|
const allowed = this.errors.filter(e => this.isAllowed(e.message));
|
|
|
|
let output = '--- Console Error Capture ---\n';
|
|
|
|
if (unexpected.length > 0) {
|
|
output += `UNEXPECTED ERRORS (${unexpected.length}):\n`;
|
|
unexpected.forEach((e, i) => {
|
|
output += `[${i + 1}] ${e.type.toUpperCase()}: ${e.message}\n`;
|
|
if (e.stack) output += `Stack: ${e.stack}\n`;
|
|
});
|
|
}
|
|
|
|
if (allowed.length > 0) {
|
|
output += `\nALLOWED ERRORS (${allowed.length}):\n`;
|
|
allowed.forEach((e, i) => {
|
|
output += `[${i + 1}] ${e.type.toUpperCase()}: ${e.message}\n`;
|
|
});
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public hasErrors(): boolean {
|
|
return this.errors.length > 0;
|
|
}
|
|
|
|
public hasUnexpectedErrors(): boolean {
|
|
return this.getUnexpectedErrors().length > 0;
|
|
}
|
|
|
|
public clear(): void {
|
|
this.errors = [];
|
|
}
|
|
|
|
public async waitForErrors(timeout: number = 1000): Promise<boolean> {
|
|
await this.page.waitForTimeout(timeout);
|
|
return this.hasErrors();
|
|
}
|
|
} |