testing · git:20261029.1aa6bef · 2026-10-29 · sha256 235ec247df4601d0
testing git:20261029.1aa6befA
Immutable. This exact content never changes and is served at /api/v1/blob/235ec247df4601d0.
---
description: Test-Driven Development (TDD) discipline, Vitest, Jest, Playwright E2E with accessible locators, MSW contract tests, and mutation testing principles.
globs: *
alwaysApply: false
---
# Test-Driven Discipline, Playwright E2E & Mutation QA (`/testing`)
> **Philosophy**: *Untested code is broken by design. Write failing characterization tests before refactoring. Ban fragile CSS selectors in E2E tests—use accessible roles and semantic labels. Ban hardcoded sleep timers—use auto-waiting web-first assertions. Aim for 80%+ line and branch coverage.*
This skill establishes automated testing discipline across **Vitest**, **Jest**, **Playwright**, **Cypress**, and **Mock Service Worker (MSW)**.
---
## 1. Quick Navigation & Progressive Disclosure
| Resource Type | Document | Description |
| :--- | :--- | :--- |
| **Reference** | [references/playwright-accessible-locators.md](references/playwright-accessible-locators.md) | Accessible locator hierarchy, web-first assertions, zero sleep timeouts. |
| **Reference** | [references/tdd-and-msw-contracts.md](references/tdd-and-msw-contracts.md) | Red-Green-Refactor cycle, MSW network interception handlers, fixture isolation. |
| **Utility** | [scripts/verify_testing_hygiene.py](scripts/verify_testing_hygiene.py) | Audits tests for brittle XPath/class selectors, hardcoded sleep calls, and unisolated state. |
---
## 2. The Core Testing Discipline Gates
```mermaid
flowchart TD
A["Feature / Bug Fix Request"] --> B["Gate 1: TDD Red Phase (Failing test asserting expected behavior)"]
B --> C["Gate 2: Green Phase (Minimal production code to pass)"]
C --> D["Gate 3: Refactor Phase (Clean code under 500-line ceiling)"]
D --> E["Gate 4: Playwright E2E (Accessible Locators & Web-First Assertions)"]
E --> F["Gate 5: Coverage & Mutation Sweep (80%+ branch coverage, zero sleep timers)"]
```
1. **Gate 1: Test-Driven Red Phase**: Author unit/contract tests asserting the required behavior before modifying production files.
2. **Gate 2: Accessible E2E Locators**: In Playwright or Cypress, strictly prohibit internal class or DOM selectors (`div > button.btn-12`). Use user-facing accessible locators: `page.getByRole('button', { name: 'Save' })`, `page.getByLabel('Email')`.
3. **Gate 3: Zero Hardcoded Sleep Timers**: Prohibit `page.waitForTimeout()` or `time.sleep()`. Use Playwright web-first assertions (`await expect(locator).toBeVisible()`) that automatically retry until timeout.
4. **Gate 4: Mock Service Worker (MSW)**: Mock network requests at the HTTP transport layer using MSW handlers rather than stubbing internal class methods.
5. **Gate 5: Deterministic Test Isolation**: Every test must run in isolation with ephemeral database transactions or clean fixtures. Tests must never share mutable global state.
---
## 2. Resilient Playwright E2E Test (TypeScript)
```typescript
import { test, expect } from "@playwright/test";
test.describe("User Authentication Flow", () => {
test("successfully signs in with valid credentials and redirects to dashboard", async ({ page }) => {
await page.goto("/login");
// ✅ DEFENSIVE: Accessible user-facing locators
await page.getByLabel("Email Address").fill("developer@skillbuilder.io");
await page.getByLabel("Password").fill("SuperSecretPass123!");
await page.getByRole("button", { name: "Sign In" }).click();
// ✅ DEFENSIVE: Web-first assertion (auto-retries, zero arbitrary sleep)
await expect(page).toHaveURL("/dashboard");
await expect(page.getByRole("heading", { name: "Workspace Overview" })).toBeVisible();
await expect(page.getByText("Welcome back, Developer")).toBeVisible();
});
});
```
---
## 3. Vitest Unit Test with Mock Service Worker (TypeScript)
```typescript
import { describe, it, expect, beforeAll, afterEach, afterAll } from "vitest";
import { setupServer } from "msw/node";
import { http, HttpResponse } from "msw";
import { fetchProjects } from "./projectClient";
const server = setupServer(
http.get("https://api.skillbuilder.io/v1/projects", () => {
return HttpResponse.json([
{ id: "proj_1", name: "Telemetry Engine", status: "active" }
]);
})
);
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
describe("fetchProjects client", () => {
it("fetches and deserializes active projects cleanly", async () => {
const projects = await fetchProjects();
expect(projects).toHaveLength(1);
expect(projects[0].name).toBe("Telemetry Engine");
});
});
```
---
## 4. Testing Hygiene Verification CLI
Audit your test suites for fragile CSS selectors and arbitrary sleep timers:
```bash
python3 skills/testing/scripts/verify_testing_hygiene.py --path . --strict
```
Audited Rules:
- `TESTING-ARBITRARY-SLEEP-TIMER`: Flags `waitForTimeout()` or `time.sleep()` in test suites.
- `TESTING-FRAGILE-CSS-SELECTOR`: Flags non-semantic DOM/CSS selectors in E2E tests (`page.click('div.btn-blue')`).
- `TESTING-EMPTY-ASSERTIONS`: Flags test blocks with zero assertions or `expect()` calls.