Install
Terminal · npx$
npx skills add https://github.com/sergiodxa/agent-skills --skill frontend-testing-best-practicesWorks with Paperclip
How Frontend Testing Best Practices fits into a Paperclip company.
Frontend Testing Best Practices drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.
S
SaaS FactoryPaired
Pre-configured AI company — 18 agents, 18 skills, one-time purchase.
$27$59
Explore packSource file
SKILL.md160 linesExpandCollapse
---name: frontend-testing-best-practicesdescription: 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.--- # Testing Best Practices Guidelines for writing effective, maintainable tests that provide real confidence. Contains 6 rules focused on preferring E2E tests, minimizing mocking, and testing behavior over implementation. ## Core Philosophy 1. **Prefer E2E tests over unit tests** - Test the whole system, not isolated pieces2. **Minimize mocking** - If you need complex mocks, write an E2E test instead3. **Test behavior, not implementation** - Test what users see and do4. **Avoid testing React components directly** - Test them through E2E ## When to Apply Reference these guidelines when: - Deciding what type of test to write- Writing new E2E or unit tests- Reviewing test code- Refactoring tests ## Rules Summary ### Testing Strategy (CRITICAL) #### prefer-e2e-tests - @rules/prefer-e2e-tests.md Default to E2E tests. Only write unit tests for pure functions. ```typescript// E2E test (PREFERRED) - tests real user flowtest("user can place an order", async ({ page }) => { await createTestingAccount(page, { account_status: "active" }); await page.goto("/catalog"); await page.getByRole("heading", { name: "Example Item" }).click(); await page.getByRole("link", { name: "Buy" }).click(); // ... complete flow await expect(page.getByAltText("Thank you")).toBeVisible();}); // Unit test - ONLY for pure functionstest("formatCurrency formats with two decimals", () => { expect(formatCurrency(1234.5)).toBe("$1,234.50");});``` #### avoid-component-tests - @rules/avoid-component-tests.md Don't unit test React components. Test them through E2E or not at all. ```typescript// BAD: Component unit testdescribe("OrderCard", () => { test("renders amount", () => { render(<OrderCard amount={100} />); expect(screen.getByText("$100")).toBeInTheDocument(); });}); // GOOD: E2E test covers the component naturallytest("order history shows orders", async ({ page }) => { await page.goto("/orders"); await expect(page.getByText("$100")).toBeVisible();});``` #### minimize-mocking - @rules/minimize-mocking.md Keep mocks simple. If you need 3+ mocks, write an E2E test instead. ```typescript// BAD: Too many mocks = write E2E testvi.mock("~/lib/auth");vi.mock("~/lib/transactions");vi.mock("~/hooks/useAccount"); // GOOD: Simple MSW mock for loader testmockServer.use( http.get("/api/user", () => HttpResponse.json({ name: "John" })),);``` ### E2E Tests (HIGH) #### e2e-test-structure - @rules/e2e-test-structure.md E2E tests go in `e2e/tests/`, not `frontend/`. ```typescript// e2e/tests/order.spec.tsimport { test, expect } from "@playwright/test";import { addAccountBalance, createTestingAccount } from "./utils"; test.describe("Orders", () => { test.beforeEach(async ({ page, context }) => { await createTestingAccount(page, { account_status: "active" }); let cookies = await context.cookies(); let account_id = cookies.find((c) => c.name === "account_id").value; await addAccountBalance({ account_id, amount: 10000, replaceBalance: true }); }); test("place order with default values", async ({ page }) => { await page.goto("/catalog"); // ... user flow });});``` #### e2e-selectors - @rules/e2e-selectors.md Use accessible selectors: role > label > text > testid. ```typescript// GOOD: Role-based (preferred)await page.getByRole("button", { name: "Submit" }).click();await page.getByRole("heading", { name: "Dashboard" }); // GOOD: Label-basedawait page.getByLabel("Email").fill("test@example.com"); // OK: Test ID when no accessible selector existsawait expect(page.getByTestId("balance")).toHaveText("$1,234"); // BAD: CSS selectorsawait page.locator(".btn-primary").click();``` ### Unit Tests (MEDIUM) #### unit-test-structure - @rules/unit-test-structure.md Unit tests for pure functions only. Co-locate with source files. ```typescript// app/utils/format.test.tsimport { describe, test, expect } from "vitest";import { formatCurrency } from "./format"; describe("formatCurrency", () => { test("formats positive amounts", () => { expect(formatCurrency(1234.5)).toBe("$1,234.50"); }); test("handles zero", () => { expect(formatCurrency(0)).toBe("$0.00"); });});``` ## Key Files - `e2e/tests/` - E2E tests (Playwright)- `e2e/tests/utils.ts` - E2E test utilities- `vitest.config.ts` - Unit test configuration- `vitest.setup.ts` - Global test setup with MSW- `app/utils/test-utils.ts` - Unit test utilitiesRelated skills