一键导入
test-create-fixture
Create HTML test fixture for UI components. Uses project templates to create isolated test pages for TDD validation.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create HTML test fixture for UI components. Uses project templates to create isolated test pages for TDD validation.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Merges bookend agent reports into revised readiness, complexity, and decomposition plan. Produces the final evidence-backed assessment consumed by sprint-architect-agent.
Fast filesystem readiness scan — counts docs, source files, manifests, platform signals. Produces initial ReadinessReport for agent spawning decisions.
Scores proposal complexity against codebase surface. Uses proposal text analysis and readiness stats to determine decomposition tier and agent count.
Generation-time design taste for web UI work. Anti-cliche bans, layout and motion hard rules, and client-intent dials. Advisory only - shapes drafts; declared measured contracts remain the sole gate authority.
Rigorously reasons about definitions, proofs, and computations in algebra, analysis, discrete math, probability, linear algebra, and applied math. Verifies derivations, spots invalid steps, and states assumptions clearly. Use when solving or proving math problems, reviewing mathematical arguments, modeling with equations, interpreting statistics, or when the user mentions proofs, lemmas, theorems, integrals, series, matrices, optimization, or numerical methods.
Visual verification for interactive elements (popups, modals, tooltips). Clicks elements and captures screenshots for analysis. Bypasses MCP browser tool limitations with cross-origin CSS.
| name | test-create-fixture |
| description | Create HTML test fixture for UI components. Uses project templates to create isolated test pages for TDD validation. |
Creates HTML test fixture files for UI components. Used by dev agents during TDD to create isolated test pages before implementation.
{
"project_dir": "/path/to/project",
"ticket_id": "TICKET-XXX_A.1",
"component_path": "src/components/impact/MetricCard.js",
"fixture_path": "src/tests/metric-card.html",
"component_name": "MetricCard",
"component_class": "MetricCard",
"acceptance_criteria": [
{"id": "AC-001", "description": "Counter animates from 0 to target"},
{"id": "AC-002", "description": "Displays unit label correctly"}
]
}
NEVER use relative paths like ../../ in fixture imports.
The server runs from src/ directory, making src/ the web root:
src/tests/*.html → served at /tests/*.htmlsrc/components/**/*.js → served at /components/**/*.jsWHY relative paths break:
fixture_path: src/tests/metric-card.html
component_path: src/components/impact/MetricCard.js
WRONG: ../../components/impact/MetricCard.js
→ resolves to project_root/components/impact/MetricCard.js (OUTSIDE src/)
→ FILE NOT FOUND
RIGHT: /components/impact/MetricCard.js
→ resolves from server root (src/) to src/components/impact/MetricCard.js
→ FILE FOUND ✓
# Template location (in order of priority):
# 1. Project-specific: {project_dir}/templates/tests/component-fixture.html
# 2. Harness: {project_dir}/harness/templates/component-fixture.html
# 3. Global: templates/project/tests/web/component-fixture.template.html
Replace mustache-style variables in template:
| Variable | Source | Example |
|---|---|---|
{{TICKET_ID}} | input.ticket_id | TICKET-OXY-003_A.1 |
{{COMPONENT_NAME}} | input.component_name | MetricCard |
{{COMPONENT_PATH}} | Absolute URL from server root | /components/impact/MetricCard.js |
{{COMPONENT_CLASS}} | input.component_class | MetricCard |
{{COMPONENT_CSS}} | CSS absolute URL | /styles/metric-card.css |
{{COMPONENT_OPTIONS}} | Default init options | {} or from ticket |
{{COMPONENT_SELECTOR}} | data-* attribute name (kebab-case) | circular-progress |
{{#ACCEPTANCE_CRITERIA}} | Loop over ACs | Creates test sections |
{{AC_ID}} | Each AC ID | AC-001 |
{{AC_DESCRIPTION}} | Each AC description | Counter animates... |
CRITICAL: Check for import_prefix in context first!
The import_prefix context variable tells you if the server needs a path prefix (e.g., /src).
// FIRST: Check if import_prefix is provided in context
// If import_prefix = "/src", paths need the /src prefix
// If import_prefix = "", server serves from src/ directly
function toAbsoluteUrl(filePath, importPrefix) {
// Remove src/ prefix if present to get relative path
let relativePath = filePath;
if (filePath.startsWith('src/')) {
relativePath = filePath.slice(4); // Remove 'src/'
}
// Apply import_prefix if provided (e.g., "/src" when server runs from project root)
if (importPrefix) {
return importPrefix + '/' + relativePath;
}
// Default: assume server runs from src/, no prefix needed
return '/' + relativePath;
}
// Examples WITH import_prefix="/src" (server at project root):
// src/components/impact/MetricCard.js → /src/components/impact/MetricCard.js
// src/styles/metric-card.css → /src/styles/metric-card.css
// Examples WITHOUT import_prefix (server at src/):
// src/components/impact/MetricCard.js → /components/impact/MetricCard.js
// src/styles/metric-card.css → /styles/metric-card.css
Always check context for import_prefix before generating import paths!
For each acceptance criterion, create a test section:
<div class="test-section" id="test-AC-001">
<h2>AC-001: Counter animates from 0 to target</h2>
<div data-test-scenario="ac-001"></div>
</div>
// Ensure directory exists
const fixtureDir = path.dirname(fixturePath);
await fs.mkdir(fixtureDir, { recursive: true });
// Write processed template
await fs.writeFile(fixturePath, processedTemplate);
{
"skill": "test-create-fixture",
"status": "success|failure",
"fixture_created": "src/tests/metric-card.html",
"template_used": "templates/project/tests/web/component-fixture.template.html",
"variables_replaced": {
"TICKET_ID": "TICKET-OXY-003_A.1",
"COMPONENT_NAME": "MetricCard",
"COMPONENT_PATH": "/components/impact/MetricCard.js",
"ACCEPTANCE_CRITERIA": 2
},
"test_sections": ["AC-001", "AC-002"],
"warnings": [],
"next_action": "validate_fixture"
}
Initial fixtures focus on happy path ONLY. Edge case testing is deferred to later phases.
When an AC describes edge case behavior (missing files, errors, invalid data), do NOT test it directly. Instead:
// AC-3: "No runtime errors when data file is missing"
// DEFERRED - mark as deferred, don't request missing file
setOutput('ac-3', JSON.stringify({
status: 'deferred',
note: 'Edge case test deferred until happy path validated'
}, null, 2));
Rationale: Early TDD phases validate that components work correctly with valid inputs. Edge case testing requires additional infrastructure (mock servers, error injection) that may not exist yet.
The generated fixture MUST include:
// Set SYNCHRONOUSLY (before async init) for browser timing consistency
window.__testModule = {
ComponentClass, // The class constructor
initComponentFactory, // Factory function if available
...otherExports // All named exports from module
};
// Set AFTER async init completes
window.__testInstances = [...]; // Array of initialized instances
window.__getTestInstance = () => instances[0];
window.__getTestInstances = () => instances;
window.__isInitialized = () => initComplete && !error;
window.__getInitError = () => initError;
Why __testModule is CRITICAL:
page.waitForFunction(() => window.__testModule) to wait for module<!DOCTYPE html>
<html lang="en">
<head>
<title>MetricCard Test - TICKET-OXY-003_A.1</title>
<!-- ABSOLUTE URLs - server root is src/ -->
<link rel="stylesheet" href="/styles/impact/metric-card.css">
</head>
<body>
<div class="test-container">
<h1>MetricCard Test</h1>
<div class="test-section" id="test-AC-001">
<h2>AC-001: Counter animates from 0 to target</h2>
<div data-testid="ac-001-container"></div>
</div>
<div class="test-section" id="test-AC-002">
<h2>AC-002: Displays unit label correctly</h2>
<div data-testid="ac-002-container"></div>
</div>
<div id="test-status">Loading...</div>
</div>
<script type="module">
// ABSOLUTE URL - NOT relative! Server root is src/
import { MetricCard } from '/components/impact/MetricCard.js';
// ... initialization code
</script>
</body>
</html>