playwright

A set of guidelines for Playwright, a tool that tests web applications in real browsers. It covers end-to-end tests, which check complete user flows, along with reusable test setup and page objects, which keep page interactions in one place.

In plain words
What is it for?
Use it to test web pages and user journeys across Chromium, Firefox, WebKit, and mobile browser settings, including tests that run in parallel or in continuous integration.
Why use it?
It helps make browser tests more reliable and easier to maintain by using stable selectors, browser-aware checks, failure screenshots, traces, and consistent configuration.

Cursor rule

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add rules/renvia-code/best-cursor-rules/playwright
Clone the repo
git clone --depth 1 https://github.com/Renvia-code/best-cursor-rules
Per session 0 Nothing until a file matches its globs; then the whole rule loads.
When invoked 1,966 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00000 $0.01966
Opus 5 $0.00000 $0.00983
Sonnet 5 $0.00000 $0.00393
Haiku 4.5 $0.00000 $0.00197

Measured yesterday against content hash 688c6bf2d0ef, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

playwright scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

rules/testing/playwright.mdc · 358 lines

How it starts

The opening of the file, as written. The whole thing — 358 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Playwright Best Practices

Overview

Aspect Recommendation
Pattern Page Object Model
Assertions Web-first assertions
Selectors Test IDs or role-based
Parallel Run tests in parallel

Configuration

playwright.config.ts

import { defineConfig, devices } from '@playwright/test'

export default defineConfig({
  testDir: './e2e',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: 'html',
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
    {
      name: 'Mobile Chrome',
      use: { ...devices['Pixel 5'] },
    },
  ],
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
})

Basic Tests

First Test

import { test, expect } from '@playwright/test'

test('homepage has title', async ({ page }) => {
  await page.goto('/')
  
  await expect(page).toHaveTitle(/My App/)
})

test('navigation works', async ({ page }) => {
  await page.goto('/')
  
  await page.getByRole('link', { name: 'About' }).click()
  
  await expect(page).toHaveURL('/about')
  await expect(page.getByRole('heading', { name: 'About Us' })).toBeVisible()
})

Selectors

Recommended (Role-based)

// ✅ Best - Role-based selectors
await page.getByRole('button', { name: 'Submit' }).click()
await page.getByRole('textbox', { name: 'Email' }).fill('[email protected]')
await page.getByRole('link', { name: 'Home' }).click()
await page.getByRole('heading', { level: 1 }).toBeVisible()

// ✅ Good - Test IDs
await page.getByTestId('submit-button').click()

// ✅ Good - Labels and placeholders
await page.getByLabel('Email').fill('[email protected]')
await page.getByPlaceholder('Search...').fill('query')
await page.getByText('Welcome back').toBeVisible()

Read the full file on GitHub · 358 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. yesterday First seen · 358 lines · 0 tokens per session scan A 688c6bf2d0ef

Subscribe to this mod's changes

playwright is a cursor rule published in the GitHub repository Renvia-code/best-cursor-rules (12 stars, last pushed 9mo ago), licensed CC0-1.0. It costs nothing until one of its globs matches a file; then it loads 1,966 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.