Follow-up from #1336 / PR #1339, which fixed a real flake but did so by hand-rolling a mechanism the repo already owns.
What landed
auto-save-off.spec.ts re-opens the flow under test through a local reopenFlow:
const flowLoaded = page.waitForResponse(/* GET /api/v1/flows/{id} 200 */);
await page.goto(`/flow/${flowId}`);
await flowLoaded;
await page.waitForSelector('[data-testid="canvas_controls_dropdown"]');
That is correct as far as it goes, and it is validated — but it duplicates helpers/flows/open-flow-by-id.ts (#1214), whose whole reason for existing is that this block "was hand-copied into three specs and had already diverged on every axis that matters". This is a fourth copy, added by the very PR that was fixing a parallel-safety bug of the kind that helper documents.
What the copy is missing
Two guarantees, both relevant to this spec:
Care needed in the migration (do not just swap the call)
The local copy waits for GET /api/v1/flows/{id} before touching the canvas, and that wait is load-bearer for a specific assertion: the discard check is div-generic-node count === 0, which passes vacuously if it reads a canvas whose graph has not been applied yet. openFlowById gates on canvas_controls_dropdown + writability, which does not by itself prove the graph was applied. So the flow-load wait has to survive the migration (register the response promise, call openFlowById, then await it) — or be replaced by something that provably orders the count after the graph.
Done when
Follow-up from #1336 / PR #1339, which fixed a real flake but did so by hand-rolling a mechanism the repo already owns.
What landed
auto-save-off.spec.tsre-opens the flow under test through a localreopenFlow:That is correct as far as it goes, and it is validated — but it duplicates
helpers/flows/open-flow-by-id.ts(#1214), whose whole reason for existing is that this block "was hand-copied into three specs and had already diverged on every axis that matters". This is a fourth copy, added by the very PR that was fixing a parallel-safety bug of the kind that helper documents.What the copy is missing
Two guarantees, both relevant to this spec:
openFlowByIdcallsseedAssistantDiscoveredBEFORE the document load, so the onboarding overlay cannot appear. Not hypothetical here: the CI failure artifact that opened [Daily #1330] auto-save-off — reopening the just-created flow's card intermittently times out at 45 s (recurrent 2×) #1336 shows the "Try the new Langflow Assistant!" dialog painted over the canvas. It was not the cause of that flake, but this spec clicks the on-canvassave-flow-buttonand the back chevron, so an overlay is a live click-interception risk.openFlowByIdwaits formenu_bar_displayto report enabled, i.e. it refuses to hand back an editor whilePOST /api/v1/authz/me/permissionsis still in flight — the renameFlow residual flake: read-only save button and missing flow_name header (~7%, not the #995 clobber) #1005 window in which a mutation is silently swallowed. This spec adds components immediately after every re-open, so it is exactly the caller that gate exists for.Care needed in the migration (do not just swap the call)
The local copy waits for
GET /api/v1/flows/{id}before touching the canvas, and that wait is load-bearer for a specific assertion: the discard check isdiv-generic-nodecount=== 0, which passes vacuously if it reads a canvas whose graph has not been applied yet.openFlowByIdgates oncanvas_controls_dropdown+ writability, which does not by itself prove the graph was applied. So the flow-load wait has to survive the migration (register the response promise, callopenFlowById, then await it) — or be replaced by something that provably orders the count after the graph.Done when
openFlowById, with the graph-applied ordering preserved for thecount === 0assertion.docs/flow-functionality/auto-save-off.mdnames the by-URL re-open explicitly).--retries=0runs plus the--workers=4burst that reproduced [Daily #1330] auto-save-off — reopening the just-created flow's card intermittently times out at 45 s (recurrent 2×) #1336 (3/8 before the fix, 8/8 after), and executed force-fails including one that proves the discard assertion still fails when it should.