Browser Checks run a Playwright script in headless Chromium on a schedule. The check fails when an assertion breaks or the global timeout fires, and every run keeps logs, screenshots, video, and a Playwright trace for replay.

Go to app.hyperping.io and click New monitor.
Select Browser as the ping protocol and give the monitor a name. Pick the runtime from the runtime card, the default is 2026.05.
Paste a Playwright script into the editor, add any secrets as environment variables, click Run to test, then save to schedule the monitor.
The 2026.05 runtime is the default for new browser checks. It runs on Node 24 with Playwright 1.59.1 and adds three capabilities on top of the script API.
Web VitalsLCP / CLS / TBT / FCP / TTFBStep reportingtest.step()test.step('...') call shows up in the run view with a green or red status and its own duration. A failed multi-step check points at the exact stage that broke instead of dropping a wall of logs on the on-call engineer.Trace and videoretain-on-failureThe runtime injects a PerformanceObserver into every page your script opens. After each navigation it captures the five Core Web Vitals and stores them on the run, so you can watch them trend without writing any custom timing code.
playwright1.59.1@playwright/test1.59.1typescript^5.6.spec.ts files directly.expect^29uuid^9.0.1lodash4.17.21moment^2.30.1axios^1.13.2btoa1.2.1jsonwebtoken^9.0.2date-fns^2.30.0crypto-js^4.2.0The 2023.04 runtime runs on Node 16 with Playwright 1.33 and is kept around for existing checks. New checks default to 2026.05 and there's no automatic migration, switch the runtime on the monitor's settings page when you're ready.
playwright ^1.33.0, @playwright/test 1.33typescript ^5.0.4Secrets, tokens, and per-monitor configuration belong in environment variables, not in the script. Add them in the monitor's settings panel below the editor and reference them from the script as process.env.NAME.
Double check is enabled by default. When a run fails, the runtime immediately retries from a different region before opening an outage. This filters out network blips and one-shot flake without making you wait for the next scheduled run.
Each browser check has a 2-minute global timeout for the entire run. Individual tests inherit Playwright's 30-second default. Override the per-test timeout when you have a slow flow:
test.setTimeout(120_000); // 2 minutes in millisecondsLong flows are usually better split into separate checks, one per critical path, rather than packed into a single 2-minute run.
Every run keeps its logs, screenshots, video, and trace indefinitely. Failed runs in 2026.05 attach a video of the run and a Playwright trace to the log row, so you can replay exactly what the browser did.
A login flow with two assertions, using process.env for credentials:
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ page }) => {
await page.goto('https://app.acme.com/login');
await page.locator('input[type="text"]').type(process.env.EMAIL);
await page.locator('input[type="password"]').type(process.env.PASSWORD);
await page.getByRole('button', { name: 'Sign in', exact: true }).click();
});
test('has title', async ({ page }) => {
await expect(page).toHaveTitle(/Acme/);
});
test('is logged in', async ({ page }) => {
const content = page.locator('#project-id');
await expect(content).toHaveText('project_12345');
});One step in the test never completed, usually a locator that matches nothing or a page that never finished loading. Open the trace on the failed run to see where time was spent. If the flow is legitimately slow, raise the limit with test.setTimeout, and keep the whole run under the 2-minute cap.
The page often renders differently in headless Chromium: cookie banners, geo popups, and A/B variants show up for a fresh session in a datacenter region. Watch the video of the failed run to see what the browser saw, then dismiss the overlay in the script or use a locator that doesn't depend on it. Prefer getByRole over CSS selectors so a class rename doesn't break the check.
Most flake comes from racing the app: asserting before data loads, or a hard waitForTimeout that is sometimes too short. Replace sleeps with web-first assertions like await expect(locator).toBeVisible(), which retry until the condition is met. Double check already retries failures from a second region before opening an outage, so a persistent alternation points at the script or the app, not the network.
Check that the credentials are set as environment variables on the monitor and read with process.env, they are not copied from your local .env. Bot protection and captchas also trigger more often for datacenter IPs, so whitelist the probe regions or use a dedicated test account on a captcha-free path.
Split the flow into separate checks, one per critical path. Shorter checks give clearer alerts, and a slow step in one flow won't push another into the global timeout.
New to Playwright? The Learn Playwright guides cover locators, assertions, waits, and codegen from scratch. For the full API, see the upstream Playwright docs.