FN-5986: add browser demo lifecycle board flow
Add a browser demo workflow and supporting fixtures for board walkthroughs. - add a demo README plus seeded Browser Demo Lifecycle workflow with Todo, In Progress, In Review, QA, and Publish columns - seed representative browser demo tasks and lifecycle log entries across the custom workflow columns - update the live simulator to advance workflow tasks through QA and Publish while preserving the legacy merge path - add a core lifecycle test covering workflow selection and the Todo → In Progress → In Review → QA → Publish transitions Files changed: demo/README.md | 25 ++++ demo/seed.ts | 131 ++++++++++++++++++++- demo/simulate.ts | 35 ++++-- packages/core/src/__tests__/browser-demo-lifecycle.test.ts | 71 +++++++++++ 4 files changed, 248 insertions(+), 14 deletions(-) Fusion-Task-Id: FN-5986 Fusion-Task-Lineage: 9638f7da-9b50-4de1-8ffa-d861dbf7aff2
This commit is contained in:
71
packages/core/src/__tests__/browser-demo-lifecycle.test.ts
Normal file
71
packages/core/src/__tests__/browser-demo-lifecycle.test.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
// @vitest-environment node
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
||||
|
||||
import type { WorkflowIr } from "../workflow-ir-types.js";
|
||||
import { createTaskStoreTestHarness } from "./store-test-helpers.js";
|
||||
|
||||
function browserDemoLifecycleIr(): WorkflowIr {
|
||||
return {
|
||||
version: "v2",
|
||||
name: "browser-demo-lifecycle",
|
||||
columns: [
|
||||
{ id: "todo", name: "Todo", traits: [{ trait: "intake" }] },
|
||||
{ id: "in-progress", name: "In Progress", traits: [{ trait: "wip" }] },
|
||||
{ id: "in-review", name: "In Review", traits: [{ trait: "merge-blocker" }] },
|
||||
{ id: "qa", name: "QA", traits: [] },
|
||||
{ id: "publish", name: "Publish", traits: [{ trait: "complete" }] },
|
||||
],
|
||||
nodes: [
|
||||
{ id: "start", kind: "start", column: "todo" },
|
||||
{ id: "implement", kind: "prompt", column: "in-progress", config: { prompt: "Implement" } },
|
||||
{ id: "review", kind: "prompt", column: "in-review", config: { prompt: "Review" } },
|
||||
{ id: "qa-check", kind: "gate", column: "qa", config: { scriptName: "test", name: "QA" } },
|
||||
{ id: "end", kind: "end", column: "publish" },
|
||||
],
|
||||
edges: [
|
||||
{ from: "start", to: "implement", condition: "success" },
|
||||
{ from: "implement", to: "review", condition: "success" },
|
||||
{ from: "review", to: "qa-check", condition: "success" },
|
||||
{ from: "qa-check", to: "end", condition: "success" },
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
describe("browser demo lifecycle workflow", () => {
|
||||
const harness = createTaskStoreTestHarness();
|
||||
let store: ReturnType<typeof harness.store>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await harness.beforeEach();
|
||||
store = harness.store();
|
||||
await store.updateGlobalSettings({ experimentalFeatures: { workflowColumns: true } });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await harness.afterEach();
|
||||
});
|
||||
|
||||
it("supports the Todo → In Progress → In Review → QA → Publish board walkthrough", async () => {
|
||||
const workflow = await store.createWorkflowDefinition({
|
||||
name: "Browser Demo Lifecycle",
|
||||
ir: browserDemoLifecycleIr(),
|
||||
});
|
||||
const task = await store.createTask({ description: "Browser walkthrough task", title: "Demo lifecycle" });
|
||||
|
||||
const selection = await store.selectTaskWorkflowAndReconcile(task.id, workflow.id);
|
||||
expect(selection.reconciliation).toEqual({ preserved: false, fromColumn: "triage", toColumn: "todo" });
|
||||
expect((await store.getTask(task.id)).column).toBe("todo");
|
||||
|
||||
await store.moveTask(task.id, "in-progress", { moveSource: "user" });
|
||||
await store.moveTask(task.id, "in-review", { moveSource: "user", allowDirectInReviewMove: true });
|
||||
await store.moveTask(task.id, "qa", { moveSource: "user" });
|
||||
await store.moveTask(task.id, "publish", { moveSource: "user" });
|
||||
|
||||
const detail = await store.getTask(task.id);
|
||||
expect(detail.column).toBe("publish");
|
||||
|
||||
const listed = await store.listTasks({ column: "publish" });
|
||||
expect(listed.map((item) => item.id)).toContain(task.id);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user