The gap between HTTP 200 and actual function
Modern web applications consist of three layers: the plain HTML document the server delivers, the JavaScript bundle that provides interactivity, and the API calls that load data in the background. Uptime monitoring checks the first layer — and sometimes not even that. Typical failures that slip through:
- Broken JavaScript bundle: A deploy writes a syntax error into the minified JS. The page loads (HTTP 200), but React / Svelte / Vue don't initialize. Buttons don't react.
- Broken API call in checkout: The frontend is delivered, the cart submit hangs on
/api/cart/addwith HTTP 500. The homepage doesn't notice. - Broken selector after redesign: The developer renamed
#add-to-carttobutton[data-action=cart]— and forgot that a third-party plugin expects the old selector. - Third-party outage: A hosted consent banner blocks the whole UI on failure. Uptime says „OK“, the user sees only the loading spinner.
- WAF rule misfires: A new firewall rule blocks silent form submissions — but the GET request on
/keeps working.
The average checkout abandonment rate in German e-commerce sits at around 70 % (Baymard Institute), a notable share of which stems from technical issues — from visible JavaScript errors to invisible backend timeouts. A failure that goes unnoticed often runs for hours — until a customer complains via email or social media.
What browser monitoring actually does
A synthetic check runs a predefined scenario in a real, headlessly controlled Chromium browser: open page, click selector, fill field, wait for element, assert text or URL. When a step breaks, a screenshot of the state at the moment of failure is captured immediately and an alert fires — including step number and error message.
Unlike classical uptime, every check is a full browser with JavaScript, cookies, localStorage, network inspection and DOM. This makes the check behave exactly like a user — except the small detail that it blocks the site's own analytics tracker (so your reach measurements aren't polluted by test pageviews) and sends a distinct user agent you can filter in your analytics.
Which flows to monitor first?
Not every click on the site needs its own monitor. Value emerges at the few, revenue-critical paths. These five are the right starting point for most sites:
The most expensive flow when it breaks. Run every 15 minutes — with a fixed test product that is never out of stock.
Dedicated monitoring account with minimal permissions that runs the form submit, redirect and an assertion on .dashboard-greeting.
Dummy email that is server-side ignored. Verifies that the form runs through to the confirmation page and the thank-you page shows.
Query with a known result — verifies that the search API doesn't silently return 'no results' when products exist.
Click on 'download' → verifies the response has Content-Type application/pdf and is > 10 KB — catches dead download links.
For multilingual sites — verifies that the /en flow works just like /de and doesn't silently end in 404.
Set up a monitor in 3 steps
Because every click is added manually, the barrier often feels higher than it is. In practice a clean flow monitor needs 5 to 10 steps and is ready in a few minutes. The typical sequence:
- Open target page (
goto): Define the starting URL. The runner automatically waits fornetworkidle(state where no network requests are running anymore). - Wait for element (
wait_for): Most important step for single-page apps — otherwise the runner clicks before the DOM finished hydrating. Pick a CSS selector for an element that appears only when the page is ready. - Fill fields / clicks (
fill,click): In order enter login email, enter password, click submit. Every action with its own selector. - Set assertion (
assert_text,assert_url): After the submit: the URL contains/dashboardor the textWelcomeis in the header. Without an assertion, the monitor doesn't catch a silent fail. - Optional: screenshot: At the end of a successful flow a snapshot for documentation — also for the audit trail.
CSS classes from CSS-in-JS (e.g. .sc-abc123xyz) change on every build. Use data-test-id="cart-submit" or fixed IDs instead. Talk to your dev team — it's a 5-minute fix in the code and saves years of flaky tests.
Intervals, alerts and timings
A browser run typically takes 2 to 8 seconds and consumes resources. Well-chosen intervals range from 5 minutes (critical checkouts during business hours) to 1-2 hours (non-critical flows like newsletter signup). Reduce to minimal frequency at night when your audience sleeps — the carbon savings are small but measurable.
On failure the monitor fires an alert of type browser_monitor_failed on all configured channels — typically email, Slack, Telegram or webhook. XICTRAQ dedupes for 10 minutes so a flaky selector doesn't cause 100 alerts per hour. Also helpful: multi-step escalation — if nobody acknowledges the alert with the acknowledge link within 15 minutes, an SMS lands with on-call.
Working together with uptime and API monitoring
Browser monitoring doesn't replace uptime and API monitoring — it complements them. The division of labour:
| Check type | Checks | Typical frequency | Cost |
|---|---|---|---|
| Uptime | HTTP reachability of homepage | 30 s – 5 min | Very cheap — a single GET request |
| API monitoring | Individual REST endpoints with assertions | 1 – 5 min | Cheap — a single HTTP call |
| Browser monitoring | Complete user flows in real Chromium | 5 – 60 min | Higher — one Chromium browser per run |
The combination is decisive: uptime detects infrastructure failures in seconds, API monitoring catches broken backend endpoints in minutes, browser monitoring finds broken user flows — including JavaScript errors, broken third-party integrations and incorrect selector behaviour — at an interval matching real user frequency.
Three common objections
„We already have E2E tests in Playwright / Cypress in our CI.“ — True, but those typically run on pull request or the nightly build, not every 15 minutes in production. Browser monitoring isn't a replacement for CI tests, it's their production counterpart.
„We'll pollute our analytics with it.“ — That's exactly why a good runner blocks the site's own tracker and sends a dedicated user agent (XICTRAQ-BrowserMonitor/1.0) you can filter server-side and in your analytics tools. With cookieless analytics this is especially simple — no session cookie to ignore.
„The password sits in plaintext in the configuration.“ — For monitoring setup a dedicated test account with minimal permissions is the recommended approach instead of a production user. Fill values are stored encrypted in the database and decrypted server-side only at run time — and a secrets vault with variable references ({{secret.password}}) is on the roadmap.
How does browser monitoring differ from uptime monitoring?
How often should a checkout monitor run?
Does the monitoring pollute our analytics?
XICTRAQ-BrowserMonitor/1.0 server-side from analytics, so test pageviews and clicks don't show up in your own reach measurement.What happens with a flaky selector?
wait_for step on a stable element typically solves it. XICTRAQ additionally dedupes alerts for 10 minutes so no alert storm occurs if a selector intermittently recovers.Can I store passwords safely in the monitor?
Does browser monitoring replace our Playwright CI tests?
Secure the critical flows now
A classical uptime dashboard that continuously shows „100 %“ is rarely the full truth in practice — it's a statement about a single GET request. For checkout, login and contact forms you need a second layer closer to the real user. With one monitor per critical flow, that gap is typically closed in an afternoon — and the next checkout glitch reaches monitoring before the support call does.
This article is based on data from: Cart Abandonment (Baymard Institute).