# console-monitor _(no submodules)_ ## Purpose `attachConsoleMonitor` attaches a listener to a Playwright `Page` and captures every console message emitted during the test. Its `assertClean()` method fails the test if any captured message matches the configured severity levels, providing an automated gate against unexpected JavaScript errors, deprecation warnings, and other console noise that would otherwise require manual log inspection. It mirrors the DevTools console experience, making CI failures straightforward to reproduce locally by opening the same URL. The monitor is designed for test-runner-agnostic use: it collects messages into a plain array so tests can inspect them directly, and it throws a standard `Error` so any test framework can catch it without adapter libraries. ## Features - Registers a single `page.on("console")` listener — no polling, no page evaluation - Configurable `failOn` severity levels: `"error"`, `"warning"`, `"info"` (defaults to `["error"]`) - Per-message ignore regexp list for suppressing known-safe console noise (e.g. React DevTools banner) - Normalises Playwright's `"warn"` type alias to `"warning"` for consistent level matching - `assertClean()` throws with a multi-line message listing every failing console entry - Exposes the raw `messages` array for test-specific assertions beyond what `assertClean` covers ## Usage: Basic Example ```typescript import { attachConsoleMonitor } from "@suaveplan/testing-e2e/console-monitor"; import { test, expect } from "@playwright/test"; test("page loads without console errors", async ({ page }) => { const monitor = attachConsoleMonitor(page); await page.goto("http://localhost:3200/"); await page.waitForLoadState("networkidle"); monitor.assertClean(); }); ``` ## Usage: Advanced Example ```typescript import { attachConsoleMonitor } from "@suaveplan/testing-e2e/console-monitor"; import { test } from "@playwright/test"; test("dashboard emits no errors or warnings, ignoring React DevTools banner", async ({ page }) => { const monitor = attachConsoleMonitor(page, { failOn: ["error", "warning"], ignore: [ /Download the React DevTools/, /ReactDOM.render is no longer supported/, ], }); await page.goto("http://localhost:3200/dashboard"); await page.waitForSelector("[data-testid=dashboard-ready]"); // Can also inspect messages directly before asserting const warnings = monitor.messages.filter((m) => m.type() === "warning"); console.log(`Captured ${warnings.length} warnings (all ignored)`); monitor.assertClean(); }); ``` ## API Reference ### `attachConsoleMonitor(page: Page, options?: ConsoleMonitorOptions): ConsoleMonitor` Registers a console message collector on the given Playwright page. **Parameters:** - `page` — Playwright `Page` instance to monitor - `options.failOn` — array of severity levels that cause `assertClean()` to throw; defaults to `["error"]` - `options.ignore` — array of `RegExp` patterns; messages whose text matches any pattern are excluded from failure consideration regardless of severity **Returns:** `ConsoleMonitor` - `.messages` — read-only array of all `ConsoleMessage` instances collected since `attachConsoleMonitor` was called - `.assertClean()` — throws `Error` if any collected message matches a `failOn` level and is not suppressed by an `ignore` pattern; the error message includes a formatted list of every offending entry ### `ConsoleMonitor` interface ```typescript interface ConsoleMonitor { readonly messages: ConsoleMessage[]; assertClean(): void; } ``` ### `ConsoleMonitorOptions` interface ```typescript interface ConsoleMonitorOptions { failOn?: Array<"error" | "warning" | "info">; ignore?: RegExp[]; } ``` ## Implementation Notes Playwright uses `"warn"` as a type string in some browser contexts despite DevTools calling it `"warning"`. The internal `PLAYWRIGHT_TYPE_MAP` normalises `"warn"` to `"warning"` so tests using `failOn: ["warning"]` reliably catch both variants without requiring callers to know about this inconsistency. The `messages` getter returns the live internal array directly rather than a copy. This is intentional: test authors who iterate `messages` after `assertClean()` see exactly what was collected, with no copy overhead. Since tests run synchronously relative to the listener, mutation during iteration is not a concern in practice. Type resolution for unrecognised console types (e.g. `"debug"`, `"verbose"`, `"table"`) falls back to `"info"`, which means they are only included in failures if `failOn` explicitly includes `"info"`.