cdp-mcp 0.1.0
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/LICENSE +21 -0
- package/README.md +240 -0
- package/dist/index.js +345 -0
- package/dist/index.js.map +1 -0
- package/dist/server.js +27 -0
- package/dist/server.js.map +1 -0
- package/dist/session/browser.js +394 -0
- package/dist/session/browser.js.map +1 -0
- package/dist/session/buffers.js +43 -0
- package/dist/session/buffers.js.map +1 -0
- package/dist/session/pause.js +99 -0
- package/dist/session/pause.js.map +1 -0
- package/dist/session/state.js +93 -0
- package/dist/session/state.js.map +1 -0
- package/dist/sourcemap/loader.js +138 -0
- package/dist/sourcemap/loader.js.map +1 -0
- package/dist/sourcemap/normalize.js +59 -0
- package/dist/sourcemap/normalize.js.map +1 -0
- package/dist/sourcemap/store.js +185 -0
- package/dist/sourcemap/store.js.map +1 -0
- package/dist/tools/_register.js +30 -0
- package/dist/tools/_register.js.map +1 -0
- package/dist/tools/breakpoints.js +164 -0
- package/dist/tools/breakpoints.js.map +1 -0
- package/dist/tools/console.js +48 -0
- package/dist/tools/console.js.map +1 -0
- package/dist/tools/dom.js +527 -0
- package/dist/tools/dom.js.map +1 -0
- package/dist/tools/execution.js +89 -0
- package/dist/tools/execution.js.map +1 -0
- package/dist/tools/inspect.js +178 -0
- package/dist/tools/inspect.js.map +1 -0
- package/dist/tools/nav.js +136 -0
- package/dist/tools/nav.js.map +1 -0
- package/dist/tools/network.js +137 -0
- package/dist/tools/network.js.map +1 -0
- package/dist/tools/session.js +76 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/tools/source.js +63 -0
- package/dist/tools/source.js.map +1 -0
- package/dist/util/browser-resolve.js +263 -0
- package/dist/util/browser-resolve.js.map +1 -0
- package/dist/util/errors.js +12 -0
- package/dist/util/errors.js.map +1 -0
- package/dist/util/format.js +65 -0
- package/dist/util/format.js.map +1 -0
- package/dist/util/log.js +34 -0
- package/dist/util/log.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { requireSession } from "../session/state.js";
|
|
3
|
+
import { truncate } from "../util/format.js";
|
|
4
|
+
import { registerJsonTool } from "./_register.js";
|
|
5
|
+
const LEVELS = ["log", "info", "warn", "error", "debug", "trace", "verbose"];
|
|
6
|
+
export function registerConsoleTools(server) {
|
|
7
|
+
registerJsonTool(server, "get_console_logs", "Query the buffered console + uncaught-exception stream. Paginate with `since` (the seq from the last call).", {
|
|
8
|
+
since: z.number().int().nonnegative().optional(),
|
|
9
|
+
level: z.enum(LEVELS).optional(),
|
|
10
|
+
search: z.string().optional().describe("Substring filter on message text"),
|
|
11
|
+
limit: z.number().int().positive().optional(),
|
|
12
|
+
}, async (input) => {
|
|
13
|
+
const s = requireSession();
|
|
14
|
+
const search = input.search?.toLowerCase();
|
|
15
|
+
const items = s.console.query({
|
|
16
|
+
since: input.since ?? 0,
|
|
17
|
+
limit: input.limit ?? 100,
|
|
18
|
+
filter: (e) => {
|
|
19
|
+
if (input.level && e.level !== input.level)
|
|
20
|
+
return false;
|
|
21
|
+
if (search && !e.text.toLowerCase().includes(search))
|
|
22
|
+
return false;
|
|
23
|
+
return true;
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
cursor: items.length ? items[items.length - 1].seq : input.since ?? 0,
|
|
28
|
+
items: items.map((e) => ({
|
|
29
|
+
seq: e.seq,
|
|
30
|
+
ts: e.ts,
|
|
31
|
+
level: e.level,
|
|
32
|
+
source: e.source,
|
|
33
|
+
text: truncate(e.text, 1000),
|
|
34
|
+
file: e.mappedFile,
|
|
35
|
+
line: e.mappedLine,
|
|
36
|
+
column: e.mappedColumn,
|
|
37
|
+
js_url: e.url,
|
|
38
|
+
js_line: e.lineNumber != null ? e.lineNumber + 1 : undefined,
|
|
39
|
+
})),
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
registerJsonTool(server, "clear_console", "Clear the buffered console stream (does not clear the browser's own console).", undefined, async () => {
|
|
43
|
+
const s = requireSession();
|
|
44
|
+
s.console.clear();
|
|
45
|
+
return "cleared";
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=console.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/tools/console.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
import { requireSession } from "../session/state.js";
|
|
4
|
+
import { ToolError } from "../util/errors.js";
|
|
5
|
+
import { registerJsonTool } from "./_register.js";
|
|
6
|
+
const locatorBySchema = z.enum(["css", "text", "role", "test_id", "testId", "label", "placeholder", "name"]);
|
|
7
|
+
const locatorShape = {
|
|
8
|
+
by: locatorBySchema.optional().describe("Locator strategy. Omit when passing selector/css for a CSS lookup."),
|
|
9
|
+
selector: z.string().optional().describe("CSS selector. Equivalent to by=css."),
|
|
10
|
+
css: z.string().optional().describe("CSS selector. Equivalent to selector."),
|
|
11
|
+
text: z.string().optional().describe("Text to match for by=text."),
|
|
12
|
+
role: z.string().optional().describe("ARIA/implicit role for by=role, e.g. button, link, textbox."),
|
|
13
|
+
name: z.string().optional().describe("Accessible name, field name, or fallback value depending on the locator strategy."),
|
|
14
|
+
test_id: z.string().optional().describe("Value for data-testid, data-test-id, or data-test."),
|
|
15
|
+
testId: z.string().optional().describe("CamelCase alias for test_id."),
|
|
16
|
+
label: z.string().optional().describe("Label text for by=label."),
|
|
17
|
+
placeholder: z.string().optional().describe("Placeholder text for by=placeholder."),
|
|
18
|
+
exact: z.boolean().optional().describe("Default false: substring match for text/name-like fields."),
|
|
19
|
+
};
|
|
20
|
+
const waitStateSchema = z.enum(["visible", "hidden", "attached", "detached"]);
|
|
21
|
+
export function registerDomTools(server) {
|
|
22
|
+
registerJsonTool(server, "query_selector", "Find an element by CSS selector. Returns nodeId + a short preview.", { selector: z.string() }, async (input) => {
|
|
23
|
+
const s = requireSession();
|
|
24
|
+
const doc = await s.client.send("DOM.getDocument", { depth: 1 });
|
|
25
|
+
const found = await s.client.send("DOM.querySelector", {
|
|
26
|
+
nodeId: doc.root.nodeId,
|
|
27
|
+
selector: input.selector,
|
|
28
|
+
});
|
|
29
|
+
if (!found.nodeId)
|
|
30
|
+
return { found: false };
|
|
31
|
+
const desc = await s.client.send("DOM.describeNode", { nodeId: found.nodeId, depth: 0 });
|
|
32
|
+
return {
|
|
33
|
+
found: true,
|
|
34
|
+
node_id: found.nodeId,
|
|
35
|
+
tag: desc.node.nodeName?.toLowerCase(),
|
|
36
|
+
attrs: pairsToObj(desc.node.attributes ?? []),
|
|
37
|
+
text_preview: (desc.node.nodeValue ?? "").slice(0, 200),
|
|
38
|
+
backend_node_id: desc.node.backendNodeId,
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
registerJsonTool(server, "get_element_html", "Get the outer (or inner) HTML for an element.", {
|
|
42
|
+
selector: z.string().optional(),
|
|
43
|
+
node_id: z.number().int().positive().optional(),
|
|
44
|
+
outer: z.boolean().optional().describe("Default true"),
|
|
45
|
+
}, async (input) => {
|
|
46
|
+
const s = requireSession();
|
|
47
|
+
let nodeId = input.node_id;
|
|
48
|
+
if (!nodeId) {
|
|
49
|
+
if (!input.selector)
|
|
50
|
+
throw new ToolError("missing_arg", "selector or node_id required");
|
|
51
|
+
const doc = await s.client.send("DOM.getDocument", { depth: 1 });
|
|
52
|
+
const found = await s.client.send("DOM.querySelector", {
|
|
53
|
+
nodeId: doc.root.nodeId,
|
|
54
|
+
selector: input.selector,
|
|
55
|
+
});
|
|
56
|
+
if (!found.nodeId)
|
|
57
|
+
throw new ToolError("not_found", `No element matches ${input.selector}`);
|
|
58
|
+
nodeId = found.nodeId;
|
|
59
|
+
}
|
|
60
|
+
const outer = input.outer ?? true;
|
|
61
|
+
const html = await s.client.send("DOM.getOuterHTML", { nodeId });
|
|
62
|
+
if (outer)
|
|
63
|
+
return { node_id: nodeId, html: html.outerHTML };
|
|
64
|
+
// CDP has no direct innerHTML — derive it.
|
|
65
|
+
const wrapper = html.outerHTML.replace(/^<[^>]+>/, "").replace(/<\/[^>]+>$/, "");
|
|
66
|
+
return { node_id: nodeId, html: wrapper };
|
|
67
|
+
});
|
|
68
|
+
registerJsonTool(server, "locate", "Find elements with a structured LocatorSpec, e.g. { by: 'role', role: 'button', name: 'Submit' }.", {
|
|
69
|
+
...locatorShape,
|
|
70
|
+
include_hidden: z.boolean().optional().describe("Default false: only return visible matches."),
|
|
71
|
+
limit: z.number().int().positive().max(100).optional().describe("Default 20."),
|
|
72
|
+
}, async (input) => {
|
|
73
|
+
const locator = normalizeLocator(input);
|
|
74
|
+
const result = await evaluateLocator(locator, {
|
|
75
|
+
includeHidden: input.include_hidden ?? false,
|
|
76
|
+
limit: input.limit ?? 20,
|
|
77
|
+
});
|
|
78
|
+
if (!result.ok)
|
|
79
|
+
throw new ToolError("invalid_locator", result.error ?? "Invalid locator");
|
|
80
|
+
return result;
|
|
81
|
+
});
|
|
82
|
+
registerJsonTool(server, "wait_for", "Poll until a structured LocatorSpec reaches the requested DOM state.", {
|
|
83
|
+
...locatorShape,
|
|
84
|
+
state: waitStateSchema.optional().describe("Default visible."),
|
|
85
|
+
timeout_ms: z.number().int().positive().optional().describe("Default 5000."),
|
|
86
|
+
interval_ms: z.number().int().positive().optional().describe("Default 100."),
|
|
87
|
+
}, async (input) => {
|
|
88
|
+
const locator = normalizeLocator(input);
|
|
89
|
+
const state = input.state ?? "visible";
|
|
90
|
+
const timeoutMs = input.timeout_ms ?? 5000;
|
|
91
|
+
const intervalMs = input.interval_ms ?? 100;
|
|
92
|
+
const started = Date.now();
|
|
93
|
+
let lastResult = null;
|
|
94
|
+
while (Date.now() - started <= timeoutMs) {
|
|
95
|
+
lastResult = await evaluateLocator(locator, { includeHidden: true, limit: 20 });
|
|
96
|
+
if (!lastResult.ok)
|
|
97
|
+
throw new ToolError("invalid_locator", lastResult.error ?? "Invalid locator");
|
|
98
|
+
if (matchesWaitState(lastResult, state)) {
|
|
99
|
+
return {
|
|
100
|
+
state,
|
|
101
|
+
elapsed_ms: Date.now() - started,
|
|
102
|
+
locator,
|
|
103
|
+
result: lastResult,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
await delay(Math.min(intervalMs, Math.max(1, timeoutMs - (Date.now() - started))));
|
|
107
|
+
}
|
|
108
|
+
throw new ToolError("timeout", `Timed out after ${timeoutMs}ms waiting for ${describeLocator(locator)} to be ${state}; last count=${lastResult?.count ?? 0}, visible=${lastResult?.visible_count ?? 0}`);
|
|
109
|
+
});
|
|
110
|
+
registerJsonTool(server, "get_form_state", "Read named form fields using [name=\"...\"] selectors. Omit names to read every named control in the form/page.", {
|
|
111
|
+
names: z.array(z.string()).optional(),
|
|
112
|
+
form_selector: z.string().optional().describe("Optional CSS selector for the form or container to inspect."),
|
|
113
|
+
}, async (input) => {
|
|
114
|
+
const s = requireSession();
|
|
115
|
+
const res = await s.client.send("Runtime.evaluate", {
|
|
116
|
+
expression: buildFormStateExpression(input),
|
|
117
|
+
returnByValue: true,
|
|
118
|
+
});
|
|
119
|
+
const value = res.result.value;
|
|
120
|
+
if (!value.ok)
|
|
121
|
+
throw new ToolError("invalid_selector", value.error ?? "Unable to read form state");
|
|
122
|
+
return value;
|
|
123
|
+
});
|
|
124
|
+
registerJsonTool(server, "click", "Click an element matched by CSS selector. Uses synthetic input events.", { selector: z.string() }, async (input) => {
|
|
125
|
+
const s = requireSession();
|
|
126
|
+
const expr = `(() => {
|
|
127
|
+
const el = document.querySelector(${JSON.stringify(input.selector)});
|
|
128
|
+
if (!el) return { ok: false, error: "no match" };
|
|
129
|
+
el.scrollIntoView({ block: "center", inline: "center" });
|
|
130
|
+
const r = el.getBoundingClientRect();
|
|
131
|
+
return { ok: true, x: r.left + r.width / 2, y: r.top + r.height / 2 };
|
|
132
|
+
})()`;
|
|
133
|
+
const res = await s.client.send("Runtime.evaluate", {
|
|
134
|
+
expression: expr,
|
|
135
|
+
returnByValue: true,
|
|
136
|
+
});
|
|
137
|
+
const v = res.result.value;
|
|
138
|
+
if (!v.ok)
|
|
139
|
+
throw new ToolError("not_found", `click: ${v.error ?? "unknown"}`);
|
|
140
|
+
const x = v.x;
|
|
141
|
+
const y = v.y;
|
|
142
|
+
await s.client.send("Input.dispatchMouseEvent", { type: "mouseMoved", x, y });
|
|
143
|
+
await s.client.send("Input.dispatchMouseEvent", { type: "mousePressed", x, y, button: "left", clickCount: 1 });
|
|
144
|
+
await s.client.send("Input.dispatchMouseEvent", { type: "mouseReleased", x, y, button: "left", clickCount: 1 });
|
|
145
|
+
return { clicked: input.selector, x, y };
|
|
146
|
+
});
|
|
147
|
+
registerJsonTool(server, "type_text", "Focus a CSS-selected element and type text into it.", { selector: z.string(), text: z.string(), clear_first: z.boolean().optional() }, async (input) => {
|
|
148
|
+
const s = requireSession();
|
|
149
|
+
const focus = await s.client.send("Runtime.evaluate", {
|
|
150
|
+
expression: `(() => {
|
|
151
|
+
const el = document.querySelector(${JSON.stringify(input.selector)});
|
|
152
|
+
if (!el) return false;
|
|
153
|
+
el.focus();
|
|
154
|
+
${input.clear_first ? "if ('value' in el) el.value = '';" : ""}
|
|
155
|
+
return true;
|
|
156
|
+
})()`,
|
|
157
|
+
returnByValue: true,
|
|
158
|
+
});
|
|
159
|
+
if (focus.result.value !== true)
|
|
160
|
+
throw new ToolError("not_found", `type_text: ${input.selector}`);
|
|
161
|
+
await s.client.send("Input.insertText", { text: input.text });
|
|
162
|
+
return { typed: input.text.length, into: input.selector };
|
|
163
|
+
});
|
|
164
|
+
registerJsonTool(server, "press_key", "Send a key press to the focused element (e.g. Enter, Tab, Escape).", { key: z.string() }, async (input) => {
|
|
165
|
+
const s = requireSession();
|
|
166
|
+
await s.client.send("Input.dispatchKeyEvent", { type: "keyDown", key: input.key });
|
|
167
|
+
await s.client.send("Input.dispatchKeyEvent", { type: "keyUp", key: input.key });
|
|
168
|
+
return { pressed: input.key };
|
|
169
|
+
});
|
|
170
|
+
registerJsonTool(server, "screenshot", "Take a screenshot of the current page. Returns base64 PNG by default, or saves to a file.", {
|
|
171
|
+
full_page: z.boolean().optional(),
|
|
172
|
+
path: z.string().optional().describe("If set, save to this absolute path and return path instead of base64"),
|
|
173
|
+
format: z.enum(["png", "jpeg"]).optional(),
|
|
174
|
+
quality: z.number().int().min(1).max(100).optional(),
|
|
175
|
+
}, async (input) => {
|
|
176
|
+
const s = requireSession();
|
|
177
|
+
const r = await s.client.send("Page.captureScreenshot", {
|
|
178
|
+
format: input.format ?? "png",
|
|
179
|
+
...(input.quality && input.format === "jpeg" ? { quality: input.quality } : {}),
|
|
180
|
+
captureBeyondViewport: !!input.full_page,
|
|
181
|
+
});
|
|
182
|
+
if (input.path) {
|
|
183
|
+
await writeFile(input.path, Buffer.from(r.data, "base64"));
|
|
184
|
+
return { saved: input.path, bytes: r.data.length };
|
|
185
|
+
}
|
|
186
|
+
return { format: input.format ?? "png", base64: r.data };
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
function pairsToObj(pairs) {
|
|
190
|
+
const out = {};
|
|
191
|
+
for (let i = 0; i < pairs.length; i += 2) {
|
|
192
|
+
out[pairs[i] ?? ""] = pairs[i + 1] ?? "";
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
function normalizeLocator(input) {
|
|
197
|
+
const by = input.by ?? (input.selector || input.css ? "css" : undefined);
|
|
198
|
+
if (!by)
|
|
199
|
+
throw new ToolError("missing_arg", "by is required unless selector/css is supplied");
|
|
200
|
+
switch (by) {
|
|
201
|
+
case "css": {
|
|
202
|
+
const selector = input.selector ?? input.css;
|
|
203
|
+
if (!selector)
|
|
204
|
+
throw new ToolError("missing_arg", "selector or css is required for by=css");
|
|
205
|
+
return { ...input, by, selector };
|
|
206
|
+
}
|
|
207
|
+
case "role":
|
|
208
|
+
if (!input.role)
|
|
209
|
+
throw new ToolError("missing_arg", "role is required for by=role");
|
|
210
|
+
return { ...input, by };
|
|
211
|
+
case "text":
|
|
212
|
+
if (!input.text && !input.name)
|
|
213
|
+
throw new ToolError("missing_arg", "text or name is required for by=text");
|
|
214
|
+
return { ...input, by, text: input.text ?? input.name };
|
|
215
|
+
case "test_id":
|
|
216
|
+
case "testId": {
|
|
217
|
+
const testId = input.test_id ?? input.testId ?? input.name;
|
|
218
|
+
if (!testId)
|
|
219
|
+
throw new ToolError("missing_arg", `test_id, testId, or name is required for by=${by}`);
|
|
220
|
+
return { ...input, by, test_id: testId };
|
|
221
|
+
}
|
|
222
|
+
case "label": {
|
|
223
|
+
const label = input.label ?? input.name;
|
|
224
|
+
if (!label)
|
|
225
|
+
throw new ToolError("missing_arg", "label or name is required for by=label");
|
|
226
|
+
return { ...input, by, label };
|
|
227
|
+
}
|
|
228
|
+
case "placeholder": {
|
|
229
|
+
const placeholder = input.placeholder ?? input.name;
|
|
230
|
+
if (!placeholder)
|
|
231
|
+
throw new ToolError("missing_arg", "placeholder or name is required for by=placeholder");
|
|
232
|
+
return { ...input, by, placeholder };
|
|
233
|
+
}
|
|
234
|
+
case "name":
|
|
235
|
+
if (!input.name)
|
|
236
|
+
throw new ToolError("missing_arg", "name is required for by=name");
|
|
237
|
+
return { ...input, by };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function evaluateLocator(locator, options) {
|
|
241
|
+
const s = requireSession();
|
|
242
|
+
const res = await s.client.send("Runtime.evaluate", {
|
|
243
|
+
expression: buildLocateExpression(locator, options),
|
|
244
|
+
returnByValue: true,
|
|
245
|
+
});
|
|
246
|
+
return res.result.value;
|
|
247
|
+
}
|
|
248
|
+
function matchesWaitState(result, state) {
|
|
249
|
+
switch (state) {
|
|
250
|
+
case "visible":
|
|
251
|
+
return result.visible_count > 0;
|
|
252
|
+
case "attached":
|
|
253
|
+
return result.count > 0;
|
|
254
|
+
case "hidden":
|
|
255
|
+
return result.count === 0 || result.visible_count === 0;
|
|
256
|
+
case "detached":
|
|
257
|
+
return result.count === 0;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function delay(ms) {
|
|
261
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
262
|
+
}
|
|
263
|
+
function describeLocator(locator) {
|
|
264
|
+
return JSON.stringify(locator);
|
|
265
|
+
}
|
|
266
|
+
function buildLocateExpression(locator, options) {
|
|
267
|
+
return `(() => {
|
|
268
|
+
const spec = ${JSON.stringify(locator)};
|
|
269
|
+
const options = ${JSON.stringify(options)};
|
|
270
|
+
${locatorRuntimeScript()}
|
|
271
|
+
return locate(spec, options);
|
|
272
|
+
})()`;
|
|
273
|
+
}
|
|
274
|
+
function buildFormStateExpression(input) {
|
|
275
|
+
return `(() => {
|
|
276
|
+
const input = ${JSON.stringify(input)};
|
|
277
|
+
${formStateRuntimeScript()}
|
|
278
|
+
return readFormState(input);
|
|
279
|
+
})()`;
|
|
280
|
+
}
|
|
281
|
+
function locatorRuntimeScript() {
|
|
282
|
+
return String.raw `
|
|
283
|
+
const compact = (value) => (value || "").replace(/\s+/g, " ").trim();
|
|
284
|
+
const lower = (value) => compact(value).toLowerCase();
|
|
285
|
+
const cssEscape = (value) => globalThis.CSS?.escape ? globalThis.CSS.escape(value) : String(value).replace(/["\\]/g, "\\$&");
|
|
286
|
+
const matchesText = (actual, expected, exact) => {
|
|
287
|
+
if (expected == null || expected === "") return true;
|
|
288
|
+
const a = lower(actual);
|
|
289
|
+
const e = lower(expected);
|
|
290
|
+
return exact ? a === e : a.includes(e);
|
|
291
|
+
};
|
|
292
|
+
const textOf = (el) => compact(el.innerText || el.textContent || "");
|
|
293
|
+
const isVisible = (el) => {
|
|
294
|
+
if (!el.isConnected) return false;
|
|
295
|
+
const style = getComputedStyle(el);
|
|
296
|
+
if (style.visibility === "hidden" || style.display === "none" || Number(style.opacity) === 0) return false;
|
|
297
|
+
const rect = el.getBoundingClientRect();
|
|
298
|
+
return rect.width > 0 && rect.height > 0;
|
|
299
|
+
};
|
|
300
|
+
const labelText = (el) => {
|
|
301
|
+
if ("labels" in el && el.labels && el.labels.length > 0) {
|
|
302
|
+
return compact(Array.from(el.labels).map((label) => label.innerText || label.textContent || "").join(" "));
|
|
303
|
+
}
|
|
304
|
+
return "";
|
|
305
|
+
};
|
|
306
|
+
const accessibleName = (el) => {
|
|
307
|
+
const ariaLabel = el.getAttribute("aria-label");
|
|
308
|
+
if (ariaLabel) return compact(ariaLabel);
|
|
309
|
+
const labelledBy = el.getAttribute("aria-labelledby");
|
|
310
|
+
if (labelledBy) {
|
|
311
|
+
const text = labelledBy
|
|
312
|
+
.split(/\s+/)
|
|
313
|
+
.map((id) => document.getElementById(id)?.innerText || document.getElementById(id)?.textContent || "")
|
|
314
|
+
.join(" ");
|
|
315
|
+
if (compact(text)) return compact(text);
|
|
316
|
+
}
|
|
317
|
+
const label = labelText(el);
|
|
318
|
+
if (label) return label;
|
|
319
|
+
if (el instanceof HTMLInputElement && ["button", "submit", "reset"].includes(el.type)) return compact(el.value);
|
|
320
|
+
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) return compact(el.placeholder || el.value || "");
|
|
321
|
+
if (el instanceof HTMLImageElement) return compact(el.alt || "");
|
|
322
|
+
return textOf(el);
|
|
323
|
+
};
|
|
324
|
+
const implicitRole = (el) => {
|
|
325
|
+
const explicit = el.getAttribute("role");
|
|
326
|
+
if (explicit) return lower(explicit.split(/\s+/)[0]);
|
|
327
|
+
const tag = el.tagName.toLowerCase();
|
|
328
|
+
if (tag === "button") return "button";
|
|
329
|
+
if (tag === "a" && el.hasAttribute("href")) return "link";
|
|
330
|
+
if (/^h[1-6]$/.test(tag)) return "heading";
|
|
331
|
+
if (tag === "textarea") return "textbox";
|
|
332
|
+
if (tag === "select") return el.multiple ? "listbox" : "combobox";
|
|
333
|
+
if (tag === "img") return "img";
|
|
334
|
+
if (el.isContentEditable) return "textbox";
|
|
335
|
+
if (tag === "input") {
|
|
336
|
+
const type = lower(el.getAttribute("type") || "text");
|
|
337
|
+
if (["button", "submit", "reset"].includes(type)) return "button";
|
|
338
|
+
if (type === "checkbox") return "checkbox";
|
|
339
|
+
if (type === "radio") return "radio";
|
|
340
|
+
if (type === "range") return "slider";
|
|
341
|
+
if (["email", "password", "search", "tel", "text", "url", ""].includes(type)) return "textbox";
|
|
342
|
+
if (type === "number") return "spinbutton";
|
|
343
|
+
}
|
|
344
|
+
return "";
|
|
345
|
+
};
|
|
346
|
+
const cssPath = (el) => {
|
|
347
|
+
if (el.id) return "#" + cssEscape(el.id);
|
|
348
|
+
const testId = el.getAttribute("data-testid") || el.getAttribute("data-test-id") || el.getAttribute("data-test");
|
|
349
|
+
if (testId) return "[" + (el.hasAttribute("data-testid") ? "data-testid" : el.hasAttribute("data-test-id") ? "data-test-id" : "data-test") + "=\"" + cssEscape(testId) + "\"]";
|
|
350
|
+
const parts = [];
|
|
351
|
+
let node = el;
|
|
352
|
+
while (node && node.nodeType === Node.ELEMENT_NODE && parts.length < 5) {
|
|
353
|
+
const tag = node.tagName.toLowerCase();
|
|
354
|
+
const name = node.getAttribute("name");
|
|
355
|
+
if (name) {
|
|
356
|
+
parts.unshift(tag + "[name=\"" + cssEscape(name) + "\"]");
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
const siblings = Array.from(node.parentElement?.children || []).filter((child) => child.tagName === node.tagName);
|
|
360
|
+
const index = siblings.indexOf(node) + 1;
|
|
361
|
+
parts.unshift(siblings.length > 1 ? tag + ":nth-of-type(" + index + ")" : tag);
|
|
362
|
+
node = node.parentElement;
|
|
363
|
+
}
|
|
364
|
+
return parts.join(" > ");
|
|
365
|
+
};
|
|
366
|
+
const elementInfo = (el) => {
|
|
367
|
+
const rect = el.getBoundingClientRect();
|
|
368
|
+
const info = {
|
|
369
|
+
selector: cssPath(el),
|
|
370
|
+
tag: el.tagName.toLowerCase(),
|
|
371
|
+
role: implicitRole(el) || undefined,
|
|
372
|
+
name: accessibleName(el) || undefined,
|
|
373
|
+
text: textOf(el).slice(0, 300),
|
|
374
|
+
visible: isVisible(el),
|
|
375
|
+
disabled: "disabled" in el ? !!el.disabled : undefined,
|
|
376
|
+
value: "value" in el ? el.value : undefined,
|
|
377
|
+
checked: "checked" in el ? !!el.checked : undefined,
|
|
378
|
+
bbox: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
|
|
379
|
+
};
|
|
380
|
+
return Object.fromEntries(Object.entries(info).filter(([, value]) => value !== undefined && value !== ""));
|
|
381
|
+
};
|
|
382
|
+
const queryAll = (selector) => {
|
|
383
|
+
try {
|
|
384
|
+
return { ok: true, elements: Array.from(document.querySelectorAll(selector)) };
|
|
385
|
+
} catch (error) {
|
|
386
|
+
return { ok: false, error: "Invalid CSS selector " + selector + ": " + error.message };
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
const leafTextMatches = (el, expected, exact) => {
|
|
390
|
+
if (!matchesText(textOf(el), expected, exact)) return false;
|
|
391
|
+
return !Array.from(el.children).some((child) => matchesText(textOf(child), expected, exact));
|
|
392
|
+
};
|
|
393
|
+
const findElements = (spec) => {
|
|
394
|
+
const by = spec.by || (spec.selector || spec.css ? "css" : "");
|
|
395
|
+
const exact = !!spec.exact;
|
|
396
|
+
if (by === "css") return queryAll(spec.selector || spec.css);
|
|
397
|
+
if (by === "text") {
|
|
398
|
+
return { ok: true, elements: Array.from(document.querySelectorAll("body *")).filter((el) => leafTextMatches(el, spec.text || spec.name, exact)) };
|
|
399
|
+
}
|
|
400
|
+
if (by === "role") {
|
|
401
|
+
return { ok: true, elements: Array.from(document.querySelectorAll("body *")).filter((el) => implicitRole(el) === lower(spec.role) && matchesText(accessibleName(el), spec.name, exact)) };
|
|
402
|
+
}
|
|
403
|
+
if (by === "test_id" || by === "testId") {
|
|
404
|
+
const wanted = spec.test_id || spec.testId || spec.name;
|
|
405
|
+
const candidates = Array.from(document.querySelectorAll("[data-testid], [data-test-id], [data-test]"));
|
|
406
|
+
return { ok: true, elements: candidates.filter((el) => [el.getAttribute("data-testid"), el.getAttribute("data-test-id"), el.getAttribute("data-test")].some((value) => matchesText(value, wanted, true))) };
|
|
407
|
+
}
|
|
408
|
+
if (by === "label") {
|
|
409
|
+
const wanted = spec.label || spec.name;
|
|
410
|
+
const controls = [];
|
|
411
|
+
for (const label of Array.from(document.querySelectorAll("label"))) {
|
|
412
|
+
if (!matchesText(textOf(label), wanted, exact)) continue;
|
|
413
|
+
const control = label.control || label.querySelector("input, textarea, select, button");
|
|
414
|
+
if (control) controls.push(control);
|
|
415
|
+
}
|
|
416
|
+
return { ok: true, elements: controls };
|
|
417
|
+
}
|
|
418
|
+
if (by === "placeholder") {
|
|
419
|
+
const wanted = spec.placeholder || spec.name;
|
|
420
|
+
return { ok: true, elements: Array.from(document.querySelectorAll("[placeholder]")).filter((el) => matchesText(el.getAttribute("placeholder"), wanted, exact)) };
|
|
421
|
+
}
|
|
422
|
+
if (by === "name") {
|
|
423
|
+
return { ok: true, elements: Array.from(document.querySelectorAll("[name]")).filter((el) => matchesText(el.getAttribute("name"), spec.name, true)) };
|
|
424
|
+
}
|
|
425
|
+
return { ok: false, error: "Unsupported locator strategy: " + by };
|
|
426
|
+
};
|
|
427
|
+
const locate = (spec, options) => {
|
|
428
|
+
const found = findElements(spec);
|
|
429
|
+
if (!found.ok) return { ok: false, error: found.error, found: false, count: 0, visible_count: 0, matches: [] };
|
|
430
|
+
const all = found.elements;
|
|
431
|
+
const visible = all.filter(isVisible);
|
|
432
|
+
const returned = (options.includeHidden ? all : visible).slice(0, options.limit || 20).map(elementInfo);
|
|
433
|
+
return {
|
|
434
|
+
ok: true,
|
|
435
|
+
found: returned.length > 0,
|
|
436
|
+
count: all.length,
|
|
437
|
+
visible_count: visible.length,
|
|
438
|
+
matches: returned,
|
|
439
|
+
};
|
|
440
|
+
};
|
|
441
|
+
`;
|
|
442
|
+
}
|
|
443
|
+
function formStateRuntimeScript() {
|
|
444
|
+
return String.raw `
|
|
445
|
+
const compact = (value) => (value || "").replace(/\s+/g, " ").trim();
|
|
446
|
+
const isVisible = (el) => {
|
|
447
|
+
if (!el.isConnected) return false;
|
|
448
|
+
const style = getComputedStyle(el);
|
|
449
|
+
if (style.visibility === "hidden" || style.display === "none" || Number(style.opacity) === 0) return false;
|
|
450
|
+
const rect = el.getBoundingClientRect();
|
|
451
|
+
return rect.width > 0 && rect.height > 0;
|
|
452
|
+
};
|
|
453
|
+
const controlValue = (el) => {
|
|
454
|
+
if (el instanceof HTMLSelectElement) {
|
|
455
|
+
if (el.multiple) return Array.from(el.selectedOptions).map((option) => option.value);
|
|
456
|
+
return el.value;
|
|
457
|
+
}
|
|
458
|
+
if (el instanceof HTMLInputElement && el.type === "checkbox") return el.checked;
|
|
459
|
+
if (el instanceof HTMLInputElement && el.type === "radio") return el.checked ? el.value : null;
|
|
460
|
+
return "value" in el ? el.value : null;
|
|
461
|
+
};
|
|
462
|
+
const describeControl = (el) => ({
|
|
463
|
+
tag: el.tagName.toLowerCase(),
|
|
464
|
+
type: el.getAttribute("type") || undefined,
|
|
465
|
+
value: controlValue(el),
|
|
466
|
+
raw_value: "value" in el ? el.value : undefined,
|
|
467
|
+
checked: "checked" in el ? !!el.checked : undefined,
|
|
468
|
+
disabled: "disabled" in el ? !!el.disabled : undefined,
|
|
469
|
+
visible: isVisible(el),
|
|
470
|
+
text: compact(el.innerText || el.textContent || "").slice(0, 200) || undefined,
|
|
471
|
+
});
|
|
472
|
+
const summarizeGroup = (controls) => {
|
|
473
|
+
const radioControls = controls.filter((el) => el instanceof HTMLInputElement && el.type === "radio");
|
|
474
|
+
if (radioControls.length > 0) {
|
|
475
|
+
const checked = radioControls.find((el) => el.checked);
|
|
476
|
+
return {
|
|
477
|
+
kind: "radio_group",
|
|
478
|
+
value: checked ? checked.value : null,
|
|
479
|
+
controls: radioControls.map(describeControl),
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
const checkboxControls = controls.filter((el) => el instanceof HTMLInputElement && el.type === "checkbox");
|
|
483
|
+
if (checkboxControls.length > 1) {
|
|
484
|
+
return {
|
|
485
|
+
kind: "checkbox_group",
|
|
486
|
+
value: checkboxControls.filter((el) => el.checked).map((el) => el.value),
|
|
487
|
+
controls: checkboxControls.map(describeControl),
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
return {
|
|
491
|
+
kind: controls.length === 1 ? "field" : "field_group",
|
|
492
|
+
value: controls.length === 1 ? controlValue(controls[0]) : controls.map(controlValue),
|
|
493
|
+
controls: controls.map(describeControl),
|
|
494
|
+
};
|
|
495
|
+
};
|
|
496
|
+
const readFormState = (input) => {
|
|
497
|
+
let root = document;
|
|
498
|
+
if (input.form_selector) {
|
|
499
|
+
try {
|
|
500
|
+
root = document.querySelector(input.form_selector);
|
|
501
|
+
} catch (error) {
|
|
502
|
+
return { ok: false, error: "Invalid form_selector " + input.form_selector + ": " + error.message };
|
|
503
|
+
}
|
|
504
|
+
if (!root) return { ok: false, error: "No element matches form_selector " + input.form_selector };
|
|
505
|
+
}
|
|
506
|
+
const controls = Array.from(root.querySelectorAll("input[name], textarea[name], select[name], button[name]"));
|
|
507
|
+
const wantedNames = input.names || Array.from(new Set(controls.map((el) => el.getAttribute("name")).filter(Boolean)));
|
|
508
|
+
const fields = {};
|
|
509
|
+
const missing = [];
|
|
510
|
+
for (const name of wantedNames) {
|
|
511
|
+
const matches = controls.filter((el) => el.getAttribute("name") === name);
|
|
512
|
+
if (matches.length === 0) {
|
|
513
|
+
missing.push(name);
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
fields[name] = summarizeGroup(matches);
|
|
517
|
+
}
|
|
518
|
+
return {
|
|
519
|
+
ok: true,
|
|
520
|
+
form_selector: input.form_selector || null,
|
|
521
|
+
fields,
|
|
522
|
+
missing,
|
|
523
|
+
};
|
|
524
|
+
};
|
|
525
|
+
`;
|
|
526
|
+
}
|
|
527
|
+
//# sourceMappingURL=dom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../../src/tools/dom.ts"],"names":[],"mappings":"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"}
|