import test from "node:test"; import assert from "node:assert/strict"; import { renderNodeLibrary } from "./components/node-library.tsx"; import { renderWorkflowEditorPage } from "./workflow-editor-page.tsx"; import { renderRunDetailPage } from "../runs/run-detail-page.tsx"; import { renderRunsPage } from "../runs/runs-page.tsx"; test("node library renders categories", () => { const html = renderNodeLibrary(); assert.match(html, /Source/); assert.match(html, /Transform/); assert.match(html, /Inspect/); assert.match(html, /Export/); }); test("node config panel opens when a node is selected", () => { const html = renderWorkflowEditorPage({ workspaceName: "Team Workspace", projectName: "Pipeline Project", workflowName: "Delivery Normalize", selectedNodeId: "rename-folder", }); assert.match(html, /Node Configuration/); assert.match(html, /Rename Delivery Folder/); assert.match(html, /Executor/); assert.match(html, /Runtime Target/); assert.match(html, /Artifact Title/); assert.match(html, /Code Hook/); }); test("run detail view shows node status badges from run data", () => { const html = renderRunDetailPage({ workspaceName: "Team Workspace", projectName: "Pipeline Project", run: { id: "run-1", workflowName: "Delivery Normalize", status: "running", assetIds: ["asset-1"], durationMs: 2450, summaryLabel: "2 tasks complete, 1 running, 1 stdout line", canCancelRun: true, canRetryRun: false, }, tasks: [ { id: "task-1", nodeId: "source-asset", nodeName: "Source Asset", status: "success", assetIds: ["asset-1"], artifactIds: ["artifact-1"], durationMs: 1200, summaryLabel: "Processed 1 asset", stdoutLines: ["asset ready"], stderrLines: [], logLines: ["Asset loaded"], }, { id: "task-2", nodeId: "validate-structure", nodeName: "Validate Structure", status: "running", assetIds: ["asset-1"], artifactIds: ["artifact-2"], durationMs: 2450, summaryLabel: "Validated delivery package structure", stdoutLines: ["Checking metadata"], stderrLines: ["Minor warning"], logLines: ["Checking metadata"], canRetry: true, nodeDefinitionId: "validate-structure", codeHookLabel: "python:process", executorConfigLabel: "{\"url\":\"http://127.0.0.1:3010/mock\"}", }, ], selectedTaskId: "task-2", }); assert.match(html, /Source Asset/); assert.match(html, /success/); assert.match(html, /Validate Structure/); assert.match(html, /running/); assert.match(html, /Checking metadata/); assert.match(html, /Input assets: asset-1/); assert.match(html, /Run duration: 2450 ms/); assert.match(html, /2 tasks complete, 1 running, 1 stdout line/); assert.match(html, /Cancel Run/); assert.match(html, /Duration: 2450 ms/); assert.match(html, /Validated delivery package structure/); assert.match(html, /Stdout/); assert.match(html, /Minor warning/); assert.match(html, /Retry Task/); assert.match(html, /Definition: validate-structure/); assert.match(html, /Code Hook: python:process/); assert.match(html, /Executor Config/); assert.match(html, /\/explore\/artifact-2/); }); test("runs page renders project-scoped run history with workflow links", () => { const html = renderRunsPage({ workspaceName: "Team Workspace", projectName: "Pipeline Project", runs: [ { id: "run-1", workflowName: "Delivery Normalize", status: "success", assetIds: ["asset-1"], }, { id: "run-2", workflowName: "Archive Extract", status: "running", assetIds: ["asset-2", "asset-3"], }, ], }); assert.match(html, /Recent workflow executions/); assert.match(html, /Delivery Normalize/); assert.match(html, /Archive Extract/); assert.match(html, /Input assets: asset-2, asset-3/); assert.match(html, /\/runs\/run-2/); });