Recommended Free Tools
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Attach a page.on('console') listener before the navigation or interaction you are investigating, then inspect each message’s type and text. Treat that stream separately from uncaught page exceptions (page.on('pageerror')), transport-level request failures (page.on('requestfailed')), and HTTP error responses (a response with status 404 or 503). This separation tells you whether the page logged an error, crashed JavaScript, failed to obtain a response, or received an ordinary HTTP response that your application considers an error.
Capture console errors before they happen
Playwright emits a console event when page JavaScript calls a console API such as console.log(), console.warn(), or console.error(). Register the listener before page.goto(), a click, or any other action that might generate the message. The event exposes a type and rendered text; msg.args() is available when you need the original console arguments rather than only their displayed text. The Page API documents the event and related methods.
import { test } from '@playwright/test';
test('collect browser diagnostics', async ({ page }) => {
page.on('console', msg => {
const line = `[browser console:${msg.type()}] ${msg.text()}`;
if (msg.type() === 'error') {
console.error(line);
} else {
console.log(line);
}
});
page.on('pageerror', error => {
console.error(`[uncaught page exception] ${error.message}`);
});
page.on('requestfailed', request => {
console.error(
`[request failed] ${request.url()} ${request.failure()?.errorText ?? ''}`
);
});
page.on('response', response => {
if (response.status() >= 400) {
console.error(`[HTTP ${response.status()}] ${response.url()}`);
}
});
await page.goto('https://example.com');
await page.getByRole('button', { name: 'Load data' }).click();
});
The console listener above prints every message but highlights only those whose msg.type() is error. Filtering at the event boundary is useful in a focused diagnostic test; retaining warnings and logs is often better while you are trying to understand a sequence. Keep the URL and action that preceded the message in your test output so a CI log remains useful after the browser closes.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsConsole calls, uncaught exceptions, and network failures are different signals
A console error is a deliberate call made by page code. It does not prove that JavaScript threw, and it does not prove that a request failed. Conversely, a broken page can throw an exception without calling console.error(). Use the signal that matches the question you are asking.
#1 Best Overall
| Signal | What causes it | What to inspect | What it does not mean |
|---|---|---|---|
page.on('console') |
Page JavaScript invokes a console API. | msg.type(), msg.text(), and, when needed, msg.args(). |
It is not automatically an uncaught exception or a failed HTTP request. |
page.on('pageerror') |
An exception escapes page JavaScript without being caught. | The error message and stack information exposed by the error object. | It is not the same stream as a page’s explicit console calls. |
page.on('requestfailed') |
The request cannot obtain an HTTP response because of a transport or network error. | request.url() and request.failure()?.errorText. |
It is not emitted merely because the server returned status 404 or 503. |
page.on('response') |
A response is received, including an HTTP 4xx or 5xx response. | response.status(), URL, and response headers or body when appropriate. |
An HTTP error status is not a transport-level request failure. |
Playwright’s request documentation explains that a 404 or 503 is still a completed response from the HTTP standpoint, so the request can finish normally rather than emit requestfailed. Inspect response status separately when your test needs to flag application or server errors: Request API.
Make the log tell you which action caused the error
Raw timestamps are often insufficient when a test performs several clicks and navigations. Playwright Trace Viewer connects browser output to the action that was running when it appeared. Record a trace for the failing run, open it in Trace Viewer, and select the relevant action. The action’s log, source location, console output, and related network activity are shown together; browser messages and test-file logs are distinguished. Selecting an action filters the console view to output associated with that action. The workflow is described in the Trace Viewer documentation.
A practical investigation sequence is:
- Reproduce the failure with tracing enabled for the run or retry that matters.
- In Trace Viewer, select the first action after which the page becomes incorrect.
- Compare the browser console entries with that action’s source, screenshots, and network activity.
- Use the request URL and response status to determine whether the message followed a transport failure, an HTTP error, or neither.
- Move the corresponding listener earlier if the first message predates your current diagnostic code.
Read recent history after an action or navigation
For cases where you do not want to stream every event, recent-history methods are available on Page. page.consoleMessages() returns recent console messages and page.pageErrors() returns recent uncaught page errors. The Page API lists both methods as added in Playwright v1.56. Their all and since-navigation filtering options were added in v1.59, so check the version installed in your project before using those filters: Page API.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchawait page.goto('https://example.com');
const recentConsole = await page.consoleMessages();
for (const message of recentConsole) {
if (message.type() === 'error') {
console.error(`[recent console] ${message.text()}`);
}
}
const recentExceptions = await page.pageErrors();
for (const error of recentExceptions) {
console.error(`[recent page error] ${error.message}`);
}
The buffered history is bounded: the API currently retains up to 200 console messages and up to 200 page errors. A listener registered before the action is therefore the safer choice when every message matters, while the retrieval methods are convenient for a bounded snapshot after a step. The ConsoleMessage reference is published under the /docs/next/ path; verify details against the stable documentation and your installed Playwright version.
Rank #2
Capture diagnostics across every page in a browser context
A page-level listener covers one tab. Tests that open popups, new tabs, or several pages in the same context can subscribe at the context level instead. browserContext.on('console') receives console events from pages in that context, and browserContext.on('weberror') receives unhandled exceptions across those pages. The BrowserContext API documents these events.
const context = await browser.newContext();
context.on('console', message => {
console.log(`[${message.type()}] ${message.page()?.url() ?? 'unknown page'} ${message.text()}`);
});
context.on('weberror', webError => {
console.error(`[context page error] ${webError.error().message}`);
});
const page = await context.newPage();
await page.goto('https://example.com');
Use page listeners when you need a narrow, test-local record. Use context listeners when a failure may originate in a popup or another page and you need one collector for the whole browser context. Include the page URL in context-level output so messages from multiple tabs do not become indistinguishable.
Understand why a 404 is not a requestfailed event
There are two separate diagnostic paths:
- No HTTP response: DNS failure, a refused connection, a reset connection, or another network error can produce
requestfailed. Readrequest.failure()?.errorTextand the request URL. - HTTP response with an error status: a server can return 404, 401, 429, 500, or 503 successfully at the transport layer. Observe the response and inspect its status. Decide in test code which statuses are failures for your application.
When a page logs “API failed” after receiving a 503, you may see both a console message and a normal response event, but not requestfailed. Logging both streams prevents you from chasing the wrong root cause.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Inspect a live failure with Debug mode or UI Mode
For an interactive investigation, start Playwright in debug mode with PWDEBUG=console. Put await page.pause() immediately before the action you want to examine, then use the browser’s developer tools while execution is paused. This lets you reproduce the action and inspect the live console and network panels rather than relying only on post-run output. The workflow is covered in Debugging Tests.
Rank #3
Playwright Test’s UI Mode provides another interactive route. Its console and network inspection views show request and response details alongside the selected test step. Use UI Mode when you need to step through a test repeatedly; use Trace Viewer when you need a durable artifact from CI. See UI Mode.
Build a useful diagnostic policy
Fail only on signals that represent a defect
Some applications intentionally write warnings or errors for expected conditions. A blanket “fail on every console error” rule can turn normal behavior into flaky tests. Start by collecting messages, then define a filter for known benign text or URLs. Treat unexpected uncaught page exceptions as a separate, usually higher-priority signal.
Keep messages attributable
Prefix records with the signal name, message type, URL, and the test action or step that was running. For context-wide listeners, include the page URL. For network events, retain the request URL and failure text; for HTTP responses, retain the status. This gives a CI reader enough information to reproduce the problem without scrolling through undifferentiated browser output.
Register once and register early
Install listeners in a fixture or setup hook when every test needs the same policy. Install them directly in a diagnostic test when you are narrowing one failure. In either case, registration must precede the navigation, popup creation, or interaction under investigation. Messages emitted earlier cannot be reconstructed from a listener that did not exist yet.
Use bounded history deliberately
The 200-entry limit on recent console and page-error history means a long-running page can evict the earliest evidence. Stream important events to the test log or capture them around the action of interest instead of assuming the final snapshot contains the entire session.
Troubleshoot missing or confusing output
| Symptom | Likely cause | Fix |
|---|---|---|
| No console messages appear. | The listener was attached after navigation or after the code that logged the message. | Register page.on('console') before goto() or the triggering action. For a broad test suite, attach it in setup. |
| A visible 404 or 503 is not reported as request failure. | The server returned an HTTP response, so transport succeeded. | Listen for response and inspect response.status(); reserve requestfailed for requests that receive no response. |
| The page is broken but no console error exists. | The failure may be an uncaught exception, a rejected application path handled elsewhere, or a network problem. | Add pageerror, requestfailed, and response-status logging as separate streams. |
| Messages from a popup are missing. | A page-level listener was attached only to the original tab. | Subscribe on the browser context or attach a listener to every newly created page. |
| Recent-history methods omit the original error. | More than 200 entries were produced, or the message occurred before the retained window. | Use a live listener before the action and filter what you persist. |
| Trace output is hard to correlate. | Logs were emitted without an action or page identifier. | Select the suspected action in Trace Viewer, then add URL and step prefixes to custom logs. |
Code using all or since-navigation fails. |
The project uses a Playwright release older than v1.59. | Check the installed version; use the basic history method or upgrade before relying on those filters. |
Browser and version qualifications
Console output is produced by the browser engine and the page, so do not assume that every warning is identical across Chromium, Firefox, and WebKit. The reviewed API references do not establish complete cross-engine parity for all browser warnings. Assert on the specific application signal you need, and verify behavior in each browser project you support.
Likewise, the history APIs and filter options are versioned features. Pin or document the Playwright version used by CI, and consult the stable API page when a detail from the ConsoleMessage reference appears to differ from your installed release.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Or skip the browser setup
If you need a rendered image or PDF alongside your Playwright diagnostics, ScreenshotNeo can capture a URL with one request. It is a screenshot service, not a replacement for console, exception, or network listeners: use Playwright to read runtime errors and ScreenshotNeo when a visual artifact is the useful evidence.
Best Value
- Used Book in Good Condition
Its clean capture path accepts consent banners before taking the shot and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; each response reports the page verdict and billing state in X-Page-Verdict and X-Billed headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
The API call is documented at https://screenshotneo.com/docs/:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Every feature is included on every plan. The Free plan provides 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots, with yearly billing giving two months free. Create a free ScreenshotNeo account to try the 1,000 monthly screenshots without entering a card.
A compact investigation checklist
- Attach
console,pageerror, and network listeners before the triggering action. - Print
msg.type()andmsg.text(); inspectmsg.args()when text hides useful structure. - Use
responsefor HTTP status failures andrequestfailedfor transport failures. - Use context-level listeners when more than one page can fail.
- Use Trace Viewer to map output to an action, and Debug mode or UI Mode for live inspection.
- Remember the 200-entry history limit and the v1.56/v1.59 version boundaries.
Frequently Asked Questions
Will page.on(‘console’) report every warning shown by every browser engine?
Not necessarily. The available references do not establish complete parity for every browser warning, so validate the particular signal in each engine your test matrix supports.
Should a console.error automatically fail a Playwright test?
Only if that message represents a defect for your application. Collect it first, then filter intentional messages and apply a failure policy that matches the product’s behavior.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

