From f97d9de6f8e711bc5b9fb4e1ee2e1ec3b209bea7 Mon Sep 17 00:00:00 2001 From: Nihit <24500178+knihit@users.noreply.github.com> Date: Mon, 26 Oct 2026 04:48:22 +0000 Subject: [PATCH 01/10] Draw the run on the Execution tab with a Run button and live node states The Execution tab shows the graph of the Designer with a goal box and a Run button. Run starts a run and reads it once a second; each node shows its state as a word and a colour from the theme, and the end shows the result. The status is a live region and an API error shows in one alert. Both tabs now share the load states and the graph card. --- .../e2e/support/workflow-canvas-page.ts | 61 ++- workflow-canvas/src/App.test.tsx | 8 +- workflow-canvas/src/App.tsx | 28 +- .../src/canvas/WorkflowGraphCard.tsx | 66 +++ workflow-canvas/src/canvas/canvas.css | 75 ++++ .../src/{designer => canvas}/clipping.test.ts | 0 .../src/{designer => canvas}/clipping.ts | 0 workflow-canvas/src/canvas/nodes.tsx | 32 +- workflow-canvas/src/designer/Designer.tsx | 86 +--- .../src/execution/Execution.test.tsx | 410 ++++++++++++++++++ workflow-canvas/src/execution/Execution.tsx | 145 +++++++ workflow-canvas/src/execution/execution.css | 18 + .../src/execution/timer-scheduler.test.ts | 55 +++ .../src/execution/timer-scheduler.ts | 21 + .../src/execution/use-execution.ts | 53 +++ workflow-canvas/src/workflow/WorkflowGate.tsx | 44 ++ .../src/{designer => workflow}/states.tsx | 0 .../use-change-count.ts | 0 .../test-support/canvas-contrast.test.ts | 20 + 19 files changed, 1023 insertions(+), 99 deletions(-) create mode 100644 workflow-canvas/src/canvas/WorkflowGraphCard.tsx rename workflow-canvas/src/{designer => canvas}/clipping.test.ts (100%) rename workflow-canvas/src/{designer => canvas}/clipping.ts (100%) create mode 100644 workflow-canvas/src/execution/Execution.test.tsx create mode 100644 workflow-canvas/src/execution/Execution.tsx create mode 100644 workflow-canvas/src/execution/execution.css create mode 100644 workflow-canvas/src/execution/timer-scheduler.test.ts create mode 100644 workflow-canvas/src/execution/timer-scheduler.ts create mode 100644 workflow-canvas/src/execution/use-execution.ts create mode 100644 workflow-canvas/src/workflow/WorkflowGate.tsx rename workflow-canvas/src/{designer => workflow}/states.tsx (100%) rename workflow-canvas/src/{designer => workflow}/use-change-count.ts (100%) diff --git a/workflow-canvas/e2e/support/workflow-canvas-page.ts b/workflow-canvas/e2e/support/workflow-canvas-page.ts index 2bff325a..ec6637ff 100644 --- a/workflow-canvas/e2e/support/workflow-canvas-page.ts +++ b/workflow-canvas/e2e/support/workflow-canvas-page.ts @@ -9,9 +9,6 @@ export type TabName = (typeof TAB_NAMES)[number]; /** The two modes of the page. */ export type ThemeName = 'light' | 'dark'; -/** Text the Execution tab shows until it has real content. */ -export const PLACEHOLDER_TEXT = 'Nothing here yet.'; - /** The nodes of the workflow canvas, top to bottom, by test id. */ export const NODE_IDS = [ 'node-intent', @@ -30,6 +27,16 @@ export const NODE_NAMES = [ 'End', ] as const; +/** The words a node shows for its state in a run. */ +export type BadgeText = + 'Queued' | 'Running' | 'Done' | 'Failed' | 'Not run' | 'Passed' | 'Halted'; + +/** + * How long to wait for a step of a run on the stub. A stage takes 3 seconds + * there and the page reads the run once a second. + */ +export const STEP_TIMEOUT_MS = 10_000; + /** The most Tab presses between one node and the next one to take focus. */ const MAX_TABS_TO_NEXT_NODE = 10; @@ -41,6 +48,10 @@ export class WorkflowCanvasPage { readonly edges: Locator; readonly themeButton: Locator; readonly breadcrumbs: Locator; + readonly runButton: Locator; + readonly goal: Locator; + readonly runStatus: Locator; + readonly runError: Locator; constructor(readonly page: Page) { this.main = page.getByRole('main'); @@ -49,6 +60,10 @@ export class WorkflowCanvasPage { this.edges = this.graph.locator('.react-flow__edge'); this.themeButton = page.getByRole('button', { name: /^Theme:/ }); this.breadcrumbs = page.getByRole('navigation', { name: 'Breadcrumbs' }); + this.runButton = page.getByRole('button', { name: 'Run', exact: true }); + this.goal = page.getByLabel('Goal'); + this.runStatus = page.getByTestId('run-status'); + this.runError = page.getByTestId('run-error'); } /** @@ -96,6 +111,35 @@ export class WorkflowCanvasPage { return this.node(id).locator('.wf-port-notch'); } + /** The label that a node shows for its state in a run. */ + badge(id: NodeId): Locator { + return this.node(id).getByTestId('status-badge'); + } + + /** + * Asserts what every node shows for its state, top to bottom: the words of + * the badge, or `null` for a node with no badge. + */ + async expectBadges( + texts: readonly [ + BadgeText | null, + BadgeText | null, + BadgeText | null, + BadgeText | null, + ], + ): Promise { + for (const [index, id] of NODE_IDS.entries()) { + const text = texts[index]; + if (text === null || text === undefined) { + await expect(this.badge(id)).toHaveCount(0); + } else { + await expect(this.badge(id)).toHaveText(text, { + timeout: STEP_TIMEOUT_MS, + }); + } + } + } + /** The node that a screen reader names `name`. */ nodeNamed(name: string): Locator { return this.graph.getByRole('group', { name, exact: true }); @@ -127,15 +171,16 @@ export class WorkflowCanvasPage { ); } await expect(this.tabPanel(name)).toBeVisible(); - if (name === 'Execution') { - await expect(this.tabPanel(name)).toContainText(PLACEHOLDER_TEXT); - } } - /** Asserts a tab has finished showing its content: the graph, for Designer. */ + /** + * Asserts a tab has finished showing its content: the graph on both tabs, + * and the Run button on Execution. + */ async expectTabLoaded(name: TabName): Promise { await this.expectTabShown(name); - if (name === 'Designer') await this.expectWorkflowDrawn(); + await this.expectWorkflowDrawn(); + if (name === 'Execution') await expect(this.runButton).toBeVisible(); } /** Asserts the whole graph is on screen: every node and every edge. */ diff --git a/workflow-canvas/src/App.test.tsx b/workflow-canvas/src/App.test.tsx index 2b2f389d..8e782fce 100644 --- a/workflow-canvas/src/App.test.tsx +++ b/workflow-canvas/src/App.test.tsx @@ -79,14 +79,14 @@ describe('App', () => { ).toBeTruthy(); }); - it('shows a placeholder on the Execution tab', () => { + it('draws the workflow with a Run button on the Execution tab', async () => { render(); fireEvent.click(screen.getByRole('tab', { name: 'Execution' })); - expect( - screen.getByRole('tabpanel', { name: 'Execution' }).textContent, - ).toContain('Nothing here yet.'); + const panel = screen.getByRole('tabpanel', { name: 'Execution' }); + expect(await within(panel).findByTestId('node-stage-draft')).toBeTruthy(); + expect(within(panel).getByRole('button', { name: 'Run' })).toBeTruthy(); }); it('keeps the loaded workflow when the tabs are switched back and forth', async () => { diff --git a/workflow-canvas/src/App.tsx b/workflow-canvas/src/App.tsx index 3f294dec..fa4af464 100644 --- a/workflow-canvas/src/App.tsx +++ b/workflow-canvas/src/App.tsx @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 import AppLayout from '@cloudscape-design/components/app-layout'; -import Box from '@cloudscape-design/components/box'; import ContentLayout from '@cloudscape-design/components/content-layout'; import Header from '@cloudscape-design/components/header'; import Tabs from '@cloudscape-design/components/tabs'; @@ -10,28 +9,37 @@ import './chrome/chrome.css'; import { TOP_BAR_ID, TopBar } from './chrome/TopBar'; import { Designer } from './designer/Designer'; import { useSettled } from './designer/use-settled'; +import type { Scheduler } from './execution/core'; +import { Execution } from './execution/Execution'; +import { timerScheduler } from './execution/timer-scheduler'; +import { useExecution } from './execution/use-execution'; import { TAB_STRIP_STYLE } from './theme/tokens'; import { useThemeMode } from './theme/use-theme-mode'; import { openWorkflowName, type LoadResult } from './workflow/load-workflow'; -const placeholder = Nothing here yet.; - /** * Root component: the top bar, then the page header (breadcrumbs and title) - * with the Designer and Execution tabs. The Designer draws the workflow that - * `load` settles with; the Execution tab shows a placeholder until its - * content is built. + * with the Designer and Execution tabs. Both tabs draw the workflow that + * `load` settles with, and the Execution tab runs it, waiting with + * `scheduler` between two reads of the run. */ export function App({ load, notice, + scheduler = timerScheduler, }: { load: Promise; /** Shown above the tabs, such as the refusal of a pasted launch address. */ notice?: ReactNode; + scheduler?: Scheduler; }) { // Read here, not in the tab, so switching tabs does not load again. const result = useSettled(load); + // Kept here too, so a run goes on while the Designer tab is open. + const execution = useExecution( + result?.ok ? result.workflow.runs : undefined, + scheduler, + ); const [mode, toggleMode] = useThemeMode(); return ( <> @@ -62,7 +70,13 @@ export function App({ label: 'Designer', content: , }, - { id: 'execution', label: 'Execution', content: placeholder }, + { + id: 'execution', + label: 'Execution', + content: ( + + ), + }, ]} /> diff --git a/workflow-canvas/src/canvas/WorkflowGraphCard.tsx b/workflow-canvas/src/canvas/WorkflowGraphCard.tsx new file mode 100644 index 00000000..b43be92f --- /dev/null +++ b/workflow-canvas/src/canvas/WorkflowGraphCard.tsx @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache-2.0 +import Box from '@cloudscape-design/components/box'; +import Container from '@cloudscape-design/components/container'; +import Header from '@cloudscape-design/components/header'; +import { useMemo } from 'react'; +import type { WorkflowView } from '../api/types'; +import { buildGraph, withStatuses, type NodeStatus } from '../graph'; +import { INTENT_FITS_IN_NODE, clippedStages, textWidth } from './clipping'; +import { WorkflowCanvas } from './WorkflowCanvas'; + +/** The text that the nodes cut short, in full, under the graph. */ +function FullText({ view, harness }: { view: WorkflowView; harness: string }) { + const stages = clippedStages(view, harness); + const showIntent = textWidth(view.intent.outcome) > INTENT_FITS_IN_NODE; + if (!showIntent && stages.length === 0) return null; + return ( + + {showIntent && ( + + Intent: {view.intent.outcome} + + )} + {stages.map(({ name, agent }) => ( + + Stage {name}: {agent} · {harness} + + ))} + + ); +} + +const NO_STATUSES: ReadonlyMap = new Map(); + +/** + * The card both tabs draw the workflow in: its name, then the read-only graph. + * `statuses` puts a live state on the nodes it names, by node id. + */ +export function WorkflowGraphCard({ + view, + harness, + statuses = NO_STATUSES, +}: { + view: WorkflowView; + harness: string; + statuses?: ReadonlyMap; +}) { + const graph = useMemo( + () => withStatuses(buildGraph(view, harness), statuses), + [view, harness, statuses], + ); + return ( + + Workflow: {view.name} + + } + > + + + + ); +} diff --git a/workflow-canvas/src/canvas/canvas.css b/workflow-canvas/src/canvas/canvas.css index 98cfae8c..527c4134 100644 --- a/workflow-canvas/src/canvas/canvas.css +++ b/workflow-canvas/src/canvas/canvas.css @@ -3,6 +3,8 @@ /* * The colours of the parts that the canvas draws itself, for the light and the * dark mode. The dark values apply when the page root has data-theme="dark". + * The --wf-state-* pairs colour the state of a node in a run: the text and the + * outline of a state, and the fill behind its label. * A test (canvas-contrast.test.ts) reads this file, checks that the text, the * edges and the ports reach WCAG AA in both modes, and that the colours and * radii match the theme module. @@ -26,6 +28,14 @@ --wf-controls-bg: #ffffff; --wf-controls-bg-hover: #efebff; --wf-controls-border: #cfc7ba; + --wf-state-queued: #56516a; + --wf-state-queued-bg: #faf8f4; + --wf-state-running: #6236f0; + --wf-state-running-bg: #efebff; + --wf-state-done: #0b7a52; + --wf-state-done-bg: #e7f5ee; + --wf-state-failed: #b3261e; + --wf-state-failed-bg: #fdecec; border-radius: 12px; background: var(--wf-canvas-bg); @@ -50,6 +60,14 @@ --wf-controls-bg: #171331; --wf-controls-bg-hover: #1f1a44; --wf-controls-border: #3a3168; + --wf-state-queued: #9c93b8; + --wf-state-queued-bg: #1c1740; + --wf-state-running: #a78bfa; + --wf-state-running-bg: #1f1a44; + --wf-state-done: #3ddc97; + --wf-state-done-bg: #10281f; + --wf-state-failed: #ff8b8b; + --wf-state-failed-bg: #2b1722; } .wf-canvas .react-flow__attribution a { @@ -230,6 +248,63 @@ pointer-events: none; } +/* + * The state of a node in a run. The word in the badge is what says the state; + * the colour and the outline only back it up. A queued node has a dashed + * outline, so the states differ without colour too. + */ +.wf-badge { + position: absolute; + bottom: 10px; + left: 14px; + padding: 0 8px; + border: 1.5px solid var(--wf-badge-color); + border-radius: 8px; + background: var(--wf-badge-bg); + color: var(--wf-badge-color); + font-size: 11px; + font-weight: 700; + line-height: 1.5; +} + +.wf-node-end .wf-badge { + top: 50%; + bottom: auto; + transform: translateY(-50%); +} + +.wf-node { + --wf-badge-color: var(--wf-state-queued); + --wf-badge-bg: var(--wf-state-queued-bg); +} + +.wf-node[data-state='running'] { + --wf-badge-color: var(--wf-state-running); + --wf-badge-bg: var(--wf-state-running-bg); +} + +.wf-node[data-state='done'] { + --wf-badge-color: var(--wf-state-done); + --wf-badge-bg: var(--wf-state-done-bg); +} + +.wf-node[data-state='failed'] { + --wf-badge-color: var(--wf-state-failed); + --wf-badge-bg: var(--wf-state-failed-bg); +} + +.wf-node[data-state] .wf-node-body { + stroke: var(--wf-badge-color); +} + +.wf-node[data-state='queued'] .wf-node-body { + stroke-dasharray: 6 4; +} + +.wf-node[data-state='queued'] .wf-badge { + border-style: dashed; +} + /* * In forced-colors mode the card takes the system colours, so its text does * not sit on a patch of the dark fill. After the rules above, to win over them. diff --git a/workflow-canvas/src/designer/clipping.test.ts b/workflow-canvas/src/canvas/clipping.test.ts similarity index 100% rename from workflow-canvas/src/designer/clipping.test.ts rename to workflow-canvas/src/canvas/clipping.test.ts diff --git a/workflow-canvas/src/designer/clipping.ts b/workflow-canvas/src/canvas/clipping.ts similarity index 100% rename from workflow-canvas/src/designer/clipping.ts rename to workflow-canvas/src/canvas/clipping.ts diff --git a/workflow-canvas/src/canvas/nodes.tsx b/workflow-canvas/src/canvas/nodes.tsx index f606a6f5..848f54d5 100644 --- a/workflow-canvas/src/canvas/nodes.tsx +++ b/workflow-canvas/src/canvas/nodes.tsx @@ -5,7 +5,9 @@ import { NODE_WIDTH, SEQUENCE_IN, SEQUENCE_OUT, + type EndGraphNode, type IntentGraphNode, + type NodeStatus, type StageGraphNode, } from '../graph'; import { @@ -103,6 +105,16 @@ function Tab({ top }: { top: number }) { ); } +/** The state of a node in a run, as a word in a coloured pill. */ +function StatusBadge({ status }: { status: NodeStatus | undefined }) { + if (!status) return null; + return ( + + {status.label} + + ); +} + /** * The card behind the content of a node: one rounded outline, with a notch * just inside the top edge when run order comes in and a tab hanging from the @@ -166,7 +178,11 @@ function NodeShape({ /** The start of the workflow: the outcome it is for, with a run order out. */ export function IntentNode({ data }: NodeProps>) { return ( -
+
>) {
{data.outcome}
+
); @@ -188,6 +205,7 @@ export function StageNode({ data }: NodeProps>) {
@@ -197,15 +215,20 @@ export function StageNode({ data }: NodeProps>) {
{data.agent} · {data.harness}
+
); } -/** The finish of the workflow, with a run order in. */ -export function EndNode() { +/** The finish of the workflow, with a run order in and, after a run, its result. */ +export function EndNode({ data }: NodeProps>) { return ( -
+
end
+
); } diff --git a/workflow-canvas/src/designer/Designer.tsx b/workflow-canvas/src/designer/Designer.tsx index 0bc5989c..07446f1e 100644 --- a/workflow-canvas/src/designer/Designer.tsx +++ b/workflow-canvas/src/designer/Designer.tsx @@ -1,75 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 -import Box from '@cloudscape-design/components/box'; -import Container from '@cloudscape-design/components/container'; -import Header from '@cloudscape-design/components/header'; -import { useMemo } from 'react'; -import { WorkflowCanvas } from '../canvas/WorkflowCanvas'; -import { buildGraph } from '../graph'; -import type { WorkflowView } from '../api/types'; -import type { LoadedWorkflow, LoadResult } from '../workflow/load-workflow'; -import { INTENT_FITS_IN_NODE, clippedStages, textWidth } from './clipping'; -import { EmptyState, ErrorState, LoadingState } from './states'; -import { useChangeCount } from './use-change-count'; - -/** The text that the nodes cut short, in full, under the graph. */ -function FullText({ view, harness }: { view: WorkflowView; harness: string }) { - const stages = clippedStages(view, harness); - const showIntent = textWidth(view.intent.outcome) > INTENT_FITS_IN_NODE; - if (!showIntent && stages.length === 0) return null; - return ( - - {showIntent && ( - - Intent: {view.intent.outcome} - - )} - {stages.map(({ name, agent }) => ( - - Stage {name}: {agent} · {harness} - - ))} - - ); -} - -function DrawnGraph({ - view, - harness, -}: { - view: WorkflowView; - harness: string; -}) { - const graph = useMemo(() => buildGraph(view, harness), [view, harness]); - return ( - - Workflow: {view.name} - - } - > - - - - ); -} - -function DrawnWorkflow({ workflow }: { workflow: LoadedWorkflow }) { - const { document, harness } = workflow; - const { view } = document; - if (!view) { - return ( - - ); - } - return ; -} +import { WorkflowGraphCard } from '../canvas/WorkflowGraphCard'; +import type { LoadResult } from '../workflow/load-workflow'; +import { WorkflowGate } from '../workflow/WorkflowGate'; /** * The Designer tab: the workflow drawn as a graph, or a message while it @@ -77,9 +9,11 @@ function DrawnWorkflow({ workflow }: { workflow: LoadedWorkflow }) { * nothing to draw. */ export function Designer({ result }: { result: LoadResult | undefined }) { - // A new workflow gets a new canvas, which is fitted to it when it mounts. - const swaps = useChangeCount(result); - if (!result) return ; - if (!result.ok) return ; - return ; + return ( + + {({ view, harness }) => ( + + )} + + ); } diff --git a/workflow-canvas/src/execution/Execution.test.tsx b/workflow-canvas/src/execution/Execution.test.tsx new file mode 100644 index 00000000..68803116 --- /dev/null +++ b/workflow-canvas/src/execution/Execution.test.tsx @@ -0,0 +1,410 @@ +// SPDX-License-Identifier: Apache-2.0 +import { + act, + fireEvent, + render, + screen, + waitFor, + within, +} from '@testing-library/react'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { App } from '../App'; +import type { RunView } from '../api/types'; +import { FakeScheduler } from '../test-support/fake-scheduler'; +import { HELLO_DOCUMENT, helloRun, loaded } from '../test-support/fixtures'; +import type { RunPort } from './core'; + +const RUN_ID = helloRun(0).runId; + +// A server that answers with the readings in turn and then repeats the last. +function serverShowing(...readings: RunView[]): RunPort { + let next = 0; + return { + start: vi.fn().mockResolvedValue(RUN_ID), + get: vi.fn(async () => readings[Math.min(next++, readings.length - 1)]!), + }; +} + +async function openExecution(runs: RunPort) { + const scheduler = new FakeScheduler(); + const { unmount } = render( + , + ); + await screen.findByTestId('node-end'); + fireEvent.click(screen.getByRole('tab', { name: 'Execution' })); + await screen.findByRole('button', { name: 'Run' }); + return Object.assign(scheduler, { unmount }); +} + +const runButton = () => screen.getByRole('button', { name: 'Run' }); +const isOff = (button: HTMLElement) => + button.hasAttribute('disabled') || + button.getAttribute('aria-disabled') === 'true'; +const statusLine = () => screen.getByTestId('run-status'); +const badgeOf = (testId: string) => + within(screen.getByTestId(testId)).queryByTestId('status-badge') + ?.textContent ?? null; +const badges = () => [ + badgeOf('node-intent'), + badgeOf('node-stage-draft'), + badgeOf('node-stage-review'), + badgeOf('node-end'), +]; + +async function press(button: HTMLElement) { + await act(async () => { + fireEvent.click(button); + }); +} + +async function tick(scheduler: FakeScheduler) { + await act(async () => { + scheduler.tick(); + }); +} + +afterEach(() => { + vi.restoreAllMocks(); +}); + +describe('the Execution tab before a run', () => { + it('draws the same graph as the Designer, read-only, with a Run button', async () => { + await openExecution(serverShowing(helloRun(0))); + + const graph = screen.getByRole('region', { name: 'Workflow graph' }); + for (const id of [ + 'node-intent', + 'node-stage-draft', + 'node-stage-review', + 'node-end', + ]) { + expect(within(graph).getByTestId(id)).toBeTruthy(); + } + expect( + screen.getByRole('heading', { name: 'Workflow: hello' }), + ).toBeTruthy(); + expect(isOff(runButton())).toBe(false); + }); + + it('shows no state on any node and says it is ready', async () => { + await openExecution(serverShowing(helloRun(0))); + + expect(badges()).toEqual([null, null, null, null]); + expect(statusLine().textContent).toContain('Ready. Press Run to start.'); + }); + + it('offers the outcome of the intent as the goal', async () => { + await openExecution(serverShowing(helloRun(0))); + + expect((screen.getByLabelText('Goal') as HTMLInputElement).value).toBe( + 'Add a greeting to the README', + ); + }); + + it('announces the status in a polite live region that is always there', async () => { + await openExecution(serverShowing(helloRun(0))); + + const live = statusLine(); + expect(live.getAttribute('role')).toBe('status'); + expect(live.getAttribute('aria-live')).toBe('polite'); + }); +}); + +describe('a run', () => { + it('starts with the goal the person typed', async () => { + const runs = serverShowing(helloRun(0)); + await openExecution(runs); + + fireEvent.change(screen.getByLabelText('Goal'), { + target: { value: 'Fix the typo' }, + }); + await press(runButton()); + + expect(runs.start).toHaveBeenCalledOnce(); + expect(runs.start).toHaveBeenCalledWith('Fix the typo'); + }); + + it('shows each node going from queued to running to done, in order', async () => { + const scheduler = await openExecution( + serverShowing(helloRun(0), helloRun(1), helloRun(2)), + ); + + await press(runButton()); + expect(badges()).toEqual(['Done', 'Running', 'Queued', 'Queued']); + expect(statusLine().textContent).toContain( + 'Running draft. 0 of 2 stages done.', + ); + + await tick(scheduler); + expect(badges()).toEqual(['Done', 'Done', 'Running', 'Queued']); + expect(statusLine().textContent).toContain( + 'Running review. 1 of 2 stages done.', + ); + + await tick(scheduler); + expect(badges()).toEqual(['Done', 'Done', 'Done', 'Passed']); + expect(statusLine().textContent).toContain( + 'Run passed. 2 of 2 stages done. Exit code 0.', + ); + }); + + it('puts the state in the name a screen reader reads for each node', async () => { + await openExecution(serverShowing(helloRun(0))); + + await press(runButton()); + + const graph = screen.getByRole('region', { name: 'Workflow graph' }); + expect( + within(graph).getByRole('group', { + name: 'Stage draft, agent k-developer, harness kiro-cli, running', + }), + ).toBeTruthy(); + expect( + within(graph).getByRole('group', { name: 'End, queued' }), + ).toBeTruthy(); + }); + + it('reads the run once a second, with no read in between', async () => { + const runs = serverShowing(helloRun(0), helloRun(1), helloRun(2)); + const scheduler = await openExecution(runs); + + await press(runButton()); + expect(runs.get).toHaveBeenCalledTimes(1); + expect(scheduler.waits).toEqual([1000]); + + await tick(scheduler); + await tick(scheduler); + + expect(runs.get).toHaveBeenCalledTimes(3); + expect(scheduler.waits).toEqual([1000, 1000]); + expect(runs.get).toHaveBeenCalledWith(RUN_ID); + }); + + it('cannot be started again while it is in flight, and can after it ends', async () => { + const runs = serverShowing(helloRun(0), helloRun(2)); + const scheduler = await openExecution(runs); + + await press(runButton()); + expect(isOff(runButton())).toBe(true); + expect(screen.getByLabelText('Goal').hasAttribute('disabled')).toBe(true); + await press(runButton()); + expect(runs.start).toHaveBeenCalledOnce(); + + await tick(scheduler); + expect(isOff(runButton())).toBe(false); + expect(screen.getByLabelText('Goal').hasAttribute('disabled')).toBe(false); + }); + + it('disables Run from the moment of the click, before the run is accepted', async () => { + let accept: (runId: string) => void = () => {}; + const runs: RunPort = { + start: () => new Promise((resolve) => (accept = resolve)), + get: async () => helloRun(0), + }; + await openExecution(runs); + + await press(runButton()); + + expect(isOff(runButton())).toBe(true); + expect(statusLine().textContent).toContain('Starting the run.'); + await act(async () => accept(RUN_ID)); + expect(statusLine().textContent).toContain('Running draft.'); + }); + + it('shows a failed stage, the stages that will not run and the halted result', async () => { + const scheduler = await openExecution( + serverShowing(helloRun(0), helloRun(0, { blockedAt: 0 })), + ); + + await press(runButton()); + await tick(scheduler); + + expect(badges()).toEqual(['Done', 'Failed', 'Not run', 'Halted']); + expect(statusLine().textContent).toContain( + 'Run halted at draft. 0 of 2 stages done. Exit code 1.', + ); + expect(isOff(runButton())).toBe(false); + }); + + it('shows no error alert when a stage fails: the failure is a result, not an error', async () => { + await openExecution(serverShowing(helloRun(0, { blockedAt: 1 }))); + + await press(runButton()); + + expect(screen.queryByTestId('run-error')).toBeNull(); + }); + + it('can be run again, starting from the first stage', async () => { + const runs = serverShowing(helloRun(2)); + await openExecution(runs); + await press(runButton()); + expect(badges()).toEqual(['Done', 'Done', 'Done', 'Passed']); + + runs.get = vi.fn().mockResolvedValue(helloRun(0)); + await press(runButton()); + + expect(runs.start).toHaveBeenCalledTimes(2); + expect(badges()).toEqual(['Done', 'Running', 'Queued', 'Queued']); + }); + + it('goes on while the Designer tab is open, and shows the result when back', async () => { + const scheduler = await openExecution( + serverShowing(helloRun(0), helloRun(2)), + ); + await press(runButton()); + + fireEvent.click(screen.getByRole('tab', { name: 'Designer' })); + await tick(scheduler); + fireEvent.click(screen.getByRole('tab', { name: 'Execution' })); + + expect(badges()).toEqual(['Done', 'Done', 'Done', 'Passed']); + expect(statusLine().textContent).toContain('Run passed.'); + }); + + it('shows no state on the Designer tab', async () => { + await openExecution(serverShowing(helloRun(0))); + await press(runButton()); + + fireEvent.click(screen.getByRole('tab', { name: 'Designer' })); + + expect(screen.queryAllByTestId('status-badge')).toEqual([]); + }); + + it('stops reading when the page is closed', async () => { + const runs = serverShowing(helloRun(0), helloRun(1), helloRun(2)); + const scheduler = await openExecution(runs); + await press(runButton()); + + scheduler.unmount(); + await tick(scheduler); + + expect(runs.get).toHaveBeenCalledTimes(1); + }); +}); + +describe('the goal', () => { + it('turns Run off, and says why, when the goal is empty', async () => { + const runs = serverShowing(helloRun(0)); + await openExecution(runs); + + fireEvent.change(screen.getByLabelText('Goal'), { + target: { value: ' ' }, + }); + + expect(isOff(runButton())).toBe(true); + expect(screen.getAllByText('Enter a goal to run.').length).toBeGreaterThan( + 0, + ); + await press(runButton()); + expect(runs.start).not.toHaveBeenCalled(); + }); + + it('turns Run off when the goal is too long', async () => { + await openExecution(serverShowing(helloRun(0))); + + fireEvent.change(screen.getByLabelText('Goal'), { + target: { value: 'x'.repeat(2049) }, + }); + + expect(isOff(runButton())).toBe(true); + expect( + screen.getAllByText('The goal can have at most 2048 characters.').length, + ).toBeGreaterThan(0); + }); +}); + +describe('errors from the API', () => { + it('shows one alert with the sentence of the server when the run does not start', async () => { + const runs: RunPort = { + start: vi.fn().mockRejectedValue(new Error('A run is already active.')), + get: vi.fn(), + }; + await openExecution(runs); + + await press(runButton()); + + const alert = screen.getByTestId('run-error'); + expect(within(alert).getByText('The run did not start')).toBeTruthy(); + expect(within(alert).getByText('A run is already active.')).toBeTruthy(); + expect(screen.getAllByTestId('run-error')).toHaveLength(1); + expect(statusLine().textContent).toContain('The run did not start.'); + expect(badges()).toEqual([null, null, null, null]); + expect(isOff(runButton())).toBe(false); + }); + + it('shows one alert, and clears the states, when a reading fails', async () => { + const runs: RunPort = { + start: vi.fn().mockResolvedValue(RUN_ID), + get: vi + .fn() + .mockResolvedValueOnce(helloRun(0)) + .mockRejectedValue(new Error('The server did not answer.')), + }; + const scheduler = await openExecution(runs); + await press(runButton()); + + await tick(scheduler); + + const alert = screen.getByTestId('run-error'); + expect( + within(alert).getByText('The run could not be followed'), + ).toBeTruthy(); + expect(within(alert).getByText('The server did not answer.')).toBeTruthy(); + expect(screen.getAllByTestId('run-error')).toHaveLength(1); + expect(badges()).toEqual([null, null, null, null]); + expect(isOff(runButton())).toBe(false); + }); + + it('takes the alert away when a new run starts', async () => { + const runs: RunPort = { + start: vi + .fn() + .mockRejectedValueOnce(new Error('A run is already active.')) + .mockResolvedValue(RUN_ID), + get: vi.fn().mockResolvedValue(helloRun(0)), + }; + await openExecution(runs); + await press(runButton()); + expect(screen.getByTestId('run-error')).toBeTruthy(); + + await press(runButton()); + + await waitFor(() => expect(screen.queryByTestId('run-error')).toBeNull()); + expect(badges()).toEqual(['Done', 'Running', 'Queued', 'Queued']); + }); +}); + +describe('when there is no workflow to run', () => { + it('shows the message of the failed load, with no Run button', async () => { + render( + , + ); + await screen.findByText('The code is not valid.'); + + fireEvent.click(screen.getByRole('tab', { name: 'Execution' })); + + expect( + screen.getAllByText('The code is not valid.').length, + ).toBeGreaterThan(0); + expect(screen.queryByRole('button', { name: 'Run' })).toBeNull(); + }); + + it('says it is loading while the load is under way', () => { + render( + {})} scheduler={new FakeScheduler()} />, + ); + + fireEvent.click(screen.getByRole('tab', { name: 'Execution' })); + + expect(screen.getAllByText('Loading the workflow').length).toBeGreaterThan( + 0, + ); + expect(screen.queryByRole('button', { name: 'Run' })).toBeNull(); + }); +}); diff --git a/workflow-canvas/src/execution/Execution.tsx b/workflow-canvas/src/execution/Execution.tsx new file mode 100644 index 00000000..9dcafc05 --- /dev/null +++ b/workflow-canvas/src/execution/Execution.tsx @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: Apache-2.0 +import Alert from '@cloudscape-design/components/alert'; +import Button from '@cloudscape-design/components/button'; +import Container from '@cloudscape-design/components/container'; +import FormField from '@cloudscape-design/components/form-field'; +import Header from '@cloudscape-design/components/header'; +import Input from '@cloudscape-design/components/input'; +import SpaceBetween from '@cloudscape-design/components/space-between'; +import StatusIndicator, { + type StatusIndicatorProps, +} from '@cloudscape-design/components/status-indicator'; +import { useMemo, useState } from 'react'; +import { WorkflowGraphCard } from '../canvas/WorkflowGraphCard'; +import type { LoadResult } from '../workflow/load-workflow'; +import { WorkflowGate, type DrawableWorkflow } from '../workflow/WorkflowGate'; +import { + GOAL_MAX_LENGTH, + goalProblem, + isInFlight, + nodeStatuses, + runOf, + statusKind, + statusText, + type ExecutionState, + type StatusKind, +} from './core'; +import './execution.css'; +import type { Execution as ExecutionController } from './use-execution'; + +const INDICATOR: Record = { + idle: 'pending', + busy: 'in-progress', + success: 'success', + error: 'error', +}; + +// One live region that says where the run is. It is always on the page, so a +// change of its text is announced. +function RunStatusLine({ state }: { state: ExecutionState }) { + return ( +
+ + {statusText(state)} + +
+ ); +} + +function RunError({ state }: { state: ExecutionState }) { + if (state.phase !== 'error') return null; + return ( + + {state.message} + + ); +} + +function RunPanel({ + defaultGoal, + execution, +}: { + defaultGoal: string; + execution: ExecutionController; +}) { + const [goal, setGoal] = useState(defaultGoal); + const inFlight = isInFlight(execution.state); + const problem = goalProblem(goal); + return ( + Run}> + + + setGoal(detail.value)} + /> + + + + + + ); +} + +function ExecutionView({ + workflow, + execution, +}: { + workflow: DrawableWorkflow; + execution: ExecutionController; +}) { + const { view, harness } = workflow; + const run = runOf(execution.state); + const statuses = useMemo(() => nodeStatuses(run), [run]); + return ( + + +
+ + +
+
+ ); +} + +/** + * The Execution tab: the workflow graph, read-only, a goal and a Run button, + * and the live state of every node while the run goes on. `execution` holds + * the state, so a run goes on while the Designer tab is open. + */ +export function Execution({ + result, + execution, +}: { + result: LoadResult | undefined; + execution: ExecutionController; +}) { + return ( + + {(workflow) => ( + + )} + + ); +} diff --git a/workflow-canvas/src/execution/execution.css b/workflow-canvas/src/execution/execution.css new file mode 100644 index 00000000..dd3df030 --- /dev/null +++ b/workflow-canvas/src/execution/execution.css @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * The graph beside the run panel. A plain grid, not a library breakpoint, so + * the canvas has its final width when it first fits the graph in the view. + */ +.wf-execution { + display: grid; + grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); + gap: 20px; + align-items: start; +} + +@media (max-width: 900px) { + .wf-execution { + grid-template-columns: minmax(0, 1fr); + } +} diff --git a/workflow-canvas/src/execution/timer-scheduler.test.ts b/workflow-canvas/src/execution/timer-scheduler.test.ts new file mode 100644 index 00000000..1268fdc0 --- /dev/null +++ b/workflow-canvas/src/execution/timer-scheduler.test.ts @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { timerScheduler } from './timer-scheduler'; + +beforeEach(() => { + vi.useFakeTimers(); +}); + +afterEach(() => { + vi.useRealTimers(); +}); + +function track(promise: Promise) { + const state = { done: false }; + void promise.then(() => { + state.done = true; + }); + return state; +} + +describe('timerScheduler', () => { + it('resolves once the time has passed, and not before', async () => { + const state = track( + timerScheduler.wait(1000, new AbortController().signal), + ); + + await vi.advanceTimersByTimeAsync(999); + expect(state.done).toBe(false); + + await vi.advanceTimersByTimeAsync(1); + expect(state.done).toBe(true); + }); + + it('resolves at once when the signal aborts, and leaves no timer behind', async () => { + const abort = new AbortController(); + const state = track(timerScheduler.wait(1000, abort.signal)); + + abort.abort(); + await vi.advanceTimersByTimeAsync(0); + + expect(state.done).toBe(true); + expect(vi.getTimerCount()).toBe(0); + }); + + it('resolves at once when the signal is already aborted', async () => { + const abort = new AbortController(); + abort.abort(); + + const state = track(timerScheduler.wait(1000, abort.signal)); + await vi.advanceTimersByTimeAsync(0); + + expect(state.done).toBe(true); + expect(vi.getTimerCount()).toBe(0); + }); +}); diff --git a/workflow-canvas/src/execution/timer-scheduler.ts b/workflow-canvas/src/execution/timer-scheduler.ts new file mode 100644 index 00000000..78a2e530 --- /dev/null +++ b/workflow-canvas/src/execution/timer-scheduler.ts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +import type { Scheduler } from './core'; + +/** The scheduler of the page: waits with a browser timer. */ +export const timerScheduler: Scheduler = { + wait(ms, signal) { + return new Promise((resolve) => { + if (signal.aborted) { + resolve(); + return; + } + const finish = () => { + clearTimeout(timer); + signal.removeEventListener('abort', finish); + resolve(); + }; + const timer = setTimeout(finish, ms); + signal.addEventListener('abort', finish); + }); + }, +}; diff --git a/workflow-canvas/src/execution/use-execution.ts b/workflow-canvas/src/execution/use-execution.ts new file mode 100644 index 00000000..66c602b4 --- /dev/null +++ b/workflow-canvas/src/execution/use-execution.ts @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +import { useCallback, useEffect, useReducer, useRef } from 'react'; +import { + IDLE, + reduce, + startAndFollow, + type ExecutionState, + type RunPort, + type Scheduler, +} from './core'; + +/** The state of the Execution tab and the one way to change it. */ +export interface Execution { + state: ExecutionState; + /** Starts a run with the goal; does nothing while a run is in flight. */ + start(goal: string): void; +} + +/** + * Drives one run at a time through `runs`, waiting with `scheduler`, and + * stops following it when the component unmounts. The state lives with the + * caller, so it survives a switch of tab. + */ +export function useExecution( + runs: RunPort | undefined, + scheduler: Scheduler, +): Execution { + const [state, dispatch] = useReducer(reduce, IDLE); + const active = useRef(undefined); + + useEffect(() => () => active.current?.abort(), []); + + const start = useCallback( + (goal: string) => { + if (!runs || active.current) return; + const controller = new AbortController(); + active.current = controller; + dispatch({ type: 'start' }); + void startAndFollow({ + runs, + scheduler, + goal, + emit: dispatch, + signal: controller.signal, + }).finally(() => { + if (active.current === controller) active.current = undefined; + }); + }, + [runs, scheduler], + ); + + return { state, start }; +} diff --git a/workflow-canvas/src/workflow/WorkflowGate.tsx b/workflow-canvas/src/workflow/WorkflowGate.tsx new file mode 100644 index 00000000..08350755 --- /dev/null +++ b/workflow-canvas/src/workflow/WorkflowGate.tsx @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 +import { Fragment, type ReactNode } from 'react'; +import type { WorkflowView } from '../api/types'; +import type { LoadResult } from './load-workflow'; +import { EmptyState, ErrorState, LoadingState } from './states'; +import { useChangeCount } from './use-change-count'; + +/** A workflow that can be drawn, with the harness that runs its stages. */ +export interface DrawableWorkflow { + view: WorkflowView; + harness: string; +} + +/** + * Shows what a tab shows before it has a workflow to draw: a message while + * the load is under way (`result` is `undefined`), when it failed, or when + * there is nothing to draw. Once there is a workflow it renders `children`. + */ +export function WorkflowGate({ + result, + children, +}: { + result: LoadResult | undefined; + children: (workflow: DrawableWorkflow) => ReactNode; +}) { + // A new workflow gets a new canvas, which is fitted to it when it mounts. + const swaps = useChangeCount(result); + if (!result) return ; + if (!result.ok) return ; + const { document, harness } = result.workflow; + if (!document.view) { + return ( + + ); + } + return ( + + {children({ view: document.view, harness })} + + ); +} diff --git a/workflow-canvas/src/designer/states.tsx b/workflow-canvas/src/workflow/states.tsx similarity index 100% rename from workflow-canvas/src/designer/states.tsx rename to workflow-canvas/src/workflow/states.tsx diff --git a/workflow-canvas/src/designer/use-change-count.ts b/workflow-canvas/src/workflow/use-change-count.ts similarity index 100% rename from workflow-canvas/src/designer/use-change-count.ts rename to workflow-canvas/src/workflow/use-change-count.ts diff --git a/workflow-canvas/test-support/canvas-contrast.test.ts b/workflow-canvas/test-support/canvas-contrast.test.ts index 9965784a..657a92e5 100644 --- a/workflow-canvas/test-support/canvas-contrast.test.ts +++ b/workflow-canvas/test-support/canvas-contrast.test.ts @@ -42,6 +42,8 @@ const MODES: [ThemeMode, Record][] = [ ['dark', dark], ]; +const RUN_STATES = ['queued', 'running', 'done', 'failed'] as const; + describe.each(MODES)('canvas.css colours in %s', (mode, v) => { const ratio = (a: string, b: string) => contrastRatio(v[a]!, v[b]!); @@ -92,6 +94,16 @@ describe.each(MODES)('canvas.css colours in %s', (mode, v) => { ); }); + it.each(RUN_STATES)( + 'keeps the %s state readable in its badge and visible as an outline', + (state) => { + const color = `--wf-state-${state}`; + expect(ratio(color, `${color}-bg`)).toBeGreaterThanOrEqual(AA_TEXT); + expect(ratio(color, '--wf-canvas-bg')).toBeGreaterThanOrEqual(AA_GRAPHIC); + expect(ratio(color, '--wf-node-bg')).toBeGreaterThanOrEqual(AA_GRAPHIC); + }, + ); + it('uses the colours of the theme module, and names every one it uses', () => { const c = colorsOf(mode); const k = CANVAS[mode]; @@ -112,6 +124,14 @@ describe.each(MODES)('canvas.css colours in %s', (mode, v) => { '--wf-port-letter-out': k.portLetterOut, '--wf-port-letter-in': k.portLetterIn, '--wf-port-notch-bg': k.portNotchBg, + '--wf-state-queued': c.textMuted, + '--wf-state-queued-bg': c.surfaceAlt, + '--wf-state-running': c.link, + '--wf-state-running-bg': c.infoBg, + '--wf-state-done': c.success, + '--wf-state-done-bg': c.successBg, + '--wf-state-failed': c.error, + '--wf-state-failed-bg': c.errorBg, }; expect(v).toEqual(expected); From 349c2458803db44c7af02bcb3c980cd83bf33a1b Mon Sep 17 00:00:00 2001 From: Nihit <24500178+knihit@users.noreply.github.com> Date: Mon, 26 Oct 2026 04:48:22 +0000 Subject: [PATCH 02/10] Test the Execution tab end to end, capture its screenshots and document it End-to-end tests run the stub through each stage in order, and answer the run calls themselves for a failed stage and a refused run. Axe checks the tab with a running, a failed and a passed run. The screenshots show the tab before, during and after a run, and during a run in the dark mode. --- workflow-canvas/README.md | 75 ++++++++-- .../e2e/capture/screenshots.spec.ts | 62 +++++++-- .../e2e/screenshots/execution-tab-dark.png | Bin 0 -> 70824 bytes .../screenshots/execution-tab-finished.png | Bin 0 -> 70715 bytes .../e2e/screenshots/execution-tab-idle.png | Bin 0 -> 64922 bytes .../e2e/screenshots/execution-tab-running.png | Bin 0 -> 69981 bytes .../e2e/screenshots/execution-tab.png | Bin 20898 -> 0 bytes workflow-canvas/e2e/support/run-routes.ts | 58 ++++++++ .../e2e/tests/accessibility.spec.ts | 37 +++++ workflow-canvas/e2e/tests/execution.spec.ts | 130 ++++++++++++++++++ 10 files changed, 340 insertions(+), 22 deletions(-) create mode 100644 workflow-canvas/e2e/screenshots/execution-tab-dark.png create mode 100644 workflow-canvas/e2e/screenshots/execution-tab-finished.png create mode 100644 workflow-canvas/e2e/screenshots/execution-tab-idle.png create mode 100644 workflow-canvas/e2e/screenshots/execution-tab-running.png delete mode 100644 workflow-canvas/e2e/screenshots/execution-tab.png create mode 100644 workflow-canvas/e2e/support/run-routes.ts create mode 100644 workflow-canvas/e2e/tests/execution.spec.ts diff --git a/workflow-canvas/README.md b/workflow-canvas/README.md index 20336e7f..17a4b29a 100644 --- a/workflow-canvas/README.md +++ b/workflow-canvas/README.md @@ -8,15 +8,16 @@ The page has Designer and Execution tabs. The Designer tab loads the workflow from the API and draws it, read-only: the intent, each stage in list order (name, agent and harness) and the end, joined by run-order edges. It shows a loading message, an error message or an empty message when there is nothing to -draw. The Execution tab is still a placeholder. The contract, the stub that -serves it and the tests around both are in this folder. +draw. The Execution tab draws the same graph and runs it: a Run button starts +a run, and each node shows its live state until the run ends. The contract, the +stub that serves it and the tests around both are in this folder. ## Layout - `src/`: the UI. `graph/` turns a workflow into nodes and edges and does no IO; `api/` is the typed client of the API; `launch/` and `workflow/` open the session and load the workflow; `designer/` and `canvas/` draw it; - `execution/core/` starts a run and follows it, and does no IO. It reads a run + `execution/` runs it and shows the run; `execution/core/` does no IO and reads a run once a second. A read that fails with no answer or a server error is tried again, up to three in a row; any other failure ends the following. A start that finds a run already active follows that run. Every run call takes a @@ -132,7 +133,8 @@ The data covers the first release: a workflow of an intent and stages, and the `kiro-cli` harness. It is a `hello` workflow with a `draft` stage (`k-developer`) and a `review` stage (`k-quality-assurance`). A saved change lasts until the stub stops. A run is faked and calls no agent: its stages run -for 3 seconds each, one after the other, and all of them pass. +for 3 seconds each, one after the other, and all of them pass. It runs one run +at a time and never fails a stage. ### Run the page against the stub @@ -282,6 +284,46 @@ The rest wraps the core, so the rules can be tested without a browser: outcome short, and keeps the whole text in its `title`; an outcome too long for the node is also written out in full under the graph. +## The Execution tab + +The tab draws the same graph as the Designer, read-only, with a **Goal** box +and a **Run** button beside it. The goal starts as the outcome of the +intent, because the API needs one (1 to 2048 characters) to start a run. + +- **Run** calls `POST /api/run` with the goal, then reads + `GET /api/runs/{id}` once a second until the run is `passed` or `halted`. + Run and the goal box are off from the click until the run ends. +- Each node shows a badge with a word and a colour: **Queued** (dashed + outline), **Running**, **Done** and **Failed**. The intent is Done once the run + has it. After a halt, the stages behind the failed one say **Not run**. The end + shows the result: **Passed** or **Halted**. +- A line under the button says where the run is ("Running draft. 0 of 2 stages + done."). It is a polite live region, so a screen reader announces each + change, and each node's name for a screen reader ends with its state. +- An error from the API, whether the run does not start or a read fails, shows + in one alert above the graph, with the sentence the server gave. A failed + stage is a result, not an error, so it has no alert. +- A run goes on while the Designer tab is open, and the tab shows it again when + you come back. Closing the page stops the reading, not the run. +- The colours of the states are in `src/canvas/canvas.css` and match the theme + module, checked in both modes by the contrast test. + +The code follows the ports-and-adapters split of the graph: + +- `src/execution/core/` is the core and does no IO: the state of the tab and + its reducer, the loop that starts a run and reads it (`startAndFollow`), the + node states and the status sentences. Its ports are `RunPort` (start and + read a run) and `Scheduler` (wait for some milliseconds), so a test moves + time by hand and nothing sleeps. A test (`test-support/execution-purity.test.ts`) + fails if the core imports anything but its own modules, the graph core and the + wire types, or reads a clock, randomness, the environment or the network. +- The adapters are `createHttpApi` (`startRun`, `getRun`), which `loadWorkflow` + ties to the session token, and `timerScheduler`. The token is held only by + those run calls. +- `useExecution` keeps the state in `App`, and `Execution` draws it. The + Designer and Execution tabs share `WorkflowGate` (loading, error and empty + states) and `WorkflowGraphCard` (the card with the graph). + ## Theme The page has the look of the Konductor docs theme: its colours, fonts and @@ -357,7 +399,14 @@ npx playwright install chromium Then `npm run test:e2e`. The HTML report is written to `playwright-report/`; open it with `npx playwright show-report`. Accessibility is checked with -axe-core on each tab, on the error state and in both theme modes. +axe-core on each tab, on the error state, on the Execution tab with a stage +running, a failed stage and a passed run, and in both theme modes. + +The stub runs one run at a time and never fails a stage. So the one test that +starts a real run on it (`execution.spec.ts`, the first run test) waits for the +end of the run, and the tests of a failed stage or a refused run answer the +run calls themselves (`e2e/support/run-routes.ts`). A test that starts another +run on the stub must also wait for its end, or the next test gets a 409. Shared page objects and helpers live in `e2e/support/`. New tests should extend them rather than repeat selectors: import `test` and `expect` from @@ -366,12 +415,16 @@ the app. ## Screenshots -`npm run screenshots` saves a full-page PNG of each tab to -`e2e/screenshots/`, with the Designer tab drawn from the stub, at 1280x800 with -animations frozen. The tabs are in the light theme (`designer-tab.png`, -`execution-tab.png`), and `designer-tab-dark.png` is the Designer tab after -the theme button is pressed. Pull request descriptions embed these -files, so regenerate and commit them when the UI changes. +`npm run screenshots` saves full-page PNGs to `e2e/screenshots/`, drawn from +the stub, at 1280x800 with animations frozen. The Designer tab is in the light +theme (`designer-tab.png`) and in the dark one (`designer-tab-dark.png`, after +the theme button is pressed). The Execution tab is saved before a run +(`execution-tab-idle.png`), while the first stage runs +(`execution-tab-running.png`) and after the run passed +(`execution-tab-finished.png`), all in the light theme, and while the first +stage runs in the dark theme (`execution-tab-dark.png`). Pull request +descriptions embed these files, so regenerate and commit them when the UI +changes. Only that script writes the PNGs. It uses its own config, `playwright.screenshots.config.ts`, so `npm run test:e2e`, a bare diff --git a/workflow-canvas/e2e/capture/screenshots.spec.ts b/workflow-canvas/e2e/capture/screenshots.spec.ts index 54d1e840..7997f744 100644 --- a/workflow-canvas/e2e/capture/screenshots.spec.ts +++ b/workflow-canvas/e2e/capture/screenshots.spec.ts @@ -1,18 +1,17 @@ // SPDX-License-Identifier: Apache-2.0 -import { test } from '../support/fixtures'; +import { expect, test } from '../support/fixtures'; import { saveFullPageScreenshot } from '../support/screenshots'; -import { TAB_NAMES } from '../support/workflow-canvas-page'; +import { STEP_TIMEOUT_MS } from '../support/workflow-canvas-page'; -// Run with `npm run screenshots`. These tests assert nothing: they only -// regenerate the PNGs that PR descriptions embed. -for (const name of TAB_NAMES) { - test(`capture the ${name} tab`, async ({ canvas }) => { - await canvas.selectTab(name); - await canvas.expectTabLoaded(name); +// Run with `npm run screenshots`. These tests assert only what they must to +// reach the state they save: they regenerate the PNGs that PR descriptions +// embed. +test('capture the Designer tab', async ({ canvas }) => { + await canvas.selectTab('Designer'); + await canvas.expectTabLoaded('Designer'); - await saveFullPageScreenshot(canvas.page, `${name.toLowerCase()}-tab`); - }); -} + await saveFullPageScreenshot(canvas.page, 'designer-tab'); +}); // The Designer tab in the dark mode, switched with the button like a person would. test('capture the Designer tab in the dark mode', async ({ canvas }) => { @@ -21,3 +20,44 @@ test('capture the Designer tab in the dark mode', async ({ canvas }) => { await saveFullPageScreenshot(canvas.page, 'designer-tab-dark'); }); + +// A run on the stub, saved before it starts, while its first stage runs and +// after it passed. The stub allows one run at a time, so this is one test +// that waits for the end. +test('capture the Execution tab before, during and after a run', async ({ + canvas, +}) => { + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); + await saveFullPageScreenshot(canvas.page, 'execution-tab-idle'); + + await canvas.runButton.click(); + await expect(canvas.badge('node-stage-draft')).toHaveText('Running', { + timeout: STEP_TIMEOUT_MS, + }); + await canvas.expectBadges(['Done', 'Running', 'Queued', 'Queued']); + await saveFullPageScreenshot(canvas.page, 'execution-tab-running'); + + await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); + await expect(canvas.runStatus).toContainText('Run passed.'); + await saveFullPageScreenshot(canvas.page, 'execution-tab-finished'); +}); + +// The Execution tab in the dark mode, while the first stage runs. +test('capture the Execution tab in the dark mode during a run', async ({ + canvas, +}) => { + await canvas.switchTheme(); + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); + + await canvas.runButton.click(); + await expect(canvas.badge('node-stage-draft')).toHaveText('Running', { + timeout: STEP_TIMEOUT_MS, + }); + await canvas.expectBadges(['Done', 'Running', 'Queued', 'Queued']); + await saveFullPageScreenshot(canvas.page, 'execution-tab-dark'); + + // Leave the stub free for whatever runs next. + await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); +}); diff --git a/workflow-canvas/e2e/screenshots/execution-tab-dark.png b/workflow-canvas/e2e/screenshots/execution-tab-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4963731fda6972c73d6fab83c95a9f85164874 GIT binary patch literal 70824 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 ACjbBd literal 0 HcmV?d00001 diff --git a/workflow-canvas/e2e/screenshots/execution-tab-finished.png b/workflow-canvas/e2e/screenshots/execution-tab-finished.png new file mode 100644 index 0000000000000000000000000000000000000000..cffda123d6d2980f0bbf9310d9b30ca040d05a57 GIT binary patch literal 70715 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 z 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 literal 0 HcmV?d00001 diff --git a/workflow-canvas/e2e/screenshots/execution-tab-idle.png b/workflow-canvas/e2e/screenshots/execution-tab-idle.png new file mode 100644 index 0000000000000000000000000000000000000000..dae1b2120339ad7d8aa1a5f3f03426fc821b85b4 GIT binary patch literal 64922 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≪@YV>FrU5Uo5)l+C-b7-+ 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 Ws&KsZN)LQriZ_*SWM4CU_J07&?d~f8 literal 0 HcmV?d00001 diff --git a/workflow-canvas/e2e/screenshots/execution-tab-running.png b/workflow-canvas/e2e/screenshots/execution-tab-running.png new file mode 100644 index 0000000000000000000000000000000000000000..31358e869fe9087e5822ae9a018aba932ed1e674 GIT binary patch literal 69981 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≶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, +): Promise { + await page.route('**/api/run', (route) => + route.fulfill({ status: 202, json: { run_id: RUN_ID } }), + ); + await page.route('**/api/runs/*', (route) => route.fulfill({ json: reply })); +} + +/** Makes the page's call to start a run fail with the status and body. */ +export async function refuseRunsWith( + page: Page, + status: number, + body: { error: string; code: string }, +): Promise { + await page.route('**/api/run', (route) => + route.fulfill({ status, json: body }), + ); +} diff --git a/workflow-canvas/e2e/tests/accessibility.spec.ts b/workflow-canvas/e2e/tests/accessibility.spec.ts index da8f15dc..dd45b30c 100644 --- a/workflow-canvas/e2e/tests/accessibility.spec.ts +++ b/workflow-canvas/e2e/tests/accessibility.spec.ts @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 import { expectNoAccessibilityViolations } from '../support/accessibility'; import { test } from '../support/fixtures'; +import { answerRunsWith, runReply } from '../support/run-routes'; import { TAB_NAMES, WorkflowCanvasPage } from '../support/workflow-canvas-page'; for (const name of TAB_NAMES) { @@ -21,3 +22,39 @@ test('Designer tab has no axe violations when the workflow did not load', async await expectNoAccessibilityViolations(page); }); + +// The stub runs one run at a time, so these answer the run calls themselves. +const RUN_STATES = [ + ['a stage running', runReply('running', ['running', 'pending'])], + ['a failed stage', runReply('halted', ['blocked', 'pending'])], + ['a passed run', runReply('passed', ['passed', 'passed'])], +] as const; + +for (const [name, reply] of RUN_STATES) { + test(`Execution tab has no axe violations with ${name}`, async ({ + canvas, + }) => { + await answerRunsWith(canvas.page, reply); + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); + + await canvas.runButton.click(); + await canvas.badge('node-end').waitFor(); + + await expectNoAccessibilityViolations(canvas.page); + }); +} + +test('Execution tab has no axe violations with a failed stage in the dark mode', async ({ + canvas, +}) => { + await answerRunsWith(canvas.page, runReply('halted', ['blocked', 'pending'])); + await canvas.switchTheme(); + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); + + await canvas.runButton.click(); + await canvas.badge('node-end').waitFor(); + + await expectNoAccessibilityViolations(canvas.page); +}); diff --git a/workflow-canvas/e2e/tests/execution.spec.ts b/workflow-canvas/e2e/tests/execution.spec.ts new file mode 100644 index 00000000..121c9f02 --- /dev/null +++ b/workflow-canvas/e2e/tests/execution.spec.ts @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: Apache-2.0 +import { expect, test } from '../support/fixtures'; +import { + answerRunsWith, + refuseRunsWith, + runReply, +} from '../support/run-routes'; +import { STEP_TIMEOUT_MS } from '../support/workflow-canvas-page'; + +// The stub runs one run at a time. Only the first test here starts a run on +// it, and it waits for the end; the others answer the run calls themselves. + +test.beforeEach(async ({ canvas }) => { + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); +}); + +test('draws the same graph as the Designer, read-only, with a Run button and no states', async ({ + canvas, +}) => { + await canvas.expectWorkflowDrawn(); + await expect(canvas.runButton).toBeEnabled(); + await expect(canvas.goal).toHaveValue('Add a greeting to the README'); + await expect(canvas.runStatus).toContainText('Ready. Press Run to start.'); + await canvas.expectBadges([null, null, null, null]); +}); + +test('runs the workflow on the stub: each stage goes from queued to running to done, in order', async ({ + canvas, +}) => { + await canvas.runButton.click(); + await expect(canvas.runButton).toBeDisabled(); + await expect(canvas.goal).toBeDisabled(); + + await expect(canvas.badge('node-stage-draft')).toHaveText('Running', { + timeout: STEP_TIMEOUT_MS, + }); + await canvas.expectBadges(['Done', 'Running', 'Queued', 'Queued']); + await expect(canvas.runStatus).toContainText( + 'Running draft. 0 of 2 stages done.', + ); + await expect(canvas.runButton).toBeDisabled(); + + await expect(canvas.badge('node-stage-review')).toHaveText('Running', { + timeout: STEP_TIMEOUT_MS, + }); + await canvas.expectBadges(['Done', 'Done', 'Running', 'Queued']); + await expect(canvas.runStatus).toContainText( + 'Running review. 1 of 2 stages done.', + ); + + await expect(canvas.badge('node-end')).toHaveText('Passed', { + timeout: STEP_TIMEOUT_MS, + }); + await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); + await expect(canvas.runStatus).toContainText( + 'Run passed. 2 of 2 stages done. Exit code 0.', + ); + await expect(canvas.runButton).toBeEnabled(); + await expect(canvas.runError).toHaveCount(0); +}); + +test('announces the status in a polite live region and names the state of each node', async ({ + canvas, +}) => { + await answerRunsWith( + canvas.page, + runReply('running', ['running', 'pending']), + ); + + await canvas.runButton.click(); + + await expect(canvas.runStatus).toHaveAttribute('role', 'status'); + await expect(canvas.runStatus).toHaveAttribute('aria-live', 'polite'); + await expect(canvas.runStatus).toContainText('Running draft.'); + await expect( + canvas.nodeNamed( + 'Stage draft, agent k-developer, harness kiro-cli, running', + ), + ).toBeVisible(); + await expect(canvas.nodeNamed('End, queued')).toBeVisible(); +}); + +test('shows a failed stage with its words, the stages that will not run, and the halted result', async ({ + canvas, +}) => { + // The stub never fails a stage, so the reply is made here. + await answerRunsWith(canvas.page, runReply('halted', ['blocked', 'pending'])); + + await canvas.runButton.click(); + + await canvas.expectBadges(['Done', 'Failed', 'Not run', 'Halted']); + await expect(canvas.runStatus).toContainText( + 'Run halted at draft. 0 of 2 stages done. Exit code 1.', + ); + await expect(canvas.runButton).toBeEnabled(); + await expect(canvas.runError).toHaveCount(0); +}); + +test('shows the error of the API in one alert when the run does not start', async ({ + canvas, +}) => { + await refuseRunsWith(canvas.page, 409, { + error: 'kiro-cli is not installed.', + code: 'harness_unavailable', + }); + + await canvas.runButton.click(); + + await expect(canvas.runError).toHaveCount(1); + await expect(canvas.runError).toContainText('The run did not start'); + await expect(canvas.runError).toContainText('kiro-cli is not installed.'); + await expect(canvas.runStatus).toContainText('The run did not start.'); + await canvas.expectBadges([null, null, null, null]); + await expect(canvas.runButton).toBeEnabled(); +}); + +test('keeps the run going while the Designer tab is open', async ({ + canvas, +}) => { + await answerRunsWith(canvas.page, runReply('passed', ['passed', 'passed'])); + await canvas.runButton.click(); + await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); + + await canvas.selectTab('Designer'); + await expect(canvas.page.getByTestId('status-badge')).toHaveCount(0); + await canvas.selectTab('Execution'); + + await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); +}); From 3be480d044f4cdd6eebb18820a7fe2c6569cc8db Mon Sep 17 00:00:00 2001 From: Nihit <24500178+knihit@users.noreply.github.com> Date: Tue, 27 Oct 2026 23:03:29 +0000 Subject: [PATCH 03/10] Keep the goal across tabs, announce the run error and say the run may still be going The goal box text lives in App beside the run state, so a switch of tab no longer drops what was typed or shows another goal for a run in flight; the box is read-only, not disabled, while a run is in flight, and Enter in it starts a run. The alert sits in an alert region that is always on the page, so a screen reader reads the sentence of the server, and the status line says only to see the error above. A failed read adds that the run may still be going on the server. The e2e test of a run that goes on now waits for reads while the Designer tab is open, the axe runs cover the error and the invalid goal, and the captures use fixed run replies. --- workflow-canvas/README.md | 22 +++- .../e2e/capture/screenshots.spec.ts | 45 +++++--- workflow-canvas/e2e/support/run-routes.ts | 33 +++++- .../e2e/support/workflow-canvas-page.ts | 2 + .../e2e/tests/accessibility.spec.ts | 34 +++++- workflow-canvas/e2e/tests/execution.spec.ts | 94 +++++++++++++++- workflow-canvas/src/App.tsx | 12 +- workflow-canvas/src/canvas/nodes.tsx | 2 +- .../src/execution/Execution.test.tsx | 105 +++++++++++++++++- workflow-canvas/src/execution/Execution.tsx | 82 +++++++++----- .../src/execution/core/status-text.test.ts | 10 +- .../src/execution/core/status-text.ts | 9 +- workflow-canvas/src/execution/execution.css | 6 + .../src/execution/use-execution.ts | 4 +- workflow-canvas/src/execution/use-goal.ts | 18 +++ 15 files changed, 398 insertions(+), 80 deletions(-) create mode 100644 workflow-canvas/src/execution/use-goal.ts diff --git a/workflow-canvas/README.md b/workflow-canvas/README.md index 17a4b29a..781f6b11 100644 --- a/workflow-canvas/README.md +++ b/workflow-canvas/README.md @@ -292,7 +292,9 @@ intent, because the API needs one (1 to 2048 characters) to start a run. - **Run** calls `POST /api/run` with the goal, then reads `GET /api/runs/{id}` once a second until the run is `passed` or `halted`. - Run and the goal box are off from the click until the run ends. + Run is off and the goal box is read-only from the click until the run ends. + Read-only, not greyed out, so the box keeps focus and shows the goal of that + run. Enter in the box starts a run, like the button. - Each node shows a badge with a word and a colour: **Queued** (dashed outline), **Running**, **Done** and **Failed**. The intent is Done once the run has it. After a halt, the stages behind the failed one say **Not run**. The end @@ -301,10 +303,15 @@ intent, because the API needs one (1 to 2048 characters) to start a run. done."). It is a polite live region, so a screen reader announces each change, and each node's name for a screen reader ends with its state. - An error from the API, whether the run does not start or a read fails, shows - in one alert above the graph, with the sentence the server gave. A failed - stage is a result, not an error, so it has no alert. + in one alert above the graph, with the sentence the server gave. The alert + is drawn inside an alert region that is always on the page, so a screen + reader reads the sentence when it appears; the status line then says only + "See the error above." When a read fails, the nodes are cleared and the alert + adds that the run may still be going on the server. A failed stage is a + result, not an error, so it has no alert. - A run goes on while the Designer tab is open, and the tab shows it again when - you come back. Closing the page stops the reading, not the run. + you come back, with the goal box as it was: what you typed, or the goal of + the run in flight. Closing the page stops the reading, not the run. - The colours of the states are in `src/canvas/canvas.css` and match the theme module, checked in both modes by the contrast test. @@ -400,7 +407,8 @@ npx playwright install chromium Then `npm run test:e2e`. The HTML report is written to `playwright-report/`; open it with `npx playwright show-report`. Accessibility is checked with axe-core on each tab, on the error state, on the Execution tab with a stage -running, a failed stage and a passed run, and in both theme modes. +running, a failed stage, a passed run, the error of the API and a goal that +cannot be run, and in both theme modes. The stub runs one run at a time and never fails a stage. So the one test that starts a real run on it (`execution.spec.ts`, the first run test) waits for the @@ -416,7 +424,9 @@ the app. ## Screenshots `npm run screenshots` saves full-page PNGs to `e2e/screenshots/`, drawn from -the stub, at 1280x800 with animations frozen. The Designer tab is in the light +the stub, at 1280x800 with animations frozen. The runs in the Execution +captures answer with fixed replies, so no capture depends on the clock of the +stub. The Designer tab is in the light theme (`designer-tab.png`) and in the dark one (`designer-tab-dark.png`, after the theme button is pressed). The Execution tab is saved before a run (`execution-tab-idle.png`), while the first stage runs diff --git a/workflow-canvas/e2e/capture/screenshots.spec.ts b/workflow-canvas/e2e/capture/screenshots.spec.ts index 7997f744..05064863 100644 --- a/workflow-canvas/e2e/capture/screenshots.spec.ts +++ b/workflow-canvas/e2e/capture/screenshots.spec.ts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 import { expect, test } from '../support/fixtures'; +import { answerRunsWith, runReply } from '../support/run-routes'; import { saveFullPageScreenshot } from '../support/screenshots'; -import { STEP_TIMEOUT_MS } from '../support/workflow-canvas-page'; // Run with `npm run screenshots`. These tests assert only what they must to // reach the state they save: they regenerate the PNGs that PR descriptions @@ -21,25 +21,41 @@ test('capture the Designer tab in the dark mode', async ({ canvas }) => { await saveFullPageScreenshot(canvas.page, 'designer-tab-dark'); }); -// A run on the stub, saved before it starts, while its first stage runs and -// after it passed. The stub allows one run at a time, so this is one test -// that waits for the end. -test('capture the Execution tab before, during and after a run', async ({ +// The Execution tab before a run, drawn from the stub. +test('capture the Execution tab before a run', async ({ canvas }) => { + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); + + await saveFullPageScreenshot(canvas.page, 'execution-tab-idle'); +}); + +// The runs below answer with fixed replies, not a run on the stub, so a +// capture never races the three seconds that a stage takes there. +test('capture the Execution tab while the first stage runs', async ({ canvas, }) => { + await answerRunsWith( + canvas.page, + runReply('running', ['running', 'pending']), + ); await canvas.selectTab('Execution'); await canvas.expectTabLoaded('Execution'); - await saveFullPageScreenshot(canvas.page, 'execution-tab-idle'); await canvas.runButton.click(); - await expect(canvas.badge('node-stage-draft')).toHaveText('Running', { - timeout: STEP_TIMEOUT_MS, - }); await canvas.expectBadges(['Done', 'Running', 'Queued', 'Queued']); + await saveFullPageScreenshot(canvas.page, 'execution-tab-running'); +}); +test('capture the Execution tab after the run passed', async ({ canvas }) => { + await answerRunsWith(canvas.page, runReply('passed', ['passed', 'passed'])); + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); + + await canvas.runButton.click(); await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); await expect(canvas.runStatus).toContainText('Run passed.'); + await saveFullPageScreenshot(canvas.page, 'execution-tab-finished'); }); @@ -47,17 +63,16 @@ test('capture the Execution tab before, during and after a run', async ({ test('capture the Execution tab in the dark mode during a run', async ({ canvas, }) => { + await answerRunsWith( + canvas.page, + runReply('running', ['running', 'pending']), + ); await canvas.switchTheme(); await canvas.selectTab('Execution'); await canvas.expectTabLoaded('Execution'); await canvas.runButton.click(); - await expect(canvas.badge('node-stage-draft')).toHaveText('Running', { - timeout: STEP_TIMEOUT_MS, - }); await canvas.expectBadges(['Done', 'Running', 'Queued', 'Queued']); - await saveFullPageScreenshot(canvas.page, 'execution-tab-dark'); - // Leave the stub free for whatever runs next. - await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); + await saveFullPageScreenshot(canvas.page, 'execution-tab-dark'); }); diff --git a/workflow-canvas/e2e/support/run-routes.ts b/workflow-canvas/e2e/support/run-routes.ts index edd01d36..ee1896c1 100644 --- a/workflow-canvas/e2e/support/run-routes.ts +++ b/workflow-canvas/e2e/support/run-routes.ts @@ -30,6 +30,14 @@ export function runReply( }; } +type RunReply = ReturnType; + +async function acceptRuns(page: Page): Promise { + await page.route('**/api/run', (route) => + route.fulfill({ status: 202, json: { run_id: RUN_ID } }), + ); +} + /** * Makes the page's calls to start a run and to read it answer with `reply`, * without a run on the server. For states the stub never reaches, such as a @@ -38,14 +46,31 @@ export function runReply( */ export async function answerRunsWith( page: Page, - reply: ReturnType, + reply: RunReply, ): Promise { - await page.route('**/api/run', (route) => - route.fulfill({ status: 202, json: { run_id: RUN_ID } }), - ); + await acceptRuns(page); await page.route('**/api/runs/*', (route) => route.fulfill({ json: reply })); } +/** + * Like `answerRunsWith`, but each read of the run gets the next reply, and + * the last one is repeated. `reads()` says how many reads the page has made, + * so a test can wait for one without a fixed pause. + */ +export async function answerRunsInTurn( + page: Page, + replies: readonly RunReply[], +): Promise<{ reads(): number }> { + await acceptRuns(page); + let reads = 0; + await page.route('**/api/runs/*', (route) => { + const reply = replies[Math.min(reads, replies.length - 1)]; + reads += 1; + return route.fulfill({ json: reply }); + }); + return { reads: () => reads }; +} + /** Makes the page's call to start a run fail with the status and body. */ export async function refuseRunsWith( page: Page, diff --git a/workflow-canvas/e2e/support/workflow-canvas-page.ts b/workflow-canvas/e2e/support/workflow-canvas-page.ts index ec6637ff..ca316db5 100644 --- a/workflow-canvas/e2e/support/workflow-canvas-page.ts +++ b/workflow-canvas/e2e/support/workflow-canvas-page.ts @@ -52,6 +52,7 @@ export class WorkflowCanvasPage { readonly goal: Locator; readonly runStatus: Locator; readonly runError: Locator; + readonly runAlert: Locator; constructor(readonly page: Page) { this.main = page.getByRole('main'); @@ -64,6 +65,7 @@ export class WorkflowCanvasPage { this.goal = page.getByLabel('Goal'); this.runStatus = page.getByTestId('run-status'); this.runError = page.getByTestId('run-error'); + this.runAlert = page.locator('.wf-run-error[role="alert"]'); } /** diff --git a/workflow-canvas/e2e/tests/accessibility.spec.ts b/workflow-canvas/e2e/tests/accessibility.spec.ts index dd45b30c..258cc918 100644 --- a/workflow-canvas/e2e/tests/accessibility.spec.ts +++ b/workflow-canvas/e2e/tests/accessibility.spec.ts @@ -1,7 +1,11 @@ // SPDX-License-Identifier: Apache-2.0 import { expectNoAccessibilityViolations } from '../support/accessibility'; import { test } from '../support/fixtures'; -import { answerRunsWith, runReply } from '../support/run-routes'; +import { + answerRunsWith, + refuseRunsWith, + runReply, +} from '../support/run-routes'; import { TAB_NAMES, WorkflowCanvasPage } from '../support/workflow-canvas-page'; for (const name of TAB_NAMES) { @@ -58,3 +62,31 @@ test('Execution tab has no axe violations with a failed stage in the dark mode', await expectNoAccessibilityViolations(canvas.page); }); + +test('Execution tab has no axe violations with the error of the API shown', async ({ + canvas, +}) => { + await refuseRunsWith(canvas.page, 409, { + error: 'kiro-cli is not installed.', + code: 'harness_unavailable', + }); + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); + + await canvas.runButton.click(); + await canvas.runError.waitFor(); + + await expectNoAccessibilityViolations(canvas.page); +}); + +test('Execution tab has no axe violations with a goal that cannot be run', async ({ + canvas, +}) => { + await canvas.selectTab('Execution'); + await canvas.expectTabLoaded('Execution'); + + await canvas.goal.fill(''); + await canvas.page.getByText('Enter a goal to run.').first().waitFor(); + + await expectNoAccessibilityViolations(canvas.page); +}); diff --git a/workflow-canvas/e2e/tests/execution.spec.ts b/workflow-canvas/e2e/tests/execution.spec.ts index 121c9f02..fd484670 100644 --- a/workflow-canvas/e2e/tests/execution.spec.ts +++ b/workflow-canvas/e2e/tests/execution.spec.ts @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 import { expect, test } from '../support/fixtures'; import { + answerRunsInTurn, answerRunsWith, refuseRunsWith, runReply, @@ -30,7 +31,7 @@ test('runs the workflow on the stub: each stage goes from queued to running to d }) => { await canvas.runButton.click(); await expect(canvas.runButton).toBeDisabled(); - await expect(canvas.goal).toBeDisabled(); + await expect(canvas.goal).not.toBeEditable(); await expect(canvas.badge('node-stage-draft')).toHaveText('Running', { timeout: STEP_TIMEOUT_MS, @@ -105,26 +106,109 @@ test('shows the error of the API in one alert when the run does not start', asyn code: 'harness_unavailable', }); + await expect(canvas.runAlert).toBeEmpty(); + await canvas.runButton.click(); await expect(canvas.runError).toHaveCount(1); await expect(canvas.runError).toContainText('The run did not start'); await expect(canvas.runError).toContainText('kiro-cli is not installed.'); - await expect(canvas.runStatus).toContainText('The run did not start.'); + await expect(canvas.runStatus).toContainText('See the error above.'); + await expect(canvas.runAlert).toContainText('kiro-cli is not installed.'); await canvas.expectBadges([null, null, null, null]); await expect(canvas.runButton).toBeEnabled(); }); -test('keeps the run going while the Designer tab is open', async ({ +test('says the run may still be going when it can no longer be followed', async ({ canvas, }) => { - await answerRunsWith(canvas.page, runReply('passed', ['passed', 'passed'])); + await answerRunsWith( + canvas.page, + runReply('running', ['running', 'pending']), + ); + await canvas.page.route('**/api/runs/*', (route) => + route.fulfill({ + status: 404, + json: { error: 'There is no run with this id.', code: 'not_found' }, + }), + ); + await canvas.runButton.click(); - await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); + + await expect(canvas.runError).toContainText('The run could not be followed'); + await expect(canvas.runAlert).toContainText('There is no run with this id.'); + await expect(canvas.runAlert).toContainText( + 'The run may still be going on the server.', + ); +}); + +test('keeps following the run while the Designer tab is open', async ({ + canvas, +}) => { + const server = await answerRunsInTurn(canvas.page, [ + runReply('running', ['running', 'pending']), + runReply('passed', ['passed', 'passed']), + ]); + await canvas.runButton.click(); + await canvas.expectBadges(['Done', 'Running', 'Queued', 'Queued']); await canvas.selectTab('Designer'); + await expect + .poll(server.reads, { timeout: STEP_TIMEOUT_MS }) + .toBeGreaterThanOrEqual(2); await expect(canvas.page.getByTestId('status-badge')).toHaveCount(0); await canvas.selectTab('Execution'); await canvas.expectBadges(['Done', 'Done', 'Done', 'Passed']); }); + +test('keeps the goal that was typed when the person comes back from the Designer tab', async ({ + canvas, +}) => { + await canvas.goal.fill('Fix the typo'); + + await canvas.selectTab('Designer'); + await canvas.selectTab('Execution'); + + await expect(canvas.goal).toHaveValue('Fix the typo'); + await expect(canvas.runButton).toBeEnabled(); +}); + +test('shows the goal of the run in flight, read-only, when the person comes back from the Designer tab', async ({ + canvas, +}) => { + await answerRunsWith( + canvas.page, + runReply('running', ['running', 'pending']), + ); + await canvas.goal.fill('Fix the typo'); + const started = canvas.page.waitForRequest('**/api/run'); + + await canvas.runButton.click(); + await expect(canvas.runStatus).toContainText('Running draft.'); + expect((await started).postDataJSON()).toEqual({ + params: { goal: 'Fix the typo' }, + }); + + await canvas.selectTab('Designer'); + await canvas.selectTab('Execution'); + + await expect(canvas.goal).toHaveValue('Fix the typo'); + await expect(canvas.goal).not.toBeEditable(); + await expect(canvas.runButton).toBeDisabled(); +}); + +test('starts the run when Enter is pressed in the goal box, and keeps focus there', async ({ + canvas, +}) => { + await answerRunsWith( + canvas.page, + runReply('running', ['running', 'pending']), + ); + await canvas.goal.focus(); + + await canvas.goal.press('Enter'); + + await expect(canvas.runStatus).toContainText('Running draft.'); + await expect(canvas.goal).toBeFocused(); +}); diff --git a/workflow-canvas/src/App.tsx b/workflow-canvas/src/App.tsx index fa4af464..9b92fa94 100644 --- a/workflow-canvas/src/App.tsx +++ b/workflow-canvas/src/App.tsx @@ -13,6 +13,7 @@ import type { Scheduler } from './execution/core'; import { Execution } from './execution/Execution'; import { timerScheduler } from './execution/timer-scheduler'; import { useExecution } from './execution/use-execution'; +import { useGoal } from './execution/use-goal'; import { TAB_STRIP_STYLE } from './theme/tokens'; import { useThemeMode } from './theme/use-theme-mode'; import { openWorkflowName, type LoadResult } from './workflow/load-workflow'; @@ -35,11 +36,13 @@ export function App({ }) { // Read here, not in the tab, so switching tabs does not load again. const result = useSettled(load); - // Kept here too, so a run goes on while the Designer tab is open. + // Kept here too, so a run goes on and the goal stays while the Designer tab + // is open. const execution = useExecution( result?.ok ? result.workflow.runs : undefined, scheduler, ); + const [goal, setGoal] = useGoal(result); const [mode, toggleMode] = useThemeMode(); return ( <> @@ -74,7 +77,12 @@ export function App({ id: 'execution', label: 'Execution', content: ( - + ), }, ]} diff --git a/workflow-canvas/src/canvas/nodes.tsx b/workflow-canvas/src/canvas/nodes.tsx index 848f54d5..39922e2e 100644 --- a/workflow-canvas/src/canvas/nodes.tsx +++ b/workflow-canvas/src/canvas/nodes.tsx @@ -105,7 +105,7 @@ function Tab({ top }: { top: number }) { ); } -/** The state of a node in a run, as a word in a coloured pill. */ +// The state of a node in a run, as a word in a coloured pill. function StatusBadge({ status }: { status: NodeStatus | undefined }) { if (!status) return null; return ( diff --git a/workflow-canvas/src/execution/Execution.test.tsx b/workflow-canvas/src/execution/Execution.test.tsx index 68803116..b2c47378 100644 --- a/workflow-canvas/src/execution/Execution.test.tsx +++ b/workflow-canvas/src/execution/Execution.test.tsx @@ -15,6 +15,7 @@ import { HELLO_DOCUMENT, helloRun, loaded } from '../test-support/fixtures'; import type { RunPort } from './core'; const RUN_ID = helloRun(0).runId; +const MAY_STILL_BE_RUNNING = 'The run may still be going on the server.'; // A server that answers with the readings in turn and then repeats the last. function serverShowing(...readings: RunView[]): RunPort { @@ -189,13 +190,27 @@ describe('a run', () => { await press(runButton()); expect(isOff(runButton())).toBe(true); - expect(screen.getByLabelText('Goal').hasAttribute('disabled')).toBe(true); + expect(screen.getByLabelText('Goal').hasAttribute('readonly')).toBe(true); await press(runButton()); expect(runs.start).toHaveBeenCalledOnce(); await tick(scheduler); expect(isOff(runButton())).toBe(false); - expect(screen.getByLabelText('Goal').hasAttribute('disabled')).toBe(false); + expect(screen.getByLabelText('Goal').hasAttribute('readonly')).toBe(false); + }); + + it('keeps keyboard focus in the goal box when Enter starts the run', async () => { + await openExecution(serverShowing(helloRun(0))); + const goal = screen.getByLabelText('Goal'); + goal.focus(); + + await act(async () => { + fireEvent.keyDown(goal, { key: 'Enter', keyCode: 13 }); + }); + + expect(statusLine().textContent).toContain('Running draft.'); + expect(document.activeElement).toBe(goal); + expect(goal.hasAttribute('disabled')).toBe(false); }); it('disables Run from the moment of the click, before the run is accepted', async () => { @@ -286,6 +301,71 @@ describe('a run', () => { }); describe('the goal', () => { + const goalBox = () => screen.getByLabelText('Goal') as HTMLInputElement; + const openTab = (name: string) => + fireEvent.click(screen.getByRole('tab', { name })); + + it('is kept when the person goes to the Designer tab and comes back', async () => { + await openExecution(serverShowing(helloRun(0))); + fireEvent.change(goalBox(), { target: { value: 'Fix the typo' } }); + + openTab('Designer'); + openTab('Execution'); + + expect(goalBox().value).toBe('Fix the typo'); + expect(isOff(runButton())).toBe(false); + }); + + it('shows the goal of the run in flight, read-only, when the person comes back', async () => { + const runs = serverShowing(helloRun(0)); + await openExecution(runs); + fireEvent.change(goalBox(), { target: { value: 'Fix the typo' } }); + await press(runButton()); + + openTab('Designer'); + openTab('Execution'); + + expect(goalBox().value).toBe('Fix the typo'); + expect(goalBox().readOnly).toBe(true); + expect(isOff(runButton())).toBe(true); + expect(runs.start).toHaveBeenCalledWith('Fix the typo'); + }); + + it('starts a run when Enter is pressed in the goal box', async () => { + const runs = serverShowing(helloRun(0)); + await openExecution(runs); + + await act(async () => { + fireEvent.keyDown(goalBox(), { key: 'Enter', keyCode: 13 }); + }); + + expect(runs.start).toHaveBeenCalledOnce(); + }); + + it('does not start a run on Enter when the goal is empty', async () => { + const runs = serverShowing(helloRun(0)); + await openExecution(runs); + fireEvent.change(goalBox(), { target: { value: '' } }); + + await act(async () => { + fireEvent.keyDown(goalBox(), { key: 'Enter', keyCode: 13 }); + }); + + expect(runs.start).not.toHaveBeenCalled(); + }); + + it('does not start a run on Enter while a run is in flight', async () => { + const runs = serverShowing(helloRun(0)); + await openExecution(runs); + await press(runButton()); + + await act(async () => { + fireEvent.keyDown(goalBox(), { key: 'Enter', keyCode: 13 }); + }); + + expect(runs.start).toHaveBeenCalledOnce(); + }); + it('turns Run off, and says why, when the goal is empty', async () => { const runs = serverShowing(helloRun(0)); await openExecution(runs); @@ -330,7 +410,8 @@ describe('errors from the API', () => { expect(within(alert).getByText('The run did not start')).toBeTruthy(); expect(within(alert).getByText('A run is already active.')).toBeTruthy(); expect(screen.getAllByTestId('run-error')).toHaveLength(1); - expect(statusLine().textContent).toContain('The run did not start.'); + expect(within(alert).queryByText(MAY_STILL_BE_RUNNING)).toBeNull(); + expect(statusLine().textContent).toContain('See the error above.'); expect(badges()).toEqual([null, null, null, null]); expect(isOff(runButton())).toBe(false); }); @@ -353,11 +434,29 @@ describe('errors from the API', () => { within(alert).getByText('The run could not be followed'), ).toBeTruthy(); expect(within(alert).getByText('The server did not answer.')).toBeTruthy(); + expect(within(alert).getByText(MAY_STILL_BE_RUNNING)).toBeTruthy(); expect(screen.getAllByTestId('run-error')).toHaveLength(1); + expect(statusLine().textContent).toContain('See the error above.'); expect(badges()).toEqual([null, null, null, null]); expect(isOff(runButton())).toBe(false); }); + it('puts the alert inside an alert region that is always on the page, so the sentence is announced', async () => { + const runs: RunPort = { + start: vi.fn().mockRejectedValue(new Error('A run is already active.')), + get: vi.fn(), + }; + await openExecution(runs); + const region = document.querySelector('[role="alert"].wf-run-error'); + expect(region).not.toBeNull(); + expect(region?.textContent).toBe(''); + + await press(runButton()); + + expect(region?.contains(screen.getByTestId('run-error'))).toBe(true); + expect(region?.textContent).toContain('A run is already active.'); + }); + it('takes the alert away when a new run starts', async () => { const runs: RunPort = { start: vi diff --git a/workflow-canvas/src/execution/Execution.tsx b/workflow-canvas/src/execution/Execution.tsx index 9dcafc05..0dad0042 100644 --- a/workflow-canvas/src/execution/Execution.tsx +++ b/workflow-canvas/src/execution/Execution.tsx @@ -9,7 +9,7 @@ import SpaceBetween from '@cloudscape-design/components/space-between'; import StatusIndicator, { type StatusIndicatorProps, } from '@cloudscape-design/components/status-indicator'; -import { useMemo, useState } from 'react'; +import { useMemo } from 'react'; import { WorkflowGraphCard } from '../canvas/WorkflowGraphCard'; import type { LoadResult } from '../workflow/load-workflow'; import { WorkflowGate, type DrawableWorkflow } from '../workflow/WorkflowGate'; @@ -25,7 +25,7 @@ import { type StatusKind, } from './core'; import './execution.css'; -import type { Execution as ExecutionController } from './use-execution'; +import type { ExecutionController } from './use-execution'; const INDICATOR: Record = { idle: 'pending', @@ -34,6 +34,8 @@ const INDICATOR: Record = { error: 'error', }; +const MAY_STILL_BE_RUNNING = 'The run may still be going on the server.'; + // One live region that says where the run is. It is always on the page, so a // change of its text is announced. function RunStatusLine({ state }: { state: ExecutionState }) { @@ -46,33 +48,41 @@ function RunStatusLine({ state }: { state: ExecutionState }) { ); } +// The wrapper is always on the page, so the alert that appears in it is +// announced with the sentence of the server, which the status line leaves out. function RunError({ state }: { state: ExecutionState }) { - if (state.phase !== 'error') return null; return ( - - {state.message} - +
+ {state.phase === 'error' && ( + + {state.message} + {state.started &&
{MAY_STILL_BE_RUNNING}
} +
+ )} +
); } function RunPanel({ - defaultGoal, + goal, + onGoalChange, execution, }: { - defaultGoal: string; + goal: string; + onGoalChange: (goal: string) => void; execution: ExecutionController; }) { - const [goal, setGoal] = useState(defaultGoal); const inFlight = isInFlight(execution.state); const problem = goalProblem(goal); + const canRun = !inFlight && problem === undefined; return ( Run}> @@ -84,13 +94,16 @@ function RunPanel({ > setGoal(detail.value)} + readOnly={inFlight} + onChange={({ detail }) => onGoalChange(detail.value)} + onKeyDown={({ detail }) => { + if (detail.key === 'Enter' && canRun) execution.start(goal); + }} />
+ ); @@ -131,7 +123,6 @@ function ExecutionView({ const statuses = useMemo(() => nodeStatuses(run), [run]); return (
-
+
+ {statusText(state)} +
+
+ {runErrorSentence(state)} +
+ + ); +} diff --git a/workflow-canvas/src/execution/announcements.css b/workflow-canvas/src/execution/announcements.css new file mode 100644 index 00000000..bb653cc3 --- /dev/null +++ b/workflow-canvas/src/execution/announcements.css @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* On the page for a screen reader, not for the eye. */ +.wf-visually-hidden { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + border: 0; + clip-path: inset(50%); + white-space: nowrap; +} diff --git a/workflow-canvas/src/execution/core/execution-state.test.ts b/workflow-canvas/src/execution/core/execution-state.test.ts index 7db9332c..4aa1e693 100644 --- a/workflow-canvas/src/execution/core/execution-state.test.ts +++ b/workflow-canvas/src/execution/core/execution-state.test.ts @@ -118,6 +118,7 @@ describe('reduce', () => { phase: 'error', message: 'Lost.', started: true, + runId: RUN_ID, }); }); diff --git a/workflow-canvas/src/execution/core/execution-state.ts b/workflow-canvas/src/execution/core/execution-state.ts index 296e72a1..c605740f 100644 --- a/workflow-canvas/src/execution/core/execution-state.ts +++ b/workflow-canvas/src/execution/core/execution-state.ts @@ -19,6 +19,8 @@ export type ExecutionState = started: boolean; /** Set when the start got no clear answer, so the run may be going. */ maybeStarted?: true; + /** The run that was being followed, when the failure came after it began. */ + runId?: string; }; /** Something that happened to the run, in the order it can. */ @@ -88,7 +90,7 @@ function failedOf( : { phase: 'error', message, started: false }; } if (state.phase === 'following' && runId === state.runId) { - return { phase: 'error', message, started: true }; + return { phase: 'error', message, started: true, runId: state.runId }; } return state; } diff --git a/workflow-canvas/src/execution/core/status-text.test.ts b/workflow-canvas/src/execution/core/status-text.test.ts index 46aea8d8..8d769143 100644 --- a/workflow-canvas/src/execution/core/status-text.test.ts +++ b/workflow-canvas/src/execution/core/status-text.test.ts @@ -63,13 +63,13 @@ describe('statusText and statusKind', () => { [ 'an error before the run started', { phase: 'error', message: 'x', started: false }, - 'See the error above.', + 'See the error below.', 'error', ], [ 'an error after the run started', { phase: 'error', message: 'x', started: true }, - 'See the error above.', + 'See the error below.', 'error', ], ])('says %s', (_, state, text, kind) => { diff --git a/workflow-canvas/src/execution/core/status-text.ts b/workflow-canvas/src/execution/core/status-text.ts index cfc0c74c..fa45ac3c 100644 --- a/workflow-canvas/src/execution/core/status-text.ts +++ b/workflow-canvas/src/execution/core/status-text.ts @@ -45,7 +45,7 @@ export function statusText(state: ExecutionState): string { case 'finished': return finishedText(state.run); case 'error': - return 'See the error above.'; + return 'See the error below.'; } } diff --git a/workflow-canvas/src/execution/execution.css b/workflow-canvas/src/execution/execution.css index bc5f5a37..dd3df030 100644 --- a/workflow-canvas/src/execution/execution.css +++ b/workflow-canvas/src/execution/execution.css @@ -16,9 +16,3 @@ grid-template-columns: minmax(0, 1fr); } } - -/* Room under the alert only while it has content, so the empty live region - leaves no gap. */ -.wf-run-error:not(:empty) { - margin-block-end: 20px; -} diff --git a/workflow-canvas/src/execution/run-error.ts b/workflow-canvas/src/execution/run-error.ts new file mode 100644 index 00000000..8ae05c2a --- /dev/null +++ b/workflow-canvas/src/execution/run-error.ts @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +import type { ExecutionState } from './core'; + +/** What the person is told when a run could not start or be followed. */ +export interface RunErrorText { + header: string; + /** The sentence of the server or the page. */ + message: string; + /** Said after a failure to follow: the run itself may be going on. */ + note?: string; +} + +/** The words for the error of a run, or `undefined` when there is none. */ +export function runErrorOf(state: ExecutionState): RunErrorText | undefined { + if (state.phase !== 'error') return undefined; + if (!state.started) { + return { header: 'The run did not start', message: state.message }; + } + const which = state.runId === undefined ? '' : ` (run ${state.runId})`; + return { + header: 'The run could not be followed', + message: state.message, + note: `The run may still be going on the server${which}.`, + }; +} + +const withStop = (text: string) => (/[.!?]$/.test(text) ? text : `${text}.`); + +/** The error as one run of sentences for a screen reader, or an empty string. */ +export function runErrorSentence(state: ExecutionState): string { + const error = runErrorOf(state); + if (!error) return ''; + return [error.header, error.message, error.note] + .filter((part): part is string => part !== undefined) + .map(withStop) + .join(' '); +} diff --git a/workflow-canvas/src/execution/use-goal.ts b/workflow-canvas/src/execution/use-goal.ts index 24243660..0ea7b97e 100644 --- a/workflow-canvas/src/execution/use-goal.ts +++ b/workflow-canvas/src/execution/use-goal.ts @@ -2,6 +2,12 @@ import { useState } from 'react'; import type { LoadResult } from '../workflow/load-workflow'; +// The box is one line, so a line break of the outcome becomes a space, and +// what the person reads is what the run is given. +function oneLine(text: string): string { + return text.replace(/\s*[\r\n]+\s*/g, ' '); +} + /** * The text of the Goal box: what the person typed, or the outcome of the * intent until they type. The caller keeps it, so it survives a switch of @@ -14,5 +20,5 @@ export function useGoal( const outcome = result?.ok ? result.workflow.document.view?.intent.outcome : ''; - return [typed ?? outcome ?? '', setTyped]; + return [typed ?? oneLine(outcome ?? ''), setTyped]; } From de4f25d25a0c533966ab9e05e473b307f2c5ccf0 Mon Sep 17 00:00:00 2001 From: Nihit <24500178+knihit@users.noreply.github.com> Date: Wed, 28 Oct 2026 17:03:54 +0000 Subject: [PATCH 07/10] Warn when the run has other stages than the graph A workflow can be saved while a run goes on. Node states attach by stage name, so the run may then miss some nodes. A warning above the graph names the stages that are not drawn and the ones that are not in the run. --- workflow-canvas/README.md | 3 ++ workflow-canvas/e2e/tests/execution.spec.ts | 20 +++++++ .../src/execution/Execution.test.tsx | 33 ++++++++++++ workflow-canvas/src/execution/Execution.tsx | 29 +++++++++- workflow-canvas/src/execution/core/index.ts | 1 + .../src/execution/core/stage-drift.test.ts | 53 +++++++++++++++++++ .../src/execution/core/stage-drift.ts | 30 +++++++++++ 7 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 workflow-canvas/src/execution/core/stage-drift.test.ts create mode 100644 workflow-canvas/src/execution/core/stage-drift.ts diff --git a/workflow-canvas/README.md b/workflow-canvas/README.md index 29ce83d2..a0ff517e 100644 --- a/workflow-canvas/README.md +++ b/workflow-canvas/README.md @@ -313,6 +313,9 @@ intent, because the API needs one (1 to 2048 characters) to start a run. going on the server. A failed stage is a result, not an error, so it has no alert. The goal is one line: line breaks in the outcome of the intent become spaces, and Enter that ends an input method composition starts no run. +- A workflow can be saved while a run goes on, so the run may have other stages + than the graph. Node states attach by stage name, so a warning above the + graph names the stages that are not drawn and those that are not in the run. - A run goes on while the Designer tab is open, and the tab shows it again when you come back, with the goal box as it was: what you typed, or the goal of the run in flight. Closing the page stops the reading, not the run. diff --git a/workflow-canvas/e2e/tests/execution.spec.ts b/workflow-canvas/e2e/tests/execution.spec.ts index dff711c7..2e829d29 100644 --- a/workflow-canvas/e2e/tests/execution.spec.ts +++ b/workflow-canvas/e2e/tests/execution.spec.ts @@ -98,6 +98,26 @@ test('shows a failed stage with its words, the stages that will not run, and the await expect(canvas.runError).toHaveCount(0); }); +test('says so when the stages of the run are not the stages in the graph', async ({ + canvas, +}) => { + const reply = runReply('running', ['running', 'pending']); + const run = reply.run; + await answerRunsWith(canvas.page, { + run: { + ...run, + order: ['write', 'review'], + stages: { write: { status: 'running' }, review: { status: 'pending' } }, + }, + } as unknown as typeof reply); + + await canvas.runButton.click(); + + const notice = canvas.page.getByTestId('stage-drift'); + await expect(notice).toContainText('Not drawn: write.'); + await expect(notice).toContainText('Not in the run: draft.'); +}); + test('shows the error of the API in one alert when the run does not start', async ({ canvas, }) => { diff --git a/workflow-canvas/src/execution/Execution.test.tsx b/workflow-canvas/src/execution/Execution.test.tsx index f1f7b080..1f58e794 100644 --- a/workflow-canvas/src/execution/Execution.test.tsx +++ b/workflow-canvas/src/execution/Execution.test.tsx @@ -619,6 +619,39 @@ describe('the alert, when another run is started', () => { }); }); +describe('a run whose stages are not the stages of the graph', () => { + const OTHER_STAGES: RunView = { + ...helloRun(0), + stages: [ + { name: 'write', status: 'running' }, + { name: 'review', status: 'pending' }, + ], + }; + const notice = () => screen.queryByTestId('stage-drift'); + + it('says so, naming the stages that differ, once the run is read', async () => { + const scheduler = await openExecution(serverShowing(OTHER_STAGES)); + expect(notice()).toBeNull(); + + await press(runButton()); + await tick(scheduler); + + expect(notice()?.textContent).toContain('not the stages in the graph'); + expect(notice()?.textContent).toContain('Not drawn: write.'); + expect(notice()?.textContent).toContain('Not in the run: draft.'); + }); + + it('says nothing for a run of the stages that are drawn', async () => { + const scheduler = await openExecution(serverShowing(helloRun(0))); + + await press(runButton()); + await tick(scheduler); + + expect(statusLine().textContent).toContain('Running draft'); + expect(notice()).toBeNull(); + }); +}); + describe('when there is no workflow to run', () => { it('shows the message of the failed load, with no Run button', async () => { render( diff --git a/workflow-canvas/src/execution/Execution.tsx b/workflow-canvas/src/execution/Execution.tsx index aed4be8a..cf0d461c 100644 --- a/workflow-canvas/src/execution/Execution.tsx +++ b/workflow-canvas/src/execution/Execution.tsx @@ -10,6 +10,7 @@ import StatusIndicator, { type StatusIndicatorProps, } from '@cloudscape-design/components/status-indicator'; import { useMemo } from 'react'; +import type { RunView, WorkflowView } from '../api/types'; import { WorkflowGraphCard } from '../canvas/WorkflowGraphCard'; import type { LoadResult } from '../workflow/load-workflow'; import { WorkflowGate, type DrawableWorkflow } from '../workflow/WorkflowGate'; @@ -19,6 +20,7 @@ import { isInFlight, nodeStatuses, runOf, + stageDrift, statusKind, statusText, type ExecutionState, @@ -60,6 +62,28 @@ function RunError({ state }: { state: ExecutionState }) { ); } +// A run reads the saved file, which can change while it goes on, so its stages +// can differ from the graph, and then some nodes show no state. +function StageDriftNotice({ + view, + run, +}: { + view: WorkflowView; + run: RunView | undefined; +}) { + const drift = stageDrift(view, run); + if (!drift) return null; + const { notInGraph, notInRun } = drift; + return ( + + The stages of this run are not the stages in the graph, so some nodes show + no state. The workflow file changed after the run started. + {notInGraph.length > 0 && ` Not drawn: ${notInGraph.join(', ')}.`} + {notInRun.length > 0 && ` Not in the run: ${notInRun.join(', ')}.`} + + ); +} + function RunPanel({ goal, onGoalChange, @@ -122,7 +146,8 @@ function ExecutionView({ const run = runOf(execution.state); const statuses = useMemo(() => nodeStatuses(run), [run]); return ( -
+ +
-
+ ); } diff --git a/workflow-canvas/src/execution/core/index.ts b/workflow-canvas/src/execution/core/index.ts index 2a8cd288..fd6f1a35 100644 --- a/workflow-canvas/src/execution/core/index.ts +++ b/workflow-canvas/src/execution/core/index.ts @@ -28,4 +28,5 @@ export { type RunPort, type Scheduler, } from './ports'; +export { stageDrift, type StageDrift } from './stage-drift'; export { statusKind, statusText, type StatusKind } from './status-text'; diff --git a/workflow-canvas/src/execution/core/stage-drift.test.ts b/workflow-canvas/src/execution/core/stage-drift.test.ts new file mode 100644 index 00000000..4c8bd85e --- /dev/null +++ b/workflow-canvas/src/execution/core/stage-drift.test.ts @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +import { describe, expect, it } from 'vitest'; +import { HELLO_VIEW, helloRun } from '../../test-support/fixtures'; +import { stageDrift } from './stage-drift'; + +describe('stageDrift', () => { + it('is nothing before there is a run', () => { + expect(stageDrift(HELLO_VIEW, undefined)).toBeUndefined(); + }); + + it('is nothing when the run has the stages of the graph', () => { + expect(stageDrift(HELLO_VIEW, helloRun(1))).toBeUndefined(); + }); + + it('names a stage of the run that the graph does not have', () => { + const view = { ...HELLO_VIEW, stages: [HELLO_VIEW.stages[0]!] }; + + expect(stageDrift(view, helloRun(0))).toEqual({ + notInGraph: ['review'], + notInRun: [], + }); + }); + + it('names a stage of the graph that the run does not have', () => { + const view = { + ...HELLO_VIEW, + stages: [...HELLO_VIEW.stages, { name: 'ship', agent: 'k-developer' }], + }; + + expect(stageDrift(view, helloRun(0))).toEqual({ + notInGraph: [], + notInRun: ['ship'], + }); + }); + + it('names a stage that was renamed on both sides', () => { + const view = { + ...HELLO_VIEW, + stages: [{ name: 'write', agent: 'k-developer' }, HELLO_VIEW.stages[1]!], + }; + + expect(stageDrift(view, helloRun(0))).toEqual({ + notInGraph: ['draft'], + notInRun: ['write'], + }); + }); + + it('is nothing when only the order differs', () => { + const view = { ...HELLO_VIEW, stages: [...HELLO_VIEW.stages].reverse() }; + + expect(stageDrift(view, helloRun(0))).toBeUndefined(); + }); +}); diff --git a/workflow-canvas/src/execution/core/stage-drift.ts b/workflow-canvas/src/execution/core/stage-drift.ts new file mode 100644 index 00000000..ed6f495e --- /dev/null +++ b/workflow-canvas/src/execution/core/stage-drift.ts @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +import type { RunView, WorkflowView } from '../../api/types'; + +/** The stages that the graph and the run do not share, by name. */ +export interface StageDrift { + /** Stages of the run that the graph does not draw. */ + notInGraph: string[]; + /** Stages of the graph that the run does not have. */ + notInRun: string[]; +} + +/** + * How the stages of `run` differ from those of the graph, or `undefined` when + * they are the same stages. A workflow can be saved while a run is active, so + * the run may be of an older or newer file than the graph, and node states, + * which attach by stage name, then miss some nodes. + */ +export function stageDrift( + view: WorkflowView, + run: RunView | undefined, +): StageDrift | undefined { + if (!run) return undefined; + const inGraph = view.stages.map((stage) => stage.name); + const inRun = run.stages.map((stage) => stage.name); + const notInGraph = inRun.filter((name) => !inGraph.includes(name)); + const notInRun = inGraph.filter((name) => !inRun.includes(name)); + return notInGraph.length + notInRun.length === 0 + ? undefined + : { notInGraph, notInRun }; +} From 76393ca537f5a1f09fd4501a7562c08f083462b0 Mon Sep 17 00:00:00 2001 From: Nihit <24500178+knihit@users.noreply.github.com> Date: Wed, 28 Oct 2026 19:32:32 +0000 Subject: [PATCH 08/10] Fix the run announcements, Safari Enter, and the drift notice The live status region stays empty on an error, as the alert says it all. An Enter with key code 229 starts no run, which is how Safari reports the one that ends a composition. The stage notice says the file may have changed after the page loaded, and tells the person to reload. A start with no clear answer says the run may not have started. A new workflow redraws the Execution tab canvas. --- workflow-canvas/README.md | 4 +- .../src/execution/Execution.test.tsx | 77 ++++++++++++++++++- workflow-canvas/src/execution/Execution.tsx | 13 +++- .../src/execution/RunAnnouncements.tsx | 5 +- workflow-canvas/src/execution/run-error.ts | 8 +- 5 files changed, 97 insertions(+), 10 deletions(-) diff --git a/workflow-canvas/README.md b/workflow-canvas/README.md index a0ff517e..e4f5b97f 100644 --- a/workflow-canvas/README.md +++ b/workflow-canvas/README.md @@ -297,7 +297,7 @@ intent, because the API needs one (1 to 2048 characters) to start a run. run. Enter in the box starts a run, like the button. - Each node shows a badge with a word and a colour: **Queued** (with a dashed outline), **Running**, **Done** and **Failed**. The word carries the state; - only Queued also differs in shape. The intent is Done once the run + only Queued and Not run also differ in shape. The intent is Done once the run has it. After a halt, the stages behind the failed one say **Not run**. The end shows the result: **Passed** or **Halted**. - A line under the button says where the run is ("Running draft. 0 of 2 stages @@ -308,7 +308,7 @@ intent, because the API needs one (1 to 2048 characters) to start a run. in one alert under the Run button, with the sentence the server gave. A screen reader hears it from an alert region that `App` keeps outside the tabs, so it is read when it appears even if the Designer tab is open; the - status line then says only "See the error below." When a read fails, the + status line on the tab says only "See the error below.", which the live status region leaves out. When a read fails, the nodes are cleared and the alert adds that the run (with its id) may still be going on the server. A failed stage is a result, not an error, so it has no alert. The goal is one line: line breaks in the outcome of the intent become diff --git a/workflow-canvas/src/execution/Execution.test.tsx b/workflow-canvas/src/execution/Execution.test.tsx index 1f58e794..eadf7f7a 100644 --- a/workflow-canvas/src/execution/Execution.test.tsx +++ b/workflow-canvas/src/execution/Execution.test.tsx @@ -9,10 +9,17 @@ import { } from '@testing-library/react'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { App } from '../App'; +import { Execution } from './Execution'; import type { RunView } from '../api/types'; import { FakeScheduler } from '../test-support/fake-scheduler'; import { HELLO_DOCUMENT, helloRun, loaded } from '../test-support/fixtures'; -import { MAX_READ_FAILURES, RunReadRefused, type RunPort } from './core'; +import { + IDLE, + MAX_READ_FAILURES, + RunReadRefused, + RunStartUnsure, + type RunPort, +} from './core'; const RUN_ID = helloRun(0).runId; const MAY_STILL_BE_RUNNING = `The run may still be going on the server (run ${RUN_ID}).`; @@ -359,6 +366,21 @@ describe('the goal', () => { expect(runs.start).not.toHaveBeenCalled(); }); + it('does not start a run when Enter ends a composition that Safari reports late', async () => { + const runs = serverShowing(helloRun(0)); + await openExecution(runs); + + await act(async () => { + fireEvent.keyDown(goalBox(), { + key: 'Enter', + keyCode: 229, + isComposing: false, + }); + }); + + expect(runs.start).not.toHaveBeenCalled(); + }); + it('offers a goal of one line when the outcome of the intent has line breaks', async () => { const many = { ...HELLO_DOCUMENT, @@ -534,6 +556,23 @@ describe('errors from the API', () => { ), ).toBeTruthy(); }); + + it('says the run may not have started when the start got no clear answer', async () => { + const runs: RunPort = { + start: vi.fn().mockRejectedValue(new RunStartUnsure('No answer.')), + get: vi.fn(), + }; + await openExecution(runs); + + await press(runButton()); + + const error = screen.getByTestId('run-error'); + expect(error.textContent).toContain('The run may not have started'); + expect(error.textContent).toContain('Press Run to join it.'); + expect(screen.getByTestId('run-live-alert').textContent).toBe( + 'The run may not have started. No answer. The run may be going on the server. Press Run to join it.', + ); + }); }); describe('the live regions', () => { @@ -560,7 +599,7 @@ describe('the live regions', () => { expect(alertLive().textContent).toBe( 'The run did not start. A run is already active.', ); - expect(statusLive().textContent).toBe('See the error below.'); + expect(statusLive().textContent).toBe(''); }); it('say that the run ended, while the Designer tab is open', async () => { @@ -596,6 +635,7 @@ describe('the live regions', () => { expect(alertLive().textContent).toBe( `The run could not be followed. There is no run with this id. The run may still be going on the server (run ${RUN_ID}).`, ); + expect(statusLive().textContent).toBe(''); }); }); @@ -641,6 +681,17 @@ describe('a run whose stages are not the stages of the graph', () => { expect(notice()?.textContent).toContain('Not in the run: draft.'); }); + it('says the file changed after the page loaded or after the run started, and tells the person to reload', async () => { + const scheduler = await openExecution(serverShowing(OTHER_STAGES)); + + await press(runButton()); + await tick(scheduler); + + expect(notice()?.textContent).toContain('after this page loaded'); + expect(notice()?.textContent).toContain('after the run started'); + expect(notice()?.textContent).toContain('Reload the page to draw it.'); + }); + it('says nothing for a run of the stages that are drawn', async () => { const scheduler = await openExecution(serverShowing(helloRun(0))); @@ -683,3 +734,25 @@ describe('when there is no workflow to run', () => { expect(screen.queryByRole('button', { name: 'Run' })).toBeNull(); }); }); + +describe('when the workflow is replaced', () => { + it('draws a new canvas, so it is fitted to the new workflow', () => { + const controller = { state: IDLE, start: vi.fn() }; + const draw = () => ( + + ); + const { rerender } = render(draw()); + const before = screen.getByRole('region', { name: 'Workflow graph' }); + + rerender(draw()); + + expect(screen.getByRole('region', { name: 'Workflow graph' })).not.toBe( + before, + ); + }); +}); diff --git a/workflow-canvas/src/execution/Execution.tsx b/workflow-canvas/src/execution/Execution.tsx index cf0d461c..e5381a5c 100644 --- a/workflow-canvas/src/execution/Execution.tsx +++ b/workflow-canvas/src/execution/Execution.tsx @@ -4,7 +4,7 @@ import Button from '@cloudscape-design/components/button'; import Container from '@cloudscape-design/components/container'; import FormField from '@cloudscape-design/components/form-field'; import Header from '@cloudscape-design/components/header'; -import Input from '@cloudscape-design/components/input'; +import Input, { type InputProps } from '@cloudscape-design/components/input'; import SpaceBetween from '@cloudscape-design/components/space-between'; import StatusIndicator, { type StatusIndicatorProps, @@ -30,6 +30,12 @@ import './execution.css'; import { runErrorOf } from './run-error'; import type { ExecutionController } from './use-execution'; +// Safari reports the Enter that commits a composition after it has ended, with +// `isComposing` false and the key code 229, so both are checked. +function isPlainEnter(key: InputProps.KeyDetail): boolean { + return key.key === 'Enter' && !key.isComposing && key.keyCode !== 229; +} + const INDICATOR: Record = { idle: 'pending', busy: 'in-progress', @@ -77,7 +83,8 @@ function StageDriftNotice({ return ( The stages of this run are not the stages in the graph, so some nodes show - no state. The workflow file changed after the run started. + no state. The workflow file changed after this page loaded or after the + run started. Reload the page to draw it. {notInGraph.length > 0 && ` Not drawn: ${notInGraph.join(', ')}.`} {notInRun.length > 0 && ` Not in the run: ${notInRun.join(', ')}.`} @@ -110,7 +117,7 @@ function RunPanel({ readOnly={inFlight} onChange={({ detail }) => onGoalChange(detail.value)} onKeyDown={({ detail }) => { - if (detail.key === 'Enter' && !detail.isComposing && canRun) { + if (isPlainEnter(detail) && canRun) { execution.start(goal); } }} diff --git a/workflow-canvas/src/execution/RunAnnouncements.tsx b/workflow-canvas/src/execution/RunAnnouncements.tsx index f975df70..01dc2280 100644 --- a/workflow-canvas/src/execution/RunAnnouncements.tsx +++ b/workflow-canvas/src/execution/RunAnnouncements.tsx @@ -5,7 +5,8 @@ import './announcements.css'; /** * The two live regions of the run, for a screen reader: where the run is, and - * why it failed. The page keeps them mounted outside the tabs, so a change is + * why it failed. The status stays empty on an error, as the alert says it all + * and the visible line's "See the error below." points at nothing here. The page keeps them mounted outside the tabs, so a change is * announced while the Designer tab is open too, when the Execution tab and its * visible copy of these sentences are not on the page. */ @@ -17,7 +18,7 @@ export function RunAnnouncements({ state }: { state: ExecutionState }) { className="wf-visually-hidden" data-testid="run-live-status" > - {statusText(state)} + {state.phase === 'error' ? '' : statusText(state)}
Date: Wed, 28 Oct 2026 21:06:38 +0000 Subject: [PATCH 09/10] Let go of a run when another workflow opens, and stop telling the person to reload A run that was followed stayed on the page after a pasted launch address opened another workflow: the status and the badges described the old run over the new graph, Run stayed off, and the stage note blamed a changed file. Opening another workflow now stops following the run and clears its status. The run itself goes on at its server. The stage note no longer says to reload the page. A launch code works once on a real server, so a reload ends in "no launch code". It now says to paste a fresh launch address from the server. --- .../src/execution/Execution.test.tsx | 58 ++++++++++++++++++- workflow-canvas/src/execution/Execution.tsx | 2 +- .../src/execution/use-execution.ts | 25 +++++++- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/workflow-canvas/src/execution/Execution.test.tsx b/workflow-canvas/src/execution/Execution.test.tsx index eadf7f7a..2316de32 100644 --- a/workflow-canvas/src/execution/Execution.test.tsx +++ b/workflow-canvas/src/execution/Execution.test.tsx @@ -681,7 +681,7 @@ describe('a run whose stages are not the stages of the graph', () => { expect(notice()?.textContent).toContain('Not in the run: draft.'); }); - it('says the file changed after the page loaded or after the run started, and tells the person to reload', async () => { + it('says the file changed after the page loaded or after the run started, and tells the person to paste a fresh launch address, not to reload', async () => { const scheduler = await openExecution(serverShowing(OTHER_STAGES)); await press(runButton()); @@ -689,7 +689,10 @@ describe('a run whose stages are not the stages of the graph', () => { expect(notice()?.textContent).toContain('after this page loaded'); expect(notice()?.textContent).toContain('after the run started'); - expect(notice()?.textContent).toContain('Reload the page to draw it.'); + expect(notice()?.textContent).toContain( + 'Paste a fresh launch address from the server to draw it.', + ); + expect(notice()?.textContent).not.toMatch(/reload/i); }); it('says nothing for a run of the stages that are drawn', async () => { @@ -756,3 +759,54 @@ describe('when the workflow is replaced', () => { ); }); }); + +describe('when another workflow is opened during a run', () => { + async function openSecondWorkflowMidRun() { + const scheduler = new FakeScheduler(); + const first = serverShowing(helloRun(0)); + const second = serverShowing(helloRun(0)); + const view = (runs: RunPort) => ( + + ); + const { rerender } = render(view(first)); + await screen.findByTestId('node-end'); + fireEvent.click(screen.getByRole('tab', { name: 'Execution' })); + await press(await screen.findByRole('button', { name: 'Run' })); + await tick(scheduler); + expect(statusLine().textContent).toContain('Running draft'); + + rerender(view(second)); + await waitFor(() => + expect(statusLine().textContent).toContain('Ready. Press Run to start.'), + ); + return { scheduler, first, second }; + } + + it('lets go of the run and clears its status', async () => { + await openSecondWorkflowMidRun(); + + expect(badges()).toEqual([null, null, null, null]); + expect(isOff(runButton())).toBe(false); + }); + + it('stops reading the run of the workflow that was left', async () => { + const { scheduler, first } = await openSecondWorkflowMidRun(); + const reads = vi.mocked(first.get).mock.calls.length; + + await tick(scheduler); + + expect(vi.mocked(first.get).mock.calls).toHaveLength(reads); + }); + + it('starts the next run on the workflow that is open', async () => { + const { first, second } = await openSecondWorkflowMidRun(); + + await press(runButton()); + + expect(second.start).toHaveBeenCalledOnce(); + expect(vi.mocked(first.start)).toHaveBeenCalledTimes(1); + }); +}); diff --git a/workflow-canvas/src/execution/Execution.tsx b/workflow-canvas/src/execution/Execution.tsx index e5381a5c..dc96f8f2 100644 --- a/workflow-canvas/src/execution/Execution.tsx +++ b/workflow-canvas/src/execution/Execution.tsx @@ -84,7 +84,7 @@ function StageDriftNotice({ The stages of this run are not the stages in the graph, so some nodes show no state. The workflow file changed after this page loaded or after the - run started. Reload the page to draw it. + run started. Paste a fresh launch address from the server to draw it. {notInGraph.length > 0 && ` Not drawn: ${notInGraph.join(', ')}.`} {notInRun.length > 0 && ` Not in the run: ${notInRun.join(', ')}.`} diff --git a/workflow-canvas/src/execution/use-execution.ts b/workflow-canvas/src/execution/use-execution.ts index 7cf36f11..cb18384e 100644 --- a/workflow-canvas/src/execution/use-execution.ts +++ b/workflow-canvas/src/execution/use-execution.ts @@ -4,11 +4,20 @@ import { IDLE, reduce, startAndFollow, + type ExecutionEvent, type ExecutionState, type RunPort, type Scheduler, } from './core'; +// `reset` is the hook's own event: another workflow was opened, so the run of +// the one that was left is no longer the run of this page. +type Action = ExecutionEvent | { type: 'reset' }; + +function reduceAction(state: ExecutionState, action: Action): ExecutionState { + return action.type === 'reset' ? IDLE : reduce(state, action); +} + /** The state of the Execution tab and the one way to change it. */ export interface ExecutionController { state: ExecutionState; @@ -19,17 +28,29 @@ export interface ExecutionController { /** * Drives one run at a time through `runs`, waiting with `scheduler`, and * stops following it when the component unmounts. The state lives with the - * caller, so it survives a switch of tab. + * caller, so it survives a switch of tab. When `runs` is replaced by those of + * another workflow, the run in hand is let go: it stays on its server, but + * this page no longer follows it or shows its status. */ export function useExecution( runs: RunPort | undefined, scheduler: Scheduler, ): ExecutionController { - const [state, dispatch] = useReducer(reduce, IDLE); + const [state, dispatch] = useReducer(reduceAction, IDLE); const active = useRef(undefined); + const opened = useRef(runs); useEffect(() => () => active.current?.abort(), []); + useEffect(() => { + const left = opened.current; + opened.current = runs; + if (left === undefined || runs === undefined || left === runs) return; + active.current?.abort(); + active.current = undefined; + dispatch({ type: 'reset' }); + }, [runs]); + const start = useCallback( (goal: string) => { if (!runs || active.current) return; From 50e3dff6d99a496b28984a12a5e4c554cbe2ada8 Mon Sep 17 00:00:00 2001 From: Nihit <24500178+knihit@users.noreply.github.com> Date: Wed, 28 Oct 2026 22:33:01 +0000 Subject: [PATCH 10/10] Tell the person to reload the page to draw a changed workflow file --- workflow-canvas/src/execution/Execution.test.tsx | 8 +++----- workflow-canvas/src/execution/Execution.tsx | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/workflow-canvas/src/execution/Execution.test.tsx b/workflow-canvas/src/execution/Execution.test.tsx index 2316de32..900dbc5d 100644 --- a/workflow-canvas/src/execution/Execution.test.tsx +++ b/workflow-canvas/src/execution/Execution.test.tsx @@ -681,7 +681,7 @@ describe('a run whose stages are not the stages of the graph', () => { expect(notice()?.textContent).toContain('Not in the run: draft.'); }); - it('says the file changed after the page loaded or after the run started, and tells the person to paste a fresh launch address, not to reload', async () => { + it('says the file changed after the page loaded or after the run started, and tells the person to reload the page', async () => { const scheduler = await openExecution(serverShowing(OTHER_STAGES)); await press(runButton()); @@ -689,10 +689,8 @@ describe('a run whose stages are not the stages of the graph', () => { expect(notice()?.textContent).toContain('after this page loaded'); expect(notice()?.textContent).toContain('after the run started'); - expect(notice()?.textContent).toContain( - 'Paste a fresh launch address from the server to draw it.', - ); - expect(notice()?.textContent).not.toMatch(/reload/i); + expect(notice()?.textContent).toContain('Reload the page to draw it.'); + expect(notice()?.textContent).not.toMatch(/launch address/i); }); it('says nothing for a run of the stages that are drawn', async () => { diff --git a/workflow-canvas/src/execution/Execution.tsx b/workflow-canvas/src/execution/Execution.tsx index dc96f8f2..e5381a5c 100644 --- a/workflow-canvas/src/execution/Execution.tsx +++ b/workflow-canvas/src/execution/Execution.tsx @@ -84,7 +84,7 @@ function StageDriftNotice({ The stages of this run are not the stages in the graph, so some nodes show no state. The workflow file changed after this page loaded or after the - run started. Paste a fresh launch address from the server to draw it. + run started. Reload the page to draw it. {notInGraph.length > 0 && ` Not drawn: ${notInGraph.join(', ')}.`} {notInRun.length > 0 && ` Not in the run: ${notInRun.join(', ')}.`}