@midscene/web 1.0.1-beta-20251208075922.0 → 1.0.1-beta-20251208085324.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/dist/es/bridge-mode/io-client.mjs +1 -1
- package/dist/es/bridge-mode/io-server.mjs +2 -2
- package/dist/es/bridge-mode/page-browser-side.mjs +1 -1
- package/dist/es/puppeteer/agent-launcher.mjs +6 -2
- package/dist/es/puppeteer/agent-launcher.mjs.map +1 -1
- package/dist/es/puppeteer/base-page.mjs +3 -1
- package/dist/es/puppeteer/base-page.mjs.map +1 -1
- package/dist/es/web-element.mjs.map +1 -1
- package/dist/es/web-page.mjs +33 -31
- package/dist/es/web-page.mjs.map +1 -1
- package/dist/lib/bin.js +1 -1
- package/dist/lib/bridge-mode/agent-cli-side.js +2 -2
- package/dist/lib/bridge-mode/browser.js +2 -2
- package/dist/lib/bridge-mode/common.js +2 -2
- package/dist/lib/bridge-mode/index.js +2 -2
- package/dist/lib/bridge-mode/io-client.js +3 -3
- package/dist/lib/bridge-mode/io-server.js +4 -4
- package/dist/lib/bridge-mode/page-browser-side.js +3 -3
- package/dist/lib/chrome-extension/agent.js +2 -2
- package/dist/lib/chrome-extension/cdpInput.js +2 -2
- package/dist/lib/chrome-extension/dynamic-scripts.js +2 -2
- package/dist/lib/chrome-extension/index.js +2 -2
- package/dist/lib/chrome-extension/page.js +2 -2
- package/dist/lib/index.js +2 -2
- package/dist/lib/playwright/ai-fixture.js +2 -2
- package/dist/lib/playwright/index.js +2 -2
- package/dist/lib/playwright/page.js +2 -2
- package/dist/lib/playwright/reporter/index.js +2 -2
- package/dist/lib/puppeteer/agent-launcher.js +15 -8
- package/dist/lib/puppeteer/agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer/base-page.js +5 -3
- package/dist/lib/puppeteer/base-page.js.map +1 -1
- package/dist/lib/puppeteer/index.js +2 -2
- package/dist/lib/puppeteer/page.js +2 -2
- package/dist/lib/static/index.js +2 -2
- package/dist/lib/static/static-agent.js +2 -2
- package/dist/lib/static/static-page.js +2 -2
- package/dist/lib/utils.js +2 -2
- package/dist/lib/web-element.js +2 -2
- package/dist/lib/web-element.js.map +1 -1
- package/dist/lib/web-page.js +35 -33
- package/dist/lib/web-page.js.map +1 -1
- package/dist/types/puppeteer/agent-launcher.d.ts +1 -0
- package/dist/types/puppeteer/base-page.d.ts +1 -0
- package/dist/types/web-element.d.ts +1 -0
- package/dist/types/web-page.d.ts +1 -1
- package/package.json +5 -5
package/dist/es/web-page.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-page.mjs","sources":["../../src/web-page.ts"],"sourcesContent":["import assert from 'node:assert';\nimport type { Point } from '@midscene/core';\nimport { z } from '@midscene/core';\nimport {\n AbstractInterface,\n type DeviceAction,\n defineAction,\n defineActionClearInput,\n defineActionDoubleClick,\n defineActionDragAndDrop,\n defineActionHover,\n defineActionInput,\n defineActionKeyboardPress,\n defineActionLongPress,\n defineActionRightClick,\n defineActionScroll,\n defineActionSwipe,\n defineActionTap,\n} from '@midscene/core/device';\n\nimport { sleep } from '@midscene/core/utils';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { getDebug } from '@midscene/shared/logger';\nimport { transformHotkeyInput } from '@midscene/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 navigate?(url: string): Promise<void>;\n reload?(): Promise<void>;\n goBack?(): Promise<void>;\n\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 === 'scrollToTop') {\n await page.scrollUntilTop(startingPoint);\n } else if (scrollToEventName === 'scrollToBottom') {\n await page.scrollUntilBottom(startingPoint);\n } else if (scrollToEventName === 'scrollToRight') {\n await page.scrollUntilRight(startingPoint);\n } else if (scrollToEventName === 'scrollToLeft') {\n await page.scrollUntilLeft(startingPoint);\n } else if (scrollToEventName === 'singleAction' || !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 defineAction({\n name: 'Navigate',\n description:\n 'Navigate the browser to a specified URL. Opens the URL in the current tab.',\n paramSchema: z.object({\n url: z.string().describe('The URL to navigate to'),\n }),\n call: async (param) => {\n if (!page.navigate) {\n throw new Error(\n 'Navigate operation is not supported on this page type',\n );\n }\n await page.navigate(param.url);\n },\n }),\n\n defineAction({\n name: 'Reload',\n description: 'Reload the current page',\n call: async () => {\n if (!page.reload) {\n throw new Error('Reload operation is not supported on this page type');\n }\n await page.reload();\n },\n }),\n\n defineAction({\n name: 'GoBack',\n description: 'Navigate back in browser history',\n call: async () => {\n if (!page.goBack) {\n throw new Error('GoBack operation is not supported on this page type');\n }\n await page.goBack();\n },\n }),\n];\n"],"names":["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","defineAction","z"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"web-page.mjs","sources":["../../src/web-page.ts"],"sourcesContent":["import assert from 'node:assert';\nimport type { Point } from '@midscene/core';\nimport { z } from '@midscene/core';\nimport {\n AbstractInterface,\n type DeviceAction,\n defineAction,\n defineActionClearInput,\n defineActionDoubleClick,\n defineActionDragAndDrop,\n defineActionHover,\n defineActionInput,\n defineActionKeyboardPress,\n defineActionLongPress,\n defineActionRightClick,\n defineActionScroll,\n defineActionSwipe,\n defineActionTap,\n} from '@midscene/core/device';\n\nimport { sleep } from '@midscene/core/utils';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { getDebug } from '@midscene/shared/logger';\nimport { transformHotkeyInput } from '@midscene/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 navigate?(url: string): Promise<void>;\n reload?(): Promise<void>;\n goBack?(): Promise<void>;\n\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 includeTouchEvents = false,\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 === 'scrollToTop') {\n await page.scrollUntilTop(startingPoint);\n } else if (scrollToEventName === 'scrollToBottom') {\n await page.scrollUntilBottom(startingPoint);\n } else if (scrollToEventName === 'scrollToRight') {\n await page.scrollUntilRight(startingPoint);\n } else if (scrollToEventName === 'scrollToLeft') {\n await page.scrollUntilLeft(startingPoint);\n } else if (scrollToEventName === 'singleAction' || !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 ...(includeTouchEvents\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 : []),\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 defineAction({\n name: 'Navigate',\n description:\n 'Navigate the browser to a specified URL. Opens the URL in the current tab.',\n paramSchema: z.object({\n url: z.string().describe('The URL to navigate to'),\n }),\n call: async (param) => {\n if (!page.navigate) {\n throw new Error(\n 'Navigate operation is not supported on this page type',\n );\n }\n await page.navigate(param.url);\n },\n }),\n\n defineAction({\n name: 'Reload',\n description: 'Reload the current page',\n call: async () => {\n if (!page.reload) {\n throw new Error('Reload operation is not supported on this page type');\n }\n await page.reload();\n },\n }),\n\n defineAction({\n name: 'GoBack',\n description: 'Navigate back in browser history',\n call: async () => {\n if (!page.goBack) {\n throw new Error('GoBack operation is not supported on this page type');\n }\n await page.goBack();\n },\n }),\n];\n"],"names":["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","includeTouchEvents","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","defineAction","z"],"mappings":"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"}
|
package/dist/lib/bin.js
CHANGED
|
@@ -42,7 +42,7 @@ server.app.use(external_cors_default()({
|
|
|
42
42
|
Promise.resolve().then(()=>server.launch()).then(()=>{
|
|
43
43
|
console.log(`Midscene playground server is running on http://localhost:${server.port}`);
|
|
44
44
|
});
|
|
45
|
-
for(var
|
|
45
|
+
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
46
46
|
Object.defineProperty(exports, '__esModule', {
|
|
47
47
|
value: true
|
|
48
48
|
});
|
|
@@ -154,10 +154,10 @@ class AgentOverChromeBridge extends agent_namespaceObject.Agent {
|
|
|
154
154
|
}
|
|
155
155
|
exports.AgentOverChromeBridge = __webpack_exports__.AgentOverChromeBridge;
|
|
156
156
|
exports.getBridgePageInCliSide = __webpack_exports__.getBridgePageInCliSide;
|
|
157
|
-
for(var
|
|
157
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
158
158
|
"AgentOverChromeBridge",
|
|
159
159
|
"getBridgePageInCliSide"
|
|
160
|
-
].indexOf(
|
|
160
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
161
161
|
Object.defineProperty(exports, '__esModule', {
|
|
162
162
|
value: true
|
|
163
163
|
});
|
|
@@ -28,9 +28,9 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
28
28
|
});
|
|
29
29
|
const external_page_browser_side_js_namespaceObject = require("./page-browser-side.js");
|
|
30
30
|
exports.ExtensionBridgePageBrowserSide = __webpack_exports__.ExtensionBridgePageBrowserSide;
|
|
31
|
-
for(var
|
|
31
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
32
32
|
"ExtensionBridgePageBrowserSide"
|
|
33
|
-
].indexOf(
|
|
33
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
34
34
|
Object.defineProperty(exports, '__esModule', {
|
|
35
35
|
value: true
|
|
36
36
|
});
|
|
@@ -87,7 +87,7 @@ exports.DefaultLocalEndpoint = __webpack_exports__.DefaultLocalEndpoint;
|
|
|
87
87
|
exports.KeyboardEvent = __webpack_exports__.KeyboardEvent;
|
|
88
88
|
exports.MouseEvent = __webpack_exports__.MouseEvent;
|
|
89
89
|
exports.getBridgeServerHost = __webpack_exports__.getBridgeServerHost;
|
|
90
|
-
for(var
|
|
90
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
91
91
|
"BridgeCallTimeout",
|
|
92
92
|
"BridgeErrorCodeNoClientConnected",
|
|
93
93
|
"BridgeEvent",
|
|
@@ -99,7 +99,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
|
99
99
|
"KeyboardEvent",
|
|
100
100
|
"MouseEvent",
|
|
101
101
|
"getBridgeServerHost"
|
|
102
|
-
].indexOf(
|
|
102
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
103
103
|
Object.defineProperty(exports, '__esModule', {
|
|
104
104
|
value: true
|
|
105
105
|
});
|
|
@@ -34,11 +34,11 @@ const external_io_server_js_namespaceObject = require("./io-server.js");
|
|
|
34
34
|
exports.AgentOverChromeBridge = __webpack_exports__.AgentOverChromeBridge;
|
|
35
35
|
exports.killRunningServer = __webpack_exports__.killRunningServer;
|
|
36
36
|
exports.overrideAIConfig = __webpack_exports__.overrideAIConfig;
|
|
37
|
-
for(var
|
|
37
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
38
38
|
"AgentOverChromeBridge",
|
|
39
39
|
"killRunningServer",
|
|
40
40
|
"overrideAIConfig"
|
|
41
|
-
].indexOf(
|
|
41
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
42
42
|
Object.defineProperty(exports, '__esModule', {
|
|
43
43
|
value: true
|
|
44
44
|
});
|
|
@@ -45,7 +45,7 @@ class BridgeClient {
|
|
|
45
45
|
this.socket = (0, external_socket_io_client_namespaceObject.io)(this.endpoint, {
|
|
46
46
|
reconnection: false,
|
|
47
47
|
query: {
|
|
48
|
-
version: "1.0.1-beta-
|
|
48
|
+
version: "1.0.1-beta-20251208085324.0"
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
51
|
const timeout = setTimeout(()=>{
|
|
@@ -119,9 +119,9 @@ class BridgeClient {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
exports.BridgeClient = __webpack_exports__.BridgeClient;
|
|
122
|
-
for(var
|
|
122
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
123
123
|
"BridgeClient"
|
|
124
|
-
].indexOf(
|
|
124
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
125
125
|
Object.defineProperty(exports, '__esModule', {
|
|
126
126
|
value: true
|
|
127
127
|
});
|
|
@@ -104,7 +104,7 @@ class BridgeServer {
|
|
|
104
104
|
(0, shared_utils_namespaceObject.logMsg)('one client connected');
|
|
105
105
|
this.socket = socket;
|
|
106
106
|
const clientVersion = socket.handshake.query.version;
|
|
107
|
-
(0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v1.0.1-beta-
|
|
107
|
+
(0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v1.0.1-beta-20251208085324.0, browser-side version v${clientVersion}`);
|
|
108
108
|
socket.on(external_common_js_namespaceObject.BridgeEvent.CallResponse, (params)=>{
|
|
109
109
|
const id = params.id;
|
|
110
110
|
const response = params.response;
|
|
@@ -129,7 +129,7 @@ class BridgeServer {
|
|
|
129
129
|
setTimeout(()=>{
|
|
130
130
|
this.onConnect?.();
|
|
131
131
|
const payload = {
|
|
132
|
-
version: "1.0.1-beta-
|
|
132
|
+
version: "1.0.1-beta-20251208085324.0"
|
|
133
133
|
};
|
|
134
134
|
socket.emit(external_common_js_namespaceObject.BridgeEvent.Connected, payload);
|
|
135
135
|
Promise.resolve().then(()=>{
|
|
@@ -236,10 +236,10 @@ class BridgeServer {
|
|
|
236
236
|
}
|
|
237
237
|
exports.BridgeServer = __webpack_exports__.BridgeServer;
|
|
238
238
|
exports.killRunningServer = __webpack_exports__.killRunningServer;
|
|
239
|
-
for(var
|
|
239
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
240
240
|
"BridgeServer",
|
|
241
241
|
"killRunningServer"
|
|
242
|
-
].indexOf(
|
|
242
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
243
243
|
Object.defineProperty(exports, '__esModule', {
|
|
244
244
|
value: true
|
|
245
245
|
});
|
|
@@ -84,7 +84,7 @@ class ExtensionBridgePageBrowserSide extends page_js_default() {
|
|
|
84
84
|
}
|
|
85
85
|
}, ()=>this.destroy());
|
|
86
86
|
await this.bridgeClient.connect();
|
|
87
|
-
this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.0.1-beta-
|
|
87
|
+
this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.0.1-beta-20251208085324.0`, 'log');
|
|
88
88
|
}
|
|
89
89
|
async connect() {
|
|
90
90
|
return await this.setupBridgeClient();
|
|
@@ -136,9 +136,9 @@ class ExtensionBridgePageBrowserSide extends page_js_default() {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
exports.ExtensionBridgePageBrowserSide = __webpack_exports__.ExtensionBridgePageBrowserSide;
|
|
139
|
-
for(var
|
|
139
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
140
140
|
"ExtensionBridgePageBrowserSide"
|
|
141
|
-
].indexOf(
|
|
141
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
142
142
|
Object.defineProperty(exports, '__esModule', {
|
|
143
143
|
value: true
|
|
144
144
|
});
|
|
@@ -33,9 +33,9 @@ class ChromeExtensionProxyPageAgent extends agent_namespaceObject.Agent {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
exports.ChromeExtensionProxyPageAgent = __webpack_exports__.ChromeExtensionProxyPageAgent;
|
|
36
|
-
for(var
|
|
36
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
37
37
|
"ChromeExtensionProxyPageAgent"
|
|
38
|
-
].indexOf(
|
|
38
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
39
39
|
Object.defineProperty(exports, '__esModule', {
|
|
40
40
|
value: true
|
|
41
41
|
});
|
|
@@ -198,9 +198,9 @@ function keyDescriptionForString(keyString) {
|
|
|
198
198
|
return description;
|
|
199
199
|
}
|
|
200
200
|
exports.CdpKeyboard = __webpack_exports__.CdpKeyboard;
|
|
201
|
-
for(var
|
|
201
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
202
202
|
"CdpKeyboard"
|
|
203
|
-
].indexOf(
|
|
203
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
204
204
|
Object.defineProperty(exports, '__esModule', {
|
|
205
205
|
value: true
|
|
206
206
|
});
|
|
@@ -76,11 +76,11 @@ const injectStopWaterFlowAnimation = async ()=>{
|
|
|
76
76
|
exports.getHtmlElementScript = __webpack_exports__.getHtmlElementScript;
|
|
77
77
|
exports.injectStopWaterFlowAnimation = __webpack_exports__.injectStopWaterFlowAnimation;
|
|
78
78
|
exports.injectWaterFlowAnimation = __webpack_exports__.injectWaterFlowAnimation;
|
|
79
|
-
for(var
|
|
79
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
80
80
|
"getHtmlElementScript",
|
|
81
81
|
"injectStopWaterFlowAnimation",
|
|
82
82
|
"injectWaterFlowAnimation"
|
|
83
|
-
].indexOf(
|
|
83
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
84
84
|
Object.defineProperty(exports, '__esModule', {
|
|
85
85
|
value: true
|
|
86
86
|
});
|
|
@@ -47,12 +47,12 @@ exports.ChromeExtensionProxyPage = __webpack_exports__.ChromeExtensionProxyPage;
|
|
|
47
47
|
exports.ChromeExtensionProxyPageAgent = __webpack_exports__.ChromeExtensionProxyPageAgent;
|
|
48
48
|
exports.ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED = __webpack_exports__.ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED;
|
|
49
49
|
exports.overrideAIConfig = __webpack_exports__.overrideAIConfig;
|
|
50
|
-
for(var
|
|
50
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
51
51
|
"ChromeExtensionProxyPage",
|
|
52
52
|
"ChromeExtensionProxyPageAgent",
|
|
53
53
|
"ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED",
|
|
54
54
|
"overrideAIConfig"
|
|
55
|
-
].indexOf(
|
|
55
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
56
56
|
Object.defineProperty(exports, '__esModule', {
|
|
57
57
|
value: true
|
|
58
58
|
});
|
|
@@ -641,9 +641,9 @@ class ChromeExtensionProxyPage {
|
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
643
|
exports["default"] = __webpack_exports__["default"];
|
|
644
|
-
for(var
|
|
644
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
645
645
|
"default"
|
|
646
|
-
].indexOf(
|
|
646
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
647
647
|
Object.defineProperty(exports, '__esModule', {
|
|
648
648
|
value: true
|
|
649
649
|
});
|
package/dist/lib/index.js
CHANGED
|
@@ -44,7 +44,7 @@ exports.PuppeteerAgent = __webpack_exports__.PuppeteerAgent;
|
|
|
44
44
|
exports.StaticPage = __webpack_exports__.StaticPage;
|
|
45
45
|
exports.StaticPageAgent = __webpack_exports__.StaticPageAgent;
|
|
46
46
|
exports.WebPageContextParser = __webpack_exports__.WebPageContextParser;
|
|
47
|
-
for(var
|
|
47
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
48
48
|
"PageAgent",
|
|
49
49
|
"PlaywrightAgent",
|
|
50
50
|
"PlaywrightAiFixture",
|
|
@@ -52,7 +52,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
|
52
52
|
"StaticPage",
|
|
53
53
|
"StaticPageAgent",
|
|
54
54
|
"WebPageContextParser"
|
|
55
|
-
].indexOf(
|
|
55
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
56
56
|
Object.defineProperty(exports, '__esModule', {
|
|
57
57
|
value: true
|
|
58
58
|
});
|
|
@@ -380,10 +380,10 @@ const PlaywrightAiFixture = (options)=>{
|
|
|
380
380
|
};
|
|
381
381
|
exports.PlaywrightAiFixture = __webpack_exports__.PlaywrightAiFixture;
|
|
382
382
|
exports.midsceneDumpAnnotationId = __webpack_exports__.midsceneDumpAnnotationId;
|
|
383
|
-
for(var
|
|
383
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
384
384
|
"PlaywrightAiFixture",
|
|
385
385
|
"midsceneDumpAnnotationId"
|
|
386
|
-
].indexOf(
|
|
386
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
387
387
|
Object.defineProperty(exports, '__esModule', {
|
|
388
388
|
value: true
|
|
389
389
|
});
|
|
@@ -79,12 +79,12 @@ exports.PlaywrightAgent = __webpack_exports__.PlaywrightAgent;
|
|
|
79
79
|
exports.PlaywrightAiFixture = __webpack_exports__.PlaywrightAiFixture;
|
|
80
80
|
exports.PlaywrightWebPage = __webpack_exports__.PlaywrightWebPage;
|
|
81
81
|
exports.overrideAIConfig = __webpack_exports__.overrideAIConfig;
|
|
82
|
-
for(var
|
|
82
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
83
83
|
"PlaywrightAgent",
|
|
84
84
|
"PlaywrightAiFixture",
|
|
85
85
|
"PlaywrightWebPage",
|
|
86
86
|
"overrideAIConfig"
|
|
87
|
-
].indexOf(
|
|
87
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
88
88
|
Object.defineProperty(exports, '__esModule', {
|
|
89
89
|
value: true
|
|
90
90
|
});
|
|
@@ -33,9 +33,9 @@ class WebPage extends base_page_js_namespaceObject.Page {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
exports.WebPage = __webpack_exports__.WebPage;
|
|
36
|
-
for(var
|
|
36
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
37
37
|
"WebPage"
|
|
38
|
-
].indexOf(
|
|
38
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
39
39
|
Object.defineProperty(exports, '__esModule', {
|
|
40
40
|
value: true
|
|
41
41
|
});
|
|
@@ -128,9 +128,9 @@ class MidsceneReporter {
|
|
|
128
128
|
}
|
|
129
129
|
const reporter = MidsceneReporter;
|
|
130
130
|
exports["default"] = __webpack_exports__["default"];
|
|
131
|
-
for(var
|
|
131
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
132
132
|
"default"
|
|
133
|
-
].indexOf(
|
|
133
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
134
134
|
Object.defineProperty(exports, '__esModule', {
|
|
135
135
|
value: true
|
|
136
136
|
});
|
|
@@ -34,12 +34,13 @@ var __webpack_exports__ = {};
|
|
|
34
34
|
__webpack_require__.r(__webpack_exports__);
|
|
35
35
|
__webpack_require__.d(__webpack_exports__, {
|
|
36
36
|
defaultViewportScale: ()=>defaultViewportScale,
|
|
37
|
-
defaultWaitForNetworkIdleTimeout: ()=>defaultWaitForNetworkIdleTimeout,
|
|
38
37
|
launchPuppeteerPage: ()=>launchPuppeteerPage,
|
|
39
|
-
defaultViewportWidth: ()=>defaultViewportWidth,
|
|
40
|
-
puppeteerAgentForTarget: ()=>puppeteerAgentForTarget,
|
|
41
38
|
defaultUA: ()=>defaultUA,
|
|
42
|
-
defaultViewportHeight: ()=>defaultViewportHeight
|
|
39
|
+
defaultViewportHeight: ()=>defaultViewportHeight,
|
|
40
|
+
defaultWaitForNetworkIdleTimeout: ()=>defaultWaitForNetworkIdleTimeout,
|
|
41
|
+
resolveAiActionContext: ()=>resolveAiActionContext,
|
|
42
|
+
defaultViewportWidth: ()=>defaultViewportWidth,
|
|
43
|
+
puppeteerAgentForTarget: ()=>puppeteerAgentForTarget
|
|
43
44
|
});
|
|
44
45
|
const external_node_fs_namespaceObject = require("node:fs");
|
|
45
46
|
const logger_namespaceObject = require("@midscene/shared/logger");
|
|
@@ -53,6 +54,9 @@ const defaultViewportWidth = 1440;
|
|
|
53
54
|
const defaultViewportHeight = 768;
|
|
54
55
|
const defaultViewportScale = 'darwin' === process.platform ? 2 : 1;
|
|
55
56
|
const defaultWaitForNetworkIdleTimeout = constants_namespaceObject.DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
|
|
57
|
+
function resolveAiActionContext(target, preference) {
|
|
58
|
+
return target.aiActionContext ?? preference?.aiActionContext;
|
|
59
|
+
}
|
|
56
60
|
const DANGEROUS_ARGS = [
|
|
57
61
|
'--no-sandbox',
|
|
58
62
|
'--disable-setuid-sandbox',
|
|
@@ -180,9 +184,10 @@ async function launchPuppeteerPage(target, preference, browser) {
|
|
|
180
184
|
}
|
|
181
185
|
async function puppeteerAgentForTarget(target, preference, browser) {
|
|
182
186
|
const { page, freeFn } = await launchPuppeteerPage(target, preference, browser);
|
|
187
|
+
const aiActionContext = resolveAiActionContext(target, preference);
|
|
183
188
|
const agent = new external_index_js_namespaceObject.PuppeteerAgent(page, {
|
|
184
189
|
...preference,
|
|
185
|
-
aiActionContext
|
|
190
|
+
aiActionContext,
|
|
186
191
|
forceSameTabNavigation: void 0 !== target.forceSameTabNavigation ? target.forceSameTabNavigation : true
|
|
187
192
|
});
|
|
188
193
|
freeFn.push({
|
|
@@ -201,15 +206,17 @@ exports.defaultViewportWidth = __webpack_exports__.defaultViewportWidth;
|
|
|
201
206
|
exports.defaultWaitForNetworkIdleTimeout = __webpack_exports__.defaultWaitForNetworkIdleTimeout;
|
|
202
207
|
exports.launchPuppeteerPage = __webpack_exports__.launchPuppeteerPage;
|
|
203
208
|
exports.puppeteerAgentForTarget = __webpack_exports__.puppeteerAgentForTarget;
|
|
204
|
-
|
|
209
|
+
exports.resolveAiActionContext = __webpack_exports__.resolveAiActionContext;
|
|
210
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
205
211
|
"defaultUA",
|
|
206
212
|
"defaultViewportHeight",
|
|
207
213
|
"defaultViewportScale",
|
|
208
214
|
"defaultViewportWidth",
|
|
209
215
|
"defaultWaitForNetworkIdleTimeout",
|
|
210
216
|
"launchPuppeteerPage",
|
|
211
|
-
"puppeteerAgentForTarget"
|
|
212
|
-
|
|
217
|
+
"puppeteerAgentForTarget",
|
|
218
|
+
"resolveAiActionContext"
|
|
219
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
213
220
|
Object.defineProperty(exports, '__esModule', {
|
|
214
221
|
value: true
|
|
215
222
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"puppeteer/agent-launcher.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/puppeteer/agent-launcher.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 { readFileSync } from 'node:fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nimport { PuppeteerAgent } from '@/puppeteer/index';\nimport type { AgentOpt, Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';\nimport { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from '@midscene/shared/constants';\nimport puppeteer, { type Browser } from 'puppeteer';\n\nexport const defaultUA =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';\nexport const defaultViewportWidth = 1440;\nexport const defaultViewportHeight = 768;\nexport const defaultViewportScale = process.platform === 'darwin' ? 2 : 1;\nexport const defaultWaitForNetworkIdleTimeout =\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n\n/**\n * Chrome arguments that may reduce browser security.\n * These should only be used in controlled testing environments.\n *\n * Security implications:\n * - `--no-sandbox`: Disables Chrome's sandbox security model\n * - `--disable-setuid-sandbox`: Disables setuid sandbox on Linux\n * - `--disable-web-security`: Allows cross-origin requests without CORS\n * - `--ignore-certificate-errors`: Ignores SSL/TLS certificate errors\n * - `--disable-features=IsolateOrigins`: Disables origin isolation\n * - `--disable-site-isolation-trials`: Disables site isolation\n * - `--allow-running-insecure-content`: Allows mixed HTTP/HTTPS content\n */\nconst DANGEROUS_ARGS = [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-web-security',\n '--ignore-certificate-errors',\n '--disable-features=IsolateOrigins',\n '--disable-site-isolation-trials',\n '--allow-running-insecure-content',\n] as const;\n\n/**\n * Validates Chrome launch arguments for security concerns.\n * Emits a warning if dangerous arguments are detected.\n *\n * This function filters out arguments that are already present in baseArgs\n * to avoid warning about platform-specific defaults (e.g., --no-sandbox on non-Windows).\n *\n * @param args - Chrome launch arguments to validate\n * @param baseArgs - Base Chrome arguments already configured\n *\n * @example\n * ```typescript\n * // Will show warning for --disable-web-security\n * validateChromeArgs(['--disable-web-security', '--headless'], ['--no-sandbox']);\n *\n * // Will NOT show warning for --no-sandbox (already in baseArgs)\n * validateChromeArgs(['--no-sandbox'], ['--no-sandbox', '--headless']);\n * ```\n */\nfunction validateChromeArgs(args: string[], baseArgs: string[]): void {\n // Filter out arguments that are already in baseArgs\n const newArgs = args.filter(\n (arg) =>\n !baseArgs.some((baseArg) => {\n // Check if arg starts with the same flag as baseArg (before '=' if present)\n const argFlag = arg.split('=')[0];\n const baseFlag = baseArg.split('=')[0];\n return argFlag === baseFlag;\n }),\n );\n\n const dangerousArgs = newArgs.filter((arg) =>\n DANGEROUS_ARGS.some((dangerous) => arg.startsWith(dangerous)),\n );\n\n if (dangerousArgs.length > 0) {\n console.warn(\n `Warning: Dangerous Chrome arguments detected: ${dangerousArgs.join(', ')}.\\nThese arguments may reduce browser security. Use only in controlled testing environments.`,\n );\n }\n}\n\ninterface FreeFn {\n name: string;\n fn: () => void;\n}\n\nconst launcherDebug = getDebug('puppeteer:launcher');\n\nexport async function launchPuppeteerPage(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n },\n browser?: Browser,\n) {\n assert(target.url, 'url is required');\n const freeFn: FreeFn[] = [];\n\n // prepare the environment\n const ua = target.userAgent || defaultUA;\n let width = defaultViewportWidth;\n let preferMaximizedWindow = true;\n if (target.viewportWidth) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportWidth === 'number',\n 'viewportWidth must be a number',\n );\n width = Number.parseInt(target.viewportWidth as unknown as string, 10);\n assert(width > 0, `viewportWidth must be greater than 0, but got ${width}`);\n }\n let height = defaultViewportHeight;\n if (target.viewportHeight) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportHeight === 'number',\n 'viewportHeight must be a number',\n );\n height = Number.parseInt(target.viewportHeight as unknown as string, 10);\n assert(\n height > 0,\n `viewportHeight must be greater than 0, but got ${height}`,\n );\n }\n let dpr = defaultViewportScale;\n if (target.viewportScale) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportScale === 'number',\n 'viewportScale must be a number',\n );\n dpr = Number.parseInt(target.viewportScale as unknown as string, 10);\n assert(dpr > 0, `viewportScale must be greater than 0, but got ${dpr}`);\n }\n const viewportConfig = {\n width,\n height,\n deviceScaleFactor: dpr,\n };\n\n const headed = preference?.headed || preference?.keepWindow;\n\n // only maximize window in headed mode\n preferMaximizedWindow = preferMaximizedWindow && !!headed;\n\n // launch the browser\n if (headed && process.env.CI === '1') {\n console.warn(\n 'you are probably running headed mode in CI, this will usually fail.',\n );\n }\n // do not use 'no-sandbox' on windows https://www.perplexity.ai/search/how-to-solve-this-with-nodejs-dMHpdCypRa..JA8TkQzbeQ\n const isWindows = process.platform === 'win32';\n\n const baseArgs = [\n ...(isWindows ? [] : ['--no-sandbox', '--disable-setuid-sandbox']),\n '--disable-features=HttpsFirstBalancedModeAutoEnable',\n '--disable-features=PasswordLeakDetection',\n '--disable-save-password-bubble',\n `--user-agent=\"${ua}\"`,\n preferMaximizedWindow\n ? '--start-maximized'\n : `--window-size=${width},${height + 200}`, // add 200px for the address bar\n ];\n\n // Merge custom Chrome arguments\n let args = baseArgs;\n if (target.chromeArgs && target.chromeArgs.length > 0) {\n validateChromeArgs(target.chromeArgs, baseArgs);\n\n // Custom args come after base args, allowing them to override defaults\n args = [...baseArgs, ...target.chromeArgs];\n launcherDebug(\n 'Merging custom Chrome arguments',\n target.chromeArgs,\n 'Final args',\n args,\n );\n }\n\n launcherDebug(\n 'launching browser with viewport, headed',\n headed,\n 'viewport',\n viewportConfig,\n 'args',\n args,\n 'preference',\n preference,\n );\n let browserInstance = browser;\n if (!browserInstance) {\n browserInstance = await puppeteer.launch({\n headless: !preference?.headed,\n defaultViewport: viewportConfig,\n args,\n acceptInsecureCerts: target.acceptInsecureCerts,\n });\n freeFn.push({\n name: 'puppeteer_browser',\n fn: () => {\n if (!preference?.keepWindow) {\n if (isWindows) {\n setTimeout(() => {\n browserInstance?.close();\n }, 800);\n } else {\n browserInstance?.close();\n }\n }\n },\n });\n }\n const page = await browserInstance.newPage();\n\n if (target.cookie) {\n const cookieFileContent = readFileSync(target.cookie, 'utf-8');\n await browserInstance.setCookie(...JSON.parse(cookieFileContent));\n }\n\n if (ua) {\n await page.setUserAgent(ua);\n }\n\n if (viewportConfig) {\n await page.setViewport(viewportConfig);\n }\n\n const waitForNetworkIdleTimeout =\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : defaultWaitForNetworkIdleTimeout;\n\n try {\n launcherDebug('goto', target.url);\n await page.goto(target.url);\n if (waitForNetworkIdleTimeout > 0) {\n launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);\n await page.waitForNetworkIdle({\n timeout: waitForNetworkIdleTimeout,\n });\n }\n } catch (e) {\n if (\n typeof target.waitForNetworkIdle?.continueOnNetworkIdleError ===\n 'boolean' &&\n !target.waitForNetworkIdle?.continueOnNetworkIdleError\n ) {\n const newError = new Error(`failed to wait for network idle: ${e}`, {\n cause: e,\n });\n throw newError;\n }\n const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;\n console.warn(newMessage);\n }\n\n return { page, freeFn };\n}\n\nexport async function puppeteerAgentForTarget(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n } & Partial<\n Pick<\n AgentOpt,\n | 'testId'\n | 'groupName'\n | 'groupDescription'\n | 'generateReport'\n | 'autoPrintReportMsg'\n | 'reportFileName'\n | 'replanningCycleLimit'\n | 'cache'\n | 'aiActionContext'\n >\n >,\n browser?: Browser,\n) {\n const { page, freeFn } = await launchPuppeteerPage(\n target,\n preference,\n browser,\n );\n\n // prepare Midscene agent\n const agent = new PuppeteerAgent(page, {\n ...preference,\n aiActionContext: target.aiActionContext,\n forceSameTabNavigation:\n typeof target.forceSameTabNavigation !== 'undefined'\n ? target.forceSameTabNavigation\n : true, // true for default in yaml script\n });\n\n freeFn.push({\n name: 'midscene_puppeteer_agent',\n fn: () => agent.destroy(),\n });\n\n return { agent, freeFn };\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","defaultUA","defaultViewportWidth","defaultViewportHeight","defaultViewportScale","process","defaultWaitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","DANGEROUS_ARGS","validateChromeArgs","args","baseArgs","newArgs","arg","baseArg","argFlag","baseFlag","dangerousArgs","dangerous","console","launcherDebug","getDebug","launchPuppeteerPage","target","preference","browser","assert","freeFn","ua","width","preferMaximizedWindow","Number","height","dpr","viewportConfig","headed","isWindows","browserInstance","puppeteer","setTimeout","page","cookieFileContent","readFileSync","JSON","waitForNetworkIdleTimeout","e","newError","Error","newMessage","puppeteerAgentForTarget","agent","PuppeteerAgent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"puppeteer/agent-launcher.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/puppeteer/agent-launcher.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 { readFileSync } from 'node:fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nimport { PuppeteerAgent } from '@/puppeteer/index';\nimport type { AgentOpt, Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';\nimport { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from '@midscene/shared/constants';\nimport puppeteer, { type Browser } from 'puppeteer';\n\nexport const defaultUA =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';\nexport const defaultViewportWidth = 1440;\nexport const defaultViewportHeight = 768;\nexport const defaultViewportScale = process.platform === 'darwin' ? 2 : 1;\nexport const defaultWaitForNetworkIdleTimeout =\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n\nexport function resolveAiActionContext(\n target: MidsceneYamlScriptWebEnv,\n preference?: Partial<Pick<AgentOpt, 'aiActionContext'>>,\n): AgentOpt['aiActionContext'] | undefined {\n // Prefer the web target override if provided; otherwise fall back to agent-level preference.\n return target.aiActionContext ?? preference?.aiActionContext;\n}\n\n/**\n * Chrome arguments that may reduce browser security.\n * These should only be used in controlled testing environments.\n *\n * Security implications:\n * - `--no-sandbox`: Disables Chrome's sandbox security model\n * - `--disable-setuid-sandbox`: Disables setuid sandbox on Linux\n * - `--disable-web-security`: Allows cross-origin requests without CORS\n * - `--ignore-certificate-errors`: Ignores SSL/TLS certificate errors\n * - `--disable-features=IsolateOrigins`: Disables origin isolation\n * - `--disable-site-isolation-trials`: Disables site isolation\n * - `--allow-running-insecure-content`: Allows mixed HTTP/HTTPS content\n */\nconst DANGEROUS_ARGS = [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-web-security',\n '--ignore-certificate-errors',\n '--disable-features=IsolateOrigins',\n '--disable-site-isolation-trials',\n '--allow-running-insecure-content',\n] as const;\n\n/**\n * Validates Chrome launch arguments for security concerns.\n * Emits a warning if dangerous arguments are detected.\n *\n * This function filters out arguments that are already present in baseArgs\n * to avoid warning about platform-specific defaults (e.g., --no-sandbox on non-Windows).\n *\n * @param args - Chrome launch arguments to validate\n * @param baseArgs - Base Chrome arguments already configured\n *\n * @example\n * ```typescript\n * // Will show warning for --disable-web-security\n * validateChromeArgs(['--disable-web-security', '--headless'], ['--no-sandbox']);\n *\n * // Will NOT show warning for --no-sandbox (already in baseArgs)\n * validateChromeArgs(['--no-sandbox'], ['--no-sandbox', '--headless']);\n * ```\n */\nfunction validateChromeArgs(args: string[], baseArgs: string[]): void {\n // Filter out arguments that are already in baseArgs\n const newArgs = args.filter(\n (arg) =>\n !baseArgs.some((baseArg) => {\n // Check if arg starts with the same flag as baseArg (before '=' if present)\n const argFlag = arg.split('=')[0];\n const baseFlag = baseArg.split('=')[0];\n return argFlag === baseFlag;\n }),\n );\n\n const dangerousArgs = newArgs.filter((arg) =>\n DANGEROUS_ARGS.some((dangerous) => arg.startsWith(dangerous)),\n );\n\n if (dangerousArgs.length > 0) {\n console.warn(\n `Warning: Dangerous Chrome arguments detected: ${dangerousArgs.join(', ')}.\\nThese arguments may reduce browser security. Use only in controlled testing environments.`,\n );\n }\n}\n\ninterface FreeFn {\n name: string;\n fn: () => void;\n}\n\nconst launcherDebug = getDebug('puppeteer:launcher');\n\nexport async function launchPuppeteerPage(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n },\n browser?: Browser,\n) {\n assert(target.url, 'url is required');\n const freeFn: FreeFn[] = [];\n\n // prepare the environment\n const ua = target.userAgent || defaultUA;\n let width = defaultViewportWidth;\n let preferMaximizedWindow = true;\n if (target.viewportWidth) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportWidth === 'number',\n 'viewportWidth must be a number',\n );\n width = Number.parseInt(target.viewportWidth as unknown as string, 10);\n assert(width > 0, `viewportWidth must be greater than 0, but got ${width}`);\n }\n let height = defaultViewportHeight;\n if (target.viewportHeight) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportHeight === 'number',\n 'viewportHeight must be a number',\n );\n height = Number.parseInt(target.viewportHeight as unknown as string, 10);\n assert(\n height > 0,\n `viewportHeight must be greater than 0, but got ${height}`,\n );\n }\n let dpr = defaultViewportScale;\n if (target.viewportScale) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportScale === 'number',\n 'viewportScale must be a number',\n );\n dpr = Number.parseInt(target.viewportScale as unknown as string, 10);\n assert(dpr > 0, `viewportScale must be greater than 0, but got ${dpr}`);\n }\n const viewportConfig = {\n width,\n height,\n deviceScaleFactor: dpr,\n };\n\n const headed = preference?.headed || preference?.keepWindow;\n\n // only maximize window in headed mode\n preferMaximizedWindow = preferMaximizedWindow && !!headed;\n\n // launch the browser\n if (headed && process.env.CI === '1') {\n console.warn(\n 'you are probably running headed mode in CI, this will usually fail.',\n );\n }\n // do not use 'no-sandbox' on windows https://www.perplexity.ai/search/how-to-solve-this-with-nodejs-dMHpdCypRa..JA8TkQzbeQ\n const isWindows = process.platform === 'win32';\n\n const baseArgs = [\n ...(isWindows ? [] : ['--no-sandbox', '--disable-setuid-sandbox']),\n '--disable-features=HttpsFirstBalancedModeAutoEnable',\n '--disable-features=PasswordLeakDetection',\n '--disable-save-password-bubble',\n `--user-agent=\"${ua}\"`,\n preferMaximizedWindow\n ? '--start-maximized'\n : `--window-size=${width},${height + 200}`, // add 200px for the address bar\n ];\n\n // Merge custom Chrome arguments\n let args = baseArgs;\n if (target.chromeArgs && target.chromeArgs.length > 0) {\n validateChromeArgs(target.chromeArgs, baseArgs);\n\n // Custom args come after base args, allowing them to override defaults\n args = [...baseArgs, ...target.chromeArgs];\n launcherDebug(\n 'Merging custom Chrome arguments',\n target.chromeArgs,\n 'Final args',\n args,\n );\n }\n\n launcherDebug(\n 'launching browser with viewport, headed',\n headed,\n 'viewport',\n viewportConfig,\n 'args',\n args,\n 'preference',\n preference,\n );\n let browserInstance = browser;\n if (!browserInstance) {\n browserInstance = await puppeteer.launch({\n headless: !preference?.headed,\n defaultViewport: viewportConfig,\n args,\n acceptInsecureCerts: target.acceptInsecureCerts,\n });\n freeFn.push({\n name: 'puppeteer_browser',\n fn: () => {\n if (!preference?.keepWindow) {\n if (isWindows) {\n setTimeout(() => {\n browserInstance?.close();\n }, 800);\n } else {\n browserInstance?.close();\n }\n }\n },\n });\n }\n const page = await browserInstance.newPage();\n\n if (target.cookie) {\n const cookieFileContent = readFileSync(target.cookie, 'utf-8');\n await browserInstance.setCookie(...JSON.parse(cookieFileContent));\n }\n\n if (ua) {\n await page.setUserAgent(ua);\n }\n\n if (viewportConfig) {\n await page.setViewport(viewportConfig);\n }\n\n const waitForNetworkIdleTimeout =\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : defaultWaitForNetworkIdleTimeout;\n\n try {\n launcherDebug('goto', target.url);\n await page.goto(target.url);\n if (waitForNetworkIdleTimeout > 0) {\n launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);\n await page.waitForNetworkIdle({\n timeout: waitForNetworkIdleTimeout,\n });\n }\n } catch (e) {\n if (\n typeof target.waitForNetworkIdle?.continueOnNetworkIdleError ===\n 'boolean' &&\n !target.waitForNetworkIdle?.continueOnNetworkIdleError\n ) {\n const newError = new Error(`failed to wait for network idle: ${e}`, {\n cause: e,\n });\n throw newError;\n }\n const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;\n console.warn(newMessage);\n }\n\n return { page, freeFn };\n}\n\nexport async function puppeteerAgentForTarget(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n } & Partial<\n Pick<\n AgentOpt,\n | 'testId'\n | 'groupName'\n | 'groupDescription'\n | 'generateReport'\n | 'autoPrintReportMsg'\n | 'reportFileName'\n | 'replanningCycleLimit'\n | 'cache'\n | 'aiActionContext'\n >\n >,\n browser?: Browser,\n) {\n const { page, freeFn } = await launchPuppeteerPage(\n target,\n preference,\n browser,\n );\n const aiActionContext = resolveAiActionContext(target, preference);\n\n // prepare Midscene agent\n const agent = new PuppeteerAgent(page, {\n ...preference,\n aiActionContext,\n forceSameTabNavigation:\n typeof target.forceSameTabNavigation !== 'undefined'\n ? target.forceSameTabNavigation\n : true, // true for default in yaml script\n });\n\n freeFn.push({\n name: 'midscene_puppeteer_agent',\n fn: () => agent.destroy(),\n });\n\n return { agent, freeFn };\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","defaultUA","defaultViewportWidth","defaultViewportHeight","defaultViewportScale","process","defaultWaitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","resolveAiActionContext","target","preference","DANGEROUS_ARGS","validateChromeArgs","args","baseArgs","newArgs","arg","baseArg","argFlag","baseFlag","dangerousArgs","dangerous","console","launcherDebug","getDebug","launchPuppeteerPage","browser","assert","freeFn","ua","width","preferMaximizedWindow","Number","height","dpr","viewportConfig","headed","isWindows","browserInstance","puppeteer","setTimeout","page","cookieFileContent","readFileSync","JSON","waitForNetworkIdleTimeout","e","newError","Error","newMessage","puppeteerAgentForTarget","aiActionContext","agent","PuppeteerAgent"],"mappings":";;;IACAA,oBAAoB,CAAC,GAAG,CAACC;QACxB,IAAIC,SAASD,UAAUA,OAAO,UAAU,GACvC,IAAOA,MAAM,CAAC,UAAU,GACxB,IAAOA;QACRD,oBAAoB,CAAC,CAACE,QAAQ;YAAE,GAAGA;QAAO;QAC1C,OAAOA;IACR;;;ICPAF,oBAAoB,CAAC,GAAG,CAAC,UAASG;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGH,oBAAoB,CAAC,CAACG,YAAYC,QAAQ,CAACJ,oBAAoB,CAAC,CAAC,UAASI,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAJ,oBAAoB,CAAC,GAAG,CAACM,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFP,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOQ,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;;;;;;;;;;ACGO,MAAMI,YACX;AACK,MAAMC,uBAAuB;AAC7B,MAAMC,wBAAwB;AAC9B,MAAMC,uBAAuBC,AAAqB,aAArBA,QAAQ,QAAQ,GAAgB,IAAI;AACjE,MAAMC,mCACXC,0BAAAA,qCAAqCA;AAEhC,SAASC,uBACdC,MAAgC,EAChCC,UAAuD;IAGvD,OAAOD,OAAO,eAAe,IAAIC,YAAY;AAC/C;AAeA,MAAMC,iBAAiB;IACrB;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAqBD,SAASC,mBAAmBC,IAAc,EAAEC,QAAkB;IAE5D,MAAMC,UAAUF,KAAK,MAAM,CACzB,CAACG,MACC,CAACF,SAAS,IAAI,CAAC,CAACG;YAEd,MAAMC,UAAUF,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;YACjC,MAAMG,WAAWF,QAAQ,KAAK,CAAC,IAAI,CAAC,EAAE;YACtC,OAAOC,YAAYC;QACrB;IAGJ,MAAMC,gBAAgBL,QAAQ,MAAM,CAAC,CAACC,MACpCL,eAAe,IAAI,CAAC,CAACU,YAAcL,IAAI,UAAU,CAACK;IAGpD,IAAID,cAAc,MAAM,GAAG,GACzBE,QAAQ,IAAI,CACV,CAAC,8CAA8C,EAAEF,cAAc,IAAI,CAAC,MAAM,4FAA4F,CAAC;AAG7K;AAOA,MAAMG,gBAAgBC,AAAAA,IAAAA,uBAAAA,QAAAA,AAAAA,EAAS;AAExB,eAAeC,oBACpBhB,MAAgC,EAChCC,UAGC,EACDgB,OAAiB;IAEjBC,IAAAA,sBAAAA,MAAAA,AAAAA,EAAOlB,OAAO,GAAG,EAAE;IACnB,MAAMmB,SAAmB,EAAE;IAG3B,MAAMC,KAAKpB,OAAO,SAAS,IAAIR;IAC/B,IAAI6B,QAAQ5B;IACZ,IAAI6B,wBAAwB;IAC5B,IAAItB,OAAO,aAAa,EAAE;QACxBsB,wBAAwB;QACxBJ,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,AAAgC,YAAhC,OAAOlB,OAAO,aAAa,EAC3B;QAEFqB,QAAQE,OAAO,QAAQ,CAACvB,OAAO,aAAa,EAAuB;QACnEkB,IAAAA,sBAAAA,MAAAA,AAAAA,EAAOG,QAAQ,GAAG,CAAC,8CAA8C,EAAEA,OAAO;IAC5E;IACA,IAAIG,SAAS9B;IACb,IAAIM,OAAO,cAAc,EAAE;QACzBsB,wBAAwB;QACxBJ,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,AAAiC,YAAjC,OAAOlB,OAAO,cAAc,EAC5B;QAEFwB,SAASD,OAAO,QAAQ,CAACvB,OAAO,cAAc,EAAuB;QACrEkB,IAAAA,sBAAAA,MAAAA,AAAAA,EACEM,SAAS,GACT,CAAC,+CAA+C,EAAEA,QAAQ;IAE9D;IACA,IAAIC,MAAM9B;IACV,IAAIK,OAAO,aAAa,EAAE;QACxBsB,wBAAwB;QACxBJ,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,AAAgC,YAAhC,OAAOlB,OAAO,aAAa,EAC3B;QAEFyB,MAAMF,OAAO,QAAQ,CAACvB,OAAO,aAAa,EAAuB;QACjEkB,IAAAA,sBAAAA,MAAAA,AAAAA,EAAOO,MAAM,GAAG,CAAC,8CAA8C,EAAEA,KAAK;IACxE;IACA,MAAMC,iBAAiB;QACrBL;QACAG;QACA,mBAAmBC;IACrB;IAEA,MAAME,SAAS1B,YAAY,UAAUA,YAAY;IAGjDqB,wBAAwBA,yBAAyB,CAAC,CAACK;IAGnD,IAAIA,UAAU/B,AAAmB,QAAnBA,QAAQ,GAAG,CAAC,EAAE,EAC1BiB,QAAQ,IAAI,CACV;IAIJ,MAAMe,YAAYhC,AAAqB,YAArBA,QAAQ,QAAQ;IAElC,MAAMS,WAAW;WACXuB,YAAY,EAAE,GAAG;YAAC;YAAgB;SAA2B;QACjE;QACA;QACA;QACA,CAAC,cAAc,EAAER,GAAG,CAAC,CAAC;QACtBE,wBACI,sBACA,CAAC,cAAc,EAAED,MAAM,CAAC,EAAEG,SAAS,KAAK;KAC7C;IAGD,IAAIpB,OAAOC;IACX,IAAIL,OAAO,UAAU,IAAIA,OAAO,UAAU,CAAC,MAAM,GAAG,GAAG;QACrDG,mBAAmBH,OAAO,UAAU,EAAEK;QAGtCD,OAAO;eAAIC;eAAaL,OAAO,UAAU;SAAC;QAC1Cc,cACE,mCACAd,OAAO,UAAU,EACjB,cACAI;IAEJ;IAEAU,cACE,2CACAa,QACA,YACAD,gBACA,QACAtB,MACA,cACAH;IAEF,IAAI4B,kBAAkBZ;IACtB,IAAI,CAACY,iBAAiB;QACpBA,kBAAkB,MAAMC,6BAAAA,MAAgB,CAAC;YACvC,UAAU,CAAC7B,YAAY;YACvB,iBAAiByB;YACjBtB;YACA,qBAAqBJ,OAAO,mBAAmB;QACjD;QACAmB,OAAO,IAAI,CAAC;YACV,MAAM;YACN,IAAI;gBACF,IAAI,CAAClB,YAAY,YACf,IAAI2B,WACFG,WAAW;oBACTF,iBAAiB;gBACnB,GAAG;qBAEHA,iBAAiB;YAGvB;QACF;IACF;IACA,MAAMG,OAAO,MAAMH,gBAAgB,OAAO;IAE1C,IAAI7B,OAAO,MAAM,EAAE;QACjB,MAAMiC,oBAAoBC,AAAAA,IAAAA,iCAAAA,YAAAA,AAAAA,EAAalC,OAAO,MAAM,EAAE;QACtD,MAAM6B,gBAAgB,SAAS,IAAIM,KAAK,KAAK,CAACF;IAChD;IAEA,IAAIb,IACF,MAAMY,KAAK,YAAY,CAACZ;IAG1B,IAAIM,gBACF,MAAMM,KAAK,WAAW,CAACN;IAGzB,MAAMU,4BACJ,AAA8C,YAA9C,OAAOpC,OAAO,kBAAkB,EAAE,UAC9BA,OAAO,kBAAkB,CAAC,OAAO,GACjCH;IAEN,IAAI;QACFiB,cAAc,QAAQd,OAAO,GAAG;QAChC,MAAMgC,KAAK,IAAI,CAAChC,OAAO,GAAG;QAC1B,IAAIoC,4BAA4B,GAAG;YACjCtB,cAAc,sBAAsBsB;YACpC,MAAMJ,KAAK,kBAAkB,CAAC;gBAC5B,SAASI;YACX;QACF;IACF,EAAE,OAAOC,GAAG;QACV,IACE,AACE,aADF,OAAOrC,OAAO,kBAAkB,EAAE,8BAElC,CAACA,OAAO,kBAAkB,EAAE,4BAC5B;YACA,MAAMsC,WAAW,IAAIC,MAAM,CAAC,iCAAiC,EAAEF,GAAG,EAAE;gBAClE,OAAOA;YACT;YACA,MAAMC;QACR;QACA,MAAME,aAAa,CAAC,sCAAsC,EAAEJ,0BAA0B,iCAAiC,CAAC;QACxHvB,QAAQ,IAAI,CAAC2B;IACf;IAEA,OAAO;QAAER;QAAMb;IAAO;AACxB;AAEO,eAAesB,wBACpBzC,MAAgC,EAChCC,UAgBC,EACDgB,OAAiB;IAEjB,MAAM,EAAEe,IAAI,EAAEb,MAAM,EAAE,GAAG,MAAMH,oBAC7BhB,QACAC,YACAgB;IAEF,MAAMyB,kBAAkB3C,uBAAuBC,QAAQC;IAGvD,MAAM0C,QAAQ,IAAIC,kCAAAA,cAAcA,CAACZ,MAAM;QACrC,GAAG/B,UAAU;QACbyC;QACA,wBACE,AAAyC,WAAlC1C,OAAO,sBAAsB,GAChCA,OAAO,sBAAsB,GAC7B;IACR;IAEAmB,OAAO,IAAI,CAAC;QACV,MAAM;QACN,IAAI,IAAMwB,MAAM,OAAO;IACzB;IAEA,OAAO;QAAEA;QAAOxB;IAAO;AACzB"}
|
|
@@ -56,7 +56,7 @@ const sanitizeXpaths = (xpaths)=>{
|
|
|
56
56
|
};
|
|
57
57
|
class Page {
|
|
58
58
|
actionSpace() {
|
|
59
|
-
const defaultActions = (0, external_web_page_js_namespaceObject.commonWebActionsForWebPage)(this);
|
|
59
|
+
const defaultActions = (0, external_web_page_js_namespaceObject.commonWebActionsForWebPage)(this, this.enableTouchEventsInActionSpace);
|
|
60
60
|
const customActions = this.customActions || [];
|
|
61
61
|
return [
|
|
62
62
|
...defaultActions,
|
|
@@ -490,6 +490,7 @@ class Page {
|
|
|
490
490
|
_define_property(this, "onBeforeInvokeAction", void 0);
|
|
491
491
|
_define_property(this, "onAfterInvokeAction", void 0);
|
|
492
492
|
_define_property(this, "customActions", void 0);
|
|
493
|
+
_define_property(this, "enableTouchEventsInActionSpace", void 0);
|
|
493
494
|
_define_property(this, "interfaceType", void 0);
|
|
494
495
|
_define_property(this, "everMoved", false);
|
|
495
496
|
this.underlyingPage = underlyingPage;
|
|
@@ -499,6 +500,7 @@ class Page {
|
|
|
499
500
|
this.onBeforeInvokeAction = opts?.beforeInvokeAction;
|
|
500
501
|
this.onAfterInvokeAction = opts?.afterInvokeAction;
|
|
501
502
|
this.customActions = opts?.customActions;
|
|
503
|
+
this.enableTouchEventsInActionSpace = opts?.enableTouchEventsInActionSpace ?? false;
|
|
502
504
|
}
|
|
503
505
|
}
|
|
504
506
|
function forceClosePopup(page, debugProfile) {
|
|
@@ -539,12 +541,12 @@ exports.Page = __webpack_exports__.Page;
|
|
|
539
541
|
exports.debugPage = __webpack_exports__.debugPage;
|
|
540
542
|
exports.forceChromeSelectRendering = __webpack_exports__.forceChromeSelectRendering;
|
|
541
543
|
exports.forceClosePopup = __webpack_exports__.forceClosePopup;
|
|
542
|
-
for(var
|
|
544
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
543
545
|
"Page",
|
|
544
546
|
"debugPage",
|
|
545
547
|
"forceChromeSelectRendering",
|
|
546
548
|
"forceClosePopup"
|
|
547
|
-
].indexOf(
|
|
549
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
548
550
|
Object.defineProperty(exports, '__esModule', {
|
|
549
551
|
value: true
|
|
550
552
|
});
|