Back to results

Filtered result set

27 / 1836 matches

SkillHub ClubRun DevOpsTestingFrontendFull Stack

playwright-testing

Provides concrete Playwright testing patterns for web applications, covering authentication, file handling, network mocking, and CI/CD integration. Focuses on best practices like Page Object Model, resilient locators, and avoiding flaky tests. Includes specific code examples and actionable advice for common testing scenarios.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
507
Hot score
99
Updated
March 20, 2026
Overall rating
A8.3
Composite score
7.4
Best-practice grade
B77.6

Install command

npx @skill-hub/cli install fcakyon-claude-codex-settings-playwright-testing
playwrightautomated-testingweb-testingci-cdqa

Repository

fcakyon/claude-codex-settings

Skill path: plugins/playwright-tools/skills/playwright-testing

Provides concrete Playwright testing patterns for web applications, covering authentication, file handling, network mocking, and CI/CD integration. Focuses on best practices like Page Object Model, resilient locators, and avoiding flaky tests. Includes specific code examples and actionable advice for common testing scenarios.

Open repository

Best for

Primary workflow: Run DevOps.

Technical facets: Testing, Frontend, Full Stack, DevOps, Integration.

Target audience: Frontend and full-stack developers implementing automated browser tests, QA engineers transitioning to code-based testing, teams adopting Playwright for web application testing.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: fcakyon.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install playwright-testing into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/fcakyon/claude-codex-settings before adding playwright-testing to shared team environments
  • Use playwright-testing for testing workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: playwright-testing
description: This skill should be used when user asks about "Playwright", "responsiveness test", "test with playwright", "test login flow", "file upload test", "handle authentication in tests", or "fix flaky tests".
---

# Playwright Testing Best Practices

## Test Organization

### File Structure

```
tests/
├── auth/
│   ├── login.spec.ts
│   └── signup.spec.ts
├── dashboard/
│   └── dashboard.spec.ts
├── fixtures/
│   └── test-data.ts
├── pages/
│   └── login.page.ts
└── playwright.config.ts
```

### Naming Conventions

- Files: `feature-name.spec.ts`
- Tests: Describe user behavior, not implementation
- Good: `test('user can reset password via email')`
- Bad: `test('test reset password')`

## Page Object Model

### Basic Pattern

```typescript
// pages/login.page.ts
export class LoginPage {
  constructor(private page: Page) {}

  async goto() {
    await this.page.goto("/login");
  }

  async login(email: string, password: string) {
    await this.page.getByLabel("Email").fill(email);
    await this.page.getByLabel("Password").fill(password);
    await this.page.getByRole("button", { name: "Sign in" }).click();
  }
}

// tests/login.spec.ts
test("successful login", async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.goto();
  await loginPage.login("[email protected]", "password");
  await expect(page).toHaveURL("/dashboard");
});
```

## Locator Strategies

### Priority Order (Best to Worst)

1. **`getByRole`** - Accessible, resilient
2. **`getByLabel`** - Form inputs
3. **`getByPlaceholder`** - When no label
4. **`getByText`** - Visible text
5. **`getByTestId`** - When no better option
6. **CSS/XPath** - Last resort

### Examples

```typescript
// Preferred
await page.getByRole("button", { name: "Submit" }).click();
await page.getByLabel("Email address").fill("[email protected]");

// Acceptable
await page.getByTestId("submit-button").click();

// Avoid
await page.locator("#submit-btn").click();
await page.locator('//button[@type="submit"]').click();
```

## Authentication Handling

### Storage State (Recommended)

Save logged-in state and reuse across tests:

```typescript
// global-setup.ts
async function globalSetup() {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto("/login");
  await page.getByLabel("Email").fill(process.env.TEST_USER_EMAIL);
  await page.getByLabel("Password").fill(process.env.TEST_USER_PASSWORD);
  await page.getByRole("button", { name: "Sign in" }).click();
  await page.waitForURL("/dashboard");
  await page.context().storageState({ path: "auth.json" });
  await browser.close();
}

// playwright.config.ts
export default defineConfig({
  globalSetup: "./global-setup.ts",
  use: {
    storageState: "auth.json",
  },
});
```

### Multi-User Scenarios

```typescript
// Create different auth states
const adminAuth = "admin-auth.json";
const userAuth = "user-auth.json";

test.describe("admin features", () => {
  test.use({ storageState: adminAuth });
  // Admin tests
});

test.describe("user features", () => {
  test.use({ storageState: userAuth });
  // User tests
});
```

## File Upload Handling

### Basic Upload

```typescript
// Single file
await page.getByLabel("Upload file").setInputFiles("path/to/file.pdf");

// Multiple files
await page
  .getByLabel("Upload files")
  .setInputFiles(["path/to/file1.pdf", "path/to/file2.pdf"]);

// Clear file input
await page.getByLabel("Upload file").setInputFiles([]);
```

### Drag and Drop Upload

```typescript
// Create file from buffer
const buffer = Buffer.from("file content");

await page.getByTestId("dropzone").dispatchEvent("drop", {
  dataTransfer: {
    files: [{ name: "test.txt", mimeType: "text/plain", buffer }],
  },
});
```

### File Download

```typescript
const downloadPromise = page.waitForEvent("download");
await page.getByRole("button", { name: "Download" }).click();
const download = await downloadPromise;
await download.saveAs("downloads/" + download.suggestedFilename());
```

## Waiting Strategies

### Auto-Wait (Preferred)

Playwright auto-waits for elements. Use assertions:

```typescript
// Auto-waits for element to be visible and stable
await page.getByRole("button", { name: "Submit" }).click();

// Auto-waits for condition
await expect(page.getByText("Success")).toBeVisible();
```

### Explicit Waits (When Needed)

```typescript
// Wait for navigation
await page.waitForURL("**/dashboard");

// Wait for network idle
await page.waitForLoadState("networkidle");

// Wait for specific response
await page.waitForResponse((resp) => resp.url().includes("/api/data"));
```

## Network Mocking

### Mock API Responses

```typescript
await page.route("**/api/users", async (route) => {
  await route.fulfill({
    status: 200,
    contentType: "application/json",
    body: JSON.stringify([{ id: 1, name: "Test User" }]),
  });
});

// Mock error response
await page.route("**/api/users", async (route) => {
  await route.fulfill({ status: 500 });
});
```

### Intercept and Modify

```typescript
await page.route("**/api/data", async (route) => {
  const response = await route.fetch();
  const json = await response.json();
  json.modified = true;
  await route.fulfill({ response, json });
});
```

## CI/CD Integration

### GitHub Actions Example

```yaml
- name: Run Playwright tests
  run: npx playwright test
  env:
    CI: true

- name: Upload test results
  if: always()
  uses: actions/upload-artifact@v3
  with:
    name: playwright-report
    path: playwright-report/
```

### Parallel Execution

```typescript
// playwright.config.ts
export default defineConfig({
  workers: process.env.CI ? 2 : undefined,
  fullyParallel: true,
});
```

## Debugging Failed Tests

### Debug Tools

```bash
# Run with UI mode
npx playwright test --ui

# Run with inspector
npx playwright test --debug

# Show browser
npx playwright test --headed
```

### Trace Viewer

```typescript
// playwright.config.ts
use: {
  trace: 'on-first-retry', // Capture trace on failure
}
```

## Flaky Test Fixes

### Common Causes and Solutions

**Race conditions:**

- Use proper assertions instead of hard waits
- Wait for network requests to complete

**Animation issues:**

- Disable animations in test config
- Wait for animation to complete

**Dynamic content:**

- Use flexible locators (text content, not position)
- Wait for loading states to resolve

**Test isolation:**

- Each test should set up its own state
- Don't depend on other tests' side effects

### Anti-Patterns to Avoid

```typescript
// Bad: Hard sleep
await page.waitForTimeout(5000);

// Good: Wait for condition
await expect(page.getByText("Loaded")).toBeVisible();

// Bad: Flaky selector
await page.locator(".btn:nth-child(3)").click();

// Good: Semantic selector
await page.getByRole("button", { name: "Submit" }).click();
```

## Responsive Design Testing

For comprehensive responsive testing across viewport breakpoints, use the **responsive-tester** agent. It automatically:

- Tests pages across 7 standard breakpoints (375px to 1536px)
- Detects horizontal overflow issues
- Verifies mobile-first design patterns
- Checks touch target sizes (44x44px minimum)
- Flags anti-patterns like fixed widths without mobile fallback

Trigger it by asking to "test responsiveness", "check breakpoints", or "test mobile/desktop layout".
playwright-testing | SkillHub