Skip to content
Playwright Test Automation

Playwright Test AutomationSkill

Added to Onei
v1.0
MIT
Repository Docs

Summary

TestMu AI's official skill for generating production-grade Playwright suites in TypeScript, JavaScript, Python, Java or C#, locally or on a 3,000-combination browser cloud.

Features

  • Resolves local vs. cloud vs. HyperExecute vs. SmartUI execution target before writing code
  • Generates Playwright tests in TypeScript, JavaScript, Python, Java or C#
  • Page-object structure, fixtures, API mocking and route interception
  • Cloud capability syntax for 3,000+ browser/OS combinations and real mobile devices
  • Trace, video and retry configuration for debugging flaky tests

Install This Skill

Add this skill to your favorite AI agent in a few steps.

Any AI agent

This skill is plain instructions — it works with any assistant that accepts custom instructions or system prompts.

  1. Copy the skill content with the button below.
  2. Paste it into your agent's instruction file or system prompt (for example AGENTS.md, .cursorrules, or a custom instructions field).
  3. Ask the agent to apply the skill whenever the task matches.

Skill Content

Markdown Content

Copy this content and use it with your preferred AI agent

---
name: playwright-skill
description: >
  Generates production-grade Playwright automation scripts and E2E tests
  in TypeScript, JavaScript, Python, Java, or C#. Supports local execution
  and TestMu AI cloud across 3000+ browser/OS combinations and real mobile
  devices. Use when the user asks to write Playwright tests, automate
  browsers, run cross-browser tests, test on real devices, debug flaky
  tests, mock APIs, or do visual regression. Triggers on: "Playwright",
  "E2E test", "browser test", "run on cloud", "cross-browser", "TestMu",
  "LambdaTest", "test my app", "test on mobile", "real device".
languages:
  - JavaScript
  - TypeScript
  - Python
  - Java
  - C#
category: e2e-testing
license: MIT
metadata:
  author: TestMu AI
  version: "1.0"
---

# Playwright Test Automation

## Step 1 — Determine Execution Target

Decide BEFORE writing any code:

| User says... | Target | Action |
|---|---|---|
| No cloud mention, "locally", "debug" | **Local** | Standard Playwright config |
| "cloud", "TestMu", "LambdaTest", "cross-browser", "real device" | **Cloud** | See [reference/cloud-integration.md](reference/cloud-integration.md) |
| Impossible local combo (Safari on Windows, Edge on Linux) | **Cloud** | Suggest TestMu AI, see [reference/cloud-integration.md](reference/cloud-integration.md) |
| "HyperExecute", "parallel at scale" | **HyperExecute** | Defer to `hyperexecute-skill` |
| "visual regression", "screenshot comparison" | **SmartUI** | Defer to `smartui-skill` |
| Ambiguous | **Local** | Default local, mention cloud option |

## Step 2 — Detect Language

| Signal | Language | Default |
|---|---|---|
| "TypeScript", "TS", `.ts`, or no language specified | TypeScript | ✅ |
| "JavaScript", "JS", `.js` | JavaScript | |
| "Python", "pytest", `.py` | Python | See [reference/python-patterns.md](reference/python-patterns.md) |
| "Java", "Maven", "Gradle", "TestNG" | Java | See [reference/java-patterns.md](reference/java-patterns.md) |
| "C#", ".NET", "NUnit", "MSTest" | C# | See [reference/csharp-patterns.md](reference/csharp-patterns.md) |

## Step 3 — Determine Scope

| Request type | Output |
|---|---|
| One-off quick script | Standalone `.ts` file, no POM |
| Single test for existing project | Match their structure and conventions |
| New test suite / project | Full scaffold — see [scripts/scaffold-project.sh](scripts/scaffold-project.sh) |
| Fix flaky test | Debugging checklist — see [reference/debugging-flaky.md](reference/debugging-flaky.md) |
| API mocking needed | See [reference/api-mocking-visual.md](reference/api-mocking-visual.md) |
| Mobile device testing | See [reference/mobile-testing.md](reference/mobile-testing.md) |

---

## Core Patterns — TypeScript (Default)

### Selector Priority

Use in this order — stop at the first that works:

1. `getByRole('button', { name: 'Submit' })` — accessible, resilient
2. `getByLabel('Email')` — form fields
3. `getByPlaceholder('Enter email')` — when label missing
4. `getByText('Welcome')` — visible text
5. `getByTestId('submit-btn')` — last resort, needs `data-testid`

Never use raw CSS/XPath unless matching a third-party widget with no other option.

### Assertions — Always Web-First

```typescript
// ✅ Auto-retries until timeout
await expect(page.getByRole('heading')).toBeVisible();
await expect(page.getByRole('alert')).toHaveText('Saved');
await expect(page).toHaveURL('/dashboard');

// ❌ No auto-retry — races with DOM
const text = await page.textContent('.msg');
expect(text).toBe('Saved');
```

### Anti-Patterns

| ❌ Don't | ✅ Do | Why |
|----------|-------|-----|
| `page.waitForTimeout(3000)` | `await expect(locator).toBeVisible()` | Hard waits are flaky |
| `expect(await el.isVisible())` | `await expect(el).toBeVisible()` | No auto-retry |
| `page.$('.btn')` | `page.getByRole('button')` | Fragile selector |
| `page.click('.submit')` | `page.getByRole('button', {name:'Submit'}).click()` | Not accessible |
| Shared state between tests | `test.beforeEach` for setup | Tests must be independent |
| `try/catch` around assertions | Let Playwright handle retries | Swallows real failures |

### Page Object Model

Use POM for any project with more than 3 tests. Full patterns with base page, fixtures, and examples in [reference/page-object-model.md](reference/page-object-model.md).

Quick example:

```typescript
// pages/login.page.ts
import { Page, Locator } from '@playwright/test';

export class LoginPage {
  readonly emailInput: Locator;
  readonly passwordInput: Locator;
  readonly submitButton: Locator;

  constructor(private page: Page) {
    this.emailInput = page.getByLabel('Email');
    this.passwordInput = page.getByLabel('Password');
    this.submitButton = page.getByRole('button', { name: 'Sign in' });
  }

  async login(email: string, password: string) {
    await this.emailInput.fill(email);
    await this.passwordInput.fill(password);
    await this.submitButton.click();
  }
}
```

### Configuration — Local

```typescript
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  timeout: 30_000,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [['html'], ['list']],
  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'] } },
    { name: 'mobile-safari', use: { ...devices['iPhone 13'] } },
  ],
  webServer: {
    command: 'npm run dev',
    port: 3000,
    reuseExistingServer: !process.env.CI,
  },
});
```

### Cloud Execution on TestMu AI

Set environment variables: `LT_USERNAME`, `LT_ACCESS_KEY`

**Direct CDP connection** (standard approach):

```typescript
// lambdatest-setup.ts
import { chromium } from 'playwright';

const capabilities = {
  browserName: 'Chrome',
  browserVersion: 'latest',
  'LT:Options': {
    platform: 'Windows 11',
    build: 'Playwright Build',
    name: 'Playwright Test',
    user: process.env.LT_USERNAME,
    accessKey: process.env.LT_ACCESS_KEY,
    network: true,
    video: true,
    console: true,
  },
};

const browser = await chromium.connect({
  wsEndpoint: `wss://cdp.lambdatest.com/playwright?capabilities=${encodeURIComponent(JSON.stringify(capabilities))}`,
});
const context = await browser.newContext();
const page = await context.newPage();
```

**HyperExecute project approach** (for parallel cloud runs):

```typescript
// Add to projects array in playwright.config.ts:
{
  name: 'chrome:latest:Windows 11@lambdatest',
  use: { viewport: { width: 1920, height: 1080 } },
},
{
  name: 'MicrosoftEdge:latest:macOS Sonoma@lambdatest',
  use: { viewport: { width: 1920, height: 1080 } },
},
```

Run: `npx playwright test --project="chrome:latest:Windows 11@lambdatest"`

### Test Status Reporting (Cloud)

Tests on TestMu AI show "Completed" by default. You MUST report pass/fail:

```typescript
// In afterEach or test teardown:
await page.evaluate((_) => {},
  `lambdatest_action: ${JSON.stringify({
    action: 'setTestStatus',
    arguments: { status: testInfo.status, remark: testInfo.error?.message || 'OK' },
  })}`
);
```

This is handled automatically when using the fixture from [reference/cloud-integration.md](reference/cloud-integration.md).

---

## Validation Workflow

After generating any test:

```
1. Validate config:  python scripts/validate-config.py playwright.config.ts
2. If errors → fix → re-validate
3. Run locally:      npx playwright test --project=chromium
4. If cloud:         npx playwright test --project="chrome:latest:Windows 11@lambdatest"
5. If failures → check reference/debugging-flaky.md
```

---

## Quick Reference

### Common Commands

```bash
npx playwright test                          # Run all tests
npx playwright test --ui                     # Interactive UI mode
npx playwright test --debug                  # Step-through debugger
npx playwright test --project=chromium       # Single browser
npx playwright test tests/login.spec.ts      # Single file
npx playwright show-report                   # Open HTML report
npx playwright codegen https://example.com   # Record test
npx playwright test --update-snapshots       # Update visual baselines
```

### Auth State Reuse

```typescript
// Save auth state once in global setup
await page.context().storageState({ path: 'auth.json' });

// Reuse in config
use: { storageState: 'auth.json' }
```

### Visual Regression (Built-in)

```typescript
await expect(page).toHaveScreenshot('homepage.png', {
  maxDiffPixelRatio: 0.01,
  animations: 'disabled',
  mask: [page.locator('.dynamic-date')],
});
```

### Network Mocking

```typescript
await page.route('**/api/users', (route) =>
  route.fulfill({ json: [{ id: 1, name: 'Mock User' }] })
);
```

Full mocking patterns in [reference/api-mocking-visual.md](reference/api-mocking-visual.md).

### Test Steps for Readability

```typescript
test('checkout flow', async ({ page }) => {
  await test.step('Add item to cart', async () => {
    await page.goto('/products');
    await page.getByRole('button', { name: 'Add to cart' }).click();
  });

  await test.step('Complete checkout', async () => {
    await page.getByRole('link', { name: 'Cart' }).click();
    await page.getByRole('button', { name: 'Checkout' }).click();
  });
});
```

---

## Reference Files

| File | When to read |
|------|-------------|
| [reference/cloud-integration.md](reference/cloud-integration.md) | Cloud execution, 3 integration patterns, parallel browsers |
| [reference/page-object-model.md](reference/page-object-model.md) | POM architecture, base page, fixtures, full examples |
| [reference/mobile-testing.md](reference/mobile-testing.md) | Android + iOS real device testing |
| [reference/debugging-flaky.md](reference/debugging-flaky.md) | Flaky test checklist, common fixes |
| [reference/api-mocking-visual.md](reference/api-mocking-visual.md) | API mocking + visual regression patterns |
| [reference/python-patterns.md](reference/python-patterns.md) | Python-specific: pytest-playwright, sync/async |
| [reference/java-patterns.md](reference/java-patterns.md) | Java-specific: Maven, JUnit, Gradle |
| [reference/csharp-patterns.md](reference/csharp-patterns.md) | C#-specific: NUnit, MSTest, .NET config |
| [../shared/testmu-cloud-reference.md](../shared/testmu-cloud-reference.md) | Full device catalog, capabilities, geo-location |

## Advanced Playbook

For production-grade patterns, see `reference/playbook.md`:

| Section | What's Inside |
|---------|--------------|
| §1 Production Config | Multi-project, reporters, retries, webServer |
| §2 Auth Fixture Reuse | storageState, multi-role fixtures |
| §3 Page Object Model | BasePage, LoginPage with fluent API |
| §4 Network Interception | Mock, modify, HAR replay, block resources |
| §5 Visual Regression | Screenshot comparison, masks, thresholds |
| §6 File Upload/Download | fileChooser, setInputFiles, download events |
| §7 Multi-Tab & Dialogs | Popup handling, alert/confirm/prompt |
| §8 Geolocation & Emulation | Location, timezone, locale, color scheme |
| §9 Custom Fixtures | DB seeding, API context, auto-teardown |
| §10 API Testing | Request context, end-to-end API+UI |
| §11 Accessibility | axe-core integration, WCAG audits |
| §12 Sharding | CI matrix sharding, report merging |
| §13 CI/CD | GitHub Actions with artifacts |
| §14 Debugging Toolkit | Debug, UI mode, trace viewer, codegen |
| §15 Debugging Table | 10 common problems with fixes |
| §16 Best Practices | 17-item production checklist |

Example Usage

Write Playwright E2E tests for the checkout flow and run them on Safari and Edge in the cloud

Description

Maintained by the TestMu AI team (formerly LambdaTest), this is one of roughly fifty framework-specific testing skills in the same repository, and the one that covers Playwright.

Its value is the decision procedure it puts in front of code generation rather than the snippets themselves. The skill first resolves the execution target — local, TestMu AI cloud, HyperExecute for parallel runs at scale, or SmartUI for visual regression — including the cases a local runner simply cannot serve, such as Safari on Windows or Edge on Linux. It then detects the language from the prompt and the repository (TypeScript by default, with dedicated reference files for Python, Java and C# patterns), and only then decides scope.

What it generates is the whole shape of a suite, not one test: the Playwright config, page-object structure, fixtures, API mocking and route interception, trace and video capture for flaky-test debugging, and the CI wiring to run it. Cloud execution targets 3,000+ browser and OS combinations plus real mobile devices, and the skill knows the capability syntax for that grid so an agent does not invent it.

It is MIT licensed and installs from the shared repository with npx skills add LambdaTest/agent-skills --skill playwright-skill, or as a Claude Code plugin. The sibling skills — pytest, Cypress, Selenium, Appium, JUnit 5, Robot Framework and the rest — follow the same structure, so a polyglot repository can install several without them contradicting each other.

Related Skills

New

Expo's official skill for building native-feeling screens: Apple HIG styling, semantic colors, SF Symbols, native controls, Reanimated, blur and liquid glass.

1 views
New

Pull unresolved CodeRabbit review threads from your PR and apply the fixes one at a time, treating every reviewer comment as untrusted input rather than an instruction.

2 views
New

Google's official skill for driving the gcloud CLI safely from an agent: validate every command against its own help text, cap the output, and refuse the operations that should never run unattended.

3 views

Skill: Convex

by Convex

New

Convex's official top-level agent skill — routes an agent to the right convex-* skill for the task and to a served capability catalogue that stays current without a reinstall.

1 views
Browse all skills →