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

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.
@@ -59,7 +59,8 @@ class BrowserServerBackend {
59
59
  await response.finish();
60
60
  this._sessionLog?.logResponse(response);
61
61
  } catch (error) {
62
- response.addError(String(error));
62
+ console.error("error", error);
63
+ response.addError(String(error.stack));
63
64
  } finally {
64
65
  context.setRunningTool(void 0);
65
66
  }
@@ -21,7 +21,7 @@ __export(actionRetry_exports, {
21
21
  retryWithAllowIntercept: () => retryWithAllowIntercept
22
22
  });
23
23
  module.exports = __toCommonJS(actionRetry_exports);
24
- async function retryWithAllowIntercept(action, options, mode = "never") {
24
+ async function retryWithAllowIntercept(action, options, mode = "auto") {
25
25
  if (mode === "always") {
26
26
  const optionsWithAllowIntercept = { ...options, allowIntercept: true };
27
27
  await action(optionsWithAllowIntercept);
@@ -40,9 +40,16 @@ async function retryWithAllowIntercept(action, options, mode = "never") {
40
40
  }
41
41
  if (mode === "never") {
42
42
  const enhancedError = new Error(
43
- `InterceptionError: Element is covered by an intercepting element: ${interceptorInfo}.
44
- \u{1F4A1} To allow the action on the intercepting element, retry with \`allowIntercept: "always"\`
45
- \u{1F4A1} To automatically retry when intercepted, use \`allowIntercept: "auto"\``
43
+ `RETRYABLE ERROR: Element is covered by an overlay/modal.
44
+
45
+ SOLUTION: Retry this tool call with allowIntercept option added:
46
+ Add parameter: allowIntercept: "always"
47
+
48
+ This will click through the overlay to reach the target element.
49
+
50
+ Alternative: Use allowIntercept: "auto" to automatically retry on interception.
51
+
52
+ Technical details - Intercepting element: ${interceptorInfo}`
46
53
  );
47
54
  enhancedError.stack = error.stack;
48
55
  throw enhancedError;
@@ -48,16 +48,12 @@ const fillForm = (0, import_tool.defineTabTool)({
48
48
  type: import_bundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the field"),
49
49
  ref: import_bundle.z.string().describe("Exact target field reference from the page snapshot"),
50
50
  value: import_bundle.z.string().describe("Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option.")
51
- })).describe("Fields to fill in"),
52
- allowIntercept: import_bundle.z.enum(["never", "auto", "always"]).default("never").describe(
53
- 'How to handle element interception for checkbox/radio fields: "never" (default) - fail if element is intercepted; "auto" - automatically retry with allowIntercept if intercepted; "always" - use allowIntercept from the start'
54
- )
51
+ })).describe("Fields to fill in")
55
52
  }),
56
53
  type: "input"
57
54
  },
58
55
  handle: async (tab, params, response) => {
59
56
  response.setIncludeSnapshot();
60
- const mode = params.allowIntercept;
61
57
  for (const field of params.fields) {
62
58
  const { locator, resolved } = await tab.refLocator({ element: field.name, ref: field.ref });
63
59
  const locatorSource = `await page.${resolved}`;
@@ -68,12 +64,11 @@ const fillForm = (0, import_tool.defineTabTool)({
68
64
  } else if (field.type === "checkbox" || field.type === "radio") {
69
65
  const result = await (0, import_actionRetry.retryWithAllowIntercept)(
70
66
  async (opts) => await locator.setChecked(field.value === "true", opts),
71
- {},
72
- mode
67
+ {}
73
68
  );
74
69
  if (result.mode === "auto" && result.interceptorInfo)
75
70
  (0, import_utils.addInterceptorWarning)(response, resolved, ".setChecked(value, { allowIntercept: true })", result.interceptorInfo);
76
- const needsAllowIntercept = result.mode === "auto" || result.mode === "always";
71
+ const needsAllowIntercept = result.mode === "auto" && result.interceptorInfo || result.mode === "always";
77
72
  const optionsAttr = needsAllowIntercept ? ", { allowIntercept: true }" : "";
78
73
  response.addCode(`${locatorSource}.setChecked(${field.value}${optionsAttr});`);
79
74
  } else if (field.type === "combobox") {
@@ -58,10 +58,7 @@ const elementSchema = import_bundle.z.object({
58
58
  const clickSchema = elementSchema.extend({
59
59
  doubleClick: import_bundle.z.boolean().optional().describe("Whether to perform a double click instead of a single click"),
60
60
  button: import_bundle.z.enum(["left", "right", "middle"]).optional().describe("Button to click, defaults to left"),
61
- modifiers: import_bundle.z.array(import_bundle.z.enum(["Alt", "Control", "ControlOrMeta", "Meta", "Shift"])).optional().describe("Modifier keys to press"),
62
- allowIntercept: import_bundle.z.enum(["never", "auto", "always"]).default("never").describe(
63
- 'How to handle element interception: "never" (default) - fail if element is intercepted; "auto" - automatically retry with allowIntercept if intercepted; "always" - use allowIntercept from the start'
64
- )
61
+ modifiers: import_bundle.z.array(import_bundle.z.enum(["Alt", "Control", "ControlOrMeta", "Meta", "Shift"])).optional().describe("Modifier keys to press")
65
62
  });
66
63
  const click = (0, import_tool.defineTabTool)({
67
64
  capability: "core",
@@ -75,7 +72,6 @@ const click = (0, import_tool.defineTabTool)({
75
72
  handle: async (tab, params, response) => {
76
73
  response.setIncludeSnapshot();
77
74
  const { locator, resolved } = await tab.refLocator(params);
78
- const mode = params.allowIntercept;
79
75
  const options = {
80
76
  button: params.button,
81
77
  modifiers: params.modifiers
@@ -89,15 +85,17 @@ const click = (0, import_tool.defineTabTool)({
89
85
  else
90
86
  await locator.click(opts);
91
87
  },
92
- options,
93
- mode
88
+ options
94
89
  );
95
90
  });
91
+ if (!result) {
92
+ return;
93
+ }
96
94
  if (result.mode === "auto" && result.interceptorInfo) {
97
95
  const actionName = params.doubleClick ? ".dblclick({ allowIntercept: true })" : ".click({ allowIntercept: true })";
98
96
  (0, import_utils.addInterceptorWarning)(response, resolved, actionName, result.interceptorInfo);
99
97
  }
100
- const needsAllowIntercept = result.mode === "auto" || result.mode === "always";
98
+ const needsAllowIntercept = result.mode === "auto" && result.interceptorInfo || result.mode === "always";
101
99
  const finalOptions = needsAllowIntercept ? { ...options, allowIntercept: true } : options;
102
100
  const formatted = javascript.formatObject(finalOptions, " ", "oneline");
103
101
  const optionsAttr = formatted !== "{}" ? formatted : "";
@@ -118,10 +116,7 @@ const drag = (0, import_tool.defineTabTool)({
118
116
  startElement: import_bundle.z.string().describe("Human-readable source element description used to obtain the permission to interact with the element"),
119
117
  startRef: import_bundle.z.string().describe("Exact source element reference from the page snapshot"),
120
118
  endElement: import_bundle.z.string().describe("Human-readable target element description used to obtain the permission to interact with the element"),
121
- endRef: import_bundle.z.string().describe("Exact target element reference from the page snapshot"),
122
- allowIntercept: import_bundle.z.enum(["never", "auto", "always"]).default("never").describe(
123
- 'How to handle element interception: "never" (default) - fail if element is intercepted; "auto" - automatically retry with allowIntercept if intercepted; "always" - use allowIntercept from the start'
124
- )
119
+ endRef: import_bundle.z.string().describe("Exact target element reference from the page snapshot")
125
120
  }),
126
121
  type: "input"
127
122
  },
@@ -131,18 +126,19 @@ const drag = (0, import_tool.defineTabTool)({
131
126
  { ref: params.startRef, element: params.startElement },
132
127
  { ref: params.endRef, element: params.endElement }
133
128
  ]);
134
- const mode = params.allowIntercept;
135
129
  let result;
136
130
  await tab.waitForCompletion(async () => {
137
131
  result = await (0, import_actionRetry.retryWithAllowIntercept)(
138
132
  async (opts) => await start.locator.dragTo(end.locator, opts),
139
- {},
140
- mode
133
+ {}
141
134
  );
142
135
  });
136
+ if (!result) {
137
+ return;
138
+ }
143
139
  if (result.mode === "auto" && result.interceptorInfo)
144
140
  (0, import_utils.addInterceptorWarning)(response, start.resolved, ".dragTo(target, { allowIntercept: true })", result.interceptorInfo);
145
- const needsAllowIntercept = result.mode === "auto" || result.mode === "always";
141
+ const needsAllowIntercept = result.mode === "auto" && result.interceptorInfo || result.mode === "always";
146
142
  const optionsAttr = needsAllowIntercept ? ", { allowIntercept: true }" : "";
147
143
  response.addCode(`await page.${start.resolved}.dragTo(page.${end.resolved}${optionsAttr});`);
148
144
  response.setIncludeAutoScreenshot();
@@ -154,28 +150,25 @@ const hover = (0, import_tool.defineTabTool)({
154
150
  name: "browser_hover",
155
151
  title: "Hover mouse",
156
152
  description: "Hover over element on page",
157
- inputSchema: elementSchema.extend({
158
- allowIntercept: import_bundle.z.enum(["never", "auto", "always"]).default("never").describe(
159
- 'How to handle element interception: "never" (default) - fail if element is intercepted; "auto" - automatically retry with allowIntercept if intercepted; "always" - use allowIntercept from the start'
160
- )
161
- }),
153
+ inputSchema: elementSchema,
162
154
  type: "input"
163
155
  },
164
156
  handle: async (tab, params, response) => {
165
157
  response.setIncludeSnapshot();
166
158
  const { locator, resolved } = await tab.refLocator(params);
167
- const mode = params.allowIntercept;
168
159
  let result;
169
160
  await tab.waitForCompletion(async () => {
170
161
  result = await (0, import_actionRetry.retryWithAllowIntercept)(
171
162
  async (opts) => await locator.hover(opts),
172
- {},
173
- mode
163
+ {}
174
164
  );
175
165
  });
166
+ if (!result) {
167
+ return;
168
+ }
176
169
  if (result.mode === "auto" && result.interceptorInfo)
177
170
  (0, import_utils.addInterceptorWarning)(response, resolved, ".hover({ allowIntercept: true })", result.interceptorInfo);
178
- const needsAllowIntercept = result.mode === "auto" || result.mode === "always";
171
+ const needsAllowIntercept = result.mode === "auto" && result.interceptorInfo || result.mode === "always";
179
172
  const optionsAttr = needsAllowIntercept ? "{ allowIntercept: true }" : "";
180
173
  response.addCode(`await page.${resolved}.hover(${optionsAttr});`);
181
174
  response.setIncludeAutoScreenshot();
@@ -85,10 +85,10 @@ async function generateLocators(locator) {
85
85
  return selectors.map((s) => (0, import_utils.asLocator)("javascript", s));
86
86
  }
87
87
  function addInterceptorWarning(response, targetSelector, actionName, interceptorInfo) {
88
- response.addResult(`\u26A0\uFE0F Warning: An intercepting element appears above target element \`page.${targetSelector}\``);
88
+ response.addResult(` Warning: An intercepting element was appearing above target element \`page.${targetSelector}\``);
89
+ response.addResult(` \`${actionName}\` WAS fired to the intercepting element, not the target element`);
89
90
  if (interceptorInfo)
90
- response.addResult(` Intercepting element: ${interceptorInfo}`);
91
- response.addResult(`\u2713 Retried action \`${actionName}\` and succeeded. The \`allowIntercept\` option is CRUCIAL`);
91
+ response.addResult(` Intercepting element: ${interceptorInfo}`);
92
92
  }
93
93
  // Annotate the CommonJS export names for ESM import in node:
94
94
  0 && (module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@one2x/playwright",
3
- "version": "1.57.0-alpha.10",
3
+ "version": "1.57.0-alpha.11",
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.10",
68
+ "playwright-core": "npm:@one2x/playwright-core@1.57.0-alpha.11",
69
69
  "raw-body": "^2.5.2"
70
70
  },
71
71
  "optionalDependencies": {