Skip to content

Test editing in the Designer end to end and add the changelog entry - #97

Draft
knihit wants to merge 662 commits into
wc/07c-savefrom
wc/07-editing
Draft

knihit wants to merge 662 commits into
wc/07c-savefrom
wc/07-editing

Conversation

@knihit

@knihit knihit commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Description

Layer 4 of 4 of the editing work in the Designer (this PR was the single large one and is kept for the last layer, with its comments; the first three layers are #98, #99 and #100). With this layer the Designer tab can edit a workflow and save it, tested end to end.

What it adds (7 files, +557/-10 against wc/07c-save):

  • e2e/editing/editing.spec.ts and an editing Playwright project (playwright.config.ts, with its name in playwright.shared.ts) that runs after the read-only functional project, in one worker, because it saves to the stub: change an agent, save and reload to see it; rename; add; delete the last stage and one in the middle; the whole flow with the keyboard with focus checked at each step; a name the server refuses, and one that is not a name (with the words of the server); a conflict (the test changes the file on the stub) and loading again; the draft kept across tabs and the Execution note; Execution after a save; axe in four editing states; the graph still shows every stage after 12 are added.
  • Six negative save tests: a refusal with findings (the mock carries every field of a finding in the contract) and with none, a lost session, an answer that is lost, one that cannot be read, and one that is lost with nothing written. Each counts the PUT requests the page sent and says it sent one; the file is checked only where a request reaches the stub.
  • designer-page.ts (a graph locator), editing-fixtures.ts (the guard against a second worker) and playwright.shared.ts (the project name); a fixture puts the sample workflow back before and after each test.
  • workflow-canvas/README.md: the paragraph on the two Playwright projects and the axe list. CHANGELOG.md: the entry under Unreleased.

How to review

  • The diff of this PR is 7 files, +557/-10: tests, helpers, docs and the project config. The product code was reviewed in the three layers below.
  • Run it: cd workflow-canvas && npm ci && npx playwright install chromium && npm run test:e2e (107 tests: 83 functional, 24 editing). To run only the editing tests: npx playwright test --project=editing --no-deps --workers=1.

Type of Change

  • Other: end-to-end tests and the changelog entry for editing in workflow-canvas/

Testing

  • Root npm test (tests/scripts/**/*.test.js): not applicable; this PR changes only workflow-canvas/ and the root CHANGELOG.md.
  • If cli/ changed: not applicable, cli/ is untouched
  • Smoke tested affected agent(s): not applicable, no agent changed
  • If an agent's or skill's behavior changed: not applicable, none changed
  • New or changed code files carry the required SPDX header (see AGENTS.md's License headers rule); formats without comment syntax (e.g. JSON) are exempt

Checked in workflow-canvas/ on the tree of this head: npm run lint, npm run typecheck (3 projects), npm test (78 files, 1398 tests), npm run test:stub (20 files, 359 tests), npm run api:lint, npm run build and npm run test:e2e (107 tests, against the stub) all pass. npm run screenshots gives byte-identical files.

Screenshots

The finished Designer tab, full page, 1280x800 (taken again for this head by npm run screenshots; the links are pinned to the head commit of this PR):

Opens with a stage selected Unsaved edits (agent changed, stage renamed)
Designer tab on open Designer tab with unsaved edits
After a save A problem the server found
Designer tab after a save Designer tab with a duplicate stage name
The file changed on disk Unsaved edits, dark theme
Designer tab with a conflict Designer tab with unsaved edits, dark theme

Designer tab on open, dark theme

Checklist

  • My code follows the style guidelines of this project (see AGENTS.md's Code Style & Conventions)
  • I have performed a self-review of my own changes
  • I have commented my code where necessary
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings - build is clean
  • I have added or updated tests that prove my change works (see Testing above for the exact commands)

Notes for Reviewers

Fixes from the third adversarial review

  • The "not a name" test asserts the words of the server. The 422 mock has every field a finding has in the contract.
  • The tests that say a save writes nothing count the PUT requests instead of reading a file the request never reached.
  • A new test adds stages and checks the graph still shows the first and the last (it fails without the refit).
  • The editing tests no longer skip the rest of the file after one failure; the project name is in one place; the README names --no-deps.
  • This branch takes the new wc/07c-save by merge.

Fixes from the second hands-on QA run

@knihit
knihit added this pull request to stack #79 October 26, 2026 23:12
@knihit

knihit commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor Author

Fixed in 598f518 (the CHANGELOG itself needed no further change): the CHANGELOG diff against the base of this PR (wc/07c-save) is a single hunk (@@ -72,6 +72,20 @@) with no removed lines, so the two continuation lines (Claude plugin marketplace and run-update/uninstall) keep their 2-space indent and the hunk only adds the Unreleased entry. The dedent came in with 04edf09 and 598f518 restored it; both are in the history of this branch. CI is green on 91ff49e, the head with that fix, and this branch holds the same tree.

@knihit
knihit force-pushed the wc/07-editing branch 2 times, most recently from 2338427 to 91ff49e Compare October 27, 2026 01:29
@knihit
knihit removed this pull request from stack #79 October 27, 2026 02:47
@knihit knihit changed the title Edit the agents and stages of a workflow in the Designer and save them Test editing in the Designer end to end and add the changelog entry Oct 27, 2026
@knihit
knihit changed the base branch from wc/06-execution to wc/07c-save October 27, 2026 02:47
@knihit
knihit added this pull request to stack #101 October 27, 2026 02:47
@knihit
knihit removed this pull request from stack #101 October 27, 2026 02:48
@knihit
knihit added this pull request to stack #102 October 27, 2026 02:48
knihit added 11 commits October 27, 2026 21:22
Move the scan out of the stub core's test into test-support/purity.ts, parameterised by the rules of one core, so a second core can be held to the same rule. The scan's own tests move with it, unchanged.
Open a session with the launch code in the address, load the workflow, and draw the intent, each stage in list order and the end with React Flow, read-only. The graph is built by an IO-free core. Loading, error and empty states are shown.
Open one shared session in the Playwright global setup, because a launch code works once, and answer the page's session call with it. Add canvas tests, an axe check of the error state, and regenerate the Designer screenshot.
Give each node and edge a readable aria-label built in the graph core,
and replace the edit instructions of React Flow with read-only wording.
Zoom out far enough to fit the 40 stages the API allows. Leave out a
diagnostic line that is not a whole number from 1, refuse an API version
other than 1, and keep the canvas colours in canvas.css only. Read the
real replies of the stub with the page's parsers in a test.
The badge font shorthand named Arial, which each host resolves to a
different face, so the Designer screenshot differed between a local run
and CI. Inherit the page font so the capture is the same everywhere, and
refresh the screenshot.
The server may repeat an identical diagnostic, which gave two list items
the same key. Add the index to the key and test a repeated problem.
knihit added 19 commits October 28, 2026 14:51
After the click the pointer and the focus stay on Run, which is off and
shows its reason in a tooltip. Whether the tooltip was in the PNG depended
on timing, so the capture moves the pointer away and blurs the button.
…calls

A 409 already_running names the active run, so the Execution tab follows it
instead of ending in a dead end, for example after a page reload. A failed
read is tried again before the tab gives up, a reading for another run ends
the follow with an error, and a call that gets no answer ends after a
timeout. The error sentence is announced through an alert region, and Enter
in the goal box runs.
canRetryStatus in api/api.ts holds the rule next to the "0 = no answer"
convention: no answer or a 5xx can be tried again, any 4xx cannot. The
README now says any 4xx, as the code does.
…reload

After a reload the Execution tab said Ready although a run was going. The tab
now keeps the id of the latest run in sessionStorage and, when the page opens
again, reads that run once. A run that is still running is followed as a joined
run. A run that has ended, cannot be read, or a blocked storage leaves the tab
ready.
… editor state

The IO-free part of editing a workflow in the Designer, with no UI yet:
- the draft of the stages, where each stage keeps an id while it is renamed
- the text a save writes, which replaces only the block of stages
- the findings of a check, put on the stage and field they are about
- the state of the editor and its reducer, with the selectors on it

The wire types gain the hash and read-only flag of a workflow and the path
and severity of a finding, and the page reads them.
The server reports a repeated stage name on the later stage only. A person who
renames the first stage to a name the second one has saw no mark at the field
they were editing. The problems of the draft now hold a copy of such a name
problem for the earlier stages with that name. A list of problems leaves the
copies out, and a message that several stages repeat is joined once.
…, add, rename, delete

The Designer tab gets Properties for the selected stage, with a name field,
a list of the agents Konductor ships, and Delete stage. Add stage adds the
next agent-N. A stage is chosen by a click, or by Enter or Space on its node,
and focus moves to its name. The draft is kept in App, so it survives a
switch of tab, and the Execution tab says when it holds changes that are not
saved. Nothing is written to the file yet.

The graph names a node by the id of its stage, so two stages that share a
name for a moment still have two nodes, and the canvas fits the graph again
when a stage is added or deleted.
…aved

The draft lives in the page only, so a reload or a closed tab threw it away
without a word. While the draft differs from the saved file, a beforeunload
handler now makes the browser ask whether to leave.
… a conflict

Save writes the draft through PUT /api/workflow with the hash of the file as
it was loaded. Only the block of stages of the file changes. The text is
checked with POST /api/validate a moment after the last change, and what the
server finds shows under the field and in an alert. Only an error stops a
save; warnings and notes show as notes.

A 409 says the file changed and offers to load it again. A 422 shows its
findings. A save whose answer is lost is settled by reading the file.

The client gains saveWorkflow and checkWorkflow, the findings carry their
path and severity, and the contract tests pin the limits and calls the
Designer assumes. The Execution tab draws the saved workflow.
… the earlier stage too

The problems of a draft now hold a copy of a repeated-name problem for the
earlier stage. The list of problems above the graph leaves the copies out, so
each problem is listed once, while the name field of either stage is marked.
A cleared name made the list read ': name must be ...' with an empty word
before the colon. A stage with no name is now called 'Stage 1', 'Stage 2' and
so on, by its place in the list.
A stopped server showed 'The server answered 502.' and a restarted one 'The
session token is missing or wrong.', neither with a next step. A message for
no answer, a 5xx that is not the API's, or the API's 401 now ends with what to
do: start the server again if it stopped and open the launch address it
printed.
# Conflicts:
#	CHANGELOG.md
#	workflow-canvas/README.md
#	workflow-canvas/src/main.tsx
- The editing tests run in order in one worker, and the sample fixture fails
  with the way out in another worker, so repeat-each cannot give false reds.
- A real reload is used where a reload is meant.
- Cover the keyboard delete, deleting a stage in the middle, a name that is
  not a name with its words and Save off, and the exact text a conflict
  leaves in the file.
- Cover a refused save with findings and with none, a lost session, an
  answer that is lost or unreadable, and copying the draft on a conflict.
- The stub helpers fail on a refused call. The screenshots are taken again.
…fail

The "not a name" test asserts the words of the server. The 422 mock carries
every field of a finding in the contract. The saves that write nothing count
the PUT requests the page sent, and check the file only where a request
reaches the stub. A test adds stages and checks the graph still shows them.
The editing tests no longer skip the rest of the file after one failure, and
the project name is in one place.
The problems are now in their own region under Properties, so the page object
reads the edit alerts by test id, and the refused-name test expects the name
without backticks.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant