lambdatest/agent-skillsMIT14 files

Playwright Skill

>

Specification
Skill ID
lambdatest/agent-skills/playwright-skill
Publisher
lambdatest
Repository
agent-skills
Installs
0
Files
14
License
MIT
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

lambdatest/agent-skills/playwright-skillInstalls these files
  • SKILL.md
  • reference/api-mocking-visual.md
  • reference/cloud-integration.md
  • reference/csharp-patterns.md
  • reference/debugging-flaky.md
  • reference/java-patterns.md
  • reference/mobile-testing.md
  • reference/page-object-model.md
  • reference/playbook.md
  • reference/python-patterns.md
  • scripts/scaffold-project.sh
  • scripts/validate-config.py
  • templates/lambdatest-setup.ts
  • templates/playwright.config.ts

What this skill tells the agent

Playwright Test Automation

Step 1 — Determine Execution Target

Decide BEFORE writing any code:

User says...TargetAction
No cloud mention, "locally", "debug"LocalStandard Playwright config
"cloud", "TestMu", "LambdaTest", "cross-browser", "real device"CloudSee reference/cloud-integration.md
Impossible local combo (Safari on Windows, Edge on Linux)CloudSuggest TestMu AI, see reference/cloud-integration.md
"HyperExecute", "parallel at scale"HyperExecuteDefer to hyperexecute-skill
"visual regression", "screenshot comparison"SmartUIDefer to smartui-skill
AmbiguousLocalDefault local, mention cloud option

Step 2 — Detect Language

SignalLanguageDefault
"TypeScript", "TS", .ts, or no language specifiedTypeScript✅
"JavaScript", "JS", .jsJavaScript
"Python", "pytest", .pyPythonSee reference/python-patterns.md
"Java", "Maven", "Gradle", "TestNG"JavaSee reference/java-patterns.md
"C#", ".NET", "NUnit", "MSTest"C#See reference/csharp-patterns.md

Step 3 — Determine Scope

Request typeOutput
One-off quick scriptStandalone .ts file, no POM
Single test for existing projectMatch their structure and conventions
New test suite / projectFull scaffold — see scripts/scaffold-project.sh
Fix flaky testDebugging checklist — see reference/debugging-flaky.md
API mocking neededSee reference/api-mocking-visual.md
Mobile device testingSee 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

// ✅ 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✅ DoWhy
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 teststest.beforeEach for setupTests must be independent
try/catch around assertionsLet Playwright handle retriesSwallows 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.

Quick example:

// 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

// 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):

// 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):

// 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:

// 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.


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

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

// 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)

await expect(page).toHaveScreenshot('homepage.png', {

Use this skill in a project

Open any RiverX project, search the Skills panel for lambdatest/agent-skills/playwright-skill, and install it in one click.

Use this skill