@browserbasehq/orca 3.2.1-preview.2 → 3.4.0-preview-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/lib/inference.js +2 -9
- package/dist/cjs/lib/inference.js.map +1 -1
- package/dist/cjs/lib/prompt.js +3 -1
- package/dist/cjs/lib/prompt.js.map +1 -1
- package/dist/cjs/lib/v3/agent/AgentProvider.js +3 -0
- package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/fillFormVision.js +16 -12
- package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
- package/dist/cjs/lib/v3/agent/utils/validateExperimentalFeatures.js +0 -4
- package/dist/cjs/lib/v3/agent/utils/validateExperimentalFeatures.js.map +1 -1
- package/dist/cjs/lib/v3/api.d.ts +1 -0
- package/dist/cjs/lib/v3/api.js +15 -3
- package/dist/cjs/lib/v3/api.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/a11yScripts.generated.js +1 -1
- package/dist/cjs/lib/v3/dom/build/a11yScripts.generated.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.js +1 -1
- package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.d.ts +1 -1
- package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.js +1 -1
- package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/screenshotScripts.generated.js +1 -1
- package/dist/cjs/lib/v3/dom/build/screenshotScripts.generated.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/scriptV3Content.d.ts +1 -1
- package/dist/cjs/lib/v3/dom/build/scriptV3Content.js +1 -1
- package/dist/cjs/lib/v3/dom/build/scriptV3Content.js.map +1 -1
- package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.d.ts +24 -0
- package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.js +31 -0
- package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.js.map +1 -0
- package/dist/cjs/lib/v3/handlers/extractHandler.js +3 -1
- package/dist/cjs/lib/v3/handlers/extractHandler.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/observeHandler.js +2 -1
- package/dist/cjs/lib/v3/handlers/observeHandler.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +3 -5
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
- package/dist/cjs/lib/v3/index.d.ts +1 -1
- package/dist/cjs/lib/v3/llm/CerebrasClient.js +1 -1
- package/dist/cjs/lib/v3/llm/CerebrasClient.js.map +1 -1
- package/dist/cjs/lib/v3/llm/GroqClient.js +1 -1
- package/dist/cjs/lib/v3/llm/GroqClient.js.map +1 -1
- package/dist/cjs/lib/v3/types/private/agent.d.ts +5 -0
- package/dist/cjs/lib/v3/types/private/agent.js +11 -0
- package/dist/cjs/lib/v3/types/private/agent.js.map +1 -1
- package/dist/cjs/lib/v3/types/private/handlers.d.ts +2 -0
- package/dist/cjs/lib/v3/types/private/handlers.js.map +1 -1
- package/dist/cjs/lib/v3/types/private/snapshot.d.ts +8 -0
- package/dist/cjs/lib/v3/types/private/snapshot.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/agent.d.ts +2 -3
- package/dist/cjs/lib/v3/types/public/agent.js +3 -0
- package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/api.d.ts +7 -1
- package/dist/cjs/lib/v3/types/public/api.js +22 -2
- package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/methods.d.ts +2 -0
- package/dist/cjs/lib/v3/types/public/methods.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/a11yTree.js +21 -12
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/a11yTree.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.d.ts +11 -2
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.js +268 -21
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/domTree.js +60 -7
- package/dist/cjs/lib/v3/understudy/a11y/snapshot/domTree.js.map +1 -1
- package/dist/cjs/lib/v3/understudy/frameRegistry.js +16 -5
- package/dist/cjs/lib/v3/understudy/frameRegistry.js.map +1 -1
- package/dist/cjs/lib/v3/v3.d.ts +1 -0
- package/dist/cjs/lib/v3/v3.js +18 -14
- package/dist/cjs/lib/v3/v3.js.map +1 -1
- package/dist/cjs/lib/version.d.ts +1 -1
- package/dist/cjs/lib/version.js +1 -1
- package/dist/cjs/lib/version.js.map +1 -1
- package/dist/cjs/tests/integration/observe-element-id-format.spec.js +130 -0
- package/dist/cjs/tests/integration/observe-element-id-format.spec.js.map +1 -0
- package/dist/cjs/tests/unit/agent-mode-routing.test.js +88 -0
- package/dist/cjs/tests/unit/agent-mode-routing.test.js.map +1 -0
- package/dist/cjs/tests/unit/agent-temperature.test.d.ts +1 -0
- package/dist/cjs/tests/unit/agent-temperature.test.js +191 -0
- package/dist/cjs/tests/unit/agent-temperature.test.js.map +1 -0
- package/dist/cjs/tests/unit/agent-variables-validation.test.d.ts +1 -0
- package/dist/cjs/tests/unit/agent-variables-validation.test.js +43 -0
- package/dist/cjs/tests/unit/agent-variables-validation.test.js.map +1 -0
- package/dist/cjs/tests/unit/api-client-observe-variables.test.js +49 -0
- package/dist/cjs/tests/unit/api-client-observe-variables.test.js.map +1 -1
- package/dist/cjs/tests/unit/api-optional-model-api-key.test.js +60 -0
- package/dist/cjs/tests/unit/api-optional-model-api-key.test.js.map +1 -1
- package/dist/cjs/tests/unit/api-variables-schema.test.js +32 -0
- package/dist/cjs/tests/unit/api-variables-schema.test.js.map +1 -1
- package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.d.ts +1 -0
- package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.js +60 -0
- package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.js.map +1 -0
- package/dist/cjs/tests/unit/inference-temperature.test.d.ts +1 -0
- package/dist/cjs/tests/unit/inference-temperature.test.js +65 -0
- package/dist/cjs/tests/unit/inference-temperature.test.js.map +1 -0
- package/dist/cjs/tests/unit/openai-compatible-temperature.test.d.ts +1 -0
- package/dist/cjs/tests/unit/openai-compatible-temperature.test.js +84 -0
- package/dist/cjs/tests/unit/openai-compatible-temperature.test.js.map +1 -0
- package/dist/cjs/tests/unit/prompt-observe-variables.test.js +6 -0
- package/dist/cjs/tests/unit/prompt-observe-variables.test.js.map +1 -1
- package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js +3 -0
- package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
- package/dist/cjs/tests/unit/public-api/public-types.test.js.map +1 -1
- package/dist/cjs/tests/unit/snapshot-a11y-resolvers.test.js +106 -5
- package/dist/cjs/tests/unit/snapshot-a11y-resolvers.test.js.map +1 -1
- package/dist/cjs/tests/unit/snapshot-a11y-tree-utils.test.js +20 -0
- package/dist/cjs/tests/unit/snapshot-a11y-tree-utils.test.js.map +1 -1
- package/dist/cjs/tests/unit/snapshot-capture-orchestration.test.js +119 -9
- package/dist/cjs/tests/unit/snapshot-capture-orchestration.test.js.map +1 -1
- package/dist/cjs/tests/unit/timeout-handlers.test.js +36 -0
- package/dist/cjs/tests/unit/timeout-handlers.test.js.map +1 -1
- package/dist/esm/lib/inference.js +2 -9
- package/dist/esm/lib/inference.js.map +1 -1
- package/dist/esm/lib/prompt.js +3 -1
- package/dist/esm/lib/prompt.js.map +1 -1
- package/dist/esm/lib/v3/agent/AgentProvider.js +3 -0
- package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/fillFormVision.js +16 -12
- package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
- package/dist/esm/lib/v3/agent/utils/validateExperimentalFeatures.js +0 -4
- package/dist/esm/lib/v3/agent/utils/validateExperimentalFeatures.js.map +1 -1
- package/dist/esm/lib/v3/api.d.ts +1 -0
- package/dist/esm/lib/v3/api.js +15 -3
- package/dist/esm/lib/v3/api.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/a11yScripts.generated.js +1 -1
- package/dist/esm/lib/v3/dom/build/a11yScripts.generated.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/locatorScripts.generated.js +1 -1
- package/dist/esm/lib/v3/dom/build/locatorScripts.generated.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/reRenderScriptContent.d.ts +1 -1
- package/dist/esm/lib/v3/dom/build/reRenderScriptContent.js +1 -1
- package/dist/esm/lib/v3/dom/build/reRenderScriptContent.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/screenshotScripts.generated.js +1 -1
- package/dist/esm/lib/v3/dom/build/screenshotScripts.generated.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/scriptV3Content.d.ts +1 -1
- package/dist/esm/lib/v3/dom/build/scriptV3Content.js +1 -1
- package/dist/esm/lib/v3/dom/build/scriptV3Content.js.map +1 -1
- package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.d.ts +24 -0
- package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.js +28 -0
- package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.js.map +1 -0
- package/dist/esm/lib/v3/handlers/extractHandler.js +3 -1
- package/dist/esm/lib/v3/handlers/extractHandler.js.map +1 -1
- package/dist/esm/lib/v3/handlers/observeHandler.js +2 -1
- package/dist/esm/lib/v3/handlers/observeHandler.js.map +1 -1
- package/dist/esm/lib/v3/handlers/v3AgentHandler.js +3 -5
- package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
- package/dist/esm/lib/v3/index.d.ts +1 -1
- package/dist/esm/lib/v3/llm/CerebrasClient.js +1 -1
- package/dist/esm/lib/v3/llm/CerebrasClient.js.map +1 -1
- package/dist/esm/lib/v3/llm/GroqClient.js +1 -1
- package/dist/esm/lib/v3/llm/GroqClient.js.map +1 -1
- package/dist/esm/lib/v3/types/private/agent.d.ts +5 -0
- package/dist/esm/lib/v3/types/private/agent.js +10 -1
- package/dist/esm/lib/v3/types/private/agent.js.map +1 -1
- package/dist/esm/lib/v3/types/private/handlers.d.ts +2 -0
- package/dist/esm/lib/v3/types/private/handlers.js.map +1 -1
- package/dist/esm/lib/v3/types/private/snapshot.d.ts +8 -0
- package/dist/esm/lib/v3/types/private/snapshot.js.map +1 -1
- package/dist/esm/lib/v3/types/public/agent.d.ts +2 -3
- package/dist/esm/lib/v3/types/public/agent.js +3 -0
- package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
- package/dist/esm/lib/v3/types/public/api.d.ts +7 -1
- package/dist/esm/lib/v3/types/public/api.js +22 -2
- package/dist/esm/lib/v3/types/public/api.js.map +1 -1
- package/dist/esm/lib/v3/types/public/methods.d.ts +2 -0
- package/dist/esm/lib/v3/types/public/methods.js.map +1 -1
- package/dist/esm/lib/v3/understudy/a11y/snapshot/a11yTree.js +21 -12
- package/dist/esm/lib/v3/understudy/a11y/snapshot/a11yTree.js.map +1 -1
- package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.d.ts +11 -2
- package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.js +267 -22
- package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.js.map +1 -1
- package/dist/esm/lib/v3/understudy/a11y/snapshot/domTree.js +60 -7
- package/dist/esm/lib/v3/understudy/a11y/snapshot/domTree.js.map +1 -1
- package/dist/esm/lib/v3/understudy/frameRegistry.js +16 -5
- package/dist/esm/lib/v3/understudy/frameRegistry.js.map +1 -1
- package/dist/esm/lib/v3/v3.d.ts +1 -0
- package/dist/esm/lib/v3/v3.js +18 -14
- package/dist/esm/lib/v3/v3.js.map +1 -1
- package/dist/esm/lib/version.d.ts +1 -1
- package/dist/esm/lib/version.js +1 -1
- package/dist/esm/lib/version.js.map +1 -1
- package/dist/esm/tests/integration/observe-element-id-format.spec.d.ts +1 -0
- package/dist/esm/tests/integration/observe-element-id-format.spec.js +128 -0
- package/dist/esm/tests/integration/observe-element-id-format.spec.js.map +1 -0
- package/dist/esm/tests/unit/agent-mode-routing.test.d.ts +1 -0
- package/dist/esm/tests/unit/agent-mode-routing.test.js +86 -0
- package/dist/esm/tests/unit/agent-mode-routing.test.js.map +1 -0
- package/dist/esm/tests/unit/agent-temperature.test.d.ts +1 -0
- package/dist/esm/tests/unit/agent-temperature.test.js +189 -0
- package/dist/esm/tests/unit/agent-temperature.test.js.map +1 -0
- package/dist/esm/tests/unit/agent-variables-validation.test.d.ts +1 -0
- package/dist/esm/tests/unit/agent-variables-validation.test.js +41 -0
- package/dist/esm/tests/unit/agent-variables-validation.test.js.map +1 -0
- package/dist/esm/tests/unit/api-client-observe-variables.test.js +49 -0
- package/dist/esm/tests/unit/api-client-observe-variables.test.js.map +1 -1
- package/dist/esm/tests/unit/api-optional-model-api-key.test.js +60 -0
- package/dist/esm/tests/unit/api-optional-model-api-key.test.js.map +1 -1
- package/dist/esm/tests/unit/api-variables-schema.test.js +32 -0
- package/dist/esm/tests/unit/api-variables-schema.test.js.map +1 -1
- package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.d.ts +1 -0
- package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.js +58 -0
- package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.js.map +1 -0
- package/dist/esm/tests/unit/inference-temperature.test.d.ts +1 -0
- package/dist/esm/tests/unit/inference-temperature.test.js +63 -0
- package/dist/esm/tests/unit/inference-temperature.test.js.map +1 -0
- package/dist/esm/tests/unit/openai-compatible-temperature.test.d.ts +1 -0
- package/dist/esm/tests/unit/openai-compatible-temperature.test.js +82 -0
- package/dist/esm/tests/unit/openai-compatible-temperature.test.js.map +1 -0
- package/dist/esm/tests/unit/prompt-observe-variables.test.js +6 -0
- package/dist/esm/tests/unit/prompt-observe-variables.test.js.map +1 -1
- package/dist/esm/tests/unit/public-api/llm-and-agents.test.js +3 -0
- package/dist/esm/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
- package/dist/esm/tests/unit/public-api/public-types.test.js.map +1 -1
- package/dist/esm/tests/unit/snapshot-a11y-resolvers.test.js +106 -5
- package/dist/esm/tests/unit/snapshot-a11y-resolvers.test.js.map +1 -1
- package/dist/esm/tests/unit/snapshot-a11y-tree-utils.test.js +20 -0
- package/dist/esm/tests/unit/snapshot-a11y-tree-utils.test.js.map +1 -1
- package/dist/esm/tests/unit/snapshot-capture-orchestration.test.js +119 -9
- package/dist/esm/tests/unit/snapshot-capture-orchestration.test.js.map +1 -1
- package/dist/esm/tests/unit/timeout-handlers.test.js +36 -0
- package/dist/esm/tests/unit/timeout-handlers.test.js.map +1 -1
- package/package.json +3 -3
- package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js +0 -56
- package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js.map +0 -1
- package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js +0 -54
- package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js.map +0 -1
- /package/dist/cjs/tests/integration/{agent-captcha-autosolve.spec.d.ts → observe-element-id-format.spec.d.ts} +0 -0
- /package/dist/{esm/tests/integration/agent-captcha-autosolve.spec.d.ts → cjs/tests/unit/agent-mode-routing.test.d.ts} +0 -0
|
@@ -38,6 +38,7 @@ const capture = __importStar(require("../../lib/v3/understudy/a11y/snapshot/capt
|
|
|
38
38
|
const a11yTree = __importStar(require("../../lib/v3/understudy/a11y/snapshot/a11yTree.js"));
|
|
39
39
|
const domTree = __importStar(require("../../lib/v3/understudy/a11y/snapshot/domTree.js"));
|
|
40
40
|
const focusSelectors = __importStar(require("../../lib/v3/understudy/a11y/snapshot/focusSelectors.js"));
|
|
41
|
+
const selectorResolver_js_1 = require("../../lib/v3/understudy/selectorResolver.js");
|
|
41
42
|
const mockCDPSession_js_1 = require("./helpers/mockCDPSession.js");
|
|
42
43
|
const makeProtocolFrame = (id) => ({
|
|
43
44
|
id,
|
|
@@ -89,6 +90,22 @@ const makeSessionIndex = () => ({
|
|
|
89
90
|
[201, 200],
|
|
90
91
|
]),
|
|
91
92
|
contentDocRootByIframe: new Map([[150, 200]]),
|
|
93
|
+
enterByBe: new Map([
|
|
94
|
+
[100, 0],
|
|
95
|
+
[101, 1],
|
|
96
|
+
[102, 2],
|
|
97
|
+
[150, 3],
|
|
98
|
+
[200, 4],
|
|
99
|
+
[201, 5],
|
|
100
|
+
]),
|
|
101
|
+
exitByBe: new Map([
|
|
102
|
+
[101, 6],
|
|
103
|
+
[102, 7],
|
|
104
|
+
[201, 8],
|
|
105
|
+
[200, 9],
|
|
106
|
+
[150, 10],
|
|
107
|
+
[100, 11],
|
|
108
|
+
]),
|
|
92
109
|
});
|
|
93
110
|
(0, vitest_1.beforeEach)(() => {
|
|
94
111
|
vitest_1.vi.restoreAllMocks();
|
|
@@ -189,7 +206,7 @@ const makeSessionIndex = () => ({
|
|
|
189
206
|
urlMap: { [`url-${frameId}`]: `https://${frameId}.test` },
|
|
190
207
|
scopeApplied: false,
|
|
191
208
|
}));
|
|
192
|
-
const result = await capture.collectPerFrameMaps(page, context, sessionToIndex, { experimental: true }, true, context.frames);
|
|
209
|
+
const result = await capture.collectPerFrameMaps(page, context, sessionToIndex, { experimental: true }, true, context.frames, new Map());
|
|
193
210
|
(0, vitest_1.expect)(result.perFrameOutlines).toEqual([
|
|
194
211
|
{ frameId: "frame-1", outline: "outline-frame-1" },
|
|
195
212
|
{ frameId: "frame-2", outline: "outline-frame-2" },
|
|
@@ -228,7 +245,7 @@ const makeSessionIndex = () => ({
|
|
|
228
245
|
scopeApplied: false,
|
|
229
246
|
});
|
|
230
247
|
const sessionToIndex = new Map();
|
|
231
|
-
const result = await capture.collectPerFrameMaps(page, context, sessionToIndex, undefined, false, context.frames);
|
|
248
|
+
const result = await capture.collectPerFrameMaps(page, context, sessionToIndex, undefined, false, context.frames, new Map());
|
|
232
249
|
(0, vitest_1.expect)(buildSpy).toHaveBeenCalledWith(session, false);
|
|
233
250
|
(0, vitest_1.expect)(sessionToIndex.get("new-session")).toBe(idx);
|
|
234
251
|
(0, vitest_1.expect)(result.perFrameMaps.get("frame-9")?.xpathMap["2-100"]).toBe("/");
|
|
@@ -254,7 +271,7 @@ const makeSessionIndex = () => ({
|
|
|
254
271
|
urlMap: {},
|
|
255
272
|
scopeApplied: false,
|
|
256
273
|
});
|
|
257
|
-
const result = await capture.collectPerFrameMaps(page, context, sessionToIndex, undefined, true, ["frame-1"]);
|
|
274
|
+
const result = await capture.collectPerFrameMaps(page, context, sessionToIndex, undefined, true, ["frame-1"], new Map());
|
|
258
275
|
(0, vitest_1.expect)(a11ySpy).toHaveBeenCalledTimes(1);
|
|
259
276
|
(0, vitest_1.expect)(result.perFrameMaps.has("frame-2")).toBe(false);
|
|
260
277
|
(0, vitest_1.expect)(result.perFrameOutlines.map((o) => o.frameId)).toEqual(["frame-1"]);
|
|
@@ -286,9 +303,7 @@ const makeSessionIndex = () => ({
|
|
|
286
303
|
});
|
|
287
304
|
const buildIndexSpy = vitest_1.vi
|
|
288
305
|
.spyOn(domTree, "buildSessionDomIndex")
|
|
289
|
-
.
|
|
290
|
-
throw new Error("should not build session index when scoped");
|
|
291
|
-
});
|
|
306
|
+
.mockResolvedValue(makeSessionIndex());
|
|
292
307
|
const result = await capture.captureHybridSnapshot(page, options);
|
|
293
308
|
(0, vitest_1.expect)(result.combinedTree).toBe("scoped outline");
|
|
294
309
|
(0, vitest_1.expect)(result.combinedUrlMap["0-100"]).toBe("https://frame-1.test");
|
|
@@ -321,9 +336,7 @@ const makeSessionIndex = () => ({
|
|
|
321
336
|
});
|
|
322
337
|
const buildIndexSpy = vitest_1.vi
|
|
323
338
|
.spyOn(domTree, "buildSessionDomIndex")
|
|
324
|
-
.
|
|
325
|
-
throw new Error("should not build session index when scoped");
|
|
326
|
-
});
|
|
339
|
+
.mockResolvedValue(makeSessionIndex());
|
|
327
340
|
const result = await capture.captureHybridSnapshot(page, options);
|
|
328
341
|
(0, vitest_1.expect)(result.combinedTree).toBe("scoped outline");
|
|
329
342
|
(0, vitest_1.expect)(result.combinedUrlMap["0-100"]).toBe("https://frame-1.test");
|
|
@@ -331,6 +344,103 @@ const makeSessionIndex = () => ({
|
|
|
331
344
|
(0, vitest_1.expect)(a11ySpy).toHaveBeenCalled();
|
|
332
345
|
(0, vitest_1.expect)(buildIndexSpy).not.toHaveBeenCalled();
|
|
333
346
|
});
|
|
347
|
+
(0, vitest_1.it)("filters ignored nodes out of the merged snapshot artifacts", async () => {
|
|
348
|
+
const session = new mockCDPSession_js_1.MockCDPSession({
|
|
349
|
+
"DOM.getFrameOwner": async () => ({ backendNodeId: 150 }),
|
|
350
|
+
"DOM.describeNode": async (params) => ({
|
|
351
|
+
node: {
|
|
352
|
+
backendNodeId: params?.objectId === "ignored-object-a"
|
|
353
|
+
? 201
|
|
354
|
+
: params?.objectId === "ignored-object-b"
|
|
355
|
+
? 202
|
|
356
|
+
: 0,
|
|
357
|
+
},
|
|
358
|
+
}),
|
|
359
|
+
}, "session-a");
|
|
360
|
+
const page = makePage({
|
|
361
|
+
asProtocolFrameTree: () => makeFrameTree("frame-1", [makeFrameTree("frame-2")]),
|
|
362
|
+
listAllFrameIds: () => ["frame-1", "frame-2"],
|
|
363
|
+
getSessionForFrame: () => session,
|
|
364
|
+
getOrdinal: (frameId) => (frameId === "frame-1" ? 0 : 1),
|
|
365
|
+
});
|
|
366
|
+
const idx = makeSessionIndex();
|
|
367
|
+
idx.absByBe.set(202, "/html[1]/body[1]/iframe[1]/aside[1]");
|
|
368
|
+
idx.tagByBe.set(202, "aside");
|
|
369
|
+
idx.docRootOf.set(202, 200);
|
|
370
|
+
idx.enterByBe.set(202, 6);
|
|
371
|
+
idx.exitByBe.set(202, 7);
|
|
372
|
+
idx.exitByBe.set(201, 8);
|
|
373
|
+
idx.exitByBe.set(200, 9);
|
|
374
|
+
idx.exitByBe.set(150, 10);
|
|
375
|
+
idx.exitByBe.set(100, 11);
|
|
376
|
+
vitest_1.vi.spyOn(domTree, "buildSessionDomIndex").mockResolvedValue(idx);
|
|
377
|
+
vitest_1.vi.spyOn(focusSelectors, "resolveCssFocusFrameAndTail").mockResolvedValue({
|
|
378
|
+
targetFrameId: "frame-2",
|
|
379
|
+
tailSelector: ".ad",
|
|
380
|
+
absPrefix: "/html/body/iframe[1]",
|
|
381
|
+
});
|
|
382
|
+
vitest_1.vi.spyOn(selectorResolver_js_1.FrameSelectorResolver.prototype, "resolveAll").mockResolvedValue([
|
|
383
|
+
{ objectId: "ignored-object-a", nodeId: null },
|
|
384
|
+
{ objectId: "ignored-object-b", nodeId: null },
|
|
385
|
+
]);
|
|
386
|
+
vitest_1.vi.spyOn(a11yTree, "a11yForFrame").mockImplementation(async (_sess, frameId, opts) => ({
|
|
387
|
+
outline: opts.isIgnoredBackendNode?.(201) && opts.isIgnoredBackendNode?.(202)
|
|
388
|
+
? `outline-${frameId}-filtered`
|
|
389
|
+
: `outline-${frameId}`,
|
|
390
|
+
urlMap: frameId === "frame-2" &&
|
|
391
|
+
opts.isIgnoredBackendNode?.(201) &&
|
|
392
|
+
opts.isIgnoredBackendNode?.(202)
|
|
393
|
+
? {}
|
|
394
|
+
: { [`url-${frameId}`]: `https://${frameId}.test` },
|
|
395
|
+
scopeApplied: false,
|
|
396
|
+
}));
|
|
397
|
+
const snapshot = await capture.captureHybridSnapshot(page, {
|
|
398
|
+
ignoreSelectors: [".ad"],
|
|
399
|
+
});
|
|
400
|
+
(0, vitest_1.expect)(snapshot.combinedXpathMap["1-201"]).toBeUndefined();
|
|
401
|
+
(0, vitest_1.expect)(snapshot.combinedXpathMap["1-202"]).toBeUndefined();
|
|
402
|
+
(0, vitest_1.expect)(snapshot.combinedUrlMap["url-frame-2"]).toBeUndefined();
|
|
403
|
+
(0, vitest_1.expect)(snapshot.perFrame?.find((frame) => frame.frameId === "frame-2")?.outline).toContain("filtered");
|
|
404
|
+
});
|
|
405
|
+
(0, vitest_1.it)("excludes child frame subtrees when an ignored node is an iframe host", async () => {
|
|
406
|
+
const session = new mockCDPSession_js_1.MockCDPSession({
|
|
407
|
+
"DOM.getFrameOwner": async () => ({ backendNodeId: 150 }),
|
|
408
|
+
"DOM.describeNode": async (params) => ({
|
|
409
|
+
node: { backendNodeId: params?.objectId === "iframe-host" ? 150 : 0 },
|
|
410
|
+
}),
|
|
411
|
+
}, "session-a");
|
|
412
|
+
const page = makePage({
|
|
413
|
+
asProtocolFrameTree: () => makeFrameTree("frame-1", [makeFrameTree("frame-2")]),
|
|
414
|
+
listAllFrameIds: () => ["frame-1", "frame-2"],
|
|
415
|
+
getSessionForFrame: () => session,
|
|
416
|
+
getOrdinal: (frameId) => (frameId === "frame-1" ? 0 : 1),
|
|
417
|
+
});
|
|
418
|
+
vitest_1.vi.spyOn(domTree, "buildSessionDomIndex").mockResolvedValue(makeSessionIndex());
|
|
419
|
+
vitest_1.vi.spyOn(focusSelectors, "resolveCssFocusFrameAndTail").mockResolvedValue({
|
|
420
|
+
targetFrameId: "frame-1",
|
|
421
|
+
tailSelector: "iframe.ad",
|
|
422
|
+
absPrefix: "",
|
|
423
|
+
});
|
|
424
|
+
vitest_1.vi.spyOn(selectorResolver_js_1.FrameSelectorResolver.prototype, "resolveAll").mockResolvedValue([
|
|
425
|
+
{ objectId: "iframe-host", nodeId: null },
|
|
426
|
+
]);
|
|
427
|
+
vitest_1.vi.spyOn(a11yTree, "a11yForFrame").mockImplementation(async (_sess, frameId, opts) => ({
|
|
428
|
+
outline: frameId === "frame-2" && opts.isIgnoredBackendNode?.(200)
|
|
429
|
+
? ""
|
|
430
|
+
: `outline-${frameId}`,
|
|
431
|
+
urlMap: frameId === "frame-2" && opts.isIgnoredBackendNode?.(200)
|
|
432
|
+
? {}
|
|
433
|
+
: { [`url-${frameId}`]: `https://${frameId}.test` },
|
|
434
|
+
scopeApplied: false,
|
|
435
|
+
}));
|
|
436
|
+
const snapshot = await capture.captureHybridSnapshot(page, {
|
|
437
|
+
ignoreSelectors: ["iframe.ad"],
|
|
438
|
+
});
|
|
439
|
+
(0, vitest_1.expect)(snapshot.combinedXpathMap["1-200"]).toBeUndefined();
|
|
440
|
+
(0, vitest_1.expect)(snapshot.combinedXpathMap["1-201"]).toBeUndefined();
|
|
441
|
+
(0, vitest_1.expect)(snapshot.combinedUrlMap["url-frame-2"]).toBeUndefined();
|
|
442
|
+
(0, vitest_1.expect)(snapshot.combinedTree).not.toContain("outline-frame-2");
|
|
443
|
+
});
|
|
334
444
|
(0, vitest_1.it)("collects per-frame data and merges it when no scoped snapshot is available", async () => {
|
|
335
445
|
const session = new mockCDPSession_js_1.MockCDPSession({
|
|
336
446
|
"DOM.getFrameOwner": async () => ({ backendNodeId: 150 }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot-capture-orchestration.test.js","sourceRoot":"","sources":["../../../../tests/unit/snapshot-capture-orchestration.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Protocol } from \"devtools-protocol\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\nimport type { CDPSessionLike } from \"../../lib/v3/understudy/cdp.js\";\nimport type { Page } from \"../../lib/v3/understudy/page.js\";\nimport type {\n FrameContext,\n SessionDomIndex,\n} from \"../../lib/v3/types/private/index.js\";\nimport * as capture from \"../../lib/v3/understudy/a11y/snapshot/capture.js\";\nimport * as a11yTree from \"../../lib/v3/understudy/a11y/snapshot/a11yTree.js\";\nimport * as domTree from \"../../lib/v3/understudy/a11y/snapshot/domTree.js\";\nimport * as focusSelectors from \"../../lib/v3/understudy/a11y/snapshot/focusSelectors.js\";\nimport { MockCDPSession } from \"./helpers/mockCDPSession.js\";\n\nconst makeProtocolFrame = (id: string): Protocol.Page.Frame =>\n ({\n id,\n loaderId: `${id}-loader`,\n url: \"https://example.com\",\n securityOrigin: \"https://example.com\",\n mimeType: \"text/html\",\n }) as unknown as Protocol.Page.Frame;\n\nconst makeFrameTree = (\n id: string,\n children: Protocol.Page.FrameTree[] = [],\n): Protocol.Page.FrameTree => ({\n frame: makeProtocolFrame(id),\n childFrames: children,\n});\n\ntype PageStub = Pick<\n Page,\n | \"mainFrameId\"\n | \"asProtocolFrameTree\"\n | \"listAllFrameIds\"\n | \"getSessionForFrame\"\n | \"getOrdinal\"\n>;\n\nconst makePage = (overrides: Partial<PageStub> = {}): Page => {\n const defaultSession = new MockCDPSession({}, \"default-session\");\n const base: PageStub = {\n mainFrameId: () => \"frame-1\",\n asProtocolFrameTree: () => makeFrameTree(\"frame-1\"),\n listAllFrameIds: () => [\"frame-1\"],\n getSessionForFrame: () => defaultSession,\n getOrdinal: () => 0,\n };\n return { ...base, ...overrides } as unknown as Page;\n};\n\nconst makeSessionIndex = (): SessionDomIndex => ({\n rootBackend: 100,\n absByBe: new Map([\n [100, \"/\"],\n [101, \"/html[1]\"],\n [102, \"/html[1]/body[1]\"],\n [150, \"/html[1]/body[1]/iframe[1]\"],\n [200, \"/html[1]/body[1]/iframe[1]\"],\n [201, \"/html[1]/body[1]/iframe[1]/div[1]\"],\n ]),\n tagByBe: new Map([\n [100, \"#document\"],\n [101, \"html\"],\n [102, \"body\"],\n [150, \"iframe\"],\n [200, \"#document\"],\n [201, \"div\"],\n ]),\n scrollByBe: new Map([[201, true]]),\n docRootOf: new Map([\n [100, 100],\n [101, 100],\n [102, 100],\n [150, 100],\n [200, 200],\n [201, 200],\n ]),\n contentDocRootByIframe: new Map([[150, 200]]),\n});\n\nbeforeEach(() => {\n vi.restoreAllMocks();\n});\n\ndescribe(\"buildFrameContext\", () => {\n it(\"indexes parent relationships from the frame tree\", () => {\n const frameTree = makeFrameTree(\"frame-1\", [\n makeFrameTree(\"frame-2\", [makeFrameTree(\"frame-3\")]),\n makeFrameTree(\"frame-4\"),\n ]);\n const page = makePage({\n asProtocolFrameTree: () => frameTree,\n listAllFrameIds: () => [\"frame-1\", \"frame-2\", \"frame-3\", \"frame-4\"],\n });\n\n const context = capture.buildFrameContext(page);\n\n expect(context.rootId).toBe(\"frame-1\");\n expect(context.frames).toEqual([\n \"frame-1\",\n \"frame-2\",\n \"frame-3\",\n \"frame-4\",\n ]);\n expect(context.parentByFrame.get(\"frame-1\")).toBeNull();\n expect(context.parentByFrame.get(\"frame-2\")).toBe(\"frame-1\");\n expect(context.parentByFrame.get(\"frame-3\")).toBe(\"frame-2\");\n expect(context.parentByFrame.get(\"frame-4\")).toBe(\"frame-1\");\n });\n});\n\ndescribe(\"buildSessionIndexes\", () => {\n it(\"deduplicates frames that share the same CDP session id\", async () => {\n const session = new MockCDPSession({}, \"session-a\");\n const page = makePage({\n // Every frame lookup returns the same session instance, so buildSessionIndexes\n // should call buildSessionDomIndex only once and reuse the result.\n getSessionForFrame: () => session,\n });\n const idx = makeSessionIndex();\n const spy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockResolvedValue(idx);\n\n const result = await capture.buildSessionIndexes(\n page,\n [\"frame-1\", \"frame-2\"],\n true,\n );\n\n expect(spy).toHaveBeenCalledTimes(1); // only one DOM.getDocument per session id\n expect(spy).toHaveBeenCalledWith(session, true);\n expect(result.get(\"session-a\")).toBe(idx);\n });\n\n it(\"builds indexes for sessions without ids using the 'root' key\", async () => {\n const sessionWithoutId: CDPSessionLike = {\n id: undefined,\n async send<R = unknown>(\n _method: string,\n _params?: Record<string, unknown>,\n ): Promise<R> {\n void _method;\n void _params;\n return {} as R;\n },\n on() {},\n off() {},\n async close() {},\n };\n const sessionWithId = new MockCDPSession({}, \"child-session\");\n const page = makePage({\n getSessionForFrame: (frameId: string) =>\n frameId === \"frame-1\" ? sessionWithoutId : sessionWithId,\n });\n\n const idxA = makeSessionIndex();\n const idxB = makeSessionIndex();\n const spy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockResolvedValueOnce(idxA)\n .mockResolvedValueOnce(idxB);\n\n const result = await capture.buildSessionIndexes(\n page,\n [\"frame-1\", \"frame-2\"],\n false,\n );\n\n // Verifies the helper invokes buildSessionDomIndex once for each unique session,\n // keying anonymous sessions as \"root\" so downstream lookups remain stable.\n expect(spy).toHaveBeenNthCalledWith(1, sessionWithoutId, false);\n expect(spy).toHaveBeenNthCalledWith(2, sessionWithId, false);\n expect(result.get(\"root\")).toBe(idxA);\n expect(result.get(\"child-session\")).toBe(idxB);\n });\n});\n\ndescribe(\"collectPerFrameMaps\", () => {\n it(\"builds per-frame xpath/tag maps and outlines from a shared session index\", async () => {\n const session = new MockCDPSession(\n {\n \"DOM.getFrameOwner\": async () => ({ backendNodeId: 150 }),\n },\n \"session-a\",\n );\n const page = makePage({\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n const context: FrameContext = {\n rootId: \"frame-1\",\n frames: [\"frame-1\", \"frame-2\"],\n parentByFrame: new Map([\n [\"frame-1\", null],\n [\"frame-2\", \"frame-1\"],\n ]),\n };\n const sessionIndex = makeSessionIndex();\n const sessionToIndex = new Map([[session.id, sessionIndex]]);\n\n vi.spyOn(a11yTree, \"a11yForFrame\").mockImplementation(\n async (_sess, frameId) => ({\n outline: `outline-${frameId}`,\n urlMap: { [`url-${frameId}`]: `https://${frameId}.test` },\n scopeApplied: false,\n }),\n );\n\n const result = await capture.collectPerFrameMaps(\n page,\n context,\n sessionToIndex,\n { experimental: true },\n true,\n context.frames,\n );\n\n expect(result.perFrameOutlines).toEqual([\n { frameId: \"frame-1\", outline: \"outline-frame-1\" },\n { frameId: \"frame-2\", outline: \"outline-frame-2\" },\n ]);\n const rootMaps = result.perFrameMaps.get(\"frame-1\");\n expect(rootMaps?.xpathMap[\"0-100\"]).toBe(\"/\");\n expect(rootMaps?.xpathMap[\"0-101\"]).toBe(\"/html[1]\");\n expect(rootMaps?.xpathMap[\"0-102\"]).toBe(\"/html[1]/body[1]\");\n const childMaps = result.perFrameMaps.get(\"frame-2\");\n expect(childMaps?.xpathMap[\"1-200\"]).toBe(\"/\");\n expect(childMaps?.xpathMap[\"1-201\"]).toBe(\"/div[1]\");\n expect(childMaps?.scrollableMap[\"1-201\"]).toBe(true);\n expect(childMaps?.urlMap).toEqual({\n \"url-frame-2\": \"https://frame-2.test\",\n });\n expect(session.callsFor(\"DOM.getFrameOwner\")).toHaveLength(1);\n });\n\n it(\"builds a missing session index on demand and memoizes it\", async () => {\n const session = new MockCDPSession({}, \"new-session\");\n const page = makePage({\n getSessionForFrame: () => session,\n getOrdinal: () => 2,\n });\n const context: FrameContext = {\n rootId: \"frame-9\",\n frames: [\"frame-9\"],\n parentByFrame: new Map([[\"frame-9\", null]]),\n };\n const idx = makeSessionIndex();\n const buildSpy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockResolvedValue(idx);\n vi.spyOn(a11yTree, \"a11yForFrame\").mockResolvedValue({\n outline: \"outline\",\n urlMap: {},\n scopeApplied: false,\n });\n\n const sessionToIndex = new Map<string, SessionDomIndex>();\n const result = await capture.collectPerFrameMaps(\n page,\n context,\n sessionToIndex,\n undefined,\n false,\n context.frames,\n );\n\n expect(buildSpy).toHaveBeenCalledWith(session, false);\n expect(sessionToIndex.get(\"new-session\")).toBe(idx);\n expect(result.perFrameMaps.get(\"frame-9\")?.xpathMap[\"2-100\"]).toBe(\"/\");\n });\n\n it(\"skips frames that are not listed in the frameIds argument\", async () => {\n const session = new MockCDPSession({}, \"session-a\");\n const page = makePage({\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n const context: FrameContext = {\n rootId: \"frame-1\",\n frames: [\"frame-1\", \"frame-2\"],\n parentByFrame: new Map([\n [\"frame-1\", null],\n [\"frame-2\", \"frame-1\"],\n ]),\n };\n const sessionIndex = makeSessionIndex();\n const sessionToIndex = new Map([[session.id, sessionIndex]]);\n\n const a11ySpy = vi.spyOn(a11yTree, \"a11yForFrame\").mockResolvedValue({\n outline: \"outline\",\n urlMap: {},\n scopeApplied: false,\n });\n\n const result = await capture.collectPerFrameMaps(\n page,\n context,\n sessionToIndex,\n undefined,\n true,\n [\"frame-1\"],\n );\n\n expect(a11ySpy).toHaveBeenCalledTimes(1);\n expect(result.perFrameMaps.has(\"frame-2\")).toBe(false);\n expect(result.perFrameOutlines.map((o) => o.frameId)).toEqual([\"frame-1\"]);\n });\n});\n\ndescribe(\"captureHybridSnapshot\", () => {\n it(\"returns early when the scoped snapshot path succeeds\", async () => {\n const session = new MockCDPSession({}, \"session-a\");\n const page = makePage({\n getSessionForFrame: () => session,\n });\n const options = { focusSelector: \"/html\" };\n\n vi.spyOn(focusSelectors, \"resolveFocusFrameAndTail\").mockResolvedValue({\n targetFrameId: \"frame-1\",\n tailXPath: \"\",\n absPrefix: \"\",\n });\n const domMapsSpy = vi\n .spyOn(domTree, \"domMapsForSession\")\n .mockResolvedValue({\n tagNameMap: { \"0-100\": \"#document\" },\n xpathMap: { \"0-100\": \"/\" },\n scrollableMap: {},\n });\n const a11ySpy = vi.spyOn(a11yTree, \"a11yForFrame\").mockResolvedValue({\n outline: \"scoped outline\",\n urlMap: { \"0-100\": \"https://frame-1.test\" },\n scopeApplied: true,\n });\n const buildIndexSpy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockImplementation(() => {\n throw new Error(\"should not build session index when scoped\");\n });\n\n const result = await capture.captureHybridSnapshot(page, options);\n\n expect(result.combinedTree).toBe(\"scoped outline\");\n expect(result.combinedUrlMap[\"0-100\"]).toBe(\"https://frame-1.test\");\n expect(domMapsSpy).toHaveBeenCalled();\n expect(a11ySpy).toHaveBeenCalled();\n expect(buildIndexSpy).not.toHaveBeenCalled();\n });\n\n it(\"scoped snapshot still succeeds when iframe inclusion is disabled\", async () => {\n const session = new MockCDPSession({}, \"session-a\");\n const page = makePage({\n getSessionForFrame: () => session,\n });\n const options = { focusSelector: \"/html\", includeIframes: false };\n\n vi.spyOn(focusSelectors, \"resolveFocusFrameAndTail\").mockResolvedValue({\n targetFrameId: \"frame-1\",\n tailXPath: \"\",\n absPrefix: \"\",\n });\n const domMapsSpy = vi\n .spyOn(domTree, \"domMapsForSession\")\n .mockResolvedValue({\n tagNameMap: { \"0-100\": \"#document\" },\n xpathMap: { \"0-100\": \"/\" },\n scrollableMap: {},\n });\n const a11ySpy = vi.spyOn(a11yTree, \"a11yForFrame\").mockResolvedValue({\n outline: \"scoped outline\",\n urlMap: { \"0-100\": \"https://frame-1.test\" },\n scopeApplied: true,\n });\n const buildIndexSpy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockImplementation(() => {\n throw new Error(\"should not build session index when scoped\");\n });\n\n const result = await capture.captureHybridSnapshot(page, options);\n\n expect(result.combinedTree).toBe(\"scoped outline\");\n expect(result.combinedUrlMap[\"0-100\"]).toBe(\"https://frame-1.test\");\n expect(domMapsSpy).toHaveBeenCalled();\n expect(a11ySpy).toHaveBeenCalled();\n expect(buildIndexSpy).not.toHaveBeenCalled();\n });\n\n it(\"collects per-frame data and merges it when no scoped snapshot is available\", async () => {\n const session = new MockCDPSession(\n {\n \"DOM.getFrameOwner\": async () => ({ backendNodeId: 150 }),\n },\n \"session-a\",\n );\n const page = makePage({\n asProtocolFrameTree: () =>\n makeFrameTree(\"frame-1\", [makeFrameTree(\"frame-2\")]),\n listAllFrameIds: () => [\"frame-1\", \"frame-2\"],\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n\n const idx = makeSessionIndex();\n vi.spyOn(domTree, \"buildSessionDomIndex\").mockResolvedValue(idx);\n vi.spyOn(a11yTree, \"a11yForFrame\").mockImplementation(\n async (_sess, frameId) => ({\n outline:\n frameId === \"frame-1\"\n ? \"[0-150] iframe host\"\n : \"[1-200] child subtree\",\n urlMap: { [`url-${frameId}`]: `https://${frameId}.test` },\n scopeApplied: false,\n }),\n );\n\n const snapshot = await capture.captureHybridSnapshot(page);\n\n expect(snapshot.combinedTree).toContain(\"[1-200] child subtree\");\n expect(snapshot.combinedXpathMap[\"0-100\"]).toBe(\"/\");\n expect(snapshot.combinedXpathMap[\"1-201\"]).toBe(\n \"/html[1]/body[1]/iframe[1]/div[1]\",\n );\n expect(snapshot.combinedUrlMap[\"url-frame-2\"]).toBe(\"https://frame-2.test\");\n expect(snapshot.perFrame?.map((pf) => pf.frameId)).toEqual([\n \"frame-1\",\n \"frame-2\",\n ]);\n });\n\n it(\"omits iframe frames when includeIframes is false\", async () => {\n const session = new MockCDPSession(\n {\n \"DOM.getFrameOwner\": async () => ({ backendNodeId: 150 }),\n },\n \"session-a\",\n );\n const page = makePage({\n asProtocolFrameTree: () =>\n makeFrameTree(\"frame-1\", [makeFrameTree(\"frame-2\")]),\n listAllFrameIds: () => [\"frame-1\", \"frame-2\"],\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n\n const idx = makeSessionIndex();\n vi.spyOn(domTree, \"buildSessionDomIndex\").mockResolvedValue(idx);\n const a11ySpy = vi\n .spyOn(a11yTree, \"a11yForFrame\")\n .mockImplementation(async (_sess, frameId) => ({\n outline:\n frameId === \"frame-1\"\n ? \"[0-150] iframe host\"\n : \"[1-200] child subtree\",\n urlMap: { [`url-${frameId}`]: `https://${frameId}.test` },\n scopeApplied: false,\n }));\n\n const snapshot = await capture.captureHybridSnapshot(page, {\n includeIframes: false,\n });\n\n expect(a11ySpy).toHaveBeenCalledTimes(1);\n expect(session.callsFor(\"DOM.getFrameOwner\")).toHaveLength(0);\n expect(snapshot.perFrame?.map((pf) => pf.frameId)).toEqual([\"frame-1\"]);\n expect(snapshot.combinedXpathMap[\"1-201\"]).toBeUndefined();\n expect(snapshot.combinedTree).not.toContain(\"[1-200] child subtree\");\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"snapshot-capture-orchestration.test.js","sourceRoot":"","sources":["../../../../tests/unit/snapshot-capture-orchestration.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Protocol } from \"devtools-protocol\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\nimport type { CDPSessionLike } from \"../../lib/v3/understudy/cdp.js\";\nimport type { Page } from \"../../lib/v3/understudy/page.js\";\nimport type {\n FrameContext,\n SessionDomIndex,\n} from \"../../lib/v3/types/private/index.js\";\nimport * as capture from \"../../lib/v3/understudy/a11y/snapshot/capture.js\";\nimport * as a11yTree from \"../../lib/v3/understudy/a11y/snapshot/a11yTree.js\";\nimport * as domTree from \"../../lib/v3/understudy/a11y/snapshot/domTree.js\";\nimport * as focusSelectors from \"../../lib/v3/understudy/a11y/snapshot/focusSelectors.js\";\nimport { FrameSelectorResolver } from \"../../lib/v3/understudy/selectorResolver.js\";\nimport { MockCDPSession } from \"./helpers/mockCDPSession.js\";\n\nconst makeProtocolFrame = (id: string): Protocol.Page.Frame =>\n ({\n id,\n loaderId: `${id}-loader`,\n url: \"https://example.com\",\n securityOrigin: \"https://example.com\",\n mimeType: \"text/html\",\n }) as unknown as Protocol.Page.Frame;\n\nconst makeFrameTree = (\n id: string,\n children: Protocol.Page.FrameTree[] = [],\n): Protocol.Page.FrameTree => ({\n frame: makeProtocolFrame(id),\n childFrames: children,\n});\n\ntype PageStub = Pick<\n Page,\n | \"mainFrameId\"\n | \"asProtocolFrameTree\"\n | \"listAllFrameIds\"\n | \"getSessionForFrame\"\n | \"getOrdinal\"\n>;\n\nconst makePage = (overrides: Partial<PageStub> = {}): Page => {\n const defaultSession = new MockCDPSession({}, \"default-session\");\n const base: PageStub = {\n mainFrameId: () => \"frame-1\",\n asProtocolFrameTree: () => makeFrameTree(\"frame-1\"),\n listAllFrameIds: () => [\"frame-1\"],\n getSessionForFrame: () => defaultSession,\n getOrdinal: () => 0,\n };\n return { ...base, ...overrides } as unknown as Page;\n};\n\nconst makeSessionIndex = (): SessionDomIndex => ({\n rootBackend: 100,\n absByBe: new Map([\n [100, \"/\"],\n [101, \"/html[1]\"],\n [102, \"/html[1]/body[1]\"],\n [150, \"/html[1]/body[1]/iframe[1]\"],\n [200, \"/html[1]/body[1]/iframe[1]\"],\n [201, \"/html[1]/body[1]/iframe[1]/div[1]\"],\n ]),\n tagByBe: new Map([\n [100, \"#document\"],\n [101, \"html\"],\n [102, \"body\"],\n [150, \"iframe\"],\n [200, \"#document\"],\n [201, \"div\"],\n ]),\n scrollByBe: new Map([[201, true]]),\n docRootOf: new Map([\n [100, 100],\n [101, 100],\n [102, 100],\n [150, 100],\n [200, 200],\n [201, 200],\n ]),\n contentDocRootByIframe: new Map([[150, 200]]),\n enterByBe: new Map([\n [100, 0],\n [101, 1],\n [102, 2],\n [150, 3],\n [200, 4],\n [201, 5],\n ]),\n exitByBe: new Map([\n [101, 6],\n [102, 7],\n [201, 8],\n [200, 9],\n [150, 10],\n [100, 11],\n ]),\n});\n\nbeforeEach(() => {\n vi.restoreAllMocks();\n});\n\ndescribe(\"buildFrameContext\", () => {\n it(\"indexes parent relationships from the frame tree\", () => {\n const frameTree = makeFrameTree(\"frame-1\", [\n makeFrameTree(\"frame-2\", [makeFrameTree(\"frame-3\")]),\n makeFrameTree(\"frame-4\"),\n ]);\n const page = makePage({\n asProtocolFrameTree: () => frameTree,\n listAllFrameIds: () => [\"frame-1\", \"frame-2\", \"frame-3\", \"frame-4\"],\n });\n\n const context = capture.buildFrameContext(page);\n\n expect(context.rootId).toBe(\"frame-1\");\n expect(context.frames).toEqual([\n \"frame-1\",\n \"frame-2\",\n \"frame-3\",\n \"frame-4\",\n ]);\n expect(context.parentByFrame.get(\"frame-1\")).toBeNull();\n expect(context.parentByFrame.get(\"frame-2\")).toBe(\"frame-1\");\n expect(context.parentByFrame.get(\"frame-3\")).toBe(\"frame-2\");\n expect(context.parentByFrame.get(\"frame-4\")).toBe(\"frame-1\");\n });\n});\n\ndescribe(\"buildSessionIndexes\", () => {\n it(\"deduplicates frames that share the same CDP session id\", async () => {\n const session = new MockCDPSession({}, \"session-a\");\n const page = makePage({\n // Every frame lookup returns the same session instance, so buildSessionIndexes\n // should call buildSessionDomIndex only once and reuse the result.\n getSessionForFrame: () => session,\n });\n const idx = makeSessionIndex();\n const spy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockResolvedValue(idx);\n\n const result = await capture.buildSessionIndexes(\n page,\n [\"frame-1\", \"frame-2\"],\n true,\n );\n\n expect(spy).toHaveBeenCalledTimes(1); // only one DOM.getDocument per session id\n expect(spy).toHaveBeenCalledWith(session, true);\n expect(result.get(\"session-a\")).toBe(idx);\n });\n\n it(\"builds indexes for sessions without ids using the 'root' key\", async () => {\n const sessionWithoutId: CDPSessionLike = {\n id: undefined,\n async send<R = unknown>(\n _method: string,\n _params?: Record<string, unknown>,\n ): Promise<R> {\n void _method;\n void _params;\n return {} as R;\n },\n on() {},\n off() {},\n async close() {},\n };\n const sessionWithId = new MockCDPSession({}, \"child-session\");\n const page = makePage({\n getSessionForFrame: (frameId: string) =>\n frameId === \"frame-1\" ? sessionWithoutId : sessionWithId,\n });\n\n const idxA = makeSessionIndex();\n const idxB = makeSessionIndex();\n const spy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockResolvedValueOnce(idxA)\n .mockResolvedValueOnce(idxB);\n\n const result = await capture.buildSessionIndexes(\n page,\n [\"frame-1\", \"frame-2\"],\n false,\n );\n\n // Verifies the helper invokes buildSessionDomIndex once for each unique session,\n // keying anonymous sessions as \"root\" so downstream lookups remain stable.\n expect(spy).toHaveBeenNthCalledWith(1, sessionWithoutId, false);\n expect(spy).toHaveBeenNthCalledWith(2, sessionWithId, false);\n expect(result.get(\"root\")).toBe(idxA);\n expect(result.get(\"child-session\")).toBe(idxB);\n });\n});\n\ndescribe(\"collectPerFrameMaps\", () => {\n it(\"builds per-frame xpath/tag maps and outlines from a shared session index\", async () => {\n const session = new MockCDPSession(\n {\n \"DOM.getFrameOwner\": async () => ({ backendNodeId: 150 }),\n },\n \"session-a\",\n );\n const page = makePage({\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n const context: FrameContext = {\n rootId: \"frame-1\",\n frames: [\"frame-1\", \"frame-2\"],\n parentByFrame: new Map([\n [\"frame-1\", null],\n [\"frame-2\", \"frame-1\"],\n ]),\n };\n const sessionIndex = makeSessionIndex();\n const sessionToIndex = new Map([[session.id, sessionIndex]]);\n\n vi.spyOn(a11yTree, \"a11yForFrame\").mockImplementation(\n async (_sess, frameId) => ({\n outline: `outline-${frameId}`,\n urlMap: { [`url-${frameId}`]: `https://${frameId}.test` },\n scopeApplied: false,\n }),\n );\n\n const result = await capture.collectPerFrameMaps(\n page,\n context,\n sessionToIndex,\n { experimental: true },\n true,\n context.frames,\n new Map(),\n );\n\n expect(result.perFrameOutlines).toEqual([\n { frameId: \"frame-1\", outline: \"outline-frame-1\" },\n { frameId: \"frame-2\", outline: \"outline-frame-2\" },\n ]);\n const rootMaps = result.perFrameMaps.get(\"frame-1\");\n expect(rootMaps?.xpathMap[\"0-100\"]).toBe(\"/\");\n expect(rootMaps?.xpathMap[\"0-101\"]).toBe(\"/html[1]\");\n expect(rootMaps?.xpathMap[\"0-102\"]).toBe(\"/html[1]/body[1]\");\n const childMaps = result.perFrameMaps.get(\"frame-2\");\n expect(childMaps?.xpathMap[\"1-200\"]).toBe(\"/\");\n expect(childMaps?.xpathMap[\"1-201\"]).toBe(\"/div[1]\");\n expect(childMaps?.scrollableMap[\"1-201\"]).toBe(true);\n expect(childMaps?.urlMap).toEqual({\n \"url-frame-2\": \"https://frame-2.test\",\n });\n expect(session.callsFor(\"DOM.getFrameOwner\")).toHaveLength(1);\n });\n\n it(\"builds a missing session index on demand and memoizes it\", async () => {\n const session = new MockCDPSession({}, \"new-session\");\n const page = makePage({\n getSessionForFrame: () => session,\n getOrdinal: () => 2,\n });\n const context: FrameContext = {\n rootId: \"frame-9\",\n frames: [\"frame-9\"],\n parentByFrame: new Map([[\"frame-9\", null]]),\n };\n const idx = makeSessionIndex();\n const buildSpy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockResolvedValue(idx);\n vi.spyOn(a11yTree, \"a11yForFrame\").mockResolvedValue({\n outline: \"outline\",\n urlMap: {},\n scopeApplied: false,\n });\n\n const sessionToIndex = new Map<string, SessionDomIndex>();\n const result = await capture.collectPerFrameMaps(\n page,\n context,\n sessionToIndex,\n undefined,\n false,\n context.frames,\n new Map(),\n );\n\n expect(buildSpy).toHaveBeenCalledWith(session, false);\n expect(sessionToIndex.get(\"new-session\")).toBe(idx);\n expect(result.perFrameMaps.get(\"frame-9\")?.xpathMap[\"2-100\"]).toBe(\"/\");\n });\n\n it(\"skips frames that are not listed in the frameIds argument\", async () => {\n const session = new MockCDPSession({}, \"session-a\");\n const page = makePage({\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n const context: FrameContext = {\n rootId: \"frame-1\",\n frames: [\"frame-1\", \"frame-2\"],\n parentByFrame: new Map([\n [\"frame-1\", null],\n [\"frame-2\", \"frame-1\"],\n ]),\n };\n const sessionIndex = makeSessionIndex();\n const sessionToIndex = new Map([[session.id, sessionIndex]]);\n\n const a11ySpy = vi.spyOn(a11yTree, \"a11yForFrame\").mockResolvedValue({\n outline: \"outline\",\n urlMap: {},\n scopeApplied: false,\n });\n\n const result = await capture.collectPerFrameMaps(\n page,\n context,\n sessionToIndex,\n undefined,\n true,\n [\"frame-1\"],\n new Map(),\n );\n\n expect(a11ySpy).toHaveBeenCalledTimes(1);\n expect(result.perFrameMaps.has(\"frame-2\")).toBe(false);\n expect(result.perFrameOutlines.map((o) => o.frameId)).toEqual([\"frame-1\"]);\n });\n});\n\ndescribe(\"captureHybridSnapshot\", () => {\n it(\"returns early when the scoped snapshot path succeeds\", async () => {\n const session = new MockCDPSession({}, \"session-a\");\n const page = makePage({\n getSessionForFrame: () => session,\n });\n const options = { focusSelector: \"/html\" };\n\n vi.spyOn(focusSelectors, \"resolveFocusFrameAndTail\").mockResolvedValue({\n targetFrameId: \"frame-1\",\n tailXPath: \"\",\n absPrefix: \"\",\n });\n const domMapsSpy = vi\n .spyOn(domTree, \"domMapsForSession\")\n .mockResolvedValue({\n tagNameMap: { \"0-100\": \"#document\" },\n xpathMap: { \"0-100\": \"/\" },\n scrollableMap: {},\n });\n const a11ySpy = vi.spyOn(a11yTree, \"a11yForFrame\").mockResolvedValue({\n outline: \"scoped outline\",\n urlMap: { \"0-100\": \"https://frame-1.test\" },\n scopeApplied: true,\n });\n const buildIndexSpy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockResolvedValue(makeSessionIndex());\n\n const result = await capture.captureHybridSnapshot(page, options);\n\n expect(result.combinedTree).toBe(\"scoped outline\");\n expect(result.combinedUrlMap[\"0-100\"]).toBe(\"https://frame-1.test\");\n expect(domMapsSpy).toHaveBeenCalled();\n expect(a11ySpy).toHaveBeenCalled();\n expect(buildIndexSpy).not.toHaveBeenCalled();\n });\n\n it(\"scoped snapshot still succeeds when iframe inclusion is disabled\", async () => {\n const session = new MockCDPSession({}, \"session-a\");\n const page = makePage({\n getSessionForFrame: () => session,\n });\n const options = { focusSelector: \"/html\", includeIframes: false };\n\n vi.spyOn(focusSelectors, \"resolveFocusFrameAndTail\").mockResolvedValue({\n targetFrameId: \"frame-1\",\n tailXPath: \"\",\n absPrefix: \"\",\n });\n const domMapsSpy = vi\n .spyOn(domTree, \"domMapsForSession\")\n .mockResolvedValue({\n tagNameMap: { \"0-100\": \"#document\" },\n xpathMap: { \"0-100\": \"/\" },\n scrollableMap: {},\n });\n const a11ySpy = vi.spyOn(a11yTree, \"a11yForFrame\").mockResolvedValue({\n outline: \"scoped outline\",\n urlMap: { \"0-100\": \"https://frame-1.test\" },\n scopeApplied: true,\n });\n const buildIndexSpy = vi\n .spyOn(domTree, \"buildSessionDomIndex\")\n .mockResolvedValue(makeSessionIndex());\n\n const result = await capture.captureHybridSnapshot(page, options);\n\n expect(result.combinedTree).toBe(\"scoped outline\");\n expect(result.combinedUrlMap[\"0-100\"]).toBe(\"https://frame-1.test\");\n expect(domMapsSpy).toHaveBeenCalled();\n expect(a11ySpy).toHaveBeenCalled();\n expect(buildIndexSpy).not.toHaveBeenCalled();\n });\n\n it(\"filters ignored nodes out of the merged snapshot artifacts\", async () => {\n const session = new MockCDPSession(\n {\n \"DOM.getFrameOwner\": async () => ({ backendNodeId: 150 }),\n \"DOM.describeNode\": async (params) => ({\n node: {\n backendNodeId:\n params?.objectId === \"ignored-object-a\"\n ? 201\n : params?.objectId === \"ignored-object-b\"\n ? 202\n : 0,\n },\n }),\n },\n \"session-a\",\n );\n const page = makePage({\n asProtocolFrameTree: () =>\n makeFrameTree(\"frame-1\", [makeFrameTree(\"frame-2\")]),\n listAllFrameIds: () => [\"frame-1\", \"frame-2\"],\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n\n const idx = makeSessionIndex();\n idx.absByBe.set(202, \"/html[1]/body[1]/iframe[1]/aside[1]\");\n idx.tagByBe.set(202, \"aside\");\n idx.docRootOf.set(202, 200);\n idx.enterByBe.set(202, 6);\n idx.exitByBe.set(202, 7);\n idx.exitByBe.set(201, 8);\n idx.exitByBe.set(200, 9);\n idx.exitByBe.set(150, 10);\n idx.exitByBe.set(100, 11);\n vi.spyOn(domTree, \"buildSessionDomIndex\").mockResolvedValue(idx);\n vi.spyOn(focusSelectors, \"resolveCssFocusFrameAndTail\").mockResolvedValue({\n targetFrameId: \"frame-2\",\n tailSelector: \".ad\",\n absPrefix: \"/html/body/iframe[1]\",\n });\n vi.spyOn(FrameSelectorResolver.prototype, \"resolveAll\").mockResolvedValue([\n { objectId: \"ignored-object-a\", nodeId: null },\n { objectId: \"ignored-object-b\", nodeId: null },\n ]);\n vi.spyOn(a11yTree, \"a11yForFrame\").mockImplementation(\n async (_sess, frameId, opts) => ({\n outline:\n opts.isIgnoredBackendNode?.(201) && opts.isIgnoredBackendNode?.(202)\n ? `outline-${frameId}-filtered`\n : `outline-${frameId}`,\n urlMap:\n frameId === \"frame-2\" &&\n opts.isIgnoredBackendNode?.(201) &&\n opts.isIgnoredBackendNode?.(202)\n ? {}\n : { [`url-${frameId}`]: `https://${frameId}.test` },\n scopeApplied: false,\n }),\n );\n\n const snapshot = await capture.captureHybridSnapshot(page, {\n ignoreSelectors: [\".ad\"],\n });\n\n expect(snapshot.combinedXpathMap[\"1-201\"]).toBeUndefined();\n expect(snapshot.combinedXpathMap[\"1-202\"]).toBeUndefined();\n expect(snapshot.combinedUrlMap[\"url-frame-2\"]).toBeUndefined();\n expect(\n snapshot.perFrame?.find((frame) => frame.frameId === \"frame-2\")?.outline,\n ).toContain(\"filtered\");\n });\n\n it(\"excludes child frame subtrees when an ignored node is an iframe host\", async () => {\n const session = new MockCDPSession(\n {\n \"DOM.getFrameOwner\": async () => ({ backendNodeId: 150 }),\n \"DOM.describeNode\": async (params) => ({\n node: { backendNodeId: params?.objectId === \"iframe-host\" ? 150 : 0 },\n }),\n },\n \"session-a\",\n );\n const page = makePage({\n asProtocolFrameTree: () =>\n makeFrameTree(\"frame-1\", [makeFrameTree(\"frame-2\")]),\n listAllFrameIds: () => [\"frame-1\", \"frame-2\"],\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n\n vi.spyOn(domTree, \"buildSessionDomIndex\").mockResolvedValue(\n makeSessionIndex(),\n );\n vi.spyOn(focusSelectors, \"resolveCssFocusFrameAndTail\").mockResolvedValue({\n targetFrameId: \"frame-1\",\n tailSelector: \"iframe.ad\",\n absPrefix: \"\",\n });\n vi.spyOn(FrameSelectorResolver.prototype, \"resolveAll\").mockResolvedValue([\n { objectId: \"iframe-host\", nodeId: null },\n ]);\n vi.spyOn(a11yTree, \"a11yForFrame\").mockImplementation(\n async (_sess, frameId, opts) => ({\n outline:\n frameId === \"frame-2\" && opts.isIgnoredBackendNode?.(200)\n ? \"\"\n : `outline-${frameId}`,\n urlMap:\n frameId === \"frame-2\" && opts.isIgnoredBackendNode?.(200)\n ? {}\n : { [`url-${frameId}`]: `https://${frameId}.test` },\n scopeApplied: false,\n }),\n );\n\n const snapshot = await capture.captureHybridSnapshot(page, {\n ignoreSelectors: [\"iframe.ad\"],\n });\n\n expect(snapshot.combinedXpathMap[\"1-200\"]).toBeUndefined();\n expect(snapshot.combinedXpathMap[\"1-201\"]).toBeUndefined();\n expect(snapshot.combinedUrlMap[\"url-frame-2\"]).toBeUndefined();\n expect(snapshot.combinedTree).not.toContain(\"outline-frame-2\");\n });\n\n it(\"collects per-frame data and merges it when no scoped snapshot is available\", async () => {\n const session = new MockCDPSession(\n {\n \"DOM.getFrameOwner\": async () => ({ backendNodeId: 150 }),\n },\n \"session-a\",\n );\n const page = makePage({\n asProtocolFrameTree: () =>\n makeFrameTree(\"frame-1\", [makeFrameTree(\"frame-2\")]),\n listAllFrameIds: () => [\"frame-1\", \"frame-2\"],\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n\n const idx = makeSessionIndex();\n vi.spyOn(domTree, \"buildSessionDomIndex\").mockResolvedValue(idx);\n vi.spyOn(a11yTree, \"a11yForFrame\").mockImplementation(\n async (_sess, frameId) => ({\n outline:\n frameId === \"frame-1\"\n ? \"[0-150] iframe host\"\n : \"[1-200] child subtree\",\n urlMap: { [`url-${frameId}`]: `https://${frameId}.test` },\n scopeApplied: false,\n }),\n );\n\n const snapshot = await capture.captureHybridSnapshot(page);\n\n expect(snapshot.combinedTree).toContain(\"[1-200] child subtree\");\n expect(snapshot.combinedXpathMap[\"0-100\"]).toBe(\"/\");\n expect(snapshot.combinedXpathMap[\"1-201\"]).toBe(\n \"/html[1]/body[1]/iframe[1]/div[1]\",\n );\n expect(snapshot.combinedUrlMap[\"url-frame-2\"]).toBe(\"https://frame-2.test\");\n expect(snapshot.perFrame?.map((pf) => pf.frameId)).toEqual([\n \"frame-1\",\n \"frame-2\",\n ]);\n });\n\n it(\"omits iframe frames when includeIframes is false\", async () => {\n const session = new MockCDPSession(\n {\n \"DOM.getFrameOwner\": async () => ({ backendNodeId: 150 }),\n },\n \"session-a\",\n );\n const page = makePage({\n asProtocolFrameTree: () =>\n makeFrameTree(\"frame-1\", [makeFrameTree(\"frame-2\")]),\n listAllFrameIds: () => [\"frame-1\", \"frame-2\"],\n getSessionForFrame: () => session,\n getOrdinal: (frameId: string) => (frameId === \"frame-1\" ? 0 : 1),\n });\n\n const idx = makeSessionIndex();\n vi.spyOn(domTree, \"buildSessionDomIndex\").mockResolvedValue(idx);\n const a11ySpy = vi\n .spyOn(a11yTree, \"a11yForFrame\")\n .mockImplementation(async (_sess, frameId) => ({\n outline:\n frameId === \"frame-1\"\n ? \"[0-150] iframe host\"\n : \"[1-200] child subtree\",\n urlMap: { [`url-${frameId}`]: `https://${frameId}.test` },\n scopeApplied: false,\n }));\n\n const snapshot = await capture.captureHybridSnapshot(page, {\n includeIframes: false,\n });\n\n expect(a11ySpy).toHaveBeenCalledTimes(1);\n expect(session.callsFor(\"DOM.getFrameOwner\")).toHaveLength(0);\n expect(snapshot.perFrame?.map((pf) => pf.frameId)).toEqual([\"frame-1\"]);\n expect(snapshot.combinedXpathMap[\"1-201\"]).toBeUndefined();\n expect(snapshot.combinedTree).not.toContain(\"[1-200] child subtree\");\n });\n});\n"]}
|
|
@@ -770,6 +770,42 @@ vitest_1.vi.mock("../../lib/inference", () => ({
|
|
|
770
770
|
(0, vitest_1.expect)(result[0]).toHaveProperty("arguments");
|
|
771
771
|
(0, vitest_1.expect)(result[0]?.arguments).toEqual(["%username%"]);
|
|
772
772
|
});
|
|
773
|
+
(0, vitest_1.it)("observe() forwards ignoreSelectors to snapshot capture", async () => {
|
|
774
|
+
const captureHybridSnapshotMock = vitest_1.vi.mocked(index_js_1.captureHybridSnapshot);
|
|
775
|
+
captureHybridSnapshotMock.mockResolvedValue({
|
|
776
|
+
combinedTree: "tree content",
|
|
777
|
+
combinedXpathMap: { "1-0": "/html/body/button" },
|
|
778
|
+
combinedUrlMap: {},
|
|
779
|
+
});
|
|
780
|
+
const observeInferenceMock = vitest_1.vi.mocked(inference_js_1.observe);
|
|
781
|
+
observeInferenceMock.mockResolvedValue({
|
|
782
|
+
elements: [
|
|
783
|
+
{
|
|
784
|
+
elementId: "1-0",
|
|
785
|
+
description: "Submit button",
|
|
786
|
+
},
|
|
787
|
+
],
|
|
788
|
+
});
|
|
789
|
+
vitest_1.vi.mocked(timeoutGuard_js_1.createTimeoutGuard).mockImplementation(() => {
|
|
790
|
+
return vitest_1.vi.fn(() => {
|
|
791
|
+
// No-op - never throws
|
|
792
|
+
});
|
|
793
|
+
});
|
|
794
|
+
const handler = buildObserveHandler();
|
|
795
|
+
const fakePage = {
|
|
796
|
+
mainFrame: vitest_1.vi.fn().mockReturnValue({}),
|
|
797
|
+
};
|
|
798
|
+
await handler.observe({
|
|
799
|
+
instruction: "find buttons",
|
|
800
|
+
ignoreSelectors: [".cookie-banner", "#sidebar-ads"],
|
|
801
|
+
page: fakePage,
|
|
802
|
+
});
|
|
803
|
+
(0, vitest_1.expect)(captureHybridSnapshotMock).toHaveBeenCalledWith(fakePage, {
|
|
804
|
+
experimental: false,
|
|
805
|
+
focusSelector: undefined,
|
|
806
|
+
ignoreSelectors: [".cookie-banner", "#sidebar-ads"],
|
|
807
|
+
});
|
|
808
|
+
});
|
|
773
809
|
(0, vitest_1.it)("act() with zero timeout behaves as no timeout", async () => {
|
|
774
810
|
const waitForDomNetworkQuietMock = vitest_1.vi.mocked(actHandlerUtils_js_1.waitForDomNetworkQuiet);
|
|
775
811
|
waitForDomNetworkQuietMock.mockResolvedValue(undefined);
|