test(observability): validate Flow Activity and Trace Details via API + UI - #219
Conversation
… + UI
Replace the failing /monitor/transactions assertion (HTTP 422) and delete
the pagination test for the same endpoint (endpoint has no UI consumer in
Langflow). Add three new tests sharing a beforeAll-created flow:
- API: GET /api/v1/monitor/traces returns totalLatencyMs and totalTokens
for a real flow run.
- UI: Flow Activity page renders the Latency and Token columns for the run.
- UI: Trace Details modal shows the span tree (4 spans: root + Prompt +
ChatInput + LanguageModel) and the span detail panel with Latency.
beforeAll creates a temporary API key and a Basic Prompting flow from a
new fixture; runs it once to emit a trace. The run intentionally fails
("A model selection is required") but still produces the trace, so the
tests work without OPENAI_API_KEY and with 0 tokens consumed. afterAll
deletes both the flow and the API key.
There was a problem hiding this comment.
Pull request overview
This PR updates the observability monitoring regression coverage by replacing the previous /monitor/transactions assertions with a serial, end-to-end flow-based suite that generates a real trace once and validates latency/tokens via both API and UI.
Changes:
- Added a serial
describeblock that creates an API key + imports a fixture flow, runs it once (intentionally failing to avoid provider setup), and validates/api/v1/monitor/traces. - Added UI validations for Flow Activity (latency/tokens columns) and Trace Details (span tree + latency labels).
- Added a new flow snapshot fixture (
basic-prompting-trace-fixture.json) used to deterministically generate trace data without consuming tokens.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tests/tests-automations/regression/core-functionality/observability-monitoring/traces-latency-tokens.spec.ts | Replaces transactions-based checks with a serial API+UI trace validation suite using a real flow run. |
| tests/assets/flows/basic-prompting-trace-fixture.json | Adds a Basic Prompting flow snapshot used by the new trace tests to generate trace entries without provider configuration. |
Comments suppressed due to low confidence (1)
tests/tests-automations/regression/core-functionality/observability-monitoring/traces-latency-tokens.spec.ts:136
- Same as above for tokens: toHaveText() here relies on default timeouts and can flake if the grid cell appears before values are filled. Add an explicit timeout (or wait for the grid’s data row readiness) to make the test robust on CI.
const tokensCell = page
.locator('.ag-cell[col-id="totalTokens"]')
.first();
await expect(tokensCell).toBeVisible();
await expect(tokensCell).toHaveText(/^\d+$/);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| await request.post(`/api/v1/run/${flowId}`, { | ||
| headers: { "x-api-key": apiKey }, | ||
| data: { | ||
| input_value: "trace-probe", | ||
| input_type: "chat", |
There was a problem hiding this comment.
Fixed in a8255bb. Captured the response and assert expect([200, 500]).toContain(runRes.status()) — Langflow returns 200 with an error payload for component-level failures, anything outside that range (401/422/etc.) now fails fast. Also added expect.poll against /monitor/traces (30s timeout, 500/1000/2000ms intervals) in beforeAll so downstream tests no longer race the async trace writer.
| await expect(latencyCell).toHaveText(/^\d+\s*ms$/); | ||
|
|
||
| const tokensCell = page | ||
| .locator('.ag-cell[col-id="totalTokens"]') | ||
| .first(); | ||
| await expect(tokensCell).toBeVisible(); | ||
| await expect(tokensCell).toHaveText(/^\d+$/); |
There was a problem hiding this comment.
Fixed in a8255bb. Added explicit { timeout: 15000 } to both toHaveText() calls (latency cell + tokens cell), matching the toBeVisible timeout above. The default 5s expect timeout was shorter than the visibility wait, which is exactly the race condition you flagged.
- Capture POST /api/v1/run response and assert status in [200, 500] range (intentional component failure with no provider). Anything outside that range now fails fast instead of letting the suite race the trace writer in less obvious places. - Poll /api/v1/monitor/traces in beforeAll until at least one trace exists for this flow, removing the async race condition between the run call and the downstream trace queries. - Add explicit 15s timeout to toHaveText() assertions on the Flow Activity grid cells, matching the toBeVisible() timeout above and preventing intermittent failures on slower CI where the cell renders before metrics populate.
Copilot review feedback — addressed
Changes (a8255bb):
Validation pipeline run locally (against live Langflow): |
Summary
/monitor/transactionsassertion (HTTP 422 — the endpoint requiresflow_id, which the previous test omitted) with three new tests in a shareddescribeblock that creates a real flow once and validates traces both through the API and the UI./monitor/transactions: the endpoint has no React consumer in the Langflow frontend (verified viagrep useGetTransactionsQuery— defined but never imported), so it would be a regression test for a code path no user can reach.tests/assets/flows/basic-prompting-trace-fixture.json(a Basic Prompting flow snapshot) is loaded inbeforeAll. The run intentionally fails with"A model selection is required"(no provider configured) — that failure still emits the trace, so the tests work withoutOPENAI_API_KEYand consume 0 tokens.What each test validates
GET /api/v1/monitor/traces?flow_id=<id>returnstotalLatencyMs(number, ≥ 0),totalTokens(number, ≥ 0), the correctflowId, a validstatus(success/error/running), and an ISOstartTime.totalLatencyMscell text matches/^\d+\s*ms$/, columntotalTokenscell text matches/^\d+$/.Runcell openstrace-detail-view; the modal containsspan-tree+span-detail; exactly 4span-node-*(root + Prompt Template + Chat Input + Language Model);span-detailshows theLatencylabel with<N> ms; the span tree lists all three component names.Validation pipeline
npm run typecheck✅npx eslint✅ (only pre-existing warnings on tests 4–5 of the file that this PR did not touch)--retries=0 --trace=on— 3/3 green each (~10.6s / 11.0s / 12.5s).toHaveCount(4)for999andflowIdfor a sentinel both produce real failures🚨 Backend Erroraudit — 0 occurrencesOut of scope
The two remaining tests in the file (
/monitor/messagesshape,/logspage accessibility) are untouched. They have soft-pass patterns (if (empty) return;) that should be revisited but are not the focus of this PR.Test plan