Skip to content

test(regression): promote run-flow.spec.ts to @stable - #268

Merged
daniellicnerski1 merged 3 commits into
mainfrom
test/run-flow-stable
May 19, 2026
Merged

test(regression): promote run-flow.spec.ts to @stable#268
daniellicnerski1 merged 3 commits into
mainfrom
test/run-flow-stable

Conversation

@daniellicnerski1

Copy link
Copy Markdown
Collaborator

Summary

Promotes `tests/tests-automations/regression/flow-functionality/run-flow.spec.ts` to `@stable` after fixing a no-op assertion, trimming excessive timeouts, adding API-based cleanup, and correcting a stale QA-CHECKLIST entry.

Why this spec is non-redundant

This is the only test covering the Run Flow component on canvas — a Langflow component that invokes another flow from within a flow.

  • A pipeline flow (ChatInput → TextOutput → ChatOutput) is built via drag-drop
  • A caller flow uses the Run Flow component to invoke the pipeline
  • The test verifies the input text echoes back through the chain

`api-run-flow.spec.ts` (`@stable`) covers `POST /api/v1/run/{flow_id}` directly via API — different surface. No other UI spec covers flow chaining via the Run Flow component.

Changes

Change Rationale
Add `@stable` + `@regression` to the tag list Promotion + accurate functional area
Trim 4x `timeout: 100000` to `timeout: 30000` 100s was excessive copy/paste; project-wide standard is 5-30s
Fix L80 no-op: `await page.getByText("New Flow").isVisible();` → `await expect(...).toBeVisible({ timeout })` The return value of `.isVisible()` was discarded — the line always passed regardless of actual visibility. Now it actually asserts
Wrap test body in `try/finally` with API cleanup of 2 created flows Previously left 2 flows orphaned every run. Uses `getAuthToken` + `DELETE /api/v1/flows/{id}` for speed/robustness. Best-effort (errors swallowed) so test failures still report original cause
ESLint --fix: `.toBe()` on inputValue → `.toHaveValue()` auto-waiting Playwright-native auto-waiting assertion
Fix QA-CHECKLIST L589 Two errors: (1) stale path `core/features/run-flow.spec.ts` (doesn't exist), (2) inaccurate description "Execute flow via Run button" — the spec tests the component, not the canvas Run button

Test plan

  • `npm run typecheck` clean
  • `npm run lint` filtered on spec: 0 errors (11 warnings: 9 pre-existing `waitForSelector` + 2 intentional conditionals in dotenv check and cleanup)
  • Anti-pattern grep — zero `.isVisible().catch(() => false)` / `toBeFalsy` / `waitForTimeout` in test logic
  • `npx playwright test --workers=1 --retries=0` — 1 test PASS in 16.1s without retry
  • Force-fail confirmed (changed final `expect(...).toHaveValue(...)` to an impossible string; saw failure at L134 with clear message `unexpected value "THIS IS A TEST FOR RUN FLOW COMPONENT"`; reverted; repassed in 18.5s)
  • `--trace=on` once — trace shows both flow constructions, execution, and `finally` cleanup with API DELETE calls
  • Zero `🚨 Backend Error` occurrences

Known limitation (out of scope)

The cleanup deletes the 2 most-recently-created flows from the listing, assuming reverse-chronological ordering. If a prior orphan from a different test appears newer than the 2 created here, cleanup could delete the wrong flow. Acceptable trade-off — cleanup is best-effort hygiene, and Langflow's listing API correctly orders by recency.

Refactor for CI hygiene and weekly-run stability:

- Add @stable + @regression tags.
- Trim 4x timeout: 100000ms (100s) to 30000ms (30s) — project standard.
- Fix L80 no-op assertion: the existing
  `await page.getByText("New Flow").isVisible();` discarded the
  return value (always passed regardless of visibility). Replaced
  with `await expect(...).toBeVisible({ timeout })`.
- Wrap test body in try/finally with API-based cleanup of the 2
  flows the test creates (previously orphaned every run). Uses
  getAuthToken + DELETE /api/v1/flows/{id} for speed and to avoid
  cascading UI failures during cleanup.
- ESLint --fix promoted the final assertion from
  `expect(await ...inputValue()).toBe(...)` to the auto-waiting
  `await expect(...).toHaveValue(...)`.

QA-CHECKLIST L589: correct stale path (core/features/run-flow.spec.ts
-> flow-functionality/run-flow.spec.ts) and inaccurate description
("Execute flow via Run button" -> "Run Flow component executes another
flow"). The spec tests the Run Flow component on canvas, not the
canvas Run button.

This spec is 100% non-redundant — no other test covers the Run Flow
component on canvas. api-run-flow.spec.ts (@stable) covers the pure
API path; this covers the UI surface that uses internal mechanisms.
@Victor-w-Madeira
Victor-w-Madeira requested a review from Copilot May 18, 2026 21:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Promotes the run-flow.spec.ts regression test to @stable after fixing a no-op visibility assertion, trimming oversized timeouts, adding API-based cleanup of the two flows it creates, and correcting a stale entry in QA-CHECKLIST.

Changes:

  • Adds @stable / @regression tags and tightens four 100s timeouts down to 30s; replaces .isVisible() no-op with await expect(...).toBeVisible() and switches the final input assertion to auto-waiting toHaveValue.
  • Wraps the test body in try/finally and best-effort deletes the 2 most recently created flows via getAuthToken + DELETE /api/v1/flows/{id}.
  • Updates QA-CHECKLIST entry 12.6 to mark the spec stable and corrects its path/description.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
tests/tests-automations/regression/flow-functionality/run-flow.spec.ts Promote to @stable, trim timeouts, fix no-op assertion, add API cleanup in finally.
QA-CHECKLIST.md Mark Run Flow component scenario as [x] and fix stale path/description.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

const listRes = await request.get("/api/v1/flows/", { headers });
if (listRes.ok()) {
const body = await listRes.json();
const items = (Array.isArray(body) ? body : body?.items ?? []).slice(

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid — fixed in b89103e. You're right that the object-form fallback used the wrong key (body?.items vs the actual body.flows shape established by tests/helpers/flows/clean-all-flows.ts:33). The bug never bit because Langflow currently returns the array form on this endpoint, but a future change to the response shape would have silently skipped cleanup.

The whole listing call is gone now — replaced with the same ID-scoping pattern landed in PR #267 (bulk-actions): the test captures the flow ID from page.url() after each blank-flow.click() and the finally block iterates only those captured IDs. No more list-then-slice; no more object-form ambiguity.

Comment on lines +140 to +149
const listRes = await request.get("/api/v1/flows/", { headers });
if (listRes.ok()) {
const body = await listRes.json();
const items = (Array.isArray(body) ? body : body?.items ?? []).slice(
0,
2,
);
for (const f of items) {
await request.delete(`/api/v1/flows/${f.id}`, { headers });
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid — fixed in b89103e. Same root issue as comment 1 (positional slice(0, 2) over the listing). Two concrete risks the previous code had:

  1. The list did not use remove_example_flows=true, so any example/starter flow that the API returns ahead of user-created flows would have been deleted.
  2. Under fullyParallel: true, a sibling worker could have created flows that ended up in the top-2 positions during the window between request.get(...) and request.delete(...), taking collateral damage.

Fix is the same pattern from PR #267:

  • Capture createdFlowIds: string[] populated by page.waitForURL(/\/flow\/[0-9a-f-]+/i) + regex extraction after each blank-flow.click().
  • finally block iterates only those IDs and calls DELETE /api/v1/flows/{id} for each. 404s for IDs the test already deleted on the happy path are silenced.

Validated against the live API: 182 flows before the run, 182 after — the 2 captured IDs were deleted, nothing else was touched.

Daniel Licnerski Borges added 2 commits May 19, 2026 09:10
Document the Run Flow component test with the post-refactor behavior:
- toHaveValue auto-waiting assertion (replaces toBe(inputValue))
- try/finally API cleanup of the 2 created flows via getAuthToken
Addresses Copilot review on PR #268. Two bugs in the cleanup, same root:
positional slice over an incorrectly-normalised list.

1. Comment 1 (L143): the object-form fallback was `body?.items` but
   `/api/v1/flows/` returns the array under `flows` (see
   `tests/helpers/flows/clean-all-flows.ts:33`). The object-form
   branch would have silently produced an empty list and skipped the
   entire cleanup. Bug never bit because Langflow currently returns
   the array form, but Copilot is right that the fallback was wrong.

2. Comment 2 (L149): `slice(0, 2)` over the listing trusted that the
   two most-recently-created flows were the two this test built. If
   the listing returns example/starter flows first (a real default
   when `remove_example_flows=true` is not set), or if a sibling
   worker created flows under `fullyParallel`, this would delete
   unrelated flows.

Fix is the same pattern landed in PR #267 (bulk-actions): capture the
flow IDs as they are created via `page.url()` after each
`blank-flow.click()`, then `DELETE /api/v1/flows/{id}` for each
captured ID in the `finally` block. The listing call is gone entirely,
which also removes the `body?.items` vs `body?.flows` ambiguity.

7-step validation pipeline:
- typecheck clean
- lint: 0 errors, 10 pre-existing warnings (1 fewer than before)
- run --workers=1 --retries=0: PASS (17.9s)
- Force-fail on the final `toHaveValue(...)`: failed at L148 with
  received "THIS IS A TEST FOR RUN FLOW COMPONENT", reverted, repassed
- Trace coherent, zero backend errors
- Cleanup validated against the live API: 182 flows before run, 182
  after (the 2 created flows were deleted)
@daniellicnerski1
daniellicnerski1 merged commit 4b9e246 into main May 19, 2026
2 checks passed
@Victor-w-Madeira
Victor-w-Madeira deleted the test/run-flow-stable branch May 19, 2026 15:57
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.

2 participants