跳到正文
cccskills
免费在 GitHub 公开

testing-library

Test UI components the way users interact with them using Testing Library — query by role, text, and label instead of implementation details. Use when someone asks to "test React components", "Testing Library", "user-centric testing", "test accessibility", "test without implementation details", or "render and query components in tests". Covers React Testing Library, queries, user events, async testing, and accessibility assertions.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md6.5 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Testing Library

Overview

Testing Library tests UI components from the user's perspective — find elements by their accessible role, text content, or label, not by CSS class or test ID. If a user can't find a button, your test shouldn't find it either. This approach catches accessibility issues by default, survives refactors (rename a CSS class and tests still pass), and produces tests that actually prove the UI works.

When to Use

  • Testing React/Vue/Svelte components
  • Want tests that survive refactoring (no CSS selectors or internal state checks)
  • Need to verify accessibility (ARIA roles, labels)
  • Testing user interactions (clicks, typing, form submission)
  • Integration testing of component behavior (not snapshot testing)

Instructions

Setup

npm install -D @testing-library/react @testing-library/jest-dom @testing-library/user-event
# For Vitest:
npm install -D @testing-library/react vitest happy-dom
// vitest.config.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    environment: "happy-dom",
    setupFiles: ["./tests/setup.ts"],
  },
});
// tests/setup.ts — Global test setup
import "@testing-library/jest-dom/vitest";

Query Priority

Testing Library has a priority order for queries — use the highest priority that works:

// Priority 1: Accessible roles (best — tests accessibility too)
screen.getByRole("button", { name: "Submit" });
screen.getByRole("textbox", { name: "Email" });
screen.getByRole("heading", { level: 1 });

// Priority 2: Label text (forms)
screen.getByLabelText("Email address");

// Priority 3: Placeholder text
screen.getByPlaceholderText("Search...");

// Priority 4: Text content
screen.getByText("Welcome back!");

// Priority 5: Display value
screen.getByDisplayValue("user@example.com");

// Priority 6: Alt text (images)
screen.getByAltText("Company logo");

// Last resort: test IDs (avoid if possible)
screen.getByTestId("complex-widget");

Testing Component Behavior

// LoginForm.test.tsx — Test a login form from the user's perspective
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { LoginForm } from "./LoginForm";

describe("LoginForm", () => {
  it("submits the form with email and password", async () => {
    const onSubmit = vi.fn();
    const user = userEvent.setup();

    render(<LoginForm onSubmit={onSubmit} />);

    // Find elements by their accessible role/label
    await user.type(screen.getByLabelText("Email"), "kai@example.com");
    await user.type(screen.getByLabelText("Password"), "secret123");
    await user.click(screen.getByRole("button", { name: "Sign in" }));

    expect(onSubmit).toHaveBeenCalledWith({
      email: "kai@example.com",
      password: "secret123",
    });
  });

  it("shows validation error for invalid email", async () => {
    const user = userEvent.setup();
    render(<LoginForm onSubmit={vi.fn()} />);

    await user.type(screen.getByLabelText("Email"), "not-an-email");
    await user.click(screen.getByRole("button", { name: "Sign in" }));

    expect(screen.getByRole("alert")).toHaveTextContent("Invalid email address");
  });

  it("disables submit while loading", async () => {
    render(<LoginForm onSubmit={() => new Promise(() => {})} />);
    const user = userEvent.setup();

    await user.type(screen.getByLabelText("Email"), "kai@example.com");
    await user.type(screen.getByLabelText("Password"), "secret123");
    await user.click(screen.getByRole("button", { name: "Sign in" }));

    expect(screen.getByRole("button", { name: /signing in/i })).toBeDisabled();
  });
});

Async Testing

// UserProfile.test.tsx — Testing async data fetching
import { render, screen, waitFor } from "@testing-library/react";
import { UserProfile } from "./UserProfile";

it("loads and displays user data", async () => {
  render(<UserProfile userId="123" />);

  // Loading state
  expect(screen.getByText("Loading...")).toBeInTheDocument();

  // Wait for data to load
  await waitFor(() => {
    expect(screen.getByRole("heading")).toHaveTextContent("Kai Chen");
  });

  expect(screen.getByText("kai@example.com")).toBeInTheDocument();
});

it("shows error state on failure", async () => {
  // Mock API failure
  server.use(http.get("/api/users/123", () => HttpResponse.error()));

  render(<UserProfile userId="123" />);

  await waitFor(() => {
    expect(screen.getByRole("alert")).toHaveTextContent("Failed to load");
  });
});

Examples

Example 1: Test a complex form with validation

User prompt: "Write tests for a multi-step registration form with validation."

The agent will write tests that fill each step from the user's perspective, verify validation errors appear on invalid input, and confirm successful submission.

Example 2: Test an accessible data table

User prompt: "Test a sortable data table — verify sorting, filtering, and pagination work."

The agent will query table headers by role, click to sort, verify row order changes, type into filter input, and navigate pages.

Guidelines

  • Query by role first — getByRole tests accessibility for free
  • userEvent over fireEvent — simulates real user behavior (focus, type, blur)
  • userEvent.setup() at test start — creates a user instance for the test
  • waitFor for async — wait for elements to appear after data fetching
  • Avoid getByTestId — if you need it, the component might have accessibility issues
  • screen is global — no need to destructure render result
  • toBeInTheDocument() from jest-dom — readable assertions
  • Don't test implementation — state values, effect triggers, re-render counts
  • Test behavior, not structure — "user sees error" not "error div has class active"

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Audit web pages and components for WCAG 2.2 accessibility compliance. Use when a user asks to check accessibility, find a11y issues, audit for WCAG compliance, fix screen reader problems, check color contrast, ensure keyboard navigation works, or prepare for accessibility regulations like the European Accessibility Act or ADA.

中文简介正在准备中。当前显示原文说明。

jaem1n207/synchronize-tab-scrolling192026年10月19日 更新

Perform thorough code reviews with actionable, prioritized feedback. Use when a user asks to review code, check code quality, find bugs, review a pull request, audit code for issues, or get feedback on implementation. Covers correctness, security, performance, readability, and best practices across languages.

中文简介正在准备中。当前显示原文说明。

jaem1n207/synchronize-tab-scrolling192026年10月19日 更新

eslint

免费

ESLint is the standard linting tool for JavaScript and TypeScript projects. It statically analyzes your code to find problems, enforce coding conventions, and catch bugs before they reach production. ESLint 9 introduced the flat config format, replacing the legacy `.eslintrc` system with a simpler, more composable `eslint.config.js` file. With a rich plugin ecosystem covering React, TypeScript, accessibility, and import ordering, ESLint is the backbone of code quality in modern web development.

中文简介正在准备中。当前显示原文说明。

jaem1n207/synchronize-tab-scrolling192026年10月19日 更新

Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.

中文简介正在准备中。当前显示原文说明。

jaem1n207/synchronize-tab-scrolling192026年10月19日 更新

github

免费

GitHub patterns using gh CLI for pull requests, stacked PRs, code review, branching strategies, and repository automation. Use when working with GitHub PRs, merging strategies, or repository management tasks.

中文简介正在准备中。当前显示原文说明。

jaem1n207/synchronize-tab-scrolling192026年10月19日 更新

GitHub Actions workflow patterns for React Native iOS simulator and Android emulator cloud builds with downloadable artifacts. Use when setting up CI build pipelines or downloading GitHub Actions artifacts via gh CLI and GitHub API.

中文简介正在准备中。当前显示原文说明。

jaem1n207/synchronize-tab-scrolling192026年10月19日 更新

查看 jaem1n207 的全部技能

报告此技能的问题