원클릭으로
project-testing
Test framework, fixtures, and patterns for the mcp-test-client project. MUST be followed for any test work in this repo.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Test framework, fixtures, and patterns for the mcp-test-client project. MUST be followed for any test work in this repo.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
Review discipline for the mcp-test-client project — when to spawn the UX critic / spec purist / accessibility auditor / cross-model reviewers, what each must check, and how to act on findings. MUST be followed for any review of code (yours or others') in this repo.
Operating discipline of the mcp-test-client maintainer — identity, mode discipline, value-driven judgment, framework two-step ship, feedback folding, agents roster. Read at the start of every session. MUST be followed for every non-trivial action in this repo.
TypeScript / React 19 / Mantine v9 coding conventions for the mcp-test-client project, derived from observed patterns. MUST be followed for all code changes in this repo.
SOC 직업 분류 기준
| name | project-testing |
| description | Test framework, fixtures, and patterns for the mcp-test-client project. MUST be followed for any test work in this repo. |
How testing actually works in this codebase. Cite this skill from the SOW's Validation section (real-use evidence + acceptance evidence). If a pattern below doesn't fit a new test, document the divergence in the SOW's Execution log and update this skill as part of mandate 4 (retrospection on close).
package.json)vitest run / vitest)vitest.config.ts:8)@playwright/test) — e2e on Chromium only.
Firefox + WebKit projects are declared but testIgnore: /.*/ (see
playwright.config.ts:30,34) — opt in with --project=firefox|webkit
if a test asks for it.src/foo/bar.tsx → src/foo/bar.test.tsx
(or .test.ts for pure helpers). Vitest discovers
src/**/*.{test,spec}.{ts,tsx} (vitest.config.ts:11).tests/conformance/**/* and
tests/compliance/**/* — MCP wire-spec tests; same vitest runner
(vitest.config.ts:13-14).tests/e2e/*.spec.ts — Playwright. Excluded from vitest
discovery (vitest.config.ts:16).tests/fixtures/mock-mcp-server/run.ts — Node mock MCP
server on port 4321, started via node --experimental-strip-types and
spawned automatically by Playwright's webServer (playwright.config.ts:47-55).tests/setup/vitest.setup.ts — runs once per file
(vitest.config.ts:9); installs jest-dom matchers + browser-API stubs.happy-dom + jsdom in vitest 4 don't reliably expose window.localStorage.
The setup file installs a MemoryLocalStorage class
(tests/setup/vitest.setup.ts:9-43). Persistence-layer tests use a
separate MemoryStorage exported from
src/persistence/store.test.ts:6-46 (note: the test file exports a
helper that other tests import — this is the canonical pattern).
For component tests that touch the persistence store, swap the live storage via the test hook:
import { __setStorageForTests } from '../state/store-instance.ts';
import { MemoryStorage } from '../persistence/store.test.ts';
beforeEach(() => {
__setStorageForTests(new MemoryStorage());
});
(see src/ui/log-panel.test.tsx:17-39)
The setup file polyfills three Mantine dependencies that happy-dom
lacks (tests/setup/vitest.setup.ts:44-87): document.fonts,
ResizeObserver, window.matchMedia. Do not re-stub these per-test.
Every component test wraps the tree in <MantineProvider> +
<Notifications/>. Components fail at render with cryptic useTheme
errors otherwise. Reference: src/ui/log-panel.test.tsx:20-27. Use a
local Wrapper component or a renderWithMantine() helper at the top
of the file.
For components that consume context (e.g. useLog()), embed a
<TestDriver onReady={...}> child that captures the context API into a
ref, so the test can drive state imperatively via act():
function TestDriver({ onReady }: { onReady: (ctx: ReturnType<typeof useLog>) => void }) {
const ctx = useLog();
onReady(ctx);
return null;
}
(see src/ui/log-panel.test.tsx:29-56). Then act(() => h.api.appendWire(...))
in the test body to push events into the component without a real
network round-trip.
tests/fixtures/mock-mcp-server/run.ts is the e2e fixture. It exposes
two tools (echo, add) on http://127.0.0.1:4321/mcp with a
/health endpoint Playwright polls. Do not mock the MCP SDK
itself — the SDK's surface is large and brittle to mock. Real fixture +
real wire = test signal that survives SDK upgrades.
text + html + lcov (vitest.config.ts:18-19)src/**/*.{ts,tsx}; exclude: test files, src/main.tsx,
*.d.ts (vitest.config.ts:20-21)package.json:26-30)npm test — vitest single run (CI mode); the SOW Test step runs thisnpm run test:watch — vitest in watch modenpm run test:coverage — vitest + v8 coverage reportnpm run test:e2e — Playwright; auto-spawns dev server on :5173 + mock
MCP on :4321 (playwright.config.ts:39-56)npm run test:e2e:install — playwright install --with-deps (first run).agents/skills/project-maintainer/release-readiness.md makes "you used it for real"
non-negotiable. For SOW Validation evidence, this project has two
acceptable proofs and one disqualified proof:
https://ktsaou.github.io/mcp-test-client/.
Spawn a UX-critic agent with mcp__playwright_headless__* tools
(note: brief the critic to use _evaluate + _snapshot for evidence,
not _take_screenshot — the screenshot pipeline has had API-400
failures in the past, see feedback-folding.md DEC-029 lesson).feedback-folding.md 2026-04-26).After tagging, also curl the deployed index-*.js filename or check
GH Pages workflow status before claiming "shipped".
src/ui/log-headline.test.ts. describe per public
function, it.each([...]) for table-driven cases, no DOM, no Mantine.src/ui/log-panel.test.tsx. Wrapper +
TestDriver + act() to drive events; screen.getByLabelText /
getByRole for assertions; within(row) to scope per-row queries.src/persistence/store.test.ts. Uses
MemoryStorage (exported from this same file), vi.fn() for error
sinks, failNextWrite() test hook to simulate quota errors.tests/e2e/smoke.spec.ts. beforeEach clears
localStorage and reloads; matches by placeholder not label
(Mantine renders required-field labels with " *" suffix); waits up to
15 s for the MCP handshake.tests/e2e/log-row-alignment.spec.ts.
Uses getBoundingClientRect() evaluated in the page context across
multiple viewport widths; defines an explicit assertAligned() helper
with a tolerance constant; verifies a DEC's named falsifier
(DEC-014's right-edge alignment under squeeze).useTheme
errors at render.feedback-folding.md 2026-04-25
Ajv-silencing lesson; the global memory entry on this echoes the same
rule).testIgnore'd for a stated reason (browser-specific locator quirks). * to required labels). See smoke.spec.ts:18.AGENTS.md requires this.log-row-alignment.spec.ts
is the model — the DEC's falsifier becomes the test's assertion
message.(Append date — what happened — guardrail rows here as testing-related
issues surface. Empty until the first lesson is folded in.)