Skip to content

chore(trace): use a single id for calls and test runner steps - #42430

Open
Dmitry Gozman (dgozman) wants to merge 2 commits into
microsoft:mainfrom
dgozman:call-id-unification
Open

chore(trace): use a single id for calls and test runner steps#42430
Dmitry Gozman (dgozman) wants to merge 2 commits into
microsoft:mainfrom
dgozman:call-id-unification

Conversation

@dgozman

@dgozman Dmitry Gozman (dgozman) commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The client instrumentation now assigns the protocol message id, so an api call and its test runner step share a single id. Metadata.stepId is gone; call@<n> is minted in one place, the client connection, only when nothing assigned an id.
  • stepId is no longer written to the trace. TraceModernizer rewrites the ids of older traces on the fly and owns client-side stacks via appendStacks().
  • TraceModel merges actions by call id, so nonPrimaryIdToPrimaryId goes away.
  • ClientSideCallMetadata.id becomes a string — the language ports need to send the message id there instead of an int.

Design choice

This is done to unify ids between steps and actions. Alternatively, we could use the callId as a step id, except for expect calls where the step is created much earlier than the is made, and rewriting the id is too late.

The library minted `call@<wire-id>` while the test runner minted
`<category>@<ordinal>`, and the two were reconciled through a `stepId`
side-channel on every trace event. Instead, let the client instrumentation
assign the protocol message id, so a call and its step share one id.

- `Metadata.stepId` is gone; the message's own `id` is the call id, minted
  in the client connection when the instrumentation did not assign one.
- `ClientSideCallMetadata.id` is a string, so `trace.stacks` is keyed by the
  same id as the action.
- `stepId` is no longer written to the trace. `TraceModernizer` rewrites the
  ids of older traces on the fly and owns the stacks through `appendStacks()`.
- `TraceModel` merges actions by call id, dropping `nonPrimaryIdToPrimaryId`.
@github-actions

Copy link
Copy Markdown
Contributor

Test results for "tests 1"

1 failed
❌ [playwright-test] › reporter-html.spec.ts:756 › merged › trace should not hang when showing parallel api requests @ubuntu-latest-node26

5 flaky ⚠️ [chromium-library] › library/video.spec.ts:664 › screencast › should capture full viewport `@frozen-time-library-chromium-linux`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:179 › serviceWorker(), and fromServiceWorker() work `@chromium-ubuntu-22.04-node20`
⚠️ [chromium-library] › library/popup.spec.ts:260 › should not throw when click closes popup `@chromium-ubuntu-22.04-node22`
⚠️ [firefox-page] › page/page-emulate-media.spec.ts:144 › should keep reduced motion and color emulation after reload `@firefox-ubuntu-22.04-node20`
⚠️ [playwright-test] › ui-mode-test-update.spec.ts:202 › should update test locations `@ubuntu-latest-node22`

51278 passed, 1237 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

🔴 The one failure looks caused by this PR

Hi, I'm the Playwright bot and I took a first look at the CI failures.

reporter-html.spec.ts:756 › merged › trace should not hang when showing parallel api requests fails, and it exercises exactly the trace call-id merging path this PR rewrites. The other five results are flaky (passed on retry), so there's nothing to triage there.

Details

Caused by this PR

  • [playwright-test] › reporter-html.spec.ts:756 › merged › trace should not hang when showing parallel api requests — this test renders a trace with four parallel API requests across two request contexts and clicks the resulting GET actions in the actions tree. That's the precise scenario this PR reworks: TraceModel now merges actions by call id and nonPrimaryIdToPrimaryId is gone, and TraceModernizer rewrites ids on the fly. Concurrent api calls sharing/duplicating a call id are where that merge logic is most likely to collapse or reorder actions. History backs this up: across the aggregated results DB the test's final verdict was passed in 1992 of 1992 runs (0 failures, 0 retry-rescues) between 2026-07-16 and 2026-08-27 — it has never failed or flaked on any other SHA. A test that green for ~2000 runs and turns red the first time on a PR touching its exact code path is a caused-by-PR signal, not a flake.

Pre-existing flakes / infra (not triaged)

  • The five ⚠️ entries — library/video.spec.ts:664, library/chromium/chromium.spec.ts:179, library/popup.spec.ts:260, page/page-emulate-media.spec.ts:144, ui-mode-test-update.spec.ts:202 — all passed on retry and don't touch client instrumentation, trace ids, or the trace model. Unrelated to this PR.

Worth a look before merge: run the trace test locally against the parallel-request scenario and confirm the merged-by-call-id actions still resolve for concurrent API calls.

Triaged by the Playwright bot - agent run

@github-actions

Copy link
Copy Markdown
Contributor

Test results for "MCP"

8259 passed, 1361 skipped


Merge workflow run.

Step ids double as protocol call ids now, but the counter restarted for
every test while the client connection that correlates responses by id is
shared by all tests in the worker. A call still in flight when a test ended
could have its id reused by the next test, overwriting the pending callback
and failing with "Cannot find command to respond".
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