Skip to content

feat(mcp): emit structured snapshot in --json responses - #42098

Merged
pavelfeldman merged 1 commit into
microsoft:mainfrom
pavelfeldman:fix-42076
Aug 3, 2026
Merged

feat(mcp): emit structured snapshot in --json responses#42098
pavelfeldman merged 1 commit into
microsoft:mainfrom
pavelfeldman:fix-42076

Conversation

@pavelfeldman

Copy link
Copy Markdown
Member

Summary

  • Add Page.ariaSnapshotJSON and Locator.ariaSnapshotJSON returning the aria snapshot as a free form JSON object
  • MCP response sections can now carry structured content; inline snapshots in --json replies are emitted as the node tree instead of YAML text

Fixes #42076

* `name` <[string]> Accessible name of the element, if any.
* `text` <[string]> Text content of the element, when it is the only child.
* `children` <[Array]> Child nodes and text fragments.
* Boolean and value properties for element state flags: `checked`, `disabled`, `expanded`, `active`, `invalid`, `level`, `pressed` and `selected`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

* Boolean and value properties for element state flags: `checked`, `disabled`, `expanded`, `active`, `invalid`, `level`, `pressed` and `selected`.

What does this mean? Should it be just a list of boolean/number optional properties one per line?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We don't want to over-specify this type as it is a subject to change.

// Note: the resolved frame might differ from the original |frame|.
// See https://developer.mozilla.org/en-US/docs/Web/API/Document/body for body/frameset explanation.
// Non-strict, because pages with nested framesets have multiple "frameset" elements.
const resolved = await progress.race(frame.selectors.callOnSelector(selector || 'body,frameset', { strict: options.strict ?? !!selector, noDefaultPierce: !selector || options.noDefaultPierce }, ({ injected, elements }, ariaOptions) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

do we actually care about framesets here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is a pure parity with the regular snapshot

Add Page.ariaSnapshotJSON and Locator.ariaSnapshotJSON that return the
aria snapshot as a free form JSON object. MCP response sections can now
carry structured content, so inline snapshots in --json replies are
emitted as the node tree instead of YAML text.

Fixes: microsoft#42076
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🔴 One failure looks caused by this PR

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

mcp/cli-json.spec.ts › snapshot returns structured children and flags fails on WebKit across all three OSes — it's the test this PR adds, and the new structured-snapshot feature omits cursor: "pointer" on WebKit. The Firefox annotate failure is a known flake, unrelated to this PR.

Details

Caused by this PR

  • [webkit] › mcp/cli-json.spec.ts › snapshot returns structured children and flags (ubuntu + macos + windows) — the test added in this PR. It only exists on this PR's runs and fails on WebKit in all 3 attempts while passing on chromium/chrome/firefox/msedge. The diff reaches it directly: the new ariaSnapshotJSON node emits a cursor field, but WebKit doesn't report cursor: "pointer" the way the test expects, so the assertion drops that key:

    - "cursor": "pointer",
      "name": "Link",
      "role": "link",
    

    Either the cursor detection in the new snapshot code needs to work on WebKit, or the expectation should account for the engine difference (e.g. drop the cursor assertion or gate that part).

Pre-existing flake / infra

Triaged by the Playwright bot - agent run

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Test results for "MCP"

7920 passed, 1284 skipped


Merge workflow run.

@pavelfeldman

Copy link
Copy Markdown
Member Author

@microsoft-github-policy-service rerun

@pavelfeldman
pavelfeldman merged commit ea4ea1f into microsoft:main Aug 3, 2026
50 checks passed
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Test results for "tests 1"

1 flaky ⚠️ [playwright-test] › ui-mode-trace.spec.ts:827 › should update state on subsequent run `@windows-latest-node22`

51198 passed, 1188 skipped


Merge workflow run.

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.

[CLI]: --json emits formatted text wrapped in a string, not structured data

2 participants