Agent skill

Playwright E2E

by PramodDutta in PramodDutta/qaskills

Comprehensive end-to-end testing skill using Playwright for web applications, covering page objects, selectors, assertions, waits, fixtures, and test organization.

MITAuto-check passedTesting & QA

Install Playwright E2E

skills CLI
$ npx skills add PramodDutta/qaskills --skill playwright-e2e -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install PramodDutta/qaskills playwright-e2e --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/PramodDutta/qaskills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packs/qa-essentials/skills/playwright-e2e .claude/skills/playwright-e2e && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
playwright-e2e
GitHub stars
232
Token cost
~3.7k tokens
SKILL.md length
526 words
Files
1
Skills in repo
11
Repo updated
First seen
Licence
MIT

At a glance

Comprehensive end-to-end testing skill using Playwright for web applications, covering page objects, selectors, assertions, waits, fixtures, and test organization.

  • Works in 5 steps: User-centric testing -- Always write… → Resilient selectors -- Prefer getByRole,… → Auto-waiting -- Leverage Playwright's… → …
  • Tasks that involve End-to-end testing
  • SKILL.md covers Core Principles, Project Structure, Page Object Model and Writing Test Specs, plus 8 more sections
  • Calls npx

What it does

Playwright E2E is an agent skill from PramodDutta/qaskills. Comprehensive end-to-end testing skill using Playwright for web applications, covering page objects, selectors, assertions, waits, fixtures, and test organization.

Its SKILL.md is about 3.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering End-to-end testing and Browser testing. It works with Playwright. The repository describes itself as: QA Skills Directory QA Skills is a curated directory of testing-specific skills for AI coding agents (Claude Code, Cursor, Copilot, etc.). The licence is MIT.

When your agent uses it

  • Tasks that involve End-to-end testing
  • Tasks that involve Browser testing

Example prompts

  • “/playwright-e2e”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. User-centric testing -- Always write tests from the user's perspective. Tests should mirror real user journeys.
  2. Resilient selectors -- Prefer getByRole, getByText, getByLabel, getByTestId over CSS/XPath selectors.
  3. Auto-waiting -- Leverage Playwright's built-in auto-waiting. Avoid explicit waitForTimeout.
  4. Isolation -- Each test must be independent. Never rely on state from a previous test.
  5. Readability -- Tests are documentation. Write them so a new team member can understand the intent.

What it can do on your machine

Read from SKILL.md and the folder at commit 1d2a092. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npx, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Playwright E2E loads about 3.7k tokens when it runs. Until then it costs about 45 tokens; SKILL.md has 526 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~45
When it runs · the whole SKILL.md, loaded when a task matches
~3.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from PramodDutta/qaskills at commit 1d2a092, republished under its MIT licence (© PramodDutta). 526 words, ~3,748 tokens.

Download SKILL.mdSave it as .claude/skills/playwright-e2e/SKILL.md (or your agent's skills folder).
name
playwright-e2e
description
Comprehensive end-to-end testing skill using Playwright for web applications, covering page objects, selectors, assertions, waits, fixtures, and test organization.
license
MIT
metadata.author
thetestingacademy
metadata.version
1.0.0
metadata.source
https://qaskills.sh/skills/thetestingacademy/playwright-e2e

Playwright E2E Testing Skill

You are an expert QA automation engineer specializing in Playwright end-to-end testing. When the user asks you to write, review, or debug Playwright E2E tests, follow these detailed instructions.

Core Principles

  1. User-centric testing -- Always write tests from the user's perspective. Tests should mirror real user journeys.
  2. Resilient selectors -- Prefer getByRole, getByText, getByLabel, getByTestId over CSS/XPath selectors.
  3. Auto-waiting -- Leverage Playwright's built-in auto-waiting. Avoid explicit waitForTimeout.
  4. Isolation -- Each test must be independent. Never rely on state from a previous test.
  5. Readability -- Tests are documentation. Write them so a new team member can understand the intent.

Project Structure

Always organize Playwright projects with this structure:

tests/
  e2e/
    auth/
      login.spec.ts
      signup.spec.ts
    dashboard/
      dashboard.spec.ts
    checkout/
      cart.spec.ts
      payment.spec.ts
  fixtures/
    auth.fixture.ts
    db.fixture.ts
  pages/
    login.page.ts
    dashboard.page.ts
    base.page.ts
  utils/
    test-data.ts
    helpers.ts
playwright.config.ts

Page Object Model

Always implement the Page Object Model (POM). Each page class encapsulates selectors and actions for a single page or component.

Base Page Class
typescript
import { Page, Locator } from '@playwright/test';

export abstract class BasePage {
  readonly page: Page;

  constructor(page: Page) {
    this.page = page;
  }

  async navigate(path: string): Promise<void> {
    await this.page.goto(path);
  }

  async waitForPageLoad(): Promise<void> {
    await this.page.waitForLoadState('networkidle');
  }

  async getTitle(): Promise<string> {
    return this.page.title();
  }

  async takeScreenshot(name: string): Promise<Buffer> {
    return this.page.screenshot({ path: `screenshots/${name}.png`, fullPage: true });
  }
}
Concrete Page Class
typescript
import { Page, Locator, expect } from '@playwright/test';
import { BasePage } from './base.page';

export class LoginPage extends BasePage {
  readonly emailInput: Locator;
  readonly passwordInput: Locator;
  readonly submitButton: Locator;
  readonly errorMessage: Locator;
  readonly forgotPasswordLink: Locator;

  constructor(page: Page) {
    super(page);
    this.emailInput = page.getByLabel('Email');
    this.passwordInput = page.getByLabel('Password');
    this.submitButton = page.getByRole('button', { name: 'Sign in' });
    this.errorMessage = page.getByRole('alert');
    this.forgotPasswordLink = page.getByRole('link', { name: 'Forgot password?' });
  }

  async goto(): Promise<void> {
    await this.navigate('/login');
  }

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

  async expectErrorMessage(message: string): Promise<void> {
    await expect(this.errorMessage).toBeVisible();
    await expect(this.errorMessage).toHaveText(message);
  }
}

Writing Test Specs

Basic Test Structure
typescript
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/login.page';

test.describe('Login functionality', () => {
  let loginPage: LoginPage;

  test.beforeEach(async ({ page }) => {
    loginPage = new LoginPage(page);
    await loginPage.goto();
  });

  test('should login with valid credentials', async ({ page }) => {
    await loginPage.login('user@example.com', 'SecurePass123!');
    await expect(page).toHaveURL('/dashboard');
    await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible();
  });

  test('should show error for invalid credentials', async () => {
    await loginPage.login('user@example.com', 'wrongpassword');
    await loginPage.expectErrorMessage('Invalid email or password');
  });

  test('should navigate to forgot password page', async ({ page }) => {
    await loginPage.forgotPasswordLink.click();
    await expect(page).toHaveURL('/forgot-password');
  });
});

Selectors -- Priority Order

Always choose selectors in this priority order:

  1. getByRole -- Preferred. Matches the accessibility tree.

    typescript
    page.getByRole('button', { name: 'Submit' });
    page.getByRole('heading', { level: 1 });
    page.getByRole('link', { name: 'Read more' });
    page.getByRole('textbox', { name: 'Email' });
  2. getByLabel -- For form inputs associated with labels.

    typescript
    page.getByLabel('Email address');
    page.getByLabel('Password');
  3. getByPlaceholder -- When there is no label.

    typescript
    page.getByPlaceholder('Search...');
  4. getByText -- For non-interactive elements with visible text.

    typescript
    page.getByText('Welcome back');
    page.getByText(/total: \$\d+/i);
  5. getByTestId -- When semantic selectors are not feasible.

    typescript
    page.getByTestId('checkout-total');
  6. CSS/XPath -- Last resort only. Document why other options failed.

    typescript
    // Avoid unless absolutely necessary
    page.locator('.legacy-widget >> nth=0');

Assertions

Use Playwright's web-first assertions that auto-retry:

typescript
// Visibility
await expect(locator).toBeVisible();
await expect(locator).toBeHidden();

// Text content
await expect(locator).toHaveText('Expected text');
await expect(locator).toContainText('partial');
await expect(locator).toHaveText(/regex pattern/);

// Input values
await expect(locator).toHaveValue('expected value');
await expect(locator).toBeChecked();
await expect(locator).toBeDisabled();

// Page-level
await expect(page).toHaveURL('/expected-path');
await expect(page).toHaveURL(/\/users\/\d+/);
await expect(page).toHaveTitle('Page Title');

// Count
await expect(page.getByRole('listitem')).toHaveCount(5);

// CSS
await expect(locator).toHaveCSS('color', 'rgb(255, 0, 0)');
await expect(locator).toHaveClass(/active/);

// Screenshot comparison
await expect(page).toHaveScreenshot('homepage.png');
await expect(locator).toHaveScreenshot('button-hover.png');

Fixtures

Use custom fixtures to share setup logic and authenticated state:

typescript
import { test as base, Page } from '@playwright/test';
import { LoginPage } from '../pages/login.page';
import { DashboardPage } from '../pages/dashboard.page';

type MyFixtures = {
  loginPage: LoginPage;
  dashboardPage: DashboardPage;
  authenticatedPage: Page;
};

export const test = base.extend<MyFixtures>({
  loginPage: async ({ page }, use) => {
    const loginPage = new LoginPage(page);
    await loginPage.goto();
    await use(loginPage);
  },

  dashboardPage: async ({ page }, use) => {
    await use(new DashboardPage(page));
  },

  authenticatedPage: async ({ browser }, use) => {
    const context = await browser.newContext({
      storageState: 'playwright/.auth/user.json',
    });
    const page = await context.newPage();
    await use(page);
    await context.close();
  },
});

export { expect } from '@playwright/test';
Authentication State Reuse
typescript
// auth.setup.ts -- run once to store auth state
import { test as setup, expect } from '@playwright/test';

setup('authenticate', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('admin@example.com');
  await page.getByLabel('Password').fill('AdminPass123!');
  await page.getByRole('button', { name: 'Sign in' }).click();
  await expect(page).toHaveURL('/dashboard');
  await page.context().storageState({ path: 'playwright/.auth/user.json' });
});

Configuration Best Practices

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

export default defineConfig({
  testDir: './tests/e2e',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [
    ['html', { open: 'never' }],
    ['json', { outputFile: 'test-results/results.json' }],
    process.env.CI ? ['github'] : ['list'],
  ],
  use: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    actionTimeout: 10_000,
    navigationTimeout: 30_000,
  },
  projects: [
    { name: 'setup', testMatch: /.*\.setup\.ts/ },
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
      dependencies: ['setup'],
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
      dependencies: ['setup'],
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
      dependencies: ['setup'],
    },
    {
      name: 'mobile-chrome',
      use: { ...devices['Pixel 5'] },
      dependencies: ['setup'],
    },
    {
      name: 'mobile-safari',
      use: { ...devices['iPhone 13'] },
      dependencies: ['setup'],
    },
  ],
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
    timeout: 120_000,
  },
});

Handling Common Scenarios

Navigation and Routing
typescript
test('should navigate through multi-step wizard', async ({ page }) => {
  await page.goto('/wizard');

  // Step 1
  await page.getByLabel('Full name').fill('Jane Doe');
  await page.getByRole('button', { name: 'Next' }).click();

  // Step 2
  await expect(page).toHaveURL('/wizard/step-2');
  await page.getByLabel('Email').fill('jane@example.com');
  await page.getByRole('button', { name: 'Next' }).click();

  // Step 3 -- confirmation
  await expect(page).toHaveURL('/wizard/step-3');
  await expect(page.getByText('Jane Doe')).toBeVisible();
  await expect(page.getByText('jane@example.com')).toBeVisible();
});
Handling Dialogs
typescript
test('should handle confirmation dialog', async ({ page }) => {
  page.on('dialog', async (dialog) => {
    expect(dialog.type()).toBe('confirm');
    expect(dialog.message()).toBe('Are you sure you want to delete?');
    await dialog.accept();
  });

  await page.getByRole('button', { name: 'Delete' }).click();
  await expect(page.getByText('Item deleted')).toBeVisible();
});
File Upload
typescript
test('should upload a file', async ({ page }) => {
  const fileInput = page.getByLabel('Upload document');
  await fileInput.setInputFiles('test-data/sample.pdf');
  await expect(page.getByText('sample.pdf')).toBeVisible();
  await page.getByRole('button', { name: 'Submit' }).click();
  await expect(page.getByText('Upload successful')).toBeVisible();
});
Iframe Handling
typescript
test('should interact with iframe content', async ({ page }) => {
  const iframe = page.frameLocator('#payment-iframe');
  await iframe.getByLabel('Card number').fill('4111111111111111');
  await iframe.getByLabel('Expiry').fill('12/25');
  await iframe.getByLabel('CVC').fill('123');
});
Network Interception
typescript
test('should mock API response', async ({ page }) => {
  await page.route('**/api/products', async (route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify([
        { id: 1, name: 'Mocked Product', price: 9.99 },
      ]),
    });
  });

  await page.goto('/products');
  await expect(page.getByText('Mocked Product')).toBeVisible();
});

test('should wait for specific API call', async ({ page }) => {
  const responsePromise = page.waitForResponse('**/api/submit');
  await page.getByRole('button', { name: 'Submit' }).click();
  const response = await responsePromise;
  expect(response.status()).toBe(200);
});
Handling Dropdowns and Select Elements
typescript
// Native select
await page.getByLabel('Country').selectOption('US');
await page.getByLabel('Country').selectOption({ label: 'United States' });

// Custom dropdown
await page.getByRole('combobox', { name: 'Country' }).click();
await page.getByRole('option', { name: 'United States' }).click();

Best Practices

  1. Never use page.waitForTimeout() -- Use auto-waiting or explicit event waits instead.
  2. Always use test.describe blocks to group related tests.
  3. Use test.beforeEach for common setup, but keep it minimal.
  4. Tag tests for selective execution:
    typescript
    test('checkout flow @smoke @critical', async ({ page }) => { ... });
  5. Use soft assertions for non-blocking checks:
    typescript
    await expect.soft(locator).toHaveText('expected');
    await expect.soft(other).toBeVisible();
  6. Parameterize tests with test.describe and arrays:
    typescript
    const users = [
      { role: 'admin', canDelete: true },
      { role: 'viewer', canDelete: false },
    ];
    for (const { role, canDelete } of users) {
      test(`${role} delete permission`, async ({ page }) => { ... });
    }
  7. Set reasonable timeouts at the config level, not in individual tests.
  8. Use trace viewer for debugging: npx playwright show-trace trace.zip
  9. Parallelize wisely -- Use fullyParallel: true but ensure test isolation.
  10. Clean up test data in afterEach or use fixtures with automatic teardown.
Show full SKILL.md (182 more words)Show less

Anti-Patterns to Avoid

  1. Hardcoded waits -- await page.waitForTimeout(3000) is flaky and slow.
  2. Shared mutable state between tests -- Each test must stand alone.
  3. Testing implementation details -- Test behavior, not DOM structure.
  4. Overly specific selectors -- div.container > ul > li:nth-child(3) > span.text breaks on any layout change.
  5. Giant test files -- Keep test files focused on a single feature or page.
  6. Ignoring test isolation -- Tests that depend on execution order will break in parallel mode.
  7. Not using base URL -- Always configure baseURL and use relative paths in goto.
  8. Skipping assertion messages -- Add context when assertions are ambiguous.
  9. Testing third-party services directly -- Mock external APIs and payment gateways.
  10. Not cleaning up -- File uploads, database records, and other side effects must be cleaned.

Debugging Tips

  • Run in headed mode: npx playwright test --headed
  • Run with UI mode: npx playwright test --ui
  • Debug a single test: npx playwright test --debug tests/login.spec.ts
  • Generate code: npx playwright codegen https://example.com
  • View trace: npx playwright show-trace test-results/trace.zip
  • Use test.only to isolate a single test during development.
  • Use await page.pause() to pause execution and inspect the page.

© PramodDutta, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in packs/qa-essentials/skills/playwright-e2e of PramodDutta/qaskills.

Open the folder on GitHubat commit 1d2a092

Compare with similar skills

Playwright E2E next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Playwright E2E compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Playwright E2E this skillPramodDutta/qaskills232—~3.7kAutomated safety check: PassMIT
Web Application Testinganthropics/skills180k51 repos~966Automated safety check: PassApache-2.0
playwright-cli Browser Automationgithub/gh-aw5.4k24 repos~2.8kAutomated safety check: PassMIT
Write and Verify Playwright Testsappsmithorg/appsmith41k—~2.9kAutomated safety check: NotesApache-2.0
Cucumber and Playwright E2E Testslanggenius/dify158k—~682Automated safety check: PassCustom licence
E2E Testinglangflow-ai/langflow156k—~3.3kAutomated safety check: PassMIT

Similar skills

  • Web Application Testing

    anthropics/skills

    Official

    Tests local web applications with Python Playwright scripts, checking frontend behavior, capturing screenshots and reading browser console logs.

    180k GitHub starsUsed in 51 repos~966 tokens
    Testing & QAAuto-check passed
  • Official

    Drives a real browser from the command line with playwright-cli to open pages, interact, mock requests, save state and work with Playwright tests.

    5.4k GitHub starsUsed in 24 repos~2.8k tokens
    Testing & QAAuto-check passed
  • Writes a Playwright end-to-end test from a prompt, runs it against a live Appsmith deployment and retries with fixes up to three times until it passes.

    41k GitHub stars~2.9k tokensUpdated today
    Testing & QAAuto-check: notes
  • Guides changes and reviews of the Cucumber and Playwright end-to-end suite under `e2e/`: feature files, step definitions, support code, tags, locators and assertions.

    158k GitHub stars~682 tokensUpdated today
    Testing & QAAuto-check passed
  • E2E Testing

    langflow-ai/langflow

    Write and review Playwright E2E tests for Langflow. An agent skill from langflow-ai/langflow.

    156k GitHub stars~3.3k tokensUpdated today
    Testing & QAAuto-check passed
  • Handsontable Playwright E2E Tests

    handsontable/handsontable

    Guides writing and changing Playwright end-to-end tests for Handsontable using page objects, data-testid hooks and deterministic waits.

    22k GitHub stars~1.8k tokensUpdated today
    Testing & QAAuto-check passed

More from PramodDutta/qaskills

All 11 skills in this repo
  • Add Seed Skills

    PramodDutta/qaskills

    A skill your agent uses when adding or editing QA skills in seed-skills/ or getting them onto the live qaskills.sh catalog, e.g.

    232 GitHub stars~1.4k tokensUpdated 3 days ago
    Auto-check: notes
  • Publish SEO Batch

    PramodDutta/qaskills

    A skill your agent uses when publishing SEO blog articles to qaskills.sh, e.g.

    232 GitHub stars~2.2k tokensUpdated 3 days ago
    Auto-check passed
  • Ship Prod

    PramodDutta/qaskills

    A skill your agent uses when deploying qaskills.sh to production, verifying whether a deploy landed, or when a push to main did not show up on the live site, e.g.

    232 GitHub stars~1k tokensUpdated 3 days ago
    Auto-check passed
  • API Testing REST

    PramodDutta/qaskills

    Comprehensive RESTful API testing patterns covering HTTP methods, status codes, request/response validation, authentication, error handling, and contract testing.

    232 GitHub stars~4.9k tokensUpdated 3 days ago
    Auto-check passed
  • Claude Code QA

    PramodDutta/qaskills

    The complete QA skill for Claude Code — turn Claude into an expert QA engineer that picks the right test type, writes reliable Playwright, Cypress, and pytest tests, eliminates flaky tests, enforces…

    232 GitHub stars~2.3k tokensUpdated 3 days ago
    Auto-check passed
  • Cypress E2E

    PramodDutta/qaskills

    End-to-end testing skill using Cypress for web applications, covering custom commands, network intercepts, fixtures, cy.session, and component testing patterns.

    232 GitHub stars~3.4k tokensUpdated 3 days ago
    Auto-check passed

Works with

Categories

Questions about Playwright E2E

What does Playwright E2E do?

Comprehensive end-to-end testing skill using Playwright for web applications, covering page objects, selectors, assertions, waits, fixtures, and test organization. Playwright E2E is an agent skill from PramodDutta/qaskills. Comprehensive end-to-end testing skill using Playwright for web applications, covering page objects, selectors, assertions, waits, fixtures, and test organization.

When should I use Playwright E2E?

Playwright E2E fits situations like: tasks that involve End-to-end testing; tasks that involve Browser testing.

How do I install Playwright E2E in Claude Code?

Run `npx skills add PramodDutta/qaskills --skill playwright-e2e -a claude-code`. Or copy the skill folder (packs/qa-essentials/skills/playwright-e2e in PramodDutta/qaskills) into .claude/skills/playwright-e2e in your project. Claude Code loads it when a task matches its description.

How do I install Playwright E2E in Codex?

Run `npx skills add PramodDutta/qaskills --skill playwright-e2e -a codex`. Or copy the skill folder (packs/qa-essentials/skills/playwright-e2e in PramodDutta/qaskills) into .agents/skills/playwright-e2e in your project. Codex loads it when a task matches its description.

Can I use Playwright E2E in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add PramodDutta/qaskills --skill playwright-e2e -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/playwright-e2e, .gemini/skills/playwright-e2e, .github/skills/playwright-e2e and .opencode/skills/playwright-e2e in your project.

What does Playwright E2E need to run?

Going by SKILL.md and its folder, Playwright E2E needs the command-line tools its instructions call (npx).

Does Playwright E2E access the network?

SKILL.md contains no URLs. Its commands use npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Playwright E2E safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Playwright E2E use?

Playwright E2E is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Playwright E2E use?

About 3.7k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Playwright E2E?

Skills that share tags, products or a category with Playwright E2E: Web Application Testing (anthropics/skills, 180k stars), playwright-cli Browser Automation (github/gh-aw, 5.4k stars), Write and Verify Playwright Tests (appsmithorg/appsmith, 41k stars) and Cucumber and Playwright E2E Tests (langgenius/dify, 158k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Playwright E2E?

PramodDutta (a GitHub user) maintains it in PramodDutta/qaskills, which has 232 GitHub stars. The repository holds 11 skills in this directory. The repository was last updated on October 4, 2026.

Source: PramodDutta/qaskills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.