agentsclimarketplace

Playwright api fixtures cleanup

Skill kjuhwa/skills-hub/skills/testing/playwright-api-fixtures-cleanup

Self-contained Playwright E2E tests using a TestApiClient fixture that creates entities over HTTP and tears them down in afterEach — no shared DB seed, no cross-test pollution.From its SKILL.md

Install
npx -y skills add kjuhwa/skills-hub --skill playwright-api-fixtures-cleanup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.4 KB, 707 tokens by cl100k_base, as published. Nobody here has run it

When to use

  • Multi-user / multi-tenant app with an HTTP API.
  • You want E2E tests to run against a real backend, in parallel, without step-on-toes failures.
  • You're tired of beforeAll migration/seed scripts that get out of sync with app behavior.

Steps

  1. Build a TestApiClient class that:
    • Logs in as a fixed test user (dev verification code in non-prod).
    • Tracks every entity it creates (issues, workspaces, comments).
    • Exposes cleanup() to delete them all.
    export class TestApiClient {
      private token: string | null = null;
      private createdIssues: string[] = [];
      async login(email: string, name: string) {
        await fetch(`${API}/auth/send-code`, { method: "POST", body: JSON.stringify({ email }) });
        const r = await fetch(`${API}/auth/verify-code`, { method: "POST", body: JSON.stringify({ email, code: "888888" }) });
        this.token = (await r.json()).token;
      }
      async createIssue(title: string): Promise<Issue> {
        const r = await fetch(`${API}/api/issues`, { method: "POST", headers: { Authorization: `Bearer ${this.token}` }, body: JSON.stringify({ title }) });
        const issue = await r.json();
        this.createdIssues.push(issue.id);
        return issue;
      }
      async cleanup() {
        for (const id of this.createdIssues) {
          await fetch(`${API}/api/issues/${id}`, { method: "DELETE", headers: { Authorization: `Bearer ${this.token}` } });
        }
      }
      getToken() { return this.token!; }
    }
    
  2. Expose helpers that combine login + workspace scaffolding:
    export async function loginAsDefault(page: Page): Promise<string> {
      const api = new TestApiClient();
      await api.login(E2E_EMAIL, E2E_NAME);
      const ws = await api.ensureWorkspace("E2E Workspace", "e2e-workspace");
      await page.goto("/login");
      await page.evaluate(t => localStorage.setItem("app_token", t), api.getToken());
      await page.goto(`/${ws.slug}/issues`);
      return ws.slug;
    }
    
  3. Use in each spec:
    let api: TestApiClient;
    test.beforeEach(async ({ page }) => {
      api = await createTestApi();
      await loginAsDefault(page);
    });
    test.afterEach(() => api.cleanup());
    
    test("create and view issue", async ({ page }) => {
      const issue = await api.createIssue("Test Issue");
      await page.goto(`/issues/${issue.id}`);
      await expect(page.getByText("Test Issue")).toBeVisible();
    });
    

Example

See the source repo's e2e/helpers.ts and e2e/fixtures.ts.

Caveats

  • cleanup() should tolerate already-deleted entities (404s from earlier cleanup paths or cascading deletes are fine).
  • Don't share the TestApiClient across parallel tests — each gets its own via beforeEach.
  • The dev-master verification code (e.g. 888888) must only work in non-production builds; see the "verification-code-dev-master" knowledge entry.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.