Skip to content

Conversation

@chromiebot
Copy link

@chromiebot chromiebot commented Dec 31, 2025

why

what changed

test plan


Summary by cubic

Adds a public Page.snapshot() to capture a hybrid DOM + Accessibility snapshot. Returns a combined tree with XPath and URL maps, plus per-frame data; includes tests covering scoping and frame payloads.

  • New Features
    • New Page.snapshot(options) using captureHybridSnapshot.
    • Options: focusSelector (CSS or XPath), pierceShadow (default true), experimental.
    • Exported types: HybridSnapshot, SnapshotOptions, PerFrameSnapshot.

Written for commit de6bd5f. Summary will update on new commits.

Chromie Bot and others added 2 commits December 31, 2025 00:10
This test validates the new page.snapshot() method that exposes
captureHybridSnapshot functionality publicly, allowing users to
capture a hybrid DOM + Accessibility snapshot of the page.

Tests include:
- Basic snapshot with combined tree and maps
- Scoped snapshot with CSS focusSelector
- Scoped snapshot with XPath focusSelector
- Per-frame data availability

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Adds a new public page.snapshot() method that exposes the internal
captureHybridSnapshot functionality, allowing users to capture a
hybrid DOM + Accessibility snapshot of the page.

The method returns a HybridSnapshot containing:
- combinedTree: Merged outline across every frame
- combinedXpathMap: EncodedId -> absolute XPath mapping
- combinedUrlMap: EncodedId -> URL extracted from AX properties
- perFrame: Per-frame payloads with original relative data

Options include:
- focusSelector: Filter to a specific element/subtree (XPath or CSS)
- pierceShadow: Pierce shadow DOM (default: true)
- experimental: Enable experimental AX traversal tweaks

Also exports HybridSnapshot, SnapshotOptions, and PerFrameSnapshot
types publicly for TypeScript users.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@changeset-bot
Copy link

changeset-bot bot commented Dec 31, 2025

⚠️ No Changeset found

Latest commit: de6bd5f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 3 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/core/lib/v3/tests/page-snapshot.spec.ts">

<violation number="1" location="packages/core/lib/v3/tests/page-snapshot.spec.ts:83">
P2: Test verifies scoped content is present but doesn&#39;t verify that out-of-scope content (`#outside`) is excluded. Add a negative assertion to actually test the scoping behavior, otherwise this test provides false confidence.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.


expect(scopedSnapshot).toBeDefined();
expect(scopedSnapshot.combinedTree).toContain("Main Heading");
expect(scopedSnapshot.combinedTree).toContain("Main paragraph");
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Dec 31, 2025

Choose a reason for hiding this comment

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

P2: Test verifies scoped content is present but doesn't verify that out-of-scope content (#outside) is excluded. Add a negative assertion to actually test the scoping behavior, otherwise this test provides false confidence.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/lib/v3/tests/page-snapshot.spec.ts, line 83:

<comment>Test verifies scoped content is present but doesn&#39;t verify that out-of-scope content (`#outside`) is excluded. Add a negative assertion to actually test the scoping behavior, otherwise this test provides false confidence.</comment>

<file context>
@@ -0,0 +1,138 @@
+
+    expect(scopedSnapshot).toBeDefined();
+    expect(scopedSnapshot.combinedTree).toContain(&quot;Main Heading&quot;);
+    expect(scopedSnapshot.combinedTree).toContain(&quot;Main paragraph&quot;);
+  });
+
</file context>
Fix with Cubic

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 31, 2025

Greptile Summary

Exposes the internal captureHybridSnapshot functionality as a new public page.snapshot() method, allowing users to programmatically capture hybrid DOM + Accessibility snapshots that combine tree representations with XPath and URL mappings across all frames.

Key changes:

  • Added page.snapshot(options?) method with comprehensive JSDoc documentation
  • Exported HybridSnapshot, SnapshotOptions, and PerFrameSnapshot types for TypeScript users
  • Added test coverage for basic snapshot functionality, focusSelector option (CSS and XPath), and perFrame data validation
  • Method supports optional filtering via focusSelector (XPath or CSS), shadow DOM piercing, and experimental AX traversal features

This exposes the same snapshot format used internally by act/extract/observe methods, enabling advanced use cases like caching snapshots, implementing custom selectors, or debugging element targeting.

Confidence Score: 5/5

  • This PR is safe to merge with no issues identified
  • The implementation correctly wraps existing, well-tested functionality (captureHybridSnapshot) with a thin public API layer. The method signature is well-documented, test coverage is comprehensive, and the changes follow established patterns in the codebase (similar to how handlers use captureHybridSnapshot). No new logic is introduced, only exposure of internal functionality.
  • No files require special attention

Important Files Changed

Filename Overview
packages/core/lib/v3/tests/page-snapshot.spec.ts Added comprehensive tests for the new page.snapshot() method covering basic functionality, focusSelector options (CSS and XPath), and perFrame data validation
packages/core/lib/v3/types/public/page.ts Exported HybridSnapshot, SnapshotOptions, and PerFrameSnapshot types from private types for public API consumption
packages/core/lib/v3/understudy/page.ts Added public snapshot() method that wraps captureHybridSnapshot with comprehensive JSDoc documentation and @LogAction decorator

Sequence Diagram

sequenceDiagram
    participant User
    participant Page
    participant captureHybridSnapshot
    participant tryScopedSnapshot
    participant buildSessionIndexes
    participant collectPerFrameMaps
    participant computeFramePrefixes
    participant mergeFramesIntoSnapshot

    User->>Page: page.snapshot(options?)
    Page->>captureHybridSnapshot: captureHybridSnapshot(page, options)
    
    alt focusSelector provided
        captureHybridSnapshot->>tryScopedSnapshot: attempt scoped snapshot
        alt selector resolves
            tryScopedSnapshot-->>captureHybridSnapshot: HybridSnapshot (scoped)
            captureHybridSnapshot-->>Page: HybridSnapshot
            Page-->>User: snapshot result
        else selector fails
            tryScopedSnapshot-->>captureHybridSnapshot: null (fallback)
        end
    end
    
    alt full snapshot (no focusSelector or fallback)
        captureHybridSnapshot->>buildSessionIndexes: build DOM indexes per session
        buildSessionIndexes-->>captureHybridSnapshot: sessionToIndex map
        
        captureHybridSnapshot->>collectPerFrameMaps: collect per-frame DOM & A11y data
        collectPerFrameMaps-->>captureHybridSnapshot: perFrameMaps, perFrameOutlines
        
        captureHybridSnapshot->>computeFramePrefixes: compute absolute XPath prefixes
        computeFramePrefixes-->>captureHybridSnapshot: absPrefix, iframeHostEncByChild
        
        captureHybridSnapshot->>mergeFramesIntoSnapshot: merge all frames
        mergeFramesIntoSnapshot-->>captureHybridSnapshot: HybridSnapshot
        
        captureHybridSnapshot-->>Page: HybridSnapshot
        Page-->>User: snapshot result
    end
Loading

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 31, 2025

Greptile found no issues!

From now on, if a review finishes and we haven't found any issues, we will not post anything, but you can confirm that we reviewed your changes in the status check section.

This feature can be toggled off in your Code Review Settings by deselecting "Create a status check for each PR".

@miguelg719
Copy link
Collaborator

@chromiebot can we add docs to the relevant section for page.snapshot on the v3 reference docs

Adds comprehensive documentation for the page.snapshot() method to the
v3 page reference docs, including:

- Method signature and description
- All SnapshotOptions parameters (focusSelector, pierceShadow, experimental)
- Return type documentation (HybridSnapshot, PerFrameSnapshot)
- Example usage code
- Type definitions in the Types section

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@miguelg719
Copy link
Collaborator

@chromiebot simplify the docs changes for page.snapshot to match the overall level of detail in the v3 page reference docs

Reduce verbosity of page.snapshot() docs to match the overall level of
detail in the v3 page reference documentation:

- Shortened method description
- Simplified parameter descriptions
- Removed experimental parameter documentation
- Removed inline interface definitions (kept in Types section)
- Removed separate example code block
- Simplified type definitions in Types section

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
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