All skills
sergiodxa avatar

/frontend-testing-best-practices

@4d1d816

Testing best practices for the frontend. Emphasizes E2E tests over unit tests, minimal mocking, and testing behavior over implementation details. Use when writing tests or reviewing test code.

Use this Skill: https://skilld.dev/gh/sergiodxa/agent-skills/frontend-testing-best-practices

This session only. Nothing lands on disk.

rulese2e-selectors.md

≈796 tokens on demand. Your agent reads this file only when SKILL.md points to it.

E2E Test Selectors

Use accessible queries and data-testid for reliable element selection.

Selector Priority

Prefer selectors in this order (most to least preferred):

  1. Role-based - getByRole("button", { name: "Submit" })
  2. Label-based - getByLabel("Email")
  3. Text-based - getByText("Welcome")
  4. Test ID - getByTestId("balance")

Role-Based Selectors (Preferred)

// Buttons
await page.getByRole("button", { name: "Submit" }).click();
await page.getByRole("button", { name: /submit/i }).click(); // Case insensitive

// Links
await page.getByRole("link", { name: "Home" }).click();

// Headings
await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();

// Form elements
await page.getByRole("textbox", { name: "Email" }).fill("test@example.com");
await page.getByRole("checkbox", { name: "Accept terms" }).check();
await page.getByRole("combobox", { name: "Country" }).selectOption("US");

Label-Based Selectors

// Form inputs by label
await page.getByLabel("Email").fill("test@example.com");
await page.getByLabel("Password").fill("secret123");

// Partial match
await page.getByLabel(/email/i).fill("test@example.com");

Text-Based Selectors

// Exact text
await page.getByText("Welcome back").click();

// Partial/regex
await page.getByText(/welcome/i).click();

// Within a container
await page.locator(".card").getByText("Details").click();

Test ID Selectors (When Needed)

Use data-testid when:

  • Element has no accessible name
  • Multiple similar elements exist
  • Testing specific values (like balance display)
// In component
<span data-testid="balance">${balance}</span>;

// In test
await expect(page.getByTestId("balance")).toHaveText("$1,234.56");

Bad Selectors

// Bad: fragile CSS selectors
await page.locator(".btn-primary").click();
await page.locator("#submit-button").click();
await page.locator("form > div:nth-child(2) > button").click();

// Bad: implementation details
await page.locator("[class*='Button_primary']").click();

Combining Selectors

// Filter within results
await page
  .getByRole("listitem")
  .filter({ hasText: "Red Cross" })
  .getByRole("button", { name: "Donate" })
  .click();

// Within a specific region
await page
  .getByRole("region", { name: "Order history" })
  .getByRole("row")
  .first()
  .click();

Waiting for Elements

// Wait for element to be visible
await expect(page.getByRole("heading", { name: "Success" })).toBeVisible();

// Wait for element to disappear
await expect(page.getByText("Loading...")).not.toBeVisible();

// Wait for specific count
await expect(page.getByRole("listitem")).toHaveCount(5);

Rules

  1. Prefer role-based selectors - they test accessibility too
  2. Use label selectors for form inputs
  3. Use data-testid only when no accessible selector exists
  4. Never use CSS class or generated ID selectors
  5. Use filter() to narrow down multiple matches
  6. Always use await expect() for assertions

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides a set of best practices and guidelines for frontend testing, focusing on E2E tests with Playwright and unit tests with Vitest. No security issues were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    7 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 4d1d816. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago
  • Testing
  • React
  • e2e-testing
  • playwright
  • vitest
  • behavior-testing
  • mocking
  • unit-tests
  • test-strategy

README badge

README badge for sergiodxa/agent-skills/frontend-testing-best-practices

Provides guidelines for frontend testing that prioritize end-to-end tests over unit tests, minimize mocking, and test user behavior rather than implementation details. Use when writing or reviewing test code for web applications built with Playwright and Vitest.

Generated from the current SKILL.md.

When should I write unit tests vs E2E tests?
Default to E2E tests for user workflows and features. Only write unit tests for pure functions. If you need 3 or more mocks for a unit test, write an E2E test instead.
Should I test React components directly?
No. Test components through E2E tests that exercise them in a real user flow, rather than isolated component unit tests.
What selectors should I use in E2E tests?
Prefer accessible selectors in this order: role-based (getByRole), label-based (getByLabel), text-based, then test IDs. Avoid CSS selectors.
What testing tools does this skill assume?
E2E tests use Playwright, unit tests use Vitest. MSW (Mock Service Worker) is used for simple API mocking.

Generated from the current SKILL.md. These answers refresh after source changes.