@rpascene/web 0.30.8

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.
Files changed (135) hide show
  1. package/README.md +9 -0
  2. package/bin/midscene-playground +3 -0
  3. package/dist/es/bin.mjs +26 -0
  4. package/dist/es/bin.mjs.map +1 -0
  5. package/dist/es/bridge-mode/agent-cli-side.mjs +117 -0
  6. package/dist/es/bridge-mode/agent-cli-side.mjs.map +1 -0
  7. package/dist/es/bridge-mode/browser.mjs +2 -0
  8. package/dist/es/bridge-mode/common.mjs +37 -0
  9. package/dist/es/bridge-mode/common.mjs.map +1 -0
  10. package/dist/es/bridge-mode/index.mjs +4 -0
  11. package/dist/es/bridge-mode/io-client.mjs +101 -0
  12. package/dist/es/bridge-mode/io-client.mjs.map +1 -0
  13. package/dist/es/bridge-mode/io-server.mjs +208 -0
  14. package/dist/es/bridge-mode/io-server.mjs.map +1 -0
  15. package/dist/es/bridge-mode/page-browser-side.mjs +103 -0
  16. package/dist/es/bridge-mode/page-browser-side.mjs.map +1 -0
  17. package/dist/es/chrome-extension/agent.mjs +9 -0
  18. package/dist/es/chrome-extension/agent.mjs.map +1 -0
  19. package/dist/es/chrome-extension/cdpInput.mjs +174 -0
  20. package/dist/es/chrome-extension/cdpInput.mjs.LICENSE.txt +5 -0
  21. package/dist/es/chrome-extension/cdpInput.mjs.map +1 -0
  22. package/dist/es/chrome-extension/dynamic-scripts.mjs +37 -0
  23. package/dist/es/chrome-extension/dynamic-scripts.mjs.map +1 -0
  24. package/dist/es/chrome-extension/index.mjs +5 -0
  25. package/dist/es/chrome-extension/page.mjs +633 -0
  26. package/dist/es/chrome-extension/page.mjs.map +1 -0
  27. package/dist/es/index.mjs +6 -0
  28. package/dist/es/playwright/ai-fixture.mjs +325 -0
  29. package/dist/es/playwright/ai-fixture.mjs.map +1 -0
  30. package/dist/es/playwright/index.mjs +23 -0
  31. package/dist/es/playwright/index.mjs.map +1 -0
  32. package/dist/es/playwright/page.mjs +9 -0
  33. package/dist/es/playwright/page.mjs.map +1 -0
  34. package/dist/es/playwright/reporter/index.mjs +90 -0
  35. package/dist/es/playwright/reporter/index.mjs.map +1 -0
  36. package/dist/es/puppeteer/agent-launcher.mjs +132 -0
  37. package/dist/es/puppeteer/agent-launcher.mjs.map +1 -0
  38. package/dist/es/puppeteer/base-page.mjs +491 -0
  39. package/dist/es/puppeteer/base-page.mjs.map +1 -0
  40. package/dist/es/puppeteer/index.mjs +17 -0
  41. package/dist/es/puppeteer/index.mjs.map +1 -0
  42. package/dist/es/puppeteer/page.mjs +9 -0
  43. package/dist/es/puppeteer/page.mjs.map +1 -0
  44. package/dist/es/static/index.mjs +3 -0
  45. package/dist/es/static/static-agent.mjs +10 -0
  46. package/dist/es/static/static-agent.mjs.map +1 -0
  47. package/dist/es/static/static-page.mjs +132 -0
  48. package/dist/es/static/static-page.mjs.map +1 -0
  49. package/dist/es/web-element.mjs +96 -0
  50. package/dist/es/web-element.mjs.map +1 -0
  51. package/dist/es/web-page.mjs +206 -0
  52. package/dist/es/web-page.mjs.map +1 -0
  53. package/dist/lib/bin.js +54 -0
  54. package/dist/lib/bin.js.map +1 -0
  55. package/dist/lib/bridge-mode/agent-cli-side.js +154 -0
  56. package/dist/lib/bridge-mode/agent-cli-side.js.map +1 -0
  57. package/dist/lib/bridge-mode/browser.js +38 -0
  58. package/dist/lib/bridge-mode/browser.js.map +1 -0
  59. package/dist/lib/bridge-mode/common.js +95 -0
  60. package/dist/lib/bridge-mode/common.js.map +1 -0
  61. package/dist/lib/bridge-mode/index.js +46 -0
  62. package/dist/lib/bridge-mode/index.js.map +1 -0
  63. package/dist/lib/bridge-mode/io-client.js +135 -0
  64. package/dist/lib/bridge-mode/io-client.js.map +1 -0
  65. package/dist/lib/bridge-mode/io-server.js +245 -0
  66. package/dist/lib/bridge-mode/io-server.js.map +1 -0
  67. package/dist/lib/bridge-mode/page-browser-side.js +147 -0
  68. package/dist/lib/bridge-mode/page-browser-side.js.map +1 -0
  69. package/dist/lib/chrome-extension/agent.js +43 -0
  70. package/dist/lib/chrome-extension/agent.js.map +1 -0
  71. package/dist/lib/chrome-extension/cdpInput.js +208 -0
  72. package/dist/lib/chrome-extension/cdpInput.js.LICENSE.txt +5 -0
  73. package/dist/lib/chrome-extension/cdpInput.js.map +1 -0
  74. package/dist/lib/chrome-extension/dynamic-scripts.js +77 -0
  75. package/dist/lib/chrome-extension/dynamic-scripts.js.map +1 -0
  76. package/dist/lib/chrome-extension/index.js +60 -0
  77. package/dist/lib/chrome-extension/index.js.map +1 -0
  78. package/dist/lib/chrome-extension/page.js +667 -0
  79. package/dist/lib/chrome-extension/page.js.map +1 -0
  80. package/dist/lib/index.js +60 -0
  81. package/dist/lib/index.js.map +1 -0
  82. package/dist/lib/playwright/ai-fixture.js +362 -0
  83. package/dist/lib/playwright/ai-fixture.js.map +1 -0
  84. package/dist/lib/playwright/index.js +66 -0
  85. package/dist/lib/playwright/index.js.map +1 -0
  86. package/dist/lib/playwright/page.js +43 -0
  87. package/dist/lib/playwright/page.js.map +1 -0
  88. package/dist/lib/playwright/reporter/index.js +124 -0
  89. package/dist/lib/playwright/reporter/index.js.map +1 -0
  90. package/dist/lib/puppeteer/agent-launcher.js +194 -0
  91. package/dist/lib/puppeteer/agent-launcher.js.map +1 -0
  92. package/dist/lib/puppeteer/base-page.js +531 -0
  93. package/dist/lib/puppeteer/base-page.js.map +1 -0
  94. package/dist/lib/puppeteer/index.js +57 -0
  95. package/dist/lib/puppeteer/index.js.map +1 -0
  96. package/dist/lib/puppeteer/page.js +43 -0
  97. package/dist/lib/puppeteer/page.js.map +1 -0
  98. package/dist/lib/static/index.js +52 -0
  99. package/dist/lib/static/index.js.map +1 -0
  100. package/dist/lib/static/static-agent.js +44 -0
  101. package/dist/lib/static/static-agent.js.map +1 -0
  102. package/dist/lib/static/static-page.js +166 -0
  103. package/dist/lib/static/static-page.js.map +1 -0
  104. package/dist/lib/web-element.js +136 -0
  105. package/dist/lib/web-element.js.map +1 -0
  106. package/dist/lib/web-page.js +256 -0
  107. package/dist/lib/web-page.js.map +1 -0
  108. package/dist/types/bin.d.ts +1 -0
  109. package/dist/types/bridge-mode/agent-cli-side.d.ts +32 -0
  110. package/dist/types/bridge-mode/browser.d.ts +2 -0
  111. package/dist/types/bridge-mode/common.d.ts +60 -0
  112. package/dist/types/bridge-mode/index.d.ts +4 -0
  113. package/dist/types/bridge-mode/io-client.d.ts +10 -0
  114. package/dist/types/bridge-mode/io-server.d.ts +26 -0
  115. package/dist/types/bridge-mode/page-browser-side.d.ts +18 -0
  116. package/dist/types/chrome-extension/agent.d.ts +5 -0
  117. package/dist/types/chrome-extension/cdpInput.d.ts +52 -0
  118. package/dist/types/chrome-extension/dynamic-scripts.d.ts +3 -0
  119. package/dist/types/chrome-extension/index.d.ts +5 -0
  120. package/dist/types/chrome-extension/page.d.ts +95 -0
  121. package/dist/types/index.d.ts +9 -0
  122. package/dist/types/playwright/ai-fixture.d.ts +117 -0
  123. package/dist/types/playwright/index.d.ts +12 -0
  124. package/dist/types/playwright/page.d.ts +6 -0
  125. package/dist/types/playwright/reporter/index.d.ts +18 -0
  126. package/dist/types/puppeteer/agent-launcher.d.ts +29 -0
  127. package/dist/types/puppeteer/base-page.d.ts +90 -0
  128. package/dist/types/puppeteer/index.d.ts +9 -0
  129. package/dist/types/puppeteer/page.d.ts +6 -0
  130. package/dist/types/static/index.d.ts +2 -0
  131. package/dist/types/static/static-agent.d.ts +5 -0
  132. package/dist/types/static/static-page.d.ts +52 -0
  133. package/dist/types/web-element.d.ts +51 -0
  134. package/dist/types/web-page.d.ts +59 -0
  135. package/package.json +164 -0
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, definition)=>{
14
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
+ enumerable: true,
16
+ get: definition[key]
17
+ });
18
+ };
19
+ })();
20
+ (()=>{
21
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
22
+ })();
23
+ (()=>{
24
+ __webpack_require__.r = (exports1)=>{
25
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
26
+ value: 'Module'
27
+ });
28
+ Object.defineProperty(exports1, '__esModule', {
29
+ value: true
30
+ });
31
+ };
32
+ })();
33
+ var __webpack_exports__ = {};
34
+ __webpack_require__.r(__webpack_exports__);
35
+ __webpack_require__.d(__webpack_exports__, {
36
+ getKeyCommands: ()=>getKeyCommands,
37
+ commonWebActionsForWebPage: ()=>commonWebActionsForWebPage,
38
+ AbstractWebPage: ()=>AbstractWebPage
39
+ });
40
+ const external_node_assert_namespaceObject = require("node:assert");
41
+ var external_node_assert_default = /*#__PURE__*/ __webpack_require__.n(external_node_assert_namespaceObject);
42
+ const device_namespaceObject = require("@rpascene/core/device");
43
+ const utils_namespaceObject = require("@rpascene/core/utils");
44
+ const logger_namespaceObject = require("@rpascene/shared/logger");
45
+ const us_keyboard_layout_namespaceObject = require("@rpascene/shared/us-keyboard-layout");
46
+ const debug = (0, logger_namespaceObject.getDebug)('web:page');
47
+ function normalizeKeyInputs(value) {
48
+ const inputs = Array.isArray(value) ? value : [
49
+ value
50
+ ];
51
+ const result = [];
52
+ for (const input of inputs){
53
+ if ('string' != typeof input) {
54
+ result.push(input);
55
+ continue;
56
+ }
57
+ const trimmed = input.trim();
58
+ if (!trimmed) {
59
+ result.push(input);
60
+ continue;
61
+ }
62
+ let normalized = trimmed;
63
+ if (normalized.length > 1 && normalized.includes('+')) normalized = normalized.replace(/\s*\+\s*/g, ' ');
64
+ if (/\s/.test(normalized)) normalized = normalized.replace(/\s+/g, ' ');
65
+ const transformed = (0, us_keyboard_layout_namespaceObject.transformHotkeyInput)(normalized);
66
+ if (1 === transformed.length && '' === transformed[0] && '' !== trimmed) {
67
+ result.push(input);
68
+ continue;
69
+ }
70
+ if (0 === transformed.length) {
71
+ result.push(input);
72
+ continue;
73
+ }
74
+ result.push(...transformed);
75
+ }
76
+ return result;
77
+ }
78
+ function getKeyCommands(value) {
79
+ const keys = normalizeKeyInputs(value);
80
+ return keys.reduce((acc, k)=>{
81
+ const includeMeta = keys.includes('Meta') || keys.includes('Control');
82
+ if (includeMeta && ('a' === k || 'A' === k)) return acc.concat([
83
+ {
84
+ key: k,
85
+ command: 'SelectAll'
86
+ }
87
+ ]);
88
+ if (includeMeta && ('c' === k || 'C' === k)) return acc.concat([
89
+ {
90
+ key: k,
91
+ command: 'Copy'
92
+ }
93
+ ]);
94
+ if (includeMeta && ('v' === k || 'V' === k)) return acc.concat([
95
+ {
96
+ key: k,
97
+ command: 'Paste'
98
+ }
99
+ ]);
100
+ return acc.concat([
101
+ {
102
+ key: k
103
+ }
104
+ ]);
105
+ }, []);
106
+ }
107
+ class AbstractWebPage extends device_namespaceObject.AbstractInterface {
108
+ get mouse() {
109
+ return {
110
+ click: async (x, y, options)=>{},
111
+ wheel: async (deltaX, deltaY)=>{},
112
+ move: async (x, y)=>{},
113
+ drag: async (from, to)=>{}
114
+ };
115
+ }
116
+ get keyboard() {
117
+ return {
118
+ type: async (text)=>{},
119
+ press: async (action)=>{}
120
+ };
121
+ }
122
+ async clearInput(element) {}
123
+ }
124
+ const commonWebActionsForWebPage = (page)=>[
125
+ (0, device_namespaceObject.defineActionTap)(async (param)=>{
126
+ const element = param.locate;
127
+ external_node_assert_default()(element, 'Element not found, cannot tap');
128
+ await page.mouse.click(element.center[0], element.center[1], {
129
+ button: 'left'
130
+ });
131
+ }),
132
+ (0, device_namespaceObject.defineActionRightClick)(async (param)=>{
133
+ const element = param.locate;
134
+ external_node_assert_default()(element, 'Element not found, cannot right click');
135
+ await page.mouse.click(element.center[0], element.center[1], {
136
+ button: 'right'
137
+ });
138
+ }),
139
+ (0, device_namespaceObject.defineActionDoubleClick)(async (param)=>{
140
+ const element = param.locate;
141
+ external_node_assert_default()(element, 'Element not found, cannot double click');
142
+ await page.mouse.click(element.center[0], element.center[1], {
143
+ button: 'left',
144
+ count: 2
145
+ });
146
+ }),
147
+ (0, device_namespaceObject.defineActionHover)(async (param)=>{
148
+ const element = param.locate;
149
+ external_node_assert_default()(element, 'Element not found, cannot hover');
150
+ await page.mouse.move(element.center[0], element.center[1]);
151
+ }),
152
+ (0, device_namespaceObject.defineActionInput)(async (param)=>{
153
+ const element = param.locate;
154
+ if (element && 'append' !== param.mode) await page.clearInput(element);
155
+ if ('clear' === param.mode) return;
156
+ if (!param || !param.value) return;
157
+ await page.keyboard.type(param.value);
158
+ }),
159
+ (0, device_namespaceObject.defineActionKeyboardPress)(async (param)=>{
160
+ const element = param.locate;
161
+ if (element) await page.mouse.click(element.center[0], element.center[1], {
162
+ button: 'left'
163
+ });
164
+ const keys = getKeyCommands(param.keyName);
165
+ await page.keyboard.press(keys);
166
+ }),
167
+ (0, device_namespaceObject.defineActionScroll)(async (param)=>{
168
+ const element = param.locate;
169
+ const startingPoint = element ? {
170
+ left: element.center[0],
171
+ top: element.center[1]
172
+ } : void 0;
173
+ const scrollToEventName = null == param ? void 0 : param.scrollType;
174
+ if ('untilTop' === scrollToEventName) await page.scrollUntilTop(startingPoint);
175
+ else if ('untilBottom' === scrollToEventName) await page.scrollUntilBottom(startingPoint);
176
+ else if ('untilRight' === scrollToEventName) await page.scrollUntilRight(startingPoint);
177
+ else if ('untilLeft' === scrollToEventName) await page.scrollUntilLeft(startingPoint);
178
+ else if ('once' !== scrollToEventName && scrollToEventName) throw new Error(`Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(param)}`);
179
+ else {
180
+ if ((null == param ? void 0 : param.direction) !== 'down' && param && param.direction) if ('up' === param.direction) await page.scrollUp(param.distance || void 0, startingPoint);
181
+ else if ('left' === param.direction) await page.scrollLeft(param.distance || void 0, startingPoint);
182
+ else if ('right' === param.direction) await page.scrollRight(param.distance || void 0, startingPoint);
183
+ else throw new Error(`Unknown scroll direction: ${param.direction}`);
184
+ else await page.scrollDown((null == param ? void 0 : param.distance) || void 0, startingPoint);
185
+ await (0, utils_namespaceObject.sleep)(500);
186
+ }
187
+ }),
188
+ (0, device_namespaceObject.defineActionDragAndDrop)(async (param)=>{
189
+ const from = param.from;
190
+ const to = param.to;
191
+ external_node_assert_default()(from, 'missing "from" param for drag and drop');
192
+ external_node_assert_default()(to, 'missing "to" param for drag and drop');
193
+ await page.mouse.drag({
194
+ x: from.center[0],
195
+ y: from.center[1]
196
+ }, {
197
+ x: to.center[0],
198
+ y: to.center[1]
199
+ });
200
+ }),
201
+ (0, device_namespaceObject.defineActionLongPress)(async (param)=>{
202
+ const element = param.locate;
203
+ external_node_assert_default()(element, 'Element not found, cannot long press');
204
+ const duration = null == param ? void 0 : param.duration;
205
+ await page.longPress(element.center[0], element.center[1], duration);
206
+ }),
207
+ (0, device_namespaceObject.defineActionSwipe)(async (param)=>{
208
+ const { width, height } = await page.size();
209
+ const { start, end } = param;
210
+ const startPoint = start ? {
211
+ x: start.center[0],
212
+ y: start.center[1]
213
+ } : {
214
+ x: width / 2,
215
+ y: height / 2
216
+ };
217
+ let endPoint;
218
+ if (end) endPoint = {
219
+ x: end.center[0],
220
+ y: end.center[1]
221
+ };
222
+ else if (param.distance) {
223
+ const direction = param.direction;
224
+ if (!direction) throw new Error('direction is required for swipe gesture');
225
+ endPoint = {
226
+ x: startPoint.x + ('right' === direction ? param.distance : 'left' === direction ? -param.distance : 0),
227
+ y: startPoint.y + ('down' === direction ? param.distance : 'up' === direction ? -param.distance : 0)
228
+ };
229
+ } else throw new Error('Either end or distance must be specified for swipe gesture');
230
+ endPoint.x = Math.max(0, Math.min(endPoint.x, width));
231
+ endPoint.y = Math.max(0, Math.min(endPoint.y, height));
232
+ const duration = param.duration;
233
+ debug(`swipe from ${startPoint.x}, ${startPoint.y} to ${endPoint.x}, ${endPoint.y} with duration ${duration}ms, repeat is set to ${param.repeat}`);
234
+ let repeat = 'number' == typeof param.repeat ? param.repeat : 1;
235
+ if (0 === repeat) repeat = 10;
236
+ for(let i = 0; i < repeat; i++)await page.swipe(startPoint, endPoint, duration);
237
+ }),
238
+ (0, device_namespaceObject.defineActionClearInput)(async (param)=>{
239
+ const element = param.locate;
240
+ external_node_assert_default()(element, 'Element not found, cannot clear input');
241
+ await page.clearInput(element);
242
+ })
243
+ ];
244
+ exports.AbstractWebPage = __webpack_exports__.AbstractWebPage;
245
+ exports.commonWebActionsForWebPage = __webpack_exports__.commonWebActionsForWebPage;
246
+ exports.getKeyCommands = __webpack_exports__.getKeyCommands;
247
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
248
+ "AbstractWebPage",
249
+ "commonWebActionsForWebPage",
250
+ "getKeyCommands"
251
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
252
+ Object.defineProperty(exports, '__esModule', {
253
+ value: true
254
+ });
255
+
256
+ //# sourceMappingURL=web-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-page.js","sources":["webpack://@rpascene/web/webpack/runtime/compat_get_default_export","webpack://@rpascene/web/webpack/runtime/define_property_getters","webpack://@rpascene/web/webpack/runtime/has_own_property","webpack://@rpascene/web/webpack/runtime/make_namespace_object","webpack://@rpascene/web/./src/web-page.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import assert from 'node:assert';\nimport type { Point } from '@rpascene/core';\nimport {\n AbstractInterface,\n type DeviceAction,\n defineActionClearInput,\n defineActionDoubleClick,\n defineActionDragAndDrop,\n defineActionHover,\n defineActionInput,\n defineActionKeyboardPress,\n defineActionLongPress,\n defineActionRightClick,\n defineActionScroll,\n defineActionSwipe,\n defineActionTap,\n} from '@rpascene/core/device';\n\nimport { sleep } from '@rpascene/core/utils';\nimport type { ElementInfo } from '@rpascene/shared/extractor';\nimport { getDebug } from '@rpascene/shared/logger';\nimport { transformHotkeyInput } from '@rpascene/shared/us-keyboard-layout';\n\nconst debug = getDebug('web:page');\n\nfunction normalizeKeyInputs(value: string | string[]): string[] {\n const inputs = Array.isArray(value) ? value : [value];\n const result: string[] = [];\n\n for (const input of inputs) {\n if (typeof input !== 'string') {\n result.push(input as unknown as string);\n continue;\n }\n\n const trimmed = input.trim();\n if (!trimmed) {\n result.push(input);\n continue;\n }\n\n let normalized = trimmed;\n if (normalized.length > 1 && normalized.includes('+')) {\n normalized = normalized.replace(/\\s*\\+\\s*/g, ' ');\n }\n if (/\\s/.test(normalized)) {\n normalized = normalized.replace(/\\s+/g, ' ');\n }\n\n const transformed = transformHotkeyInput(normalized);\n if (transformed.length === 1 && transformed[0] === '' && trimmed !== '') {\n result.push(input);\n continue;\n }\n if (transformed.length === 0) {\n result.push(input);\n continue;\n }\n\n result.push(...transformed);\n }\n\n return result;\n}\n\nexport function getKeyCommands(\n value: string | string[],\n): Array<{ key: string; command?: string }> {\n const keys = normalizeKeyInputs(value);\n\n return keys.reduce((acc: Array<{ key: string; command?: string }>, k) => {\n const includeMeta = keys.includes('Meta') || keys.includes('Control');\n if (includeMeta && (k === 'a' || k === 'A')) {\n return acc.concat([{ key: k, command: 'SelectAll' }]);\n }\n if (includeMeta && (k === 'c' || k === 'C')) {\n return acc.concat([{ key: k, command: 'Copy' }]);\n }\n if (includeMeta && (k === 'v' || k === 'V')) {\n return acc.concat([{ key: k, command: 'Paste' }]);\n }\n return acc.concat([{ key: k }]);\n }, []);\n}\n\n// this is copied from puppeteer, but we don't want to import puppeteer here\nexport declare type KeyInput =\n | '0'\n | '1'\n | '2'\n | '3'\n | '4'\n | '5'\n | '6'\n | '7'\n | '8'\n | '9'\n | 'Power'\n | 'Eject'\n | 'Abort'\n | 'Help'\n | 'Backspace'\n | 'Tab'\n | 'Numpad5'\n | 'NumpadEnter'\n | 'Enter'\n | '\\r'\n | '\\n'\n | 'ShiftLeft'\n | 'ShiftRight'\n | 'ControlLeft'\n | 'ControlRight'\n | 'AltLeft'\n | 'AltRight'\n | 'Pause'\n | 'CapsLock'\n | 'Escape'\n | 'Convert'\n | 'NonConvert'\n | 'Space'\n | 'Numpad9'\n | 'PageUp'\n | 'Numpad3'\n | 'PageDown'\n | 'End'\n | 'Numpad1'\n | 'Home'\n | 'Numpad7'\n | 'ArrowLeft'\n | 'Numpad4'\n | 'Numpad8'\n | 'ArrowUp'\n | 'ArrowRight'\n | 'Numpad6'\n | 'Numpad2'\n | 'ArrowDown'\n | 'Select'\n | 'Open'\n | 'PrintScreen'\n | 'Insert'\n | 'Numpad0'\n | 'Delete'\n | 'NumpadDecimal'\n | 'Digit0'\n | 'Digit1'\n | 'Digit2'\n | 'Digit3'\n | 'Digit4'\n | 'Digit5'\n | 'Digit6'\n | 'Digit7'\n | 'Digit8'\n | 'Digit9'\n | 'KeyA'\n | 'KeyB'\n | 'KeyC'\n | 'KeyD'\n | 'KeyE'\n | 'KeyF'\n | 'KeyG'\n | 'KeyH'\n | 'KeyI'\n | 'KeyJ'\n | 'KeyK'\n | 'KeyL'\n | 'KeyM'\n | 'KeyN'\n | 'KeyO'\n | 'KeyP'\n | 'KeyQ'\n | 'KeyR'\n | 'KeyS'\n | 'KeyT'\n | 'KeyU'\n | 'KeyV'\n | 'KeyW'\n | 'KeyX'\n | 'KeyY'\n | 'KeyZ'\n | 'MetaLeft'\n | 'MetaRight'\n | 'ContextMenu'\n | 'NumpadMultiply'\n | 'NumpadAdd'\n | 'NumpadSubtract'\n | 'NumpadDivide'\n | 'F1'\n | 'F2'\n | 'F3'\n | 'F4'\n | 'F5'\n | 'F6'\n | 'F7'\n | 'F8'\n | 'F9'\n | 'F10'\n | 'F11'\n | 'F12'\n | 'F13'\n | 'F14'\n | 'F15'\n | 'F16'\n | 'F17'\n | 'F18'\n | 'F19'\n | 'F20'\n | 'F21'\n | 'F22'\n | 'F23'\n | 'F24'\n | 'NumLock'\n | 'ScrollLock'\n | 'AudioVolumeMute'\n | 'AudioVolumeDown'\n | 'AudioVolumeUp'\n | 'MediaTrackNext'\n | 'MediaTrackPrevious'\n | 'MediaStop'\n | 'MediaPlayPause'\n | 'Semicolon'\n | 'Equal'\n | 'NumpadEqual'\n | 'Comma'\n | 'Minus'\n | 'Period'\n | 'Slash'\n | 'Backquote'\n | 'BracketLeft'\n | 'Backslash'\n | 'BracketRight'\n | 'Quote'\n | 'AltGraph'\n | 'Props'\n | 'Cancel'\n | 'Clear'\n | 'Shift'\n | 'Control'\n | 'Alt'\n | 'Accept'\n | 'ModeChange'\n | ' '\n | 'Print'\n | 'Execute'\n | '\\u0000'\n | 'a'\n | 'b'\n | 'c'\n | 'd'\n | 'e'\n | 'f'\n | 'g'\n | 'h'\n | 'i'\n | 'j'\n | 'k'\n | 'l'\n | 'm'\n | 'n'\n | 'o'\n | 'p'\n | 'q'\n | 'r'\n | 's'\n | 't'\n | 'u'\n | 'v'\n | 'w'\n | 'x'\n | 'y'\n | 'z'\n | 'Meta'\n | '*'\n | '+'\n | '-'\n | '/'\n | ';'\n | '='\n | ','\n | '.'\n | '`'\n | '['\n | '\\\\'\n | ']'\n | \"'\"\n | 'Attn'\n | 'CrSel'\n | 'ExSel'\n | 'EraseEof'\n | 'Play'\n | 'ZoomOut'\n | ')'\n | '!'\n | '@'\n | '#'\n | '$'\n | '%'\n | '^'\n | '&'\n | '('\n | 'A'\n | 'B'\n | 'C'\n | 'D'\n | 'E'\n | 'F'\n | 'G'\n | 'H'\n | 'I'\n | 'J'\n | 'K'\n | 'L'\n | 'M'\n | 'N'\n | 'O'\n | 'P'\n | 'Q'\n | 'R'\n | 'S'\n | 'T'\n | 'U'\n | 'V'\n | 'W'\n | 'X'\n | 'Y'\n | 'Z'\n | ':'\n | '<'\n | '_'\n | '>'\n | '?'\n | '~'\n | '{'\n | '|'\n | '}'\n | '\"'\n | 'SoftLeft'\n | 'SoftRight'\n | 'Camera'\n | 'Call'\n | 'EndCall'\n | 'VolumeDown'\n | 'VolumeUp';\n\nexport type MouseButton = 'left' | 'right' | 'middle';\n\nexport interface MouseAction {\n click: (\n x: number,\n y: number,\n options: { button: MouseButton; count?: number },\n ) => Promise<void>;\n wheel: (deltaX: number, deltaY: number) => Promise<void>;\n move: (x: number, y: number) => Promise<void>;\n drag: (\n from: { x: number; y: number },\n to: { x: number; y: number },\n ) => Promise<void>;\n}\n\nexport interface KeyboardAction {\n type: (text: string) => Promise<void>;\n press: (\n action:\n | { key: KeyInput; command?: string }\n | { key: KeyInput; command?: string }[],\n ) => Promise<void>;\n}\n\nexport interface ChromePageDestroyOptions {\n closeTab?: boolean; // should close the tab when the page object is destroyed\n}\n\nexport abstract class AbstractWebPage extends AbstractInterface {\n get mouse(): MouseAction {\n return {\n click: async (\n x: number,\n y: number,\n options: { button: MouseButton },\n ) => { },\n wheel: async (deltaX: number, deltaY: number) => { },\n move: async (x: number, y: number) => { },\n drag: async (\n from: { x: number; y: number },\n to: { x: number; y: number },\n ) => { },\n };\n }\n\n get keyboard(): KeyboardAction {\n return {\n type: async (text: string) => { },\n press: async (\n action:\n | { key: KeyInput; command?: string }\n | { key: KeyInput; command?: string }[],\n ) => { },\n };\n }\n\n async clearInput(element: ElementInfo): Promise<void> { }\n\n abstract scrollUntilTop(startingPoint?: Point): Promise<void>;\n abstract scrollUntilBottom(startingPoint?: Point): Promise<void>;\n abstract scrollUntilLeft(startingPoint?: Point): Promise<void>;\n abstract scrollUntilRight(startingPoint?: Point): Promise<void>;\n abstract scrollUp(distance?: number, startingPoint?: Point): Promise<void>;\n abstract scrollDown(distance?: number, startingPoint?: Point): Promise<void>;\n abstract scrollLeft(distance?: number, startingPoint?: Point): Promise<void>;\n abstract scrollRight(distance?: number, startingPoint?: Point): Promise<void>;\n abstract longPress(x: number, y: number, duration?: number): Promise<void>;\n abstract swipe(\n from: { x: number; y: number },\n to: { x: number; y: number },\n duration?: number,\n ): Promise<void>;\n}\n// 通用页面操作\nexport const commonWebActionsForWebPage = <T extends AbstractWebPage>(\n page: T,\n): DeviceAction<any>[] => [\n defineActionTap(async (param) => {\n const element = param.locate;\n assert(element, 'Element not found, cannot tap');\n await page.mouse.click(element.center[0], element.center[1], {\n button: 'left',\n });\n }),\n defineActionRightClick(async (param) => {\n const element = param.locate;\n assert(element, 'Element not found, cannot right click');\n await page.mouse.click(element.center[0], element.center[1], {\n button: 'right',\n });\n }),\n defineActionDoubleClick(async (param) => {\n const element = param.locate;\n assert(element, 'Element not found, cannot double click');\n\n await page.mouse.click(element.center[0], element.center[1], {\n button: 'left',\n count: 2,\n });\n }),\n defineActionHover(async (param) => {\n const element = param.locate;\n assert(element, 'Element not found, cannot hover');\n await page.mouse.move(element.center[0], element.center[1]);\n }),\n defineActionInput(async (param) => {\n const element = param.locate;\n if (element && param.mode !== 'append') {\n await page.clearInput(element as unknown as ElementInfo);\n }\n\n if (param.mode === 'clear') {\n // Clear mode removes existing text without entering new characters\n return;\n }\n\n if (!param || !param.value) {\n return;\n }\n\n // Note: there is another implementation in AndroidDevicePage, which is more complex\n await page.keyboard.type(param.value);\n }),\n defineActionKeyboardPress(async (param) => {\n const element = param.locate;\n if (element) {\n await page.mouse.click(element.center[0], element.center[1], {\n button: 'left',\n });\n }\n\n const keys = getKeyCommands(param.keyName);\n await page.keyboard.press(keys as any); // TODO: fix this type error\n }),\n defineActionScroll(async (param) => {\n const element = param.locate;\n const startingPoint = element\n ? {\n left: element.center[0],\n top: element.center[1],\n }\n : undefined;\n const scrollToEventName = param?.scrollType;\n if (scrollToEventName === 'untilTop') {\n await page.scrollUntilTop(startingPoint);\n } else if (scrollToEventName === 'untilBottom') {\n await page.scrollUntilBottom(startingPoint);\n } else if (scrollToEventName === 'untilRight') {\n await page.scrollUntilRight(startingPoint);\n } else if (scrollToEventName === 'untilLeft') {\n await page.scrollUntilLeft(startingPoint);\n } else if (scrollToEventName === 'once' || !scrollToEventName) {\n if (param?.direction === 'down' || !param || !param.direction) {\n await page.scrollDown(param?.distance || undefined, startingPoint);\n } else if (param.direction === 'up') {\n await page.scrollUp(param.distance || undefined, startingPoint);\n } else if (param.direction === 'left') {\n await page.scrollLeft(param.distance || undefined, startingPoint);\n } else if (param.direction === 'right') {\n await page.scrollRight(param.distance || undefined, startingPoint);\n } else {\n throw new Error(`Unknown scroll direction: ${param.direction}`);\n }\n // until mouse event is done\n await sleep(500);\n } else {\n throw new Error(\n `Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(\n param,\n )}`,\n );\n }\n }),\n defineActionDragAndDrop(async (param) => {\n const from = param.from;\n const to = param.to;\n assert(from, 'missing \"from\" param for drag and drop');\n assert(to, 'missing \"to\" param for drag and drop');\n await page.mouse.drag(\n {\n x: from.center[0],\n y: from.center[1],\n },\n {\n x: to.center[0],\n y: to.center[1],\n },\n );\n }),\n\n defineActionLongPress(async (param) => {\n const element = param.locate;\n assert(element, 'Element not found, cannot long press');\n const duration = param?.duration;\n await page.longPress(element.center[0], element.center[1], duration);\n }),\n\n defineActionSwipe(async (param) => {\n const { width, height } = await page.size();\n const { start, end } = param;\n\n const startPoint = start\n ? {\n x: start.center[0],\n y: start.center[1],\n }\n : {\n x: width / 2,\n y: height / 2,\n };\n\n let endPoint: {\n x: number;\n y: number;\n };\n\n if (end) {\n endPoint = {\n x: end.center[0],\n y: end.center[1],\n };\n } else if (param.distance) {\n const direction = param.direction;\n if (!direction) {\n throw new Error('direction is required for swipe gesture');\n }\n\n endPoint = {\n x:\n startPoint.x +\n (direction === 'right'\n ? param.distance\n : direction === 'left'\n ? -param.distance\n : 0),\n y:\n startPoint.y +\n (direction === 'down'\n ? param.distance\n : direction === 'up'\n ? -param.distance\n : 0),\n };\n } else {\n throw new Error(\n 'Either end or distance must be specified for swipe gesture',\n );\n }\n\n // Ensure end coordinates are within bounds\n endPoint.x = Math.max(0, Math.min(endPoint.x, width));\n endPoint.y = Math.max(0, Math.min(endPoint.y, height));\n\n const duration = param.duration;\n\n debug(\n `swipe from ${startPoint.x}, ${startPoint.y} to ${endPoint.x}, ${endPoint.y} with duration ${duration}ms, repeat is set to ${param.repeat}`,\n );\n let repeat = typeof param.repeat === 'number' ? param.repeat : 1;\n if (repeat === 0) {\n repeat = 10; // 10 times is enough for infinite swipe\n }\n for (let i = 0; i < repeat; i++) {\n await page.swipe(startPoint, endPoint, duration);\n }\n }),\n\n defineActionClearInput(async (param) => {\n const element = param.locate;\n assert(element, 'Element not found, cannot clear input');\n await page.clearInput(element as unknown as ElementInfo);\n }),\n ];\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","debug","getDebug","normalizeKeyInputs","value","inputs","Array","result","input","trimmed","normalized","transformed","transformHotkeyInput","getKeyCommands","keys","acc","k","includeMeta","AbstractWebPage","AbstractInterface","x","y","options","deltaX","deltaY","from","to","text","action","element","commonWebActionsForWebPage","page","defineActionTap","param","assert","defineActionRightClick","defineActionDoubleClick","defineActionHover","defineActionInput","defineActionKeyboardPress","defineActionScroll","startingPoint","undefined","scrollToEventName","Error","JSON","sleep","defineActionDragAndDrop","defineActionLongPress","duration","defineActionSwipe","width","height","start","end","startPoint","endPoint","direction","Math","repeat","i","defineActionClearInput"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import 'dotenv/config';
@@ -0,0 +1,32 @@
1
+ import { Agent, type AgentOpt } from '@rpascene/core/agent';
2
+ import { type BridgeConnectTabOptions } from './common';
3
+ import type { ExtensionBridgePageBrowserSide } from './page-browser-side';
4
+ interface ChromeExtensionPageCliSide extends ExtensionBridgePageBrowserSide {
5
+ showStatusMessage: (message: string) => Promise<void>;
6
+ }
7
+ export declare const getBridgePageInCliSide: (timeout?: number | false, closeConflictServer?: boolean) => ChromeExtensionPageCliSide;
8
+ export declare class AgentOverChromeBridge extends Agent<ChromeExtensionPageCliSide> {
9
+ private destroyAfterDisconnectFlag?;
10
+ constructor(opts?: AgentOpt & {
11
+ closeNewTabsAfterDisconnect?: boolean;
12
+ serverListeningTimeout?: number | false;
13
+ closeConflictServer?: boolean;
14
+ });
15
+ setDestroyOptionsAfterConnect(): Promise<void>;
16
+ connectNewTabWithUrl(url: string, options?: BridgeConnectTabOptions): Promise<void>;
17
+ getBrowserTabList(): Promise<{
18
+ id: string;
19
+ title: string;
20
+ url: string;
21
+ currentActiveTab: boolean;
22
+ }[]>;
23
+ setActiveTabId(tabId: string): Promise<void>;
24
+ connectCurrentTab(options?: BridgeConnectTabOptions): Promise<void>;
25
+ aiAction(prompt: string, options?: any): Promise<{
26
+ result: Record<string, any>;
27
+ } | {
28
+ yamlFlow?: import("@rpascene/core").RpasceneYamlFlowItem[];
29
+ } | undefined>;
30
+ destroy(closeNewTabsAfterDisconnect?: boolean): Promise<void>;
31
+ }
32
+ export {};
@@ -0,0 +1,2 @@
1
+ import { ExtensionBridgePageBrowserSide } from '../bridge-mode/page-browser-side';
2
+ export { ExtensionBridgePageBrowserSide };
@@ -0,0 +1,60 @@
1
+ export declare const DefaultBridgeServerPort = 3766;
2
+ export declare const DefaultLocalEndpoint = "http://127.0.0.1:3766";
3
+ export declare const BridgeCallTimeout = 30000;
4
+ export declare enum BridgeEvent {
5
+ Call = "bridge-call",
6
+ CallResponse = "bridge-call-response",
7
+ UpdateAgentStatus = "bridge-update-agent-status",
8
+ Message = "bridge-message",
9
+ Connected = "bridge-connected",
10
+ Refused = "bridge-refused",
11
+ ConnectNewTabWithUrl = "connectNewTabWithUrl",
12
+ ConnectCurrentTab = "connectCurrentTab",
13
+ GetBrowserTabList = "getBrowserTabList",
14
+ SetDestroyOptions = "setDestroyOptions",
15
+ SetActiveTabId = "setActiveTabId"
16
+ }
17
+ export declare const BridgeSignalKill = "RPASCENE_BRIDGE_SIGNAL_KILL";
18
+ export interface BridgeConnectTabOptions {
19
+ /**
20
+ * If true, the page will always track the active tab.
21
+ * @default true
22
+ */
23
+ forceSameTabNavigation?: boolean;
24
+ }
25
+ export declare enum MouseEvent {
26
+ PREFIX = "mouse.",
27
+ Click = "mouse.click",
28
+ Wheel = "mouse.wheel",
29
+ Move = "mouse.move",
30
+ Drag = "mouse.drag"
31
+ }
32
+ export declare enum KeyboardEvent {
33
+ PREFIX = "keyboard.",
34
+ Type = "keyboard.type",
35
+ Press = "keyboard.press"
36
+ }
37
+ export declare const BridgePageType = "page-over-chrome-extension-bridge";
38
+ export declare const BridgeErrorCodeNoClientConnected = "no-client-connected";
39
+ export interface BridgeCall {
40
+ method: string;
41
+ args: any[];
42
+ response: any;
43
+ callTime: number;
44
+ responseTime: number;
45
+ callback: (error: Error | undefined, response: any) => void;
46
+ error?: Error;
47
+ }
48
+ export interface BridgeCallRequest {
49
+ id: string;
50
+ method: string;
51
+ args: any[];
52
+ }
53
+ export interface BridgeCallResponse {
54
+ id: string;
55
+ response: any;
56
+ error?: any;
57
+ }
58
+ export interface BridgeConnectedEventPayload {
59
+ version: string;
60
+ }
@@ -0,0 +1,4 @@
1
+ import { AgentOverChromeBridge } from './agent-cli-side';
2
+ export { AgentOverChromeBridge };
3
+ export { overrideAIConfig } from '@rpascene/shared/env';
4
+ export { killRunningServer } from './io-server';
@@ -0,0 +1,10 @@
1
+ export declare class BridgeClient {
2
+ endpoint: string;
3
+ onBridgeCall: (method: string, args: any[]) => Promise<any>;
4
+ onDisconnect?: (() => void) | undefined;
5
+ private socket;
6
+ serverVersion: string | null;
7
+ constructor(endpoint: string, onBridgeCall: (method: string, args: any[]) => Promise<any>, onDisconnect?: (() => void) | undefined);
8
+ connect(): Promise<unknown>;
9
+ disconnect(): void;
10
+ }
@@ -0,0 +1,26 @@
1
+ import { type BridgeCall } from './common';
2
+ export declare const killRunningServer: (port?: number) => Promise<void>;
3
+ export declare class BridgeServer {
4
+ port: number;
5
+ onConnect?: (() => void) | undefined;
6
+ onDisconnect?: ((reason: string) => void) | undefined;
7
+ closeConflictServer?: boolean | undefined;
8
+ private callId;
9
+ private io;
10
+ private socket;
11
+ private listeningTimeoutId;
12
+ private listeningTimerFlag;
13
+ private connectionTipTimer;
14
+ calls: Record<string, BridgeCall>;
15
+ private connectionLost;
16
+ private connectionLostReason;
17
+ constructor(port: number, onConnect?: (() => void) | undefined, onDisconnect?: ((reason: string) => void) | undefined, closeConflictServer?: boolean | undefined);
18
+ listen(opts?: {
19
+ timeout?: number | false;
20
+ }): Promise<void>;
21
+ private connectionLostErrorMsg;
22
+ private triggerCallResponseCallback;
23
+ private emitCall;
24
+ call<T = any>(method: string, args: any[], timeout?: number): Promise<T>;
25
+ close(): Promise<void | undefined>;
26
+ }
@@ -0,0 +1,18 @@
1
+ import ChromeExtensionProxyPage from '../chrome-extension/page';
2
+ import type { ChromePageDestroyOptions } from '../web-page';
3
+ import { type BridgeConnectTabOptions } from './common';
4
+ import { BridgeClient } from './io-client';
5
+ export declare class ExtensionBridgePageBrowserSide extends ChromeExtensionProxyPage {
6
+ onDisconnect: () => void;
7
+ onLogMessage: (message: string, type: 'log' | 'status') => void;
8
+ bridgeClient: BridgeClient | null;
9
+ private destroyOptions?;
10
+ private newlyCreatedTabIds;
11
+ constructor(onDisconnect?: () => void, onLogMessage?: (message: string, type: 'log' | 'status') => void, forceSameTabNavigation?: boolean);
12
+ private setupBridgeClient;
13
+ connect(): Promise<void>;
14
+ connectNewTabWithUrl(url: string, options?: BridgeConnectTabOptions): Promise<void>;
15
+ connectCurrentTab(options?: BridgeConnectTabOptions): Promise<void>;
16
+ setDestroyOptions(options: ChromePageDestroyOptions): Promise<void>;
17
+ destroy(): Promise<void>;
18
+ }
@@ -0,0 +1,5 @@
1
+ import { type AgentOpt, Agent as PageAgent } from '@rpascene/core/agent';
2
+ import type ChromeExtensionProxyPage from './page';
3
+ export declare class ChromeExtensionProxyPageAgent extends PageAgent {
4
+ constructor(page: ChromeExtensionProxyPage, opts?: AgentOpt);
5
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2017 Google Inc.
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { type KeyInput } from '@rpascene/shared/us-keyboard-layout';
7
+ /**
8
+ * @public
9
+ */
10
+ export interface KeyDownOptions {
11
+ /**
12
+ * @deprecated Do not use. This is automatically handled.
13
+ */
14
+ text?: string;
15
+ /**
16
+ * @deprecated Do not use. This is automatically handled.
17
+ */
18
+ commands?: string[];
19
+ }
20
+ /**
21
+ * @public
22
+ */
23
+ export interface KeyboardTypeOptions {
24
+ /**
25
+ * Time to wait between key presses in milliseconds
26
+ * @default undefined
27
+ */
28
+ delay?: number;
29
+ }
30
+ /**
31
+ * @public
32
+ */
33
+ export type KeyPressOptions = KeyDownOptions & KeyboardTypeOptions;
34
+ type InternalCDPSession = {
35
+ send: (command: string, params: any) => Promise<void>;
36
+ };
37
+ /**
38
+ * @internal
39
+ */
40
+ export declare class CdpKeyboard {
41
+ #private;
42
+ _modifiers: number;
43
+ constructor(client: InternalCDPSession);
44
+ updateClient(client: InternalCDPSession): void;
45
+ down(key: KeyInput, options?: Readonly<KeyDownOptions>): Promise<void>;
46
+ up(key: KeyInput): Promise<void>;
47
+ sendCharacter(char: string): Promise<void>;
48
+ private charIsKey;
49
+ type(text: string, options?: Readonly<KeyboardTypeOptions>): Promise<void>;
50
+ press(key: KeyInput | KeyInput[], options?: Readonly<KeyPressOptions>): Promise<void>;
51
+ }
52
+ export {};
@@ -0,0 +1,3 @@
1
+ export declare const getHtmlElementScript: () => Promise<string>;
2
+ export declare const injectWaterFlowAnimation: () => Promise<string>;
3
+ export declare const injectStopWaterFlowAnimation: () => Promise<string>;
@@ -0,0 +1,5 @@
1
+ import { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@rpascene/shared/common';
2
+ import { ChromeExtensionProxyPageAgent } from './agent';
3
+ import ChromeExtensionProxyPage from './page';
4
+ export { overrideAIConfig } from '@rpascene/shared/env';
5
+ export { ChromeExtensionProxyPage, ChromeExtensionProxyPageAgent, ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED, };
@@ -0,0 +1,95 @@
1
+ import type { ElementTreeNode, Point, Size, UIContext } from '@rpascene/core';
2
+ import type { AbstractInterface, DeviceAction } from '@rpascene/core/device';
3
+ import type { ElementInfo } from '@rpascene/shared/extractor';
4
+ import { type KeyInput, type MouseButton } from '../web-page';
5
+ export default class ChromeExtensionProxyPage implements AbstractInterface {
6
+ interfaceType: string;
7
+ forceSameTabNavigation: boolean;
8
+ private viewportSize?;
9
+ private activeTabId;
10
+ private tabIdOfDebuggerAttached;
11
+ private attachingDebugger;
12
+ private destroyed;
13
+ private isMobileEmulation;
14
+ _continueWhenFailedToAttachDebugger: boolean;
15
+ constructor(forceSameTabNavigation: boolean);
16
+ actionSpace(): DeviceAction[];
17
+ setActiveTabId(tabId: number): Promise<void>;
18
+ getActiveTabId(): Promise<number | null>;
19
+ /**
20
+ * Get a list of current tabs
21
+ * @returns {Promise<Array<{id: number, title: string, url: string}>>}
22
+ */
23
+ getBrowserTabList(): Promise<{
24
+ id: string;
25
+ title: string;
26
+ url: string;
27
+ currentActiveTab: boolean;
28
+ }[]>;
29
+ getTabIdOrConnectToCurrentTab(): Promise<number>;
30
+ private attachDebugger;
31
+ private showMousePointer;
32
+ private hideMousePointer;
33
+ private detachDebugger;
34
+ private enableWaterFlowAnimation;
35
+ private disableWaterFlowAnimation;
36
+ private sendCommandToDebugger;
37
+ private getPageContentByCDP;
38
+ evaluateJavaScript(script: string): Promise<any>;
39
+ beforeInvokeAction(): Promise<void>;
40
+ private waitUntilNetworkIdle;
41
+ getElementsInfo(): Promise<ElementInfo[]>;
42
+ getXpathsById(id: string): Promise<any>;
43
+ getXpathsByPoint(point: Point, isOrderSensitive: boolean): Promise<any>;
44
+ getElementInfoByXpath(xpath: string): Promise<any>;
45
+ getElementsNodeTree(): Promise<ElementTreeNode<ElementInfo>>;
46
+ getContext(): Promise<UIContext>;
47
+ size(): Promise<Size>;
48
+ screenshotBase64(): Promise<string>;
49
+ url(): Promise<string>;
50
+ scrollUntilTop(startingPoint?: Point): Promise<void>;
51
+ scrollUntilBottom(startingPoint?: Point): Promise<void>;
52
+ scrollUntilLeft(startingPoint?: Point): Promise<void>;
53
+ scrollUntilRight(startingPoint?: Point): Promise<void>;
54
+ scrollUp(distance?: number, startingPoint?: Point): Promise<void>;
55
+ scrollDown(distance?: number, startingPoint?: Point): Promise<void>;
56
+ scrollLeft(distance?: number, startingPoint?: Point): Promise<void>;
57
+ scrollRight(distance?: number, startingPoint?: Point): Promise<void>;
58
+ clearInput(element: ElementInfo): Promise<void>;
59
+ private latestMouseX;
60
+ private latestMouseY;
61
+ mouse: {
62
+ click: (x: number, y: number, options?: {
63
+ button?: MouseButton;
64
+ count?: number;
65
+ }) => Promise<void>;
66
+ wheel: (deltaX: number, deltaY: number, startX?: number, startY?: number) => Promise<void>;
67
+ move: (x: number, y: number) => Promise<void>;
68
+ drag: (from: {
69
+ x: number;
70
+ y: number;
71
+ }, to: {
72
+ x: number;
73
+ y: number;
74
+ }) => Promise<void>;
75
+ };
76
+ keyboard: {
77
+ type: (text: string) => Promise<void>;
78
+ press: (action: {
79
+ key: KeyInput;
80
+ command?: string;
81
+ } | {
82
+ key: KeyInput;
83
+ command?: string;
84
+ }[]) => Promise<void>;
85
+ };
86
+ destroy(): Promise<void>;
87
+ longPress(x: number, y: number, duration?: number): Promise<void>;
88
+ swipe(from: {
89
+ x: number;
90
+ y: number;
91
+ }, to: {
92
+ x: number;
93
+ y: number;
94
+ }, duration?: number): Promise<void>;
95
+ }
@@ -0,0 +1,9 @@
1
+ export { PlaywrightAiFixture } from './playwright';
2
+ export type { PlayWrightAiFixtureType } from './playwright';
3
+ export type { WebPage } from './web-element';
4
+ export type { WebUIContext } from '@rpascene/core';
5
+ export { Agent as PageAgent, type AgentOpt } from '@rpascene/core/agent';
6
+ export { PuppeteerAgent } from './puppeteer';
7
+ export { PlaywrightAgent } from './playwright';
8
+ export { StaticPageAgent, StaticPage } from './static';
9
+ export { WebPageContextParser } from './web-element';