Files
skills/docs/testkit/testing/testing-e2e/src/console-monitor/console-monitor.md
2026-05-29 08:20:56 +01:00

4.6 KiB

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

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

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

interface ConsoleMonitor {
  readonly messages: ConsoleMessage[];
  assertClean(): void;
}

ConsoleMonitorOptions interface

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".