Files
chromedevtools--chrome-devt…/tests/TextSnapshot.test.ts
T
2026-07-13 12:30:05 +08:00

176 lines
4.9 KiB
TypeScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import assert from 'node:assert';
import {afterEach, describe, it} from 'node:test';
import sinon from 'sinon';
import {TextSnapshot} from '../src/TextSnapshot.js';
import type {TextSnapshotNode} from '../src/types.js';
import {html, withMcpContext} from './utils.js';
describe('TextSnapshot', () => {
afterEach(() => {
sinon.restore();
TextSnapshot.resetCounter();
});
it('creates a snapshot', async () => {
await withMcpContext(async (_response, context) => {
const page = context.getSelectedMcpPage();
await page.pptrPage.setContent(html`<button>Click me</button>`);
const snapshot = await TextSnapshot.create(page);
assert.ok(snapshot);
assert.strictEqual(snapshot.snapshotId, '1');
assert.ok(snapshot.root);
let foundButton = false;
for (const node of snapshot.idToNode.values()) {
if (node.role === 'button' && node.name === 'Click me') {
foundButton = true;
break;
}
}
assert.ok(foundButton, 'Button should be in the snapshot');
});
});
it('inserts extraHandles into the snapshot correctly', async () => {
await withMcpContext(async (_response, context) => {
const page = context.getSelectedMcpPage();
await page.pptrPage.setContent(html`
<div
id="parent"
role="main"
>
<div
id="middle"
role="none"
>
<button id="child">Click me</button>
</div>
</div>
`);
const middleHandle = await page.pptrPage.$('#middle');
if (!middleHandle) {
throw new Error('middle element not found');
}
const backendNodeId = await middleHandle.backendNodeId();
if (!backendNodeId) {
throw new Error('Failed to get backendNodeId');
}
// Verify it is not in the snapshot by default (due to role="none")
const snapshotBefore = await TextSnapshot.create(page, {
verbose: false,
extraHandles: [],
});
let foundMiddleBefore = false;
for (const node of snapshotBefore.idToNode.values()) {
if (node.backendNodeId === backendNodeId) {
foundMiddleBefore = true;
break;
}
}
assert.ok(
!foundMiddleBefore,
'Middle element should NOT be in the snapshot when not passed as extra handle',
);
// Now take snapshot with extra handle
const snapshot = await TextSnapshot.create(page, {
verbose: false,
extraHandles: [middleHandle],
});
// Find the extra node in idToNode
let extraNode: TextSnapshotNode | undefined;
for (const node of snapshot.idToNode.values()) {
if (node.backendNodeId === backendNodeId) {
extraNode = node;
break;
}
}
assert.ok(extraNode, 'Extra node should be in the snapshot');
assert.strictEqual(
extraNode.role,
'div',
'Extra node should have role "div"',
);
// Check if the child was moved to extraNode
const childHandle = await page.pptrPage.$('#child');
if (!childHandle) {
throw new Error('child element not found');
}
const childBackendNodeId = await childHandle.backendNodeId();
let foundChild = false;
for (const child of extraNode.children) {
if (child.backendNodeId === childBackendNodeId) {
foundChild = true;
break;
}
}
assert.ok(
foundChild,
'Child node should be moved to extra node children',
);
// Find parent node in snapshot
const parentHandle = await page.pptrPage.$('#parent');
if (!parentHandle) {
throw new Error('parent element not found');
}
const parentBackendId = await parentHandle.backendNodeId();
let parentNode: TextSnapshotNode | undefined;
for (const node of snapshot.idToNode.values()) {
if (node.backendNodeId === parentBackendId) {
parentNode = node;
break;
}
}
assert.ok(parentNode, 'Parent node should be in snapshot');
// Check that child is NOT a child of parent anymore
let foundChildInParent = false;
for (const child of parentNode.children) {
if (child.backendNodeId === childBackendNodeId) {
foundChildInParent = true;
break;
}
}
assert.ok(
!foundChildInParent,
'Child node should NOT be in parent children',
);
// Check that middle IS a child of parent
let foundMiddleInParent = false;
for (const child of parentNode.children) {
if (child.backendNodeId === backendNodeId) {
foundMiddleInParent = true;
break;
}
}
assert.ok(
foundMiddleInParent,
'Middle node should be in parent children',
);
});
});
});