Playwright Monitoring Tutorial: Build Reliable Synthetic Checks
Step-by-step Playwright monitoring tutorial for production-ready synthetic checks, including selectors, retries, alerts, and CI workflows.
This tutorial walks you from zero to a production-ready Playwright synthetic monitor.
You'll build one robust check, make it less flaky, and connect it to actionable alerts.
Prerequisites
- A deployed app URL (staging or production)
- A synthetic test account
- Node.js and Playwright basics
Step 1: Start with one business-critical journey
Choose one flow with direct business impact, such as login.
import { test, expect } from "@playwright/test";
test("user can login and open dashboard", async ({ page }) => {
await page.goto("https://app.example.com/login");
await page.getByLabel("Email").fill(process.env.SYNTHETIC_EMAIL!);
await page.getByLabel("Password").fill(process.env.SYNTHETIC_PASSWORD!);
await page.getByRole("button", { name: "Sign in" }).click();
await expect(page).toHaveURL(/.*dashboard/);
await expect(page.getByText("Welcome back")).toBeVisible();
});Step 2: Use stable selectors
Prefer semantic locators:
getByRolegetByLabelgetByTestId(for custom controls)
Avoid brittle CSS selectors tied to layout classes.
Step 3: Add reliability guards
Production monitors must tolerate normal variance.
test("dashboard renders key widgets", async ({ page }) => {
await page.goto("https://app.example.com/dashboard", {
waitUntil: "domcontentloaded",
});
await expect(page.getByRole("heading", { name: /dashboard/i })).toBeVisible();
await expect(page.getByTestId("revenue-widget")).toBeVisible({ timeout: 20_000 });
});Tips:
- Set explicit timeouts for slow but acceptable elements
- Assert only what matters for user success
- Keep each monitor focused and readable
Step 4: Capture debugging evidence
When checks fail, screenshots and traces reduce MTTR.
import { test } from "@playwright/test";
test("checkout flow", async ({ page }) => {
// ... test steps
await page.screenshot({ path: "artifacts/checkout.png", fullPage: true });
});Step 5: Configure retries intentionally
Use retries to reduce false positives, not to hide real incidents.
- Retry once for known transient network issues
- Alert immediately if a critical check fails repeatedly
- Track first-failure rate to identify growing instability
Step 6: Connect checks to alerting
Route alerts based on severity:
- Critical: login/checkout failures → on-call notification
- High: dashboard/core action degradation → team Slack
- Medium: non-critical settings flow failures → issue backlog
Step 7: Schedule with business context
Recommended schedule:
- Every 5 min: login, signup, checkout
- Every 15 min: onboarding and key settings flows
- Hourly: broader end-to-end journeys
Step 8: Add to CI and release gates
Run synthetic tests in CI against preview environments to block regressions before deploy.
npx playwright test tests/synthetic/login.spec.tsThen run the same scripts in your monitoring platform after deployment.
Step 9: Keep test data healthy
- Use dedicated synthetic users
- Reset state between runs when needed
- Rotate credentials and API keys regularly
Step 10: Expand coverage gradually
After login is stable, add:
- Signup
- Upgrade/checkout
- Primary in-app action
- Third-party integration touchpoints
Related docs
Playwright for Synthetic Monitoring: The Definitive Guide
Master the use of Playwright for continuous production monitoring. Learn why Playwright is the gold standard for synthetic checks and how to optimize it for reliability.
Playwright vs Selenium, Cypress, Puppeteer: A Complete Comparison
Compare Playwright with Selenium, Cypress, Puppeteer, and WebDriverIO. See how they stack up in speed, reliability, browser support, and developer experience for web testing and automation.