diff --git a/browse/src/snapshot.ts b/browse/src/snapshot.ts index 94f961c03..3ff2ab56e 100644 --- a/browse/src/snapshot.ts +++ b/browse/src/snapshot.ts @@ -168,8 +168,6 @@ export async function handleSnapshot( // Compact filter: skip elements with no name and no inline content that aren't interactive if (opts.compact && !isInteractive && !node.name && !node.children) continue; - // Assign ref - const ref = `e${refCounter++}`; const indent = ' '.repeat(depth); // Build Playwright locator @@ -207,6 +205,7 @@ export async function handleSnapshot( } if (!handle) continue; + const ref = `e${refCounter++}`; refMap.set(ref, handle); // Format output line diff --git a/browse/test/snapshot.test.ts b/browse/test/snapshot.test.ts index 1868e4bff..72afe6564 100644 --- a/browse/test/snapshot.test.ts +++ b/browse/test/snapshot.test.ts @@ -25,6 +25,14 @@ function extractRef(snapshot: string, predicate: (line: string) => boolean): str return `@${refMatch![1]}`; } +function extractRefNumbers(snapshot: string): number[] { + return snapshot + .split('\n') + .map((line) => line.match(/@e(\d+)/)) + .filter((match): match is RegExpMatchArray => Boolean(match)) + .map((match) => Number(match[1])); +} + beforeAll(async () => { testServer = startTestServer(0); baseUrl = testServer.url; @@ -113,6 +121,15 @@ describe('Snapshot', () => { expect(result).toContain('[button]'); expect(result).toContain('Say "Hello"'); }); + + test('snapshot emits contiguous refs when skipped nodes are not materialized', async () => { + await handleWriteCommand('goto', [baseUrl + '/snapshot.html'], bm); + const result = await handleMetaCommand('snapshot', [], bm, shutdown); + const refs = extractRefNumbers(result); + + expect(refs.length).toBeGreaterThan(0); + expect(refs).toEqual(Array.from({ length: refs.length }, (_, index) => index + 1)); + }); }); // ─── Ref-Based Interaction ──────────────────────────────────────