@one2x/playwright 1.57.0-alpha.11 → 1.57.0-alpha.12

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.
@@ -23,6 +23,7 @@ __export(mouse_exports, {
23
23
  module.exports = __toCommonJS(mouse_exports);
24
24
  var import_bundle = require("../../sdk/bundle");
25
25
  var import_tool = require("./tool");
26
+ var import_snapshot = require("./snapshot");
26
27
  const elementSchema = import_bundle.z.object({
27
28
  element: import_bundle.z.string().describe("Human-readable element description used to obtain permission to interact with the element")
28
29
  });
@@ -102,8 +103,38 @@ const mouseDrag = (0, import_tool.defineTabTool)({
102
103
  response.setIncludeAutoScreenshot();
103
104
  }
104
105
  });
106
+ const mouseDragToXY = (0, import_tool.defineTabTool)({
107
+ capability: "vision",
108
+ schema: {
109
+ name: "browser_drag_to_xy",
110
+ title: "Drag element to coordinates",
111
+ description: "Drag element to specific coordinates",
112
+ inputSchema: import_snapshot.elementSchema.extend({
113
+ endX: import_bundle.z.number().describe("Target X coordinate"),
114
+ endY: import_bundle.z.number().describe("Target Y coordinate")
115
+ }),
116
+ type: "input"
117
+ },
118
+ handle: async (tab, params, response) => {
119
+ response.setIncludeSnapshot();
120
+ const { locator, resolved } = await tab.refLocator(params);
121
+ response.addCode(`// Drag ${params.element} to coordinates (${params.endX}, ${params.endY})`);
122
+ response.addCode(`await page.${resolved}.hover();`);
123
+ response.addCode(`await page.mouse.down();`);
124
+ response.addCode(`await page.mouse.move(${params.endX}, ${params.endY});`);
125
+ response.addCode(`await page.mouse.up();`);
126
+ await tab.waitForCompletion(async () => {
127
+ await locator.hover();
128
+ await tab.page.mouse.down();
129
+ await tab.page.mouse.move(params.endX, params.endY);
130
+ await tab.page.mouse.up();
131
+ });
132
+ response.setIncludeAutoScreenshot();
133
+ }
134
+ });
105
135
  var mouse_default = [
106
136
  mouseMove,
107
137
  mouseClick,
108
- mouseDrag
138
+ mouseDrag,
139
+ mouseDragToXY
109
140
  ];
@@ -228,8 +228,111 @@ const elementInspect = (0, import_tool.defineTool)({
228
228
  try {
229
229
  elementDetails = await locator.evaluate((element) => {
230
230
  const computedStyle = window.getComputedStyle(element);
231
+ const path = [];
232
+ let current = element;
233
+ while (current && current !== document.documentElement) {
234
+ const ariaRef = current._ariaRef;
235
+ const tagName = current.tagName?.toLowerCase() || "unknown";
236
+ let nodeInfo = tagName;
237
+ if (ariaRef?.ref) {
238
+ nodeInfo += ` [${ariaRef.ref}]`;
239
+ if (ariaRef.role) {
240
+ nodeInfo += ` [${ariaRef.role}]`;
241
+ }
242
+ }
243
+ path.unshift(nodeInfo);
244
+ current = current.parentElement;
245
+ }
246
+ function serializeAttributes(el) {
247
+ const essentialAttrs = ["id", "class", "type", "name", "role", "aria-label"];
248
+ const attrs = [];
249
+ for (const attrName of essentialAttrs) {
250
+ const value = el.getAttribute(attrName);
251
+ if (value) {
252
+ attrs.push(` ${attrName}="${value}"`);
253
+ }
254
+ }
255
+ return attrs.join("");
256
+ }
257
+ function buildTree(el) {
258
+ return {
259
+ element: el,
260
+ expanded: false,
261
+ childNodes: Array.from(el.children).map((child) => buildTree(child))
262
+ };
263
+ }
264
+ function renderTree(node) {
265
+ const tag = node.element.tagName.toLowerCase();
266
+ const attrs = serializeAttributes(node.element);
267
+ const openTag = `<${tag}${attrs}>`;
268
+ const closeTag = `</${tag}>`;
269
+ const selfClosing = ["img", "input", "br", "hr", "meta", "link"];
270
+ if (selfClosing.includes(tag)) {
271
+ return `<${tag}${attrs} />`;
272
+ }
273
+ if (node.childNodes.length === 0) {
274
+ const text = node.element.textContent?.trim() || "";
275
+ if (text && text.length <= 50) {
276
+ return openTag + text + closeTag;
277
+ } else if (text) {
278
+ return openTag + text.substring(0, 47) + "..." + closeTag;
279
+ }
280
+ return openTag + closeTag;
281
+ }
282
+ if (!node.expanded) {
283
+ const count = node.element.children.length;
284
+ return `${openTag}<!-- ${count} child element${count !== 1 ? "s" : ""} removed -->${closeTag}`;
285
+ }
286
+ const childrenHtml = node.childNodes.map((child) => renderTree(child)).join("");
287
+ return openTag + childrenHtml + closeTag;
288
+ }
289
+ function getExpandableNodes(node) {
290
+ const queue = [node];
291
+ const expandable = [];
292
+ while (queue.length > 0) {
293
+ const current2 = queue.shift();
294
+ if (current2.childNodes.length > 0 && !current2.expanded) {
295
+ expandable.push(current2);
296
+ }
297
+ if (current2.expanded) {
298
+ queue.push(...current2.childNodes);
299
+ }
300
+ }
301
+ return expandable;
302
+ }
303
+ function truncateIterativeDeepening(el, maxBudget) {
304
+ if (el.outerHTML.length <= maxBudget) {
305
+ return el.outerHTML;
306
+ }
307
+ const root = buildTree(el);
308
+ let currentHtml = renderTree(root);
309
+ while (currentHtml.length < maxBudget) {
310
+ const expandable = getExpandableNodes(root);
311
+ if (expandable.length === 0) {
312
+ break;
313
+ }
314
+ let expanded = false;
315
+ for (const node of expandable) {
316
+ node.expanded = true;
317
+ const newHtml = renderTree(root);
318
+ if (newHtml.length <= maxBudget) {
319
+ currentHtml = newHtml;
320
+ expanded = true;
321
+ break;
322
+ } else {
323
+ node.expanded = false;
324
+ }
325
+ }
326
+ if (!expanded) {
327
+ break;
328
+ }
329
+ }
330
+ return currentHtml;
331
+ }
231
332
  return {
232
333
  outerHTML: element.outerHTML,
334
+ truncatedHTML: truncateIterativeDeepening(element, 300),
335
+ pathToRoot: path.join(" > "),
233
336
  tagName: element.tagName.toLowerCase(),
234
337
  computedStyles: {
235
338
  display: computedStyle.display,
@@ -277,12 +380,13 @@ Try capturing a new snapshot with browser_snapshot and using the updated element
277
380
  }
278
381
  let result = `
279
382
  **Element:** ${params.element}
383
+ **Path to root:** ${elementDetails.pathToRoot}
280
384
  **Suggested Playwright Selector:**
281
385
  ${suggestedSelectors}
282
386
 
283
- **HTML:**
387
+ **HTML (truncated to 300 chars with intelligent structure preservation):**
284
388
  \`\`\`html
285
- ${elementDetails.outerHTML}
389
+ ${elementDetails.truncatedHTML}
286
390
  \`\`\`
287
391
 
288
392
  **Key Computed Styles:**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@one2x/playwright",
3
- "version": "1.57.0-alpha.11",
3
+ "version": "1.57.0-alpha.12",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -65,7 +65,7 @@
65
65
  "license": "Apache-2.0",
66
66
  "dependencies": {
67
67
  "content-type": "^1.0.5",
68
- "playwright-core": "npm:@one2x/playwright-core@1.57.0-alpha.11",
68
+ "playwright-core": "npm:@one2x/playwright-core@1.57.0-alpha.12",
69
69
  "raw-body": "^2.5.2"
70
70
  },
71
71
  "optionalDependencies": {