Skip to content

feat(reporter): introduce TestStep.subtitle, unify step formatting - #42422

Merged
Pavel Feldman (pavelfeldman) merged 1 commit into
microsoft:mainfrom
pavelfeldman:step-subtitle
Aug 27, 2026
Merged

feat(reporter): introduce TestStep.subtitle, unify step formatting#42422
Pavel Feldman (pavelfeldman) merged 1 commit into
microsoft:mainfrom
pavelfeldman:step-subtitle

Conversation

@pavelfeldman

Copy link
Copy Markdown
Member

Summary

  • TestStep now carries title, subtitle and params; subtitle is exposed in the reporter API, JSON/blob reports, HTML report and traces.
  • title/subtitle templates are the source of truth in protocol.yml: selector actions declare explicit subtitle: '{selector}' (enforced by generate_channels), navigation/fetch declare subtitle: '{url}'; {selector} renders through asLocator.
  • Removed implicit selector/url formatting hacks in the test runner, expect matchers, trace viewer, recorder call log and CLI trace tools; single-line surfaces render "title subtitle" via the shared protocolFormatter helpers.

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

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

🟢 The one failure is a pre-existing flake — this PR looks clear

[chromium-library] › library/video.spec.ts:736 › screencast › should work with video+trace on the frozen-time-library-chromium-linux bot is a long-standing flake, not something this PR broke. The same test with the same signature fails on unrelated PRs and on main, and it's retry-rescued constantly. No other real failures — the other five are flaky/retry-passed.

Details

Overall: 1 failure, 5 flaky. The single failure is a known flake unrelated to the reporter/subtitle change; the flakies passed on retry. Nothing here points at this PR.

Pre-existing flake / infra

Flaky (retry-passed in this run)

  • [chromium-library] › library/beforeunload.spec.ts:130, [chromium-library] › library/video.spec.ts:664, [firefox-page] › page/page-emulate-media.spec.ts:144, [firefox-page] › page/page-event-request.spec.ts:181, [webkit-library] › library/trace-viewer.spec.ts:1495 — all passed on retry and span browsers/areas the subtitle change doesn't drive. Normal CI noise.

Take this as a first pass rather than the final word.

Triaged by the Playwright bot - agent run

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@dgozmanDmitry Gozman (dgozman) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What a beauty!

{statusIcon(step.error || step.duration === -1 ? 'failed' : (step.skipped ? 'skipped' : 'passed'))}
<span className='step-title-text'>
{title}
{step.subtitle && <span className='step-subtitle'> {step.subtitle}</span>}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since we are searching in the subtitle as well (see stepMatchesFilter), perhaps we should apply similar highlighting (block on the line 263 new code) to the subtitle?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Good catch, done - extracted the highlight loop into highlightFilterText() and applied it to the subtitle as well. It also fixes a bug there: the non-matching chunks were taken from the lowercased string, so Click rendered as click while the filter was active.

Comment threadpackages/protocol/spec/frame.yml
await page.getByText('GET "/empty.html"').nth(2).click();
await page.getByText('GET "/empty.html"').nth(1).click();
await page.getByText('GET "/empty.html"').nth(0).click();
await page.getByTestId('actions-tree').getByText('GET', { exact: true }).nth(2).click();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does this mean we are not showing the fetch url anymore?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

We do show it, it just moved from the quoted title into the subtitle line: the step now records title: "GET", subtitle: "/empty.html". The /empty.html rendering is the pre-existing url special case in formatProtocolParam (pathname + search), so it reads GET / /empty.html where it used to read GET "/empty.html".

The test only had to change because title and subtitle are separate nodes now - updated it to assert that explicitly instead of hiding it.

…rmatting
Step and action titles are now rendered uniformly from the protocol
metadata: `title` and `subtitle` templates live in protocol.yml, with
explicit `subtitle: '{selector}'` for selector-based actions and
`subtitle: '{url}'` for navigation/fetch. The `{selector}` placeholder
is rendered through asLocator. TestStep now carries `title`, `subtitle`
and `params`; the implicit selector-appending hacks in the test runner,
expect matchers, trace viewer, recorder call log and CLI trace tools
are removed in favor of the shared protocolFormatter helpers.
@github-actions

Copy link
Copy Markdown
Contributor

Test results for "tests 1"

6 flaky⚠️ [chromium-library] › library/chromium/chromium.spec.ts:373 › should produce network events, routing, and annotations for Service Worker `@chromium-ubuntu-22.04-arm-node20`
⚠️ [chromium-library] › library/chromium/chromium.spec.ts:436 › should produce network events, routing, and annotations for Service Worker (advanced) `@chromium-ubuntu-22.04-node20`
⚠️ [chromium-library] › library/video.spec.ts:495 › screencast › should capture static page in persistent context Radoslav Kirilov (@smoke) `@chromium-ubuntu-22.04-node20`
⚠️ [firefox-page] › page/page-event-request.spec.ts:181 › should return response body when Cross-Origin-Opener-Policy is set `@firefox-ubuntu-22.04-node20`
⚠️ [webkit-library] › library/browsercontext-clearcookies.spec.ts:72 › should remove cookies by name regex `@webkit-ubuntu-22.04-node20`
⚠️ [playwright-test] › ui-mode-trace.spec.ts:827 › should update state on subsequent run `@windows-latest-node22`

51290 passed, 1237 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

Test results for "MCP"

3 failed
❌ [firefox] › mcp/annotate.spec.ts:417 › should cancel browser_annotate when the MCP client disconnects @mcp-windows-latest-firefox
❌ [firefox] › mcp/cli-devtools.spec.ts:199 › recording-start-stop @mcp-windows-latest-firefox
❌ [firefox] › mcp/cli-parsing.spec.ts:76 › negative number arguments @mcp-windows-latest-firefox

8256 passed, 1361 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

🟡 Two confirmed flakes, one I can't fully clear

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

The latest run's failures are all @mcp-windows-latest-firefox: two are known pre-existing flakes, and one (cli-devtools recording-start-stop) I can't prove either way — its evidence leans flake, but it only fails on this PR in the results DB, so I'm calling it uncertain.

Details

Overall: 3 failures in the latest MCP report, all Firefox on Windows; "tests 1" was all-flaky with no failures. This PR reworks step title/subtitle formatting across the reporter, trace and recorder call-log surfaces. Two of the three failures are unrelated pre-existing flakes; the third touches the recorder output path the PR edits, but the signature points at a capture race rather than a formatting break.

Pre-existing flake / infra

Uncertain

  • [firefox] › mcp/cli-devtools.spec.ts:199 › recording-start-stop — the results DB has no failure for this test off this PR, so I can't certify it as a pre-existing flake. That said, the evidence leans flake: it was retry-rescued in this run, only Firefox-on-Windows failed (Chromium/WebKit/Edge and the Firefox retry all passed on this same PR), and the error is Received: "Recording stopped. No actions were recorded." where the expected click was getByRole('button', { name: 'Submit' }).click(). That's the recorder not capturing the action at all — a timing race — not a mis-formatted action string, which is what a regression in this PR's title/subtitle rework would produce. A deterministic formatting break would also hit every browser, not one. To close it out I'd want to see the same test flake once on a SHA outside this PR.

Take this as a first pass, not the final word.

Triaged by the Playwright bot - agent run

@pavelfeldman
Pavel Feldman (pavelfeldman) merged commit 17454b0 into microsoft:mainAug 27, 2026
44 of 45 checks passed
Sign up for freeto 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

@pavelfeldman@dgozman