React testing
Skill aps08/fullstack-clean-architecture/.agents/skills/react_testing
Read to code, just run Docker compose.
npx -y skills add aps08/fullstack-clean-architecture --skill react_testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 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.
What its author says it does
Copied from the file, not written here
Frontend testing standards using Vitest, React Testing Library, and Playwright. Use when writing UI tests.
SKILL.md
3.6 KB, as published. Nobody here has run it
React Testing Skill
Testing Tools
- Use
Vitestas the primary test runner. - Use
@testing-library/reactfor component behavior testing. - Use
Playwrightfor all End-to-End (E2E) testing.
Directory Structure
All test files are located under web/tests/ and are organized as follows:
tests/unit/: Contains unit tests testing components, hooks, features, and utils in isolation using Vitest and React Testing Library.tests/e2e/: Contains end-to-end integration tests that run in a browser using Playwright.tests/mocks/: Contains mocks for external integrations or APIs.tests/fixtures/: Contains reusable test fixtures or data.tests/test_utils.tsx: Contains common testing utilities, such as a customrenderwrapper.
Standards & Best Practices
- Test user interactions rather than implementation details.
- Ensure all tests are isolated and don't depend on global state.
- No Comments Needed: No need to add comments inside any of the test code (like
// Arrange,// Act,// Assert). Thetestoritdescription strings are enough to explain the test logic. - Code Coverage: Ensure test coverage is strictly more than 80% of the lines.
- Mocking: Use
vi.fn()for mock functions andvi.mock()for module mocks in Vitest.
Example: Unit Test (Vitest + Testing Library)
import { fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { ArchiveCard } from "@/components/ArchiveCard";
const todo = {
id: "todo-1",
title: "Old Project Notes",
isCompleted: false,
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-03-01T00:00:00Z",
};
describe("ArchiveCard", () => {
it("renders the todo title", () => {
render(<ArchiveCard todo={todo} onRestore={vi.fn()} onDelete={vi.fn()} />);
expect(screen.getByText("Old Project Notes")).toBeInTheDocument();
});
it("calls onRestore with the todo id when Restore is clicked", () => {
const onRestore = vi.fn();
render(
<ArchiveCard todo={todo} onRestore={onRestore} onDelete={vi.fn()} />,
);
fireEvent.click(screen.getByRole("button"));
fireEvent.click(screen.getByText("Restore"));
expect(onRestore).toHaveBeenCalledWith("todo-1");
});
});
Example: E2E Test (Playwright)
import { expect, test } from "@playwright/test";
const API = process.env.API_URL || "http://localhost:8000";
const TEST_PASSWORD = "securepassword123";
test.describe("Sign Up Flow", () => {
test.afterAll(async ({ request }, testInfo) => {
const email = `e2e_signup_w${testInfo.workerIndex}@example.com`;
const res = await request.post(`${API}/v1/auth/signin`, {
data: { email, password: TEST_PASSWORD },
});
if (res.ok()) {
await request.delete(`${API}/v2/user/me`);
}
});
test("User can sign up successfully and is redirected to sign in", async ({
page,
}, testInfo) => {
const email = `e2e_signup_w${testInfo.workerIndex}@example.com`;
await page.goto("/");
await page
.getByRole("button", { name: "Sign up", exact: true })
.first()
.click();
await page.getByPlaceholder("[email protected]").fill(email);
await page.getByPlaceholder("••••••••").fill(TEST_PASSWORD);
await page.locator('button[type="submit"]').click();
await expect(page.getByText("Account created!")).toBeVisible();
await expect(page.locator('button[type="submit"]')).toHaveText(/Sign in/i);
});
});