Skip to content

Commit 9bcd5b9

Browse files
committed
add/move tests
1 parent 52731f8 commit 9bcd5b9

3 files changed

Lines changed: 300 additions & 207 deletions

File tree

tests/McpContext.test.ts

Lines changed: 0 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {NetworkFormatter} from '../src/formatters/NetworkFormatter.js';
1313
import {TextSnapshot} from '../src/TextSnapshot.js';
1414
import type {HTTPResponse} from '../src/third_party/index.js';
1515
import type {TraceResult} from '../src/trace-processing/parse.js';
16-
import type {TextSnapshotNode} from '../src/types.js';
1716

1817
import {getMockRequest, html, withMcpContext} from './utils.js';
1918

@@ -214,144 +213,4 @@ describe('McpContext', () => {
214213
fromStub.restore();
215214
});
216215
});
217-
218-
it('inserts extraHandles into the snapshot correctly', async () => {
219-
await withMcpContext(async (_response, context) => {
220-
const page = context.getSelectedMcpPage();
221-
await page.pptrPage.setContent(html`
222-
<div
223-
id="parent"
224-
role="main"
225-
>
226-
<div
227-
id="middle"
228-
role="none"
229-
>
230-
<button id="child">Click me</button>
231-
</div>
232-
</div>
233-
`);
234-
235-
const middleHandle = await page.pptrPage.$('#middle');
236-
if (!middleHandle) {
237-
throw new Error('middle element not found');
238-
}
239-
240-
const backendNodeId = await middleHandle.backendNodeId();
241-
if (!backendNodeId) {
242-
throw new Error('Failed to get backendNodeId');
243-
}
244-
245-
// Verify it is not in the snapshot by default (due to role="none")
246-
page.textSnapshot = await TextSnapshot.create(page, {
247-
verbose: false,
248-
extraHandles: [],
249-
});
250-
const snapshotBefore = page.textSnapshot;
251-
if (!snapshotBefore) {
252-
throw new Error('Snapshot not created');
253-
}
254-
255-
let foundMiddleBefore = false;
256-
for (const node of snapshotBefore.idToNode.values()) {
257-
if (node.backendNodeId === backendNodeId) {
258-
foundMiddleBefore = true;
259-
break;
260-
}
261-
}
262-
assert.ok(
263-
!foundMiddleBefore,
264-
'Middle element should NOT be in the snapshot when not passed as extra handle',
265-
);
266-
267-
// Now take snapshot with extra handle
268-
page.textSnapshot = await TextSnapshot.create(page, {
269-
verbose: false,
270-
extraHandles: [middleHandle],
271-
});
272-
273-
const snapshot = page.textSnapshot;
274-
if (!snapshot) {
275-
throw new Error('Snapshot not created');
276-
}
277-
278-
// Find the extra node in idToNode
279-
let extraNode: TextSnapshotNode | undefined;
280-
for (const node of snapshot.idToNode.values()) {
281-
if (node.backendNodeId === backendNodeId) {
282-
extraNode = node;
283-
break;
284-
}
285-
}
286-
287-
assert.ok(extraNode, 'Extra node should be in the snapshot');
288-
assert.strictEqual(
289-
extraNode.role,
290-
'div',
291-
'Extra node should have role "div"',
292-
);
293-
294-
// Check if the child was moved to extraNode
295-
const childHandle = await page.pptrPage.$('#child');
296-
if (!childHandle) {
297-
throw new Error('child element not found');
298-
}
299-
const childBackendNodeId = await childHandle.backendNodeId();
300-
301-
let foundChild = false;
302-
for (const child of extraNode.children) {
303-
if (child.backendNodeId === childBackendNodeId) {
304-
foundChild = true;
305-
break;
306-
}
307-
}
308-
assert.ok(
309-
foundChild,
310-
'Child node should be moved to extra node children',
311-
);
312-
313-
// Find parent node in snapshot
314-
const parentHandle = await page.pptrPage.$('#parent');
315-
if (!parentHandle) {
316-
throw new Error('parent element not found');
317-
}
318-
const parentBackendId = await parentHandle.backendNodeId();
319-
320-
let parentNode: TextSnapshotNode | undefined;
321-
for (const node of snapshot.idToNode.values()) {
322-
if (node.backendNodeId === parentBackendId) {
323-
parentNode = node;
324-
break;
325-
}
326-
}
327-
328-
assert.ok(parentNode, 'Parent node should be in snapshot');
329-
330-
// Check that child is NOT a child of parent anymore
331-
let foundChildInParent = false;
332-
for (const child of parentNode.children) {
333-
if (child.backendNodeId === childBackendNodeId) {
334-
foundChildInParent = true;
335-
break;
336-
}
337-
}
338-
assert.ok(
339-
!foundChildInParent,
340-
'Child node should NOT be in parent children',
341-
);
342-
343-
// Check that middle IS a child of parent
344-
let foundMiddleInParent = false;
345-
for (const child of parentNode.children) {
346-
if (child.backendNodeId === backendNodeId) {
347-
foundMiddleInParent = true;
348-
break;
349-
}
350-
}
351-
assert.ok(
352-
foundMiddleInParent,
353-
'Middle node should be in parent children',
354-
);
355-
});
356-
});
357216
});

tests/TextSnapshot.test.ts

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import assert from 'node:assert';
8+
import {afterEach, describe, it} from 'node:test';
9+
10+
import sinon from 'sinon';
11+
12+
import {TextSnapshot} from '../src/TextSnapshot.js';
13+
import type {TextSnapshotNode} from '../src/types.js';
14+
15+
import {html, withMcpContext} from './utils.js';
16+
17+
describe('TextSnapshot', () => {
18+
afterEach(() => {
19+
sinon.restore();
20+
TextSnapshot.resetCounter();
21+
});
22+
23+
it('creates a snapshot', async () => {
24+
await withMcpContext(async (_response, context) => {
25+
const page = context.getSelectedMcpPage();
26+
await page.pptrPage.setContent(html`<button>Click me</button>`);
27+
28+
const snapshot = await TextSnapshot.create(page);
29+
30+
assert.ok(snapshot);
31+
assert.strictEqual(snapshot.snapshotId, '1');
32+
assert.ok(snapshot.root);
33+
34+
let foundButton = false;
35+
for (const node of snapshot.idToNode.values()) {
36+
if (node.role === 'button' && node.name === 'Click me') {
37+
foundButton = true;
38+
break;
39+
}
40+
}
41+
assert.ok(foundButton, 'Button should be in the snapshot');
42+
});
43+
});
44+
45+
it('inserts extraHandles into the snapshot correctly', async () => {
46+
await withMcpContext(async (_response, context) => {
47+
const page = context.getSelectedMcpPage();
48+
await page.pptrPage.setContent(html`
49+
<div
50+
id="parent"
51+
role="main"
52+
>
53+
<div
54+
id="middle"
55+
role="none"
56+
>
57+
<button id="child">Click me</button>
58+
</div>
59+
</div>
60+
`);
61+
62+
const middleHandle = await page.pptrPage.$('#middle');
63+
if (!middleHandle) {
64+
throw new Error('middle element not found');
65+
}
66+
67+
const backendNodeId = await middleHandle.backendNodeId();
68+
if (!backendNodeId) {
69+
throw new Error('Failed to get backendNodeId');
70+
}
71+
72+
// Verify it is not in the snapshot by default (due to role="none")
73+
const snapshotBefore = await TextSnapshot.create(page, {
74+
verbose: false,
75+
extraHandles: [],
76+
});
77+
78+
let foundMiddleBefore = false;
79+
for (const node of snapshotBefore.idToNode.values()) {
80+
if (node.backendNodeId === backendNodeId) {
81+
foundMiddleBefore = true;
82+
break;
83+
}
84+
}
85+
assert.ok(
86+
!foundMiddleBefore,
87+
'Middle element should NOT be in the snapshot when not passed as extra handle',
88+
);
89+
90+
// Now take snapshot with extra handle
91+
const snapshot = await TextSnapshot.create(page, {
92+
verbose: false,
93+
extraHandles: [middleHandle],
94+
});
95+
96+
// Find the extra node in idToNode
97+
let extraNode: TextSnapshotNode | undefined;
98+
for (const node of snapshot.idToNode.values()) {
99+
if (node.backendNodeId === backendNodeId) {
100+
extraNode = node;
101+
break;
102+
}
103+
}
104+
105+
assert.ok(extraNode, 'Extra node should be in the snapshot');
106+
assert.strictEqual(
107+
extraNode.role,
108+
'div',
109+
'Extra node should have role "div"',
110+
);
111+
112+
// Check if the child was moved to extraNode
113+
const childHandle = await page.pptrPage.$('#child');
114+
if (!childHandle) {
115+
throw new Error('child element not found');
116+
}
117+
const childBackendNodeId = await childHandle.backendNodeId();
118+
119+
let foundChild = false;
120+
for (const child of extraNode.children) {
121+
if (child.backendNodeId === childBackendNodeId) {
122+
foundChild = true;
123+
break;
124+
}
125+
}
126+
assert.ok(
127+
foundChild,
128+
'Child node should be moved to extra node children',
129+
);
130+
131+
// Find parent node in snapshot
132+
const parentHandle = await page.pptrPage.$('#parent');
133+
if (!parentHandle) {
134+
throw new Error('parent element not found');
135+
}
136+
const parentBackendId = await parentHandle.backendNodeId();
137+
138+
let parentNode: TextSnapshotNode | undefined;
139+
for (const node of snapshot.idToNode.values()) {
140+
if (node.backendNodeId === parentBackendId) {
141+
parentNode = node;
142+
break;
143+
}
144+
}
145+
146+
assert.ok(parentNode, 'Parent node should be in snapshot');
147+
148+
// Check that child is NOT a child of parent anymore
149+
let foundChildInParent = false;
150+
for (const child of parentNode.children) {
151+
if (child.backendNodeId === childBackendNodeId) {
152+
foundChildInParent = true;
153+
break;
154+
}
155+
}
156+
assert.ok(
157+
!foundChildInParent,
158+
'Child node should NOT be in parent children',
159+
);
160+
161+
// Check that middle IS a child of parent
162+
let foundMiddleInParent = false;
163+
for (const child of parentNode.children) {
164+
if (child.backendNodeId === backendNodeId) {
165+
foundMiddleInParent = true;
166+
break;
167+
}
168+
}
169+
assert.ok(
170+
foundMiddleInParent,
171+
'Middle node should be in parent children',
172+
);
173+
});
174+
});
175+
});

0 commit comments

Comments
 (0)