@midscene/web 1.4.5 → 1.4.7

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 (53) hide show
  1. package/dist/es/bin.mjs +3 -2
  2. package/dist/es/bin.mjs.map +1 -1
  3. package/dist/es/bridge-mode/agent-cli-side.mjs +0 -1
  4. package/dist/es/bridge-mode/agent-cli-side.mjs.map +1 -1
  5. package/dist/es/bridge-mode/io-client.mjs +1 -1
  6. package/dist/es/bridge-mode/io-server.mjs +2 -2
  7. package/dist/es/bridge-mode/page-browser-side.mjs +1 -1
  8. package/dist/es/chrome-extension/page.mjs +4 -8
  9. package/dist/es/chrome-extension/page.mjs.map +1 -1
  10. package/dist/es/common/cache-helper.mjs +1 -2
  11. package/dist/es/common/cache-helper.mjs.map +1 -1
  12. package/dist/es/index.mjs +1 -2
  13. package/dist/es/mcp-server.mjs +1 -1
  14. package/dist/es/mcp-tools-puppeteer.mjs +3 -3
  15. package/dist/es/mcp-tools-puppeteer.mjs.map +1 -1
  16. package/dist/es/mcp-tools.mjs +3 -3
  17. package/dist/es/mcp-tools.mjs.map +1 -1
  18. package/dist/es/puppeteer/base-page.mjs +2 -7
  19. package/dist/es/puppeteer/base-page.mjs.map +1 -1
  20. package/dist/es/static/static-page.mjs +4 -22
  21. package/dist/es/static/static-page.mjs.map +1 -1
  22. package/dist/es/web-element.mjs +1 -10
  23. package/dist/es/web-element.mjs.map +1 -1
  24. package/dist/lib/bin.js +3 -2
  25. package/dist/lib/bin.js.map +1 -1
  26. package/dist/lib/bridge-mode/agent-cli-side.js +0 -1
  27. package/dist/lib/bridge-mode/agent-cli-side.js.map +1 -1
  28. package/dist/lib/bridge-mode/io-client.js +1 -1
  29. package/dist/lib/bridge-mode/io-server.js +2 -2
  30. package/dist/lib/bridge-mode/page-browser-side.js +1 -1
  31. package/dist/lib/chrome-extension/page.js +3 -7
  32. package/dist/lib/chrome-extension/page.js.map +1 -1
  33. package/dist/lib/common/cache-helper.js +1 -2
  34. package/dist/lib/common/cache-helper.js.map +1 -1
  35. package/dist/lib/index.js +2 -6
  36. package/dist/lib/mcp-server.js +1 -1
  37. package/dist/lib/mcp-tools-puppeteer.js +2 -2
  38. package/dist/lib/mcp-tools-puppeteer.js.map +1 -1
  39. package/dist/lib/mcp-tools.js +2 -2
  40. package/dist/lib/mcp-tools.js.map +1 -1
  41. package/dist/lib/puppeteer/base-page.js +2 -7
  42. package/dist/lib/puppeteer/base-page.js.map +1 -1
  43. package/dist/lib/static/static-page.js +4 -22
  44. package/dist/lib/static/static-page.js.map +1 -1
  45. package/dist/lib/web-element.js +2 -14
  46. package/dist/lib/web-element.js.map +1 -1
  47. package/dist/types/chrome-extension/page.d.ts +1 -2
  48. package/dist/types/common/cache-helper.d.ts +1 -1
  49. package/dist/types/index.d.ts +0 -3
  50. package/dist/types/puppeteer/base-page.d.ts +2 -3
  51. package/dist/types/static/static-page.d.ts +3 -16
  52. package/dist/types/web-element.d.ts +1 -10
  53. package/package.json +4 -4
@@ -1,4 +1,3 @@
1
- import { WebPageContextParser } from "../web-element.mjs";
2
1
  import { sleep } from "@midscene/core/utils";
3
2
  import { DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT, DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY, DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from "@midscene/shared/constants";
4
3
  import { treeToList } from "@midscene/shared/extractor";
@@ -110,7 +109,7 @@ class Page {
110
109
  const elementInfo = await this.getElementInfoByXpath(xpath);
111
110
  if (elementInfo?.rect) {
112
111
  debugPage('rectMatchesCacheFeature: found element, rect: %o', elementInfo.rect);
113
- return buildRectFromElementInfo(elementInfo, this.viewportSize?.dpr);
112
+ return buildRectFromElementInfo(elementInfo);
114
113
  }
115
114
  debugPage('rectMatchesCacheFeature: element found but no rect (elementInfo: %o)', elementInfo);
116
115
  } catch (error) {
@@ -132,8 +131,7 @@ class Page {
132
131
  if (this.viewportSize) return this.viewportSize;
133
132
  const sizeInfo = await this.evaluate(()=>({
134
133
  width: window.innerWidth,
135
- height: window.innerHeight,
136
- dpr: window.devicePixelRatio
134
+ height: window.innerHeight
137
135
  }));
138
136
  this.viewportSize = sizeInfo;
139
137
  return sizeInfo;
@@ -364,9 +362,6 @@ class Page {
364
362
  if (this.onAfterInvokeAction) await this.onAfterInvokeAction(name, param);
365
363
  }
366
364
  async destroy() {}
367
- async getContext() {
368
- return await WebPageContextParser(this, {});
369
- }
370
365
  async swipe(from, to, duration) {
371
366
  const LONG_PRESS_THRESHOLD = 500;
372
367
  const MIN_PRESS_THRESHOLD = 150;
@@ -1 +1 @@
1
- {"version":3,"file":"puppeteer/base-page.mjs","sources":["../../../src/puppeteer/base-page.ts"],"sourcesContent":["import { type WebPageAgentOpt, WebPageContextParser } from '@/web-element';\nimport type {\n DeviceAction,\n ElementCacheFeature,\n ElementTreeNode,\n Point,\n Rect,\n Size,\n UIContext,\n} from '@midscene/core';\nimport type { AbstractInterface } from '@midscene/core/device';\nimport { sleep } from '@midscene/core/utils';\nimport {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { treeToList } from '@midscene/shared/extractor';\nimport { createImgBase64ByFormat } from '@midscene/shared/img';\nimport { type DebugFunction, getDebug } from '@midscene/shared/logger';\nimport {\n getElementInfosScriptContent,\n getExtraReturnLogic,\n} from '@midscene/shared/node';\nimport { assert } from '@midscene/shared/utils';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { CDPSession, Protocol, Page as PuppeteerPage } from 'puppeteer';\nimport {\n type CacheFeatureOptions,\n type WebElementCacheFeature,\n buildRectFromElementInfo,\n judgeOrderSensitive,\n sanitizeXpaths,\n} from '../common/cache-helper';\nimport {\n type KeyInput,\n type MouseButton,\n commonWebActionsForWebPage,\n} from '../web-page';\n\nexport const debugPage = getDebug('web:page');\n\nexport class Page<\n AgentType extends 'puppeteer' | 'playwright',\n InterfaceType extends PuppeteerPage | PlaywrightPage,\n> implements AbstractInterface\n{\n underlyingPage: InterfaceType;\n protected waitForNavigationTimeout: number;\n protected waitForNetworkIdleTimeout: number;\n private viewportSize?: Size;\n private onBeforeInvokeAction?: AbstractInterface['beforeInvokeAction'];\n private onAfterInvokeAction?: AbstractInterface['afterInvokeAction'];\n private customActions?: DeviceAction<any>[];\n private enableTouchEventsInActionSpace: boolean;\n private puppeteerFileChooserSession?: CDPSession;\n private puppeteerFileChooserHandler?: (\n event: Protocol.Page.FileChooserOpenedEvent,\n ) => Promise<void>;\n interfaceType: AgentType;\n\n actionSpace(): DeviceAction[] {\n const defaultActions = commonWebActionsForWebPage(\n this,\n this.enableTouchEventsInActionSpace,\n );\n const customActions = this.customActions || [];\n return [...defaultActions, ...customActions];\n }\n\n private async evaluate<R>(\n pageFunction: string | ((...args: any[]) => R | Promise<R>),\n arg?: any,\n ): Promise<R> {\n let result: R;\n debugPage('evaluate function begin');\n if (this.interfaceType === 'puppeteer') {\n result = await (this.underlyingPage as PuppeteerPage).evaluate(\n pageFunction,\n arg,\n );\n } else {\n result = await (this.underlyingPage as PlaywrightPage).evaluate(\n pageFunction,\n arg,\n );\n }\n debugPage('evaluate function end');\n return result;\n }\n\n constructor(\n underlyingPage: InterfaceType,\n interfaceType: AgentType,\n opts?: WebPageAgentOpt,\n ) {\n this.underlyingPage = underlyingPage;\n this.interfaceType = interfaceType;\n this.waitForNavigationTimeout =\n opts?.waitForNavigationTimeout ?? DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;\n this.waitForNetworkIdleTimeout =\n opts?.waitForNetworkIdleTimeout ?? DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n this.onBeforeInvokeAction = opts?.beforeInvokeAction;\n this.onAfterInvokeAction = opts?.afterInvokeAction;\n this.customActions = opts?.customActions;\n this.enableTouchEventsInActionSpace =\n opts?.enableTouchEventsInActionSpace ?? false;\n }\n\n async evaluateJavaScript<T = any>(script: string): Promise<T> {\n return this.evaluate(script);\n }\n\n async waitForNavigation() {\n if (this.waitForNavigationTimeout === 0) {\n debugPage('waitForNavigation timeout is 0, skip waiting');\n return;\n }\n\n // issue: https://github.com/puppeteer/puppeteer/issues/3323\n if (\n this.interfaceType === 'puppeteer' ||\n this.interfaceType === 'playwright'\n ) {\n debugPage('waitForNavigation begin');\n debugPage(`waitForNavigation timeout: ${this.waitForNavigationTimeout}`);\n try {\n await (this.underlyingPage as PuppeteerPage).waitForSelector('html', {\n timeout: this.waitForNavigationTimeout,\n });\n } catch (error) {\n // Ignore timeout error, continue execution\n console.warn(\n '[midscene:warning] Waiting for the \"navigation\" has timed out, but Midscene will continue execution. Please check https://midscenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n debugPage('waitForNavigation end');\n }\n }\n\n async waitForNetworkIdle(): Promise<void> {\n if (this.interfaceType === 'puppeteer') {\n if (this.waitForNetworkIdleTimeout === 0) {\n debugPage('waitForNetworkIdle timeout is 0, skip waiting');\n return;\n }\n\n try {\n await (this.underlyingPage as PuppeteerPage).waitForNetworkIdle({\n idleTime: 200,\n concurrency: DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,\n timeout: this.waitForNetworkIdleTimeout,\n });\n } catch (error) {\n // Ignore timeout error, continue execution\n console.warn(\n '[midscene:warning] Waiting for the \"network idle\" has timed out, but Midscene will continue execution. Please check https://midscenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n } else {\n // TODO: implement playwright waitForNetworkIdle\n }\n }\n\n // @deprecated\n async getElementsInfo() {\n // const scripts = await getExtraReturnLogic();\n // const captureElementSnapshot = await this.evaluate(scripts);\n // return captureElementSnapshot as ElementInfo[];\n await this.waitForNavigation();\n debugPage('getElementsInfo begin');\n const tree = await this.getElementsNodeTree();\n debugPage('getElementsInfo end');\n return treeToList(tree);\n }\n\n private async getXpathsByPoint(point: Point, isOrderSensitive: boolean) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getXpathsByPoint({left: ${point.left}, top: ${point.top}}, ${isOrderSensitive})`,\n );\n }\n\n private async getElementInfoByXpath(xpath: string) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath(${JSON.stringify(xpath)})`,\n );\n }\n\n async cacheFeatureForPoint(\n center: [number, number],\n options?: CacheFeatureOptions,\n ): Promise<ElementCacheFeature> {\n const point: Point = { left: center[0], top: center[1] };\n\n try {\n const isOrderSensitive = await judgeOrderSensitive(options, debugPage);\n const xpaths = await this.getXpathsByPoint(point, isOrderSensitive);\n const sanitized = sanitizeXpaths(xpaths);\n if (!sanitized.length) {\n debugPage('cacheFeatureForPoint: no xpath found at point %o', center);\n }\n return { xpaths: sanitized };\n } catch (error) {\n debugPage('cacheFeatureForPoint failed: %s', error);\n return { xpaths: [] };\n }\n }\n\n async rectMatchesCacheFeature(feature: ElementCacheFeature): Promise<Rect> {\n const xpaths = sanitizeXpaths((feature as WebElementCacheFeature).xpaths);\n debugPage('rectMatchesCacheFeature: trying %d xpath(s)', xpaths.length);\n\n for (const xpath of xpaths) {\n try {\n debugPage('rectMatchesCacheFeature: evaluating xpath: %s', xpath);\n const elementInfo = await this.getElementInfoByXpath(xpath);\n if (elementInfo?.rect) {\n debugPage(\n 'rectMatchesCacheFeature: found element, rect: %o',\n elementInfo.rect,\n );\n return buildRectFromElementInfo(elementInfo, this.viewportSize?.dpr);\n }\n debugPage(\n 'rectMatchesCacheFeature: element found but no rect (elementInfo: %o)',\n elementInfo,\n );\n } catch (error) {\n debugPage(\n 'rectMatchesCacheFeature failed for xpath %s: %s',\n xpath,\n error,\n );\n }\n }\n\n throw new Error(\n `No matching element rect found for the provided cache feature (tried ${xpaths.length} xpath(s): ${xpaths.join(', ')})`,\n );\n }\n\n async getElementsNodeTree() {\n // ref: packages/web-integration/src/playwright/ai-fixture.ts popup logic\n // During test execution, a new page might be opened through a connection, and the page remains confined to the same page instance.\n // The page may go through opening, closing, and reopening; if the page is closed, evaluate may return undefined, which can lead to errors.\n await this.waitForNavigation();\n const scripts = await getExtraReturnLogic(true);\n assert(scripts, 'scripts should be set before writing report in browser');\n const startTime = Date.now();\n const captureElementSnapshot = await this.evaluate(scripts);\n const endTime = Date.now();\n debugPage(`getElementsNodeTree end, cost: ${endTime - startTime}ms`);\n return captureElementSnapshot as ElementTreeNode<ElementInfo>;\n }\n\n async size(): Promise<Size> {\n if (this.viewportSize) return this.viewportSize;\n const sizeInfo: Size = await this.evaluate(() => {\n return {\n width: window.innerWidth,\n height: window.innerHeight,\n dpr: window.devicePixelRatio,\n };\n });\n this.viewportSize = sizeInfo;\n return sizeInfo;\n }\n\n async screenshotBase64(): Promise<string> {\n const imgType = 'jpeg';\n const quality = 90;\n await this.waitForNavigation();\n const startTime = Date.now();\n debugPage('screenshotBase64 begin');\n\n let base64: string;\n if (this.interfaceType === 'puppeteer') {\n const result = await (this.underlyingPage as PuppeteerPage).screenshot({\n type: imgType,\n quality,\n encoding: 'base64',\n });\n base64 = createImgBase64ByFormat(imgType, result);\n } else if (this.interfaceType === 'playwright') {\n const buffer = await (this.underlyingPage as PlaywrightPage).screenshot({\n type: imgType,\n quality,\n timeout: 10 * 1000,\n });\n base64 = createImgBase64ByFormat(imgType, buffer.toString('base64'));\n } else {\n throw new Error('Unsupported page type for screenshot');\n }\n const endTime = Date.now();\n debugPage(`screenshotBase64 end, cost: ${endTime - startTime}ms`);\n return base64;\n }\n\n async url(): Promise<string> {\n return this.underlyingPage.url();\n }\n\n describe(): string {\n const url = this.underlyingPage.url();\n return url || '';\n }\n\n get mouse() {\n return {\n click: async (\n x: number,\n y: number,\n options?: { button?: MouseButton; count?: number },\n ) => {\n await this.mouse.move(x, y);\n const { button = 'left', count = 1 } = options || {};\n debugPage(`mouse click ${x}, ${y}, ${button}, ${count}`);\n\n if (count === 2 && this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).mouse.dblclick(x, y, {\n button,\n });\n } else if (this.interfaceType === 'puppeteer') {\n const page = this.underlyingPage as PuppeteerPage;\n if (button === 'left' && count === 1) {\n await page.mouse.click(x, y);\n } else {\n await page.mouse.click(x, y, { button, count });\n }\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).mouse.click(x, y, {\n button,\n clickCount: count,\n });\n }\n },\n wheel: async (deltaX: number, deltaY: number) => {\n debugPage(`mouse wheel ${deltaX}, ${deltaY}`);\n if (this.interfaceType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).mouse.wheel({\n deltaX,\n deltaY,\n });\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).mouse.wheel(\n deltaX,\n deltaY,\n );\n }\n },\n move: async (x: number, y: number) => {\n this.everMoved = true;\n debugPage(`mouse move to ${x}, ${y}`);\n return this.underlyingPage.mouse.move(x, y);\n },\n drag: async (\n from: { x: number; y: number },\n to: { x: number; y: number },\n ) => {\n debugPage(\n `begin mouse drag from ${from.x}, ${from.y} to ${to.x}, ${to.y}`,\n );\n await (this.underlyingPage as PlaywrightPage).mouse.move(\n from.x,\n from.y,\n );\n await sleep(200);\n await (this.underlyingPage as PlaywrightPage).mouse.down();\n await sleep(300);\n await (this.underlyingPage as PlaywrightPage).mouse.move(to.x, to.y, {\n steps: 20,\n });\n await sleep(500);\n await (this.underlyingPage as PlaywrightPage).mouse.up();\n await sleep(200);\n debugPage(\n `end mouse drag from ${from.x}, ${from.y} to ${to.x}, ${to.y}`,\n );\n },\n };\n }\n\n get keyboard() {\n return {\n type: async (text: string) => {\n debugPage(`keyboard type ${text}`);\n return this.underlyingPage.keyboard.type(text, { delay: 80 });\n },\n press: async (\n action:\n | { key: KeyInput; command?: string }\n | { key: KeyInput; command?: string }[],\n ) => {\n const keys = Array.isArray(action) ? action : [action];\n debugPage('keyboard press', keys);\n for (const k of keys) {\n const commands = k.command ? [k.command] : [];\n await this.underlyingPage.keyboard.down(k.key, { commands });\n }\n for (const k of [...keys].reverse()) {\n await this.underlyingPage.keyboard.up(k.key);\n }\n },\n down: async (key: KeyInput) => {\n debugPage(`keyboard down ${key}`);\n return this.underlyingPage.keyboard.down(key);\n },\n up: async (key: KeyInput) => {\n debugPage(`keyboard up ${key}`);\n return this.underlyingPage.keyboard.up(key);\n },\n };\n }\n\n async clearInput(element?: ElementInfo): Promise<void> {\n const backspace = async () => {\n await sleep(100);\n await this.keyboard.press([{ key: 'Backspace' }]);\n };\n\n const isMac = process.platform === 'darwin';\n debugPage('clearInput begin');\n if (isMac) {\n if (this.interfaceType === 'puppeteer') {\n // https://github.com/segment-boneyard/nightmare/issues/810#issuecomment-452669866\n element &&\n (await this.mouse.click(element.center[0], element.center[1], {\n count: 3,\n }));\n await backspace();\n }\n\n element && (await this.mouse.click(element.center[0], element.center[1]));\n await this.underlyingPage.keyboard.down('Meta');\n await this.underlyingPage.keyboard.press('a');\n await this.underlyingPage.keyboard.up('Meta');\n await backspace();\n } else {\n element && (await this.mouse.click(element.center[0], element.center[1]));\n await this.underlyingPage.keyboard.down('Control');\n await this.underlyingPage.keyboard.press('a');\n await this.underlyingPage.keyboard.up('Control');\n await backspace();\n }\n debugPage('clearInput end');\n }\n\n private everMoved = false;\n private async moveToPointBeforeScroll(point?: Point): Promise<void> {\n if (point) {\n await this.mouse.move(point.left, point.top);\n } else if (!this.everMoved) {\n // If the mouse has never moved, move it to the center of the page\n const size = await this.size();\n const targetX = Math.floor(size.width / 2);\n const targetY = Math.floor(size.height / 2);\n await this.mouse.move(targetX, targetY);\n }\n }\n\n async scrollUntilTop(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, -9999999);\n }\n\n async scrollUntilBottom(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, 9999999);\n }\n\n async scrollUntilLeft(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(-9999999, 0);\n }\n\n async scrollUntilRight(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(9999999, 0);\n }\n\n async scrollUp(distance?: number, startingPoint?: Point): Promise<void> {\n const innerHeight = await this.evaluate(() => window.innerHeight);\n const scrollDistance = distance || innerHeight * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, -scrollDistance);\n }\n\n async scrollDown(distance?: number, startingPoint?: Point): Promise<void> {\n const innerHeight = await this.evaluate(() => window.innerHeight);\n const scrollDistance = distance || innerHeight * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, scrollDistance);\n }\n\n async scrollLeft(distance?: number, startingPoint?: Point): Promise<void> {\n const innerWidth = await this.evaluate(() => window.innerWidth);\n const scrollDistance = distance || innerWidth * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(-scrollDistance, 0);\n }\n\n async scrollRight(distance?: number, startingPoint?: Point): Promise<void> {\n const innerWidth = await this.evaluate(() => window.innerWidth);\n const scrollDistance = distance || innerWidth * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(scrollDistance, 0);\n }\n\n async navigate(url: string): Promise<void> {\n debugPage(`navigate to ${url}`);\n if (this.interfaceType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).goto(url);\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).goto(url);\n } else {\n throw new Error('Unsupported page type for navigate');\n }\n }\n\n async reload(): Promise<void> {\n debugPage('reload page');\n if (this.interfaceType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).reload();\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).reload();\n } else {\n throw new Error('Unsupported page type for reload');\n }\n }\n\n async goBack(): Promise<void> {\n debugPage('go back');\n if (this.interfaceType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).goBack();\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).goBack();\n } else {\n throw new Error('Unsupported page type for go back');\n }\n }\n\n async beforeInvokeAction(name: string, param: any): Promise<void> {\n if (this.onBeforeInvokeAction) {\n await this.onBeforeInvokeAction(name, param);\n }\n }\n\n async afterInvokeAction(name: string, param: any): Promise<void> {\n await this.waitForNavigation();\n await this.waitForNetworkIdle();\n if (this.onAfterInvokeAction) {\n await this.onAfterInvokeAction(name, param);\n }\n }\n\n async destroy(): Promise<void> {}\n\n async getContext(): Promise<UIContext> {\n return await WebPageContextParser(this, {});\n }\n async swipe(\n from: { x: number; y: number },\n to: { x: number; y: number },\n duration?: number,\n ) {\n const LONG_PRESS_THRESHOLD = 500;\n const MIN_PRESS_THRESHOLD = 150;\n duration = duration || 100;\n if (duration < MIN_PRESS_THRESHOLD) {\n duration = MIN_PRESS_THRESHOLD;\n }\n if (duration > LONG_PRESS_THRESHOLD) {\n duration = LONG_PRESS_THRESHOLD;\n }\n debugPage(\n `mouse swipe from ${from.x}, ${from.y} to ${to.x}, ${to.y} with duration ${duration}ms`,\n );\n\n if (this.interfaceType === 'puppeteer') {\n const page = this.underlyingPage as PuppeteerPage;\n await page.mouse.move(from.x, from.y);\n await page.mouse.down({ button: 'left' });\n\n const steps = 30;\n const delay = duration / steps;\n for (let i = 1; i <= steps; i++) {\n const x = from.x + (to.x - from.x) * (i / steps);\n const y = from.y + (to.y - from.y) * (i / steps);\n await page.mouse.move(x, y);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n await page.mouse.up({ button: 'left' });\n } else if (this.interfaceType === 'playwright') {\n const page = this.underlyingPage as PlaywrightPage;\n await page.mouse.move(from.x, from.y);\n await page.mouse.down();\n\n const steps = 30;\n const delay = duration / steps;\n for (let i = 1; i <= steps; i++) {\n const x = from.x + (to.x - from.x) * (i / steps);\n const y = from.y + (to.y - from.y) * (i / steps);\n await page.mouse.move(x, y);\n await page.waitForTimeout(delay);\n }\n\n await page.mouse.up({ button: 'left' });\n }\n }\n async longPress(x: number, y: number, duration?: number) {\n duration = duration || 500;\n const LONG_PRESS_THRESHOLD = 600;\n const MIN_PRESS_THRESHOLD = 300;\n if (duration > LONG_PRESS_THRESHOLD) {\n duration = LONG_PRESS_THRESHOLD;\n }\n if (duration < MIN_PRESS_THRESHOLD) {\n duration = MIN_PRESS_THRESHOLD;\n }\n debugPage(`mouse longPress at ${x}, ${y} for ${duration}ms`);\n if (this.interfaceType === 'puppeteer') {\n const page = this.underlyingPage as PuppeteerPage;\n await page.mouse.move(x, y);\n await page.mouse.down({ button: 'left' });\n await new Promise((res) => setTimeout(res, duration));\n await page.mouse.up({ button: 'left' });\n } else if (this.interfaceType === 'playwright') {\n const page = this.underlyingPage as PlaywrightPage;\n await page.mouse.move(x, y);\n await page.mouse.down({ button: 'left' });\n await page.waitForTimeout(duration);\n await page.mouse.up({ button: 'left' });\n }\n }\n\n private async ensurePuppeteerFileChooserSession(\n page: PuppeteerPage,\n ): Promise<CDPSession> {\n if (this.puppeteerFileChooserSession) {\n return this.puppeteerFileChooserSession;\n }\n const session = await page.target().createCDPSession();\n await session.send('Page.enable');\n await session.send('DOM.enable');\n await session.send('Page.setInterceptFileChooserDialog', { enabled: true });\n this.puppeteerFileChooserSession = session;\n return session;\n }\n\n async registerFileChooserListener(\n handler: (\n chooser: import('@midscene/core/device').FileChooserHandler,\n ) => Promise<void>,\n ): Promise<{ dispose: () => void; getError: () => Error | undefined }> {\n if (this.interfaceType !== 'puppeteer') {\n throw new Error(\n 'registerFileChooserListener is only supported in Puppeteer',\n );\n }\n\n const page = this.underlyingPage as PuppeteerPage;\n const session = await this.ensurePuppeteerFileChooserSession(page);\n if (this.puppeteerFileChooserHandler) {\n session.off('Page.fileChooserOpened', this.puppeteerFileChooserHandler);\n }\n\n let capturedError: Error | undefined;\n\n this.puppeteerFileChooserHandler = async (event) => {\n if (event.backendNodeId === undefined) {\n debugPage('puppeteer file chooser opened without backendNodeId, skip');\n return;\n }\n try {\n await handler({\n accept: async (files: string[]) => {\n // Get node information to check attributes\n const { node } = await session.send('DOM.describeNode', {\n backendNodeId: event.backendNodeId,\n });\n // attributes is a flat array: ['attr1', 'value1', 'attr2', 'value2', ...]\n\n // Check if input has webkitdirectory attribute (Puppeteer doesn't support directory upload)\n const hasWebkitDirectory =\n node.attributes?.includes('webkitdirectory') ||\n node.attributes?.includes('directory');\n if (hasWebkitDirectory) {\n throw new Error(\n 'Directory upload (webkitdirectory) is not supported in Puppeteer. Please use Playwright instead, which supports directory upload since version 1.45.',\n );\n }\n\n // Check if input supports multiple files\n if (files.length > 1) {\n const hasMultiple = node.attributes?.includes('multiple');\n if (!hasMultiple) {\n throw new Error(\n 'Non-multiple file input can only accept single file',\n );\n }\n }\n await session.send('DOM.setFileInputFiles', {\n files,\n backendNodeId: event.backendNodeId,\n });\n },\n });\n } catch (error) {\n capturedError = error as Error;\n }\n };\n session.on('Page.fileChooserOpened', this.puppeteerFileChooserHandler);\n return {\n dispose: () => {\n if (this.puppeteerFileChooserHandler) {\n session.off(\n 'Page.fileChooserOpened',\n this.puppeteerFileChooserHandler,\n );\n }\n void session.detach();\n this.puppeteerFileChooserHandler = undefined;\n if (this.puppeteerFileChooserSession === session) {\n this.puppeteerFileChooserSession = undefined;\n }\n },\n getError: () => capturedError,\n };\n }\n}\n\nexport function forceClosePopup(\n page: PuppeteerPage | PlaywrightPage,\n debugProfile: DebugFunction,\n) {\n page.on('popup', async (popup) => {\n if (!popup) {\n console.warn('got a popup event, but the popup is not ready yet, skip');\n return;\n }\n const url = await (popup as PuppeteerPage).url();\n console.log(`Popup opened: ${url}`);\n if (!(popup as PuppeteerPage).isClosed()) {\n try {\n await (popup as PuppeteerPage).close(); // Close the newly opened TAB\n } catch (error) {\n debugProfile(`failed to close popup ${url}, error: ${error}`);\n }\n } else {\n debugProfile(`popup is already closed, skip close ${url}`);\n }\n\n if (!page.isClosed()) {\n try {\n await page.goto(url);\n } catch (error) {\n debugProfile(`failed to goto ${url}, error: ${error}`);\n }\n } else {\n debugProfile(`page is already closed, skip goto ${url}`);\n }\n });\n}\n\n/**\n * Force Chrome to render select elements using base-select appearance instead of OS-native rendering.\n * This makes select elements visible in screenshots captured by Playwright/Puppeteer.\n *\n * Reference: https://developer.chrome.com/blog/a-customizable-select\n *\n * Adds a style tag with CSS rules to make all select elements use base-select appearance.\n */\nexport function forceChromeSelectRendering(\n page: PuppeteerPage | PlaywrightPage,\n): void {\n // Force Chrome to render select elements using base-select appearance\n // Reference: https://developer.chrome.com/blog/a-customizable-select\n const styleContent = `\n/* Add by Midscene because of forceChromeSelectRendering is enabled*/\nselect {\n &, &::picker(select) {\n appearance: base-select !important;\n }\n}`;\n const styleId = 'midscene-force-select-rendering';\n\n const injectStyle = async () => {\n try {\n await (page as PuppeteerPage & PlaywrightPage).evaluate(\n (id, content) => {\n if (document.getElementById(id)) return;\n const style = document.createElement('style');\n style.id = id;\n style.textContent = content;\n document.head.appendChild(style);\n },\n styleId,\n styleContent,\n );\n debugPage(\n 'Midscene - Added base-select appearance style for select elements because of forceChromeSelectRendering is enabled',\n );\n } catch (err) {\n console.log(\n 'Midscene - Failed to add base-select appearance style:',\n err,\n );\n }\n };\n\n // Inject immediately for the current document\n void injectStyle();\n\n // Ensure the style is reapplied on future navigations/new documents\n (page as PuppeteerPage & PlaywrightPage).on('load', () => {\n void injectStyle();\n });\n}\n"],"names":["debugPage","getDebug","Page","defaultActions","commonWebActionsForWebPage","customActions","pageFunction","arg","result","script","error","console","DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY","tree","treeToList","point","isOrderSensitive","elementInfosScriptContent","getElementInfosScriptContent","xpath","JSON","center","options","judgeOrderSensitive","xpaths","sanitized","sanitizeXpaths","feature","elementInfo","buildRectFromElementInfo","Error","scripts","getExtraReturnLogic","assert","startTime","Date","captureElementSnapshot","endTime","sizeInfo","window","imgType","quality","base64","createImgBase64ByFormat","buffer","url","x","y","button","count","page","deltaX","deltaY","from","to","sleep","text","action","keys","Array","k","commands","key","element","backspace","isMac","process","size","targetX","Math","targetY","startingPoint","distance","innerHeight","scrollDistance","innerWidth","name","param","WebPageContextParser","duration","LONG_PRESS_THRESHOLD","MIN_PRESS_THRESHOLD","steps","delay","i","Promise","resolve","setTimeout","res","session","handler","capturedError","event","undefined","files","node","hasWebkitDirectory","hasMultiple","underlyingPage","interfaceType","opts","DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","forceClosePopup","debugProfile","popup","forceChromeSelectRendering","styleContent","styleId","injectStyle","id","content","document","style","err"],"mappings":"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"}
1
+ {"version":3,"file":"puppeteer/base-page.mjs","sources":["../../../src/puppeteer/base-page.ts"],"sourcesContent":["import type { WebPageAgentOpt } from '@/web-element';\nimport type {\n DeviceAction,\n ElementCacheFeature,\n ElementTreeNode,\n Point,\n Rect,\n Size,\n} from '@midscene/core';\nimport type { AbstractInterface } from '@midscene/core/device';\nimport { sleep } from '@midscene/core/utils';\nimport {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@midscene/shared/constants';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { treeToList } from '@midscene/shared/extractor';\nimport { createImgBase64ByFormat } from '@midscene/shared/img';\nimport { type DebugFunction, getDebug } from '@midscene/shared/logger';\nimport {\n getElementInfosScriptContent,\n getExtraReturnLogic,\n} from '@midscene/shared/node';\nimport { assert } from '@midscene/shared/utils';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { CDPSession, Protocol, Page as PuppeteerPage } from 'puppeteer';\nimport {\n type CacheFeatureOptions,\n type WebElementCacheFeature,\n buildRectFromElementInfo,\n judgeOrderSensitive,\n sanitizeXpaths,\n} from '../common/cache-helper';\nimport {\n type KeyInput,\n type MouseButton,\n commonWebActionsForWebPage,\n} from '../web-page';\n\nexport const debugPage = getDebug('web:page');\n\nexport class Page<\n AgentType extends 'puppeteer' | 'playwright',\n InterfaceType extends PuppeteerPage | PlaywrightPage,\n> implements AbstractInterface\n{\n underlyingPage: InterfaceType;\n protected waitForNavigationTimeout: number;\n protected waitForNetworkIdleTimeout: number;\n private viewportSize?: Size;\n private onBeforeInvokeAction?: AbstractInterface['beforeInvokeAction'];\n private onAfterInvokeAction?: AbstractInterface['afterInvokeAction'];\n private customActions?: DeviceAction<any>[];\n private enableTouchEventsInActionSpace: boolean;\n private puppeteerFileChooserSession?: CDPSession;\n private puppeteerFileChooserHandler?: (\n event: Protocol.Page.FileChooserOpenedEvent,\n ) => Promise<void>;\n interfaceType: AgentType;\n\n actionSpace(): DeviceAction[] {\n const defaultActions = commonWebActionsForWebPage(\n this,\n this.enableTouchEventsInActionSpace,\n );\n const customActions = this.customActions || [];\n return [...defaultActions, ...customActions];\n }\n\n private async evaluate<R>(\n pageFunction: string | ((...args: any[]) => R | Promise<R>),\n arg?: any,\n ): Promise<R> {\n let result: R;\n debugPage('evaluate function begin');\n if (this.interfaceType === 'puppeteer') {\n result = await (this.underlyingPage as PuppeteerPage).evaluate(\n pageFunction,\n arg,\n );\n } else {\n result = await (this.underlyingPage as PlaywrightPage).evaluate(\n pageFunction,\n arg,\n );\n }\n debugPage('evaluate function end');\n return result;\n }\n\n constructor(\n underlyingPage: InterfaceType,\n interfaceType: AgentType,\n opts?: WebPageAgentOpt,\n ) {\n this.underlyingPage = underlyingPage;\n this.interfaceType = interfaceType;\n this.waitForNavigationTimeout =\n opts?.waitForNavigationTimeout ?? DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;\n this.waitForNetworkIdleTimeout =\n opts?.waitForNetworkIdleTimeout ?? DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n this.onBeforeInvokeAction = opts?.beforeInvokeAction;\n this.onAfterInvokeAction = opts?.afterInvokeAction;\n this.customActions = opts?.customActions;\n this.enableTouchEventsInActionSpace =\n opts?.enableTouchEventsInActionSpace ?? false;\n }\n\n async evaluateJavaScript<T = any>(script: string): Promise<T> {\n return this.evaluate(script);\n }\n\n async waitForNavigation() {\n if (this.waitForNavigationTimeout === 0) {\n debugPage('waitForNavigation timeout is 0, skip waiting');\n return;\n }\n\n // issue: https://github.com/puppeteer/puppeteer/issues/3323\n if (\n this.interfaceType === 'puppeteer' ||\n this.interfaceType === 'playwright'\n ) {\n debugPage('waitForNavigation begin');\n debugPage(`waitForNavigation timeout: ${this.waitForNavigationTimeout}`);\n try {\n await (this.underlyingPage as PuppeteerPage).waitForSelector('html', {\n timeout: this.waitForNavigationTimeout,\n });\n } catch (error) {\n // Ignore timeout error, continue execution\n console.warn(\n '[midscene:warning] Waiting for the \"navigation\" has timed out, but Midscene will continue execution. Please check https://midscenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n debugPage('waitForNavigation end');\n }\n }\n\n async waitForNetworkIdle(): Promise<void> {\n if (this.interfaceType === 'puppeteer') {\n if (this.waitForNetworkIdleTimeout === 0) {\n debugPage('waitForNetworkIdle timeout is 0, skip waiting');\n return;\n }\n\n try {\n await (this.underlyingPage as PuppeteerPage).waitForNetworkIdle({\n idleTime: 200,\n concurrency: DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,\n timeout: this.waitForNetworkIdleTimeout,\n });\n } catch (error) {\n // Ignore timeout error, continue execution\n console.warn(\n '[midscene:warning] Waiting for the \"network idle\" has timed out, but Midscene will continue execution. Please check https://midscenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n } else {\n // TODO: implement playwright waitForNetworkIdle\n }\n }\n\n // @deprecated\n async getElementsInfo() {\n // const scripts = await getExtraReturnLogic();\n // const captureElementSnapshot = await this.evaluate(scripts);\n // return captureElementSnapshot as ElementInfo[];\n await this.waitForNavigation();\n debugPage('getElementsInfo begin');\n const tree = await this.getElementsNodeTree();\n debugPage('getElementsInfo end');\n return treeToList(tree);\n }\n\n private async getXpathsByPoint(point: Point, isOrderSensitive: boolean) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getXpathsByPoint({left: ${point.left}, top: ${point.top}}, ${isOrderSensitive})`,\n );\n }\n\n private async getElementInfoByXpath(xpath: string) {\n const elementInfosScriptContent = getElementInfosScriptContent();\n\n return this.evaluateJavaScript(\n `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath(${JSON.stringify(xpath)})`,\n );\n }\n\n async cacheFeatureForPoint(\n center: [number, number],\n options?: CacheFeatureOptions,\n ): Promise<ElementCacheFeature> {\n const point: Point = { left: center[0], top: center[1] };\n\n try {\n const isOrderSensitive = await judgeOrderSensitive(options, debugPage);\n const xpaths = await this.getXpathsByPoint(point, isOrderSensitive);\n const sanitized = sanitizeXpaths(xpaths);\n if (!sanitized.length) {\n debugPage('cacheFeatureForPoint: no xpath found at point %o', center);\n }\n return { xpaths: sanitized };\n } catch (error) {\n debugPage('cacheFeatureForPoint failed: %s', error);\n return { xpaths: [] };\n }\n }\n\n async rectMatchesCacheFeature(feature: ElementCacheFeature): Promise<Rect> {\n const xpaths = sanitizeXpaths((feature as WebElementCacheFeature).xpaths);\n debugPage('rectMatchesCacheFeature: trying %d xpath(s)', xpaths.length);\n\n for (const xpath of xpaths) {\n try {\n debugPage('rectMatchesCacheFeature: evaluating xpath: %s', xpath);\n const elementInfo = await this.getElementInfoByXpath(xpath);\n if (elementInfo?.rect) {\n debugPage(\n 'rectMatchesCacheFeature: found element, rect: %o',\n elementInfo.rect,\n );\n return buildRectFromElementInfo(elementInfo);\n }\n debugPage(\n 'rectMatchesCacheFeature: element found but no rect (elementInfo: %o)',\n elementInfo,\n );\n } catch (error) {\n debugPage(\n 'rectMatchesCacheFeature failed for xpath %s: %s',\n xpath,\n error,\n );\n }\n }\n\n throw new Error(\n `No matching element rect found for the provided cache feature (tried ${xpaths.length} xpath(s): ${xpaths.join(', ')})`,\n );\n }\n\n async getElementsNodeTree() {\n // ref: packages/web-integration/src/playwright/ai-fixture.ts popup logic\n // During test execution, a new page might be opened through a connection, and the page remains confined to the same page instance.\n // The page may go through opening, closing, and reopening; if the page is closed, evaluate may return undefined, which can lead to errors.\n await this.waitForNavigation();\n const scripts = await getExtraReturnLogic(true);\n assert(scripts, 'scripts should be set before writing report in browser');\n const startTime = Date.now();\n const captureElementSnapshot = await this.evaluate(scripts);\n const endTime = Date.now();\n debugPage(`getElementsNodeTree end, cost: ${endTime - startTime}ms`);\n return captureElementSnapshot as ElementTreeNode<ElementInfo>;\n }\n\n async size(): Promise<Size> {\n if (this.viewportSize) return this.viewportSize;\n const sizeInfo: Size = await this.evaluate(() => {\n return {\n width: window.innerWidth,\n height: window.innerHeight,\n };\n });\n this.viewportSize = sizeInfo;\n return sizeInfo;\n }\n\n async screenshotBase64(): Promise<string> {\n const imgType = 'jpeg';\n const quality = 90;\n await this.waitForNavigation();\n const startTime = Date.now();\n debugPage('screenshotBase64 begin');\n\n let base64: string;\n if (this.interfaceType === 'puppeteer') {\n const result = await (this.underlyingPage as PuppeteerPage).screenshot({\n type: imgType,\n quality,\n encoding: 'base64',\n });\n base64 = createImgBase64ByFormat(imgType, result);\n } else if (this.interfaceType === 'playwright') {\n const buffer = await (this.underlyingPage as PlaywrightPage).screenshot({\n type: imgType,\n quality,\n timeout: 10 * 1000,\n });\n base64 = createImgBase64ByFormat(imgType, buffer.toString('base64'));\n } else {\n throw new Error('Unsupported page type for screenshot');\n }\n const endTime = Date.now();\n debugPage(`screenshotBase64 end, cost: ${endTime - startTime}ms`);\n return base64;\n }\n\n async url(): Promise<string> {\n return this.underlyingPage.url();\n }\n\n describe(): string {\n const url = this.underlyingPage.url();\n return url || '';\n }\n\n get mouse() {\n return {\n click: async (\n x: number,\n y: number,\n options?: { button?: MouseButton; count?: number },\n ) => {\n await this.mouse.move(x, y);\n const { button = 'left', count = 1 } = options || {};\n debugPage(`mouse click ${x}, ${y}, ${button}, ${count}`);\n\n if (count === 2 && this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).mouse.dblclick(x, y, {\n button,\n });\n } else if (this.interfaceType === 'puppeteer') {\n const page = this.underlyingPage as PuppeteerPage;\n if (button === 'left' && count === 1) {\n await page.mouse.click(x, y);\n } else {\n await page.mouse.click(x, y, { button, count });\n }\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).mouse.click(x, y, {\n button,\n clickCount: count,\n });\n }\n },\n wheel: async (deltaX: number, deltaY: number) => {\n debugPage(`mouse wheel ${deltaX}, ${deltaY}`);\n if (this.interfaceType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).mouse.wheel({\n deltaX,\n deltaY,\n });\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).mouse.wheel(\n deltaX,\n deltaY,\n );\n }\n },\n move: async (x: number, y: number) => {\n this.everMoved = true;\n debugPage(`mouse move to ${x}, ${y}`);\n return this.underlyingPage.mouse.move(x, y);\n },\n drag: async (\n from: { x: number; y: number },\n to: { x: number; y: number },\n ) => {\n debugPage(\n `begin mouse drag from ${from.x}, ${from.y} to ${to.x}, ${to.y}`,\n );\n await (this.underlyingPage as PlaywrightPage).mouse.move(\n from.x,\n from.y,\n );\n await sleep(200);\n await (this.underlyingPage as PlaywrightPage).mouse.down();\n await sleep(300);\n await (this.underlyingPage as PlaywrightPage).mouse.move(to.x, to.y, {\n steps: 20,\n });\n await sleep(500);\n await (this.underlyingPage as PlaywrightPage).mouse.up();\n await sleep(200);\n debugPage(\n `end mouse drag from ${from.x}, ${from.y} to ${to.x}, ${to.y}`,\n );\n },\n };\n }\n\n get keyboard() {\n return {\n type: async (text: string) => {\n debugPage(`keyboard type ${text}`);\n return this.underlyingPage.keyboard.type(text, { delay: 80 });\n },\n press: async (\n action:\n | { key: KeyInput; command?: string }\n | { key: KeyInput; command?: string }[],\n ) => {\n const keys = Array.isArray(action) ? action : [action];\n debugPage('keyboard press', keys);\n for (const k of keys) {\n const commands = k.command ? [k.command] : [];\n await this.underlyingPage.keyboard.down(k.key, { commands });\n }\n for (const k of [...keys].reverse()) {\n await this.underlyingPage.keyboard.up(k.key);\n }\n },\n down: async (key: KeyInput) => {\n debugPage(`keyboard down ${key}`);\n return this.underlyingPage.keyboard.down(key);\n },\n up: async (key: KeyInput) => {\n debugPage(`keyboard up ${key}`);\n return this.underlyingPage.keyboard.up(key);\n },\n };\n }\n\n async clearInput(element?: ElementInfo): Promise<void> {\n const backspace = async () => {\n await sleep(100);\n await this.keyboard.press([{ key: 'Backspace' }]);\n };\n\n const isMac = process.platform === 'darwin';\n debugPage('clearInput begin');\n if (isMac) {\n if (this.interfaceType === 'puppeteer') {\n // https://github.com/segment-boneyard/nightmare/issues/810#issuecomment-452669866\n element &&\n (await this.mouse.click(element.center[0], element.center[1], {\n count: 3,\n }));\n await backspace();\n }\n\n element && (await this.mouse.click(element.center[0], element.center[1]));\n await this.underlyingPage.keyboard.down('Meta');\n await this.underlyingPage.keyboard.press('a');\n await this.underlyingPage.keyboard.up('Meta');\n await backspace();\n } else {\n element && (await this.mouse.click(element.center[0], element.center[1]));\n await this.underlyingPage.keyboard.down('Control');\n await this.underlyingPage.keyboard.press('a');\n await this.underlyingPage.keyboard.up('Control');\n await backspace();\n }\n debugPage('clearInput end');\n }\n\n private everMoved = false;\n private async moveToPointBeforeScroll(point?: Point): Promise<void> {\n if (point) {\n await this.mouse.move(point.left, point.top);\n } else if (!this.everMoved) {\n // If the mouse has never moved, move it to the center of the page\n const size = await this.size();\n const targetX = Math.floor(size.width / 2);\n const targetY = Math.floor(size.height / 2);\n await this.mouse.move(targetX, targetY);\n }\n }\n\n async scrollUntilTop(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, -9999999);\n }\n\n async scrollUntilBottom(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, 9999999);\n }\n\n async scrollUntilLeft(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(-9999999, 0);\n }\n\n async scrollUntilRight(startingPoint?: Point): Promise<void> {\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(9999999, 0);\n }\n\n async scrollUp(distance?: number, startingPoint?: Point): Promise<void> {\n const innerHeight = await this.evaluate(() => window.innerHeight);\n const scrollDistance = distance || innerHeight * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, -scrollDistance);\n }\n\n async scrollDown(distance?: number, startingPoint?: Point): Promise<void> {\n const innerHeight = await this.evaluate(() => window.innerHeight);\n const scrollDistance = distance || innerHeight * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(0, scrollDistance);\n }\n\n async scrollLeft(distance?: number, startingPoint?: Point): Promise<void> {\n const innerWidth = await this.evaluate(() => window.innerWidth);\n const scrollDistance = distance || innerWidth * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(-scrollDistance, 0);\n }\n\n async scrollRight(distance?: number, startingPoint?: Point): Promise<void> {\n const innerWidth = await this.evaluate(() => window.innerWidth);\n const scrollDistance = distance || innerWidth * 0.7;\n await this.moveToPointBeforeScroll(startingPoint);\n return this.mouse.wheel(scrollDistance, 0);\n }\n\n async navigate(url: string): Promise<void> {\n debugPage(`navigate to ${url}`);\n if (this.interfaceType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).goto(url);\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).goto(url);\n } else {\n throw new Error('Unsupported page type for navigate');\n }\n }\n\n async reload(): Promise<void> {\n debugPage('reload page');\n if (this.interfaceType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).reload();\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).reload();\n } else {\n throw new Error('Unsupported page type for reload');\n }\n }\n\n async goBack(): Promise<void> {\n debugPage('go back');\n if (this.interfaceType === 'puppeteer') {\n await (this.underlyingPage as PuppeteerPage).goBack();\n } else if (this.interfaceType === 'playwright') {\n await (this.underlyingPage as PlaywrightPage).goBack();\n } else {\n throw new Error('Unsupported page type for go back');\n }\n }\n\n async beforeInvokeAction(name: string, param: any): Promise<void> {\n if (this.onBeforeInvokeAction) {\n await this.onBeforeInvokeAction(name, param);\n }\n }\n\n async afterInvokeAction(name: string, param: any): Promise<void> {\n await this.waitForNavigation();\n await this.waitForNetworkIdle();\n if (this.onAfterInvokeAction) {\n await this.onAfterInvokeAction(name, param);\n }\n }\n\n async destroy(): Promise<void> {}\n\n async swipe(\n from: { x: number; y: number },\n to: { x: number; y: number },\n duration?: number,\n ) {\n const LONG_PRESS_THRESHOLD = 500;\n const MIN_PRESS_THRESHOLD = 150;\n duration = duration || 100;\n if (duration < MIN_PRESS_THRESHOLD) {\n duration = MIN_PRESS_THRESHOLD;\n }\n if (duration > LONG_PRESS_THRESHOLD) {\n duration = LONG_PRESS_THRESHOLD;\n }\n debugPage(\n `mouse swipe from ${from.x}, ${from.y} to ${to.x}, ${to.y} with duration ${duration}ms`,\n );\n\n if (this.interfaceType === 'puppeteer') {\n const page = this.underlyingPage as PuppeteerPage;\n await page.mouse.move(from.x, from.y);\n await page.mouse.down({ button: 'left' });\n\n const steps = 30;\n const delay = duration / steps;\n for (let i = 1; i <= steps; i++) {\n const x = from.x + (to.x - from.x) * (i / steps);\n const y = from.y + (to.y - from.y) * (i / steps);\n await page.mouse.move(x, y);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n await page.mouse.up({ button: 'left' });\n } else if (this.interfaceType === 'playwright') {\n const page = this.underlyingPage as PlaywrightPage;\n await page.mouse.move(from.x, from.y);\n await page.mouse.down();\n\n const steps = 30;\n const delay = duration / steps;\n for (let i = 1; i <= steps; i++) {\n const x = from.x + (to.x - from.x) * (i / steps);\n const y = from.y + (to.y - from.y) * (i / steps);\n await page.mouse.move(x, y);\n await page.waitForTimeout(delay);\n }\n\n await page.mouse.up({ button: 'left' });\n }\n }\n async longPress(x: number, y: number, duration?: number) {\n duration = duration || 500;\n const LONG_PRESS_THRESHOLD = 600;\n const MIN_PRESS_THRESHOLD = 300;\n if (duration > LONG_PRESS_THRESHOLD) {\n duration = LONG_PRESS_THRESHOLD;\n }\n if (duration < MIN_PRESS_THRESHOLD) {\n duration = MIN_PRESS_THRESHOLD;\n }\n debugPage(`mouse longPress at ${x}, ${y} for ${duration}ms`);\n if (this.interfaceType === 'puppeteer') {\n const page = this.underlyingPage as PuppeteerPage;\n await page.mouse.move(x, y);\n await page.mouse.down({ button: 'left' });\n await new Promise((res) => setTimeout(res, duration));\n await page.mouse.up({ button: 'left' });\n } else if (this.interfaceType === 'playwright') {\n const page = this.underlyingPage as PlaywrightPage;\n await page.mouse.move(x, y);\n await page.mouse.down({ button: 'left' });\n await page.waitForTimeout(duration);\n await page.mouse.up({ button: 'left' });\n }\n }\n\n private async ensurePuppeteerFileChooserSession(\n page: PuppeteerPage,\n ): Promise<CDPSession> {\n if (this.puppeteerFileChooserSession) {\n return this.puppeteerFileChooserSession;\n }\n const session = await page.target().createCDPSession();\n await session.send('Page.enable');\n await session.send('DOM.enable');\n await session.send('Page.setInterceptFileChooserDialog', { enabled: true });\n this.puppeteerFileChooserSession = session;\n return session;\n }\n\n async registerFileChooserListener(\n handler: (\n chooser: import('@midscene/core/device').FileChooserHandler,\n ) => Promise<void>,\n ): Promise<{ dispose: () => void; getError: () => Error | undefined }> {\n if (this.interfaceType !== 'puppeteer') {\n throw new Error(\n 'registerFileChooserListener is only supported in Puppeteer',\n );\n }\n\n const page = this.underlyingPage as PuppeteerPage;\n const session = await this.ensurePuppeteerFileChooserSession(page);\n if (this.puppeteerFileChooserHandler) {\n session.off('Page.fileChooserOpened', this.puppeteerFileChooserHandler);\n }\n\n let capturedError: Error | undefined;\n\n this.puppeteerFileChooserHandler = async (event) => {\n if (event.backendNodeId === undefined) {\n debugPage('puppeteer file chooser opened without backendNodeId, skip');\n return;\n }\n try {\n await handler({\n accept: async (files: string[]) => {\n // Get node information to check attributes\n const { node } = await session.send('DOM.describeNode', {\n backendNodeId: event.backendNodeId,\n });\n // attributes is a flat array: ['attr1', 'value1', 'attr2', 'value2', ...]\n\n // Check if input has webkitdirectory attribute (Puppeteer doesn't support directory upload)\n const hasWebkitDirectory =\n node.attributes?.includes('webkitdirectory') ||\n node.attributes?.includes('directory');\n if (hasWebkitDirectory) {\n throw new Error(\n 'Directory upload (webkitdirectory) is not supported in Puppeteer. Please use Playwright instead, which supports directory upload since version 1.45.',\n );\n }\n\n // Check if input supports multiple files\n if (files.length > 1) {\n const hasMultiple = node.attributes?.includes('multiple');\n if (!hasMultiple) {\n throw new Error(\n 'Non-multiple file input can only accept single file',\n );\n }\n }\n await session.send('DOM.setFileInputFiles', {\n files,\n backendNodeId: event.backendNodeId,\n });\n },\n });\n } catch (error) {\n capturedError = error as Error;\n }\n };\n session.on('Page.fileChooserOpened', this.puppeteerFileChooserHandler);\n return {\n dispose: () => {\n if (this.puppeteerFileChooserHandler) {\n session.off(\n 'Page.fileChooserOpened',\n this.puppeteerFileChooserHandler,\n );\n }\n void session.detach();\n this.puppeteerFileChooserHandler = undefined;\n if (this.puppeteerFileChooserSession === session) {\n this.puppeteerFileChooserSession = undefined;\n }\n },\n getError: () => capturedError,\n };\n }\n}\n\nexport function forceClosePopup(\n page: PuppeteerPage | PlaywrightPage,\n debugProfile: DebugFunction,\n) {\n page.on('popup', async (popup) => {\n if (!popup) {\n console.warn('got a popup event, but the popup is not ready yet, skip');\n return;\n }\n const url = await (popup as PuppeteerPage).url();\n console.log(`Popup opened: ${url}`);\n if (!(popup as PuppeteerPage).isClosed()) {\n try {\n await (popup as PuppeteerPage).close(); // Close the newly opened TAB\n } catch (error) {\n debugProfile(`failed to close popup ${url}, error: ${error}`);\n }\n } else {\n debugProfile(`popup is already closed, skip close ${url}`);\n }\n\n if (!page.isClosed()) {\n try {\n await page.goto(url);\n } catch (error) {\n debugProfile(`failed to goto ${url}, error: ${error}`);\n }\n } else {\n debugProfile(`page is already closed, skip goto ${url}`);\n }\n });\n}\n\n/**\n * Force Chrome to render select elements using base-select appearance instead of OS-native rendering.\n * This makes select elements visible in screenshots captured by Playwright/Puppeteer.\n *\n * Reference: https://developer.chrome.com/blog/a-customizable-select\n *\n * Adds a style tag with CSS rules to make all select elements use base-select appearance.\n */\nexport function forceChromeSelectRendering(\n page: PuppeteerPage | PlaywrightPage,\n): void {\n // Force Chrome to render select elements using base-select appearance\n // Reference: https://developer.chrome.com/blog/a-customizable-select\n const styleContent = `\n/* Add by Midscene because of forceChromeSelectRendering is enabled*/\nselect {\n &, &::picker(select) {\n appearance: base-select !important;\n }\n}`;\n const styleId = 'midscene-force-select-rendering';\n\n const injectStyle = async () => {\n try {\n await (page as PuppeteerPage & PlaywrightPage).evaluate(\n (id, content) => {\n if (document.getElementById(id)) return;\n const style = document.createElement('style');\n style.id = id;\n style.textContent = content;\n document.head.appendChild(style);\n },\n styleId,\n styleContent,\n );\n debugPage(\n 'Midscene - Added base-select appearance style for select elements because of forceChromeSelectRendering is enabled',\n );\n } catch (err) {\n console.log(\n 'Midscene - Failed to add base-select appearance style:',\n err,\n );\n }\n };\n\n // Inject immediately for the current document\n void injectStyle();\n\n // Ensure the style is reapplied on future navigations/new documents\n (page as PuppeteerPage & PlaywrightPage).on('load', () => {\n void injectStyle();\n });\n}\n"],"names":["debugPage","getDebug","Page","defaultActions","commonWebActionsForWebPage","customActions","pageFunction","arg","result","script","error","console","DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY","tree","treeToList","point","isOrderSensitive","elementInfosScriptContent","getElementInfosScriptContent","xpath","JSON","center","options","judgeOrderSensitive","xpaths","sanitized","sanitizeXpaths","feature","elementInfo","buildRectFromElementInfo","Error","scripts","getExtraReturnLogic","assert","startTime","Date","captureElementSnapshot","endTime","sizeInfo","window","imgType","quality","base64","createImgBase64ByFormat","buffer","url","x","y","button","count","page","deltaX","deltaY","from","to","sleep","text","action","keys","Array","k","commands","key","element","backspace","isMac","process","size","targetX","Math","targetY","startingPoint","distance","innerHeight","scrollDistance","innerWidth","name","param","duration","LONG_PRESS_THRESHOLD","MIN_PRESS_THRESHOLD","steps","delay","i","Promise","resolve","setTimeout","res","session","handler","capturedError","event","undefined","files","node","hasWebkitDirectory","hasMultiple","underlyingPage","interfaceType","opts","DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","forceClosePopup","debugProfile","popup","forceChromeSelectRendering","styleContent","styleId","injectStyle","id","content","document","style","err"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- import { ScreenshotItem } from "@midscene/core";
2
1
  import { defineActionDragAndDrop, defineActionHover, defineActionInput, defineActionKeyboardPress, defineActionRightClick, defineActionScroll, defineActionSwipe, defineActionTap } from "@midscene/core/device";
3
2
  import { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from "@midscene/shared/common";
4
3
  function _define_property(obj, key, value) {
@@ -60,20 +59,13 @@ class StaticPage {
60
59
  }
61
60
  async size() {
62
61
  return {
63
- ...this.uiContext.size,
64
- dpr: this.uiContext.size.dpr || 1
62
+ ...this.uiContext.shotSize
65
63
  };
66
64
  }
67
65
  async screenshotBase64() {
68
- if ('screenshot' in this.uiContext && this.uiContext.screenshot) {
69
- const screenshot = this.uiContext.screenshot;
70
- if ('object' == typeof screenshot && 'base64' in screenshot) return screenshot.base64;
71
- return screenshot;
72
- }
73
- const legacyContext = this.uiContext;
74
- const base64 = legacyContext.screenshotBase64;
75
- if (!base64) throw new Error('screenshot base64 is empty');
76
- return base64;
66
+ const screenshot = this.uiContext.screenshot;
67
+ if ('object' == typeof screenshot && 'base64' in screenshot) return screenshot.base64;
68
+ return screenshot;
77
69
  }
78
70
  async url() {
79
71
  return Promise.resolve('https://static_page_without_url');
@@ -106,16 +98,6 @@ class StaticPage {
106
98
  return ThrowNotImplemented('clearInput');
107
99
  }
108
100
  async destroy() {}
109
- async getContext() {
110
- if ('screenshot' in this.uiContext && this.uiContext.screenshot) return this.uiContext;
111
- const screenshotBase64 = await this.screenshotBase64();
112
- const screenshot = ScreenshotItem.create(screenshotBase64);
113
- const size = await this.size();
114
- return {
115
- screenshot,
116
- size
117
- };
118
- }
119
101
  updateContext(newContext) {
120
102
  this.uiContext = newContext;
121
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"static/static-page.mjs","sources":["../../../src/static/static-page.ts"],"sourcesContent":["import type { DeviceAction, Point, UIContext } from '@midscene/core';\nimport type { AbstractInterface } from '@midscene/core/device';\nimport { ScreenshotItem } from '@midscene/core';\nimport {\n defineActionDragAndDrop,\n defineActionHover,\n defineActionInput,\n defineActionKeyboardPress,\n defineActionRightClick,\n defineActionScroll,\n defineActionSwipe,\n defineActionTap,\n} from '@midscene/core/device';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\n\ntype WebUIContext = UIContext | {\n screenshotBase64?: string;\n size: { width: number; height: number; dpr?: number };\n};\n\nconst ThrowNotImplemented = (methodName: string) => {\n throw new Error(\n `The method \"${methodName}\" is not implemented as designed since this is a static UI context. (${ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED})`,\n );\n};\n\nexport default class StaticPage implements AbstractInterface {\n interfaceType = 'static';\n\n private uiContext: WebUIContext;\n\n constructor(uiContext: WebUIContext) {\n this.uiContext = uiContext;\n }\n\n actionSpace(): DeviceAction[] {\n // Return available actions for static page - they will throw \"not implemented\" errors when executed\n // but need to be available for planning phase\n return [\n defineActionTap(async (param) => {\n ThrowNotImplemented('Tap');\n }),\n defineActionRightClick(async (param) => {\n ThrowNotImplemented('RightClick');\n }),\n defineActionHover(async (param) => {\n ThrowNotImplemented('Hover');\n }),\n defineActionInput(async (param) => {\n ThrowNotImplemented('Input');\n }),\n defineActionKeyboardPress(async (param) => {\n ThrowNotImplemented('KeyboardPress');\n }),\n defineActionScroll(async (param) => {\n ThrowNotImplemented('Scroll');\n }),\n defineActionDragAndDrop(async (param) => {\n ThrowNotImplemented('DragAndDrop');\n }),\n defineActionSwipe(async (param) => {\n ThrowNotImplemented('Swipe');\n }),\n ];\n }\n\n async evaluateJavaScript<T = unknown>(script: string): Promise<T> {\n return ThrowNotImplemented('evaluateJavaScript');\n }\n\n // @deprecated\n async getElementsInfo() {\n return ThrowNotImplemented('getElementsInfo');\n }\n\n async getElementsNodeTree() {\n return ThrowNotImplemented('getElementsNodeTree');\n }\n\n async getXpathsByPoint(point: Point) {\n return ThrowNotImplemented('getXpathsByPoint');\n }\n\n async getElementInfoByXpath(xpath: string) {\n return ThrowNotImplemented('getElementInfoByXpath');\n }\n\n async size() {\n return {\n ...this.uiContext.size,\n dpr: this.uiContext.size.dpr || 1,\n };\n }\n\n async screenshotBase64() {\n // Check if this is a UIContext with screenshot property\n if ('screenshot' in this.uiContext && this.uiContext.screenshot) {\n const screenshot = this.uiContext.screenshot;\n if (typeof screenshot === 'object' && 'base64' in screenshot) {\n return (screenshot as { base64: string }).base64;\n }\n return screenshot as unknown as string;\n }\n\n // Check legacy screenshotBase64 field\n const legacyContext = this.uiContext as { screenshotBase64?: string };\n const base64 = legacyContext.screenshotBase64;\n\n if (!base64) {\n throw new Error('screenshot base64 is empty');\n }\n return base64;\n }\n\n async url() {\n return Promise.resolve('https://static_page_without_url');\n }\n\n async scrollUntilTop(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilTop');\n }\n\n async scrollUntilBottom(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilBottom');\n }\n\n async scrollUntilLeft(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilLeft');\n }\n\n async scrollUntilRight(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilRight');\n }\n\n async scrollUp(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollUp');\n }\n\n async scrollDown(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollDown');\n }\n\n async scrollLeft(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollLeft');\n }\n\n async scrollRight(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollRight');\n }\n\n async clearInput() {\n return ThrowNotImplemented('clearInput');\n }\n\n mouse = {\n click: ThrowNotImplemented.bind(null, 'mouse.click'),\n wheel: ThrowNotImplemented.bind(null, 'mouse.wheel'),\n move: ThrowNotImplemented.bind(null, 'mouse.move'),\n drag: ThrowNotImplemented.bind(null, 'mouse.drag'),\n };\n\n keyboard = {\n type: ThrowNotImplemented.bind(null, 'keyboard.type'),\n press: ThrowNotImplemented.bind(null, 'keyboard.press'),\n };\n\n async destroy(): Promise<void> {\n //\n }\n\n async getContext(): Promise<UIContext> {\n // If the context already has a screenshot property, return it as-is\n if ('screenshot' in this.uiContext && this.uiContext.screenshot) {\n return this.uiContext as UIContext;\n }\n\n // Otherwise, create a proper UIContext from the legacy format\n const screenshotBase64 = await this.screenshotBase64();\n const screenshot = ScreenshotItem.create(screenshotBase64);\n const size = await this.size();\n\n return {\n screenshot,\n size,\n };\n }\n\n updateContext(newContext: WebUIContext): void {\n this.uiContext = newContext;\n }\n}\n"],"names":["ThrowNotImplemented","methodName","Error","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","StaticPage","defineActionTap","param","defineActionRightClick","defineActionHover","defineActionInput","defineActionKeyboardPress","defineActionScroll","defineActionDragAndDrop","defineActionSwipe","script","point","xpath","screenshot","legacyContext","base64","Promise","startingPoint","distance","screenshotBase64","ScreenshotItem","size","newContext","uiContext"],"mappings":"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"}
1
+ {"version":3,"file":"static/static-page.mjs","sources":["../../../src/static/static-page.ts"],"sourcesContent":["import type { DeviceAction, Point, UIContext } from '@midscene/core';\nimport type { AbstractInterface } from '@midscene/core/device';\nimport {\n defineActionDragAndDrop,\n defineActionHover,\n defineActionInput,\n defineActionKeyboardPress,\n defineActionRightClick,\n defineActionScroll,\n defineActionSwipe,\n defineActionTap,\n} from '@midscene/core/device';\nimport { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED } from '@midscene/shared/common';\n\n\nconst ThrowNotImplemented = (methodName: string) => {\n throw new Error(\n `The method \"${methodName}\" is not implemented as designed since this is a static UI context. (${ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED})`,\n );\n};\n\ntype StaticPageUIContext = Omit<UIContext, 'deprecatedDpr'>;\n\nexport default class StaticPage implements AbstractInterface {\n interfaceType = 'static';\n\n private uiContext: StaticPageUIContext;\n\n constructor(uiContext: StaticPageUIContext) {\n this.uiContext = uiContext;\n }\n\n actionSpace(): DeviceAction[] {\n // Return available actions for static page - they will throw \"not implemented\" errors when executed\n // but need to be available for planning phase\n return [\n defineActionTap(async (param) => {\n ThrowNotImplemented('Tap');\n }),\n defineActionRightClick(async (param) => {\n ThrowNotImplemented('RightClick');\n }),\n defineActionHover(async (param) => {\n ThrowNotImplemented('Hover');\n }),\n defineActionInput(async (param) => {\n ThrowNotImplemented('Input');\n }),\n defineActionKeyboardPress(async (param) => {\n ThrowNotImplemented('KeyboardPress');\n }),\n defineActionScroll(async (param) => {\n ThrowNotImplemented('Scroll');\n }),\n defineActionDragAndDrop(async (param) => {\n ThrowNotImplemented('DragAndDrop');\n }),\n defineActionSwipe(async (param) => {\n ThrowNotImplemented('Swipe');\n }),\n ];\n }\n\n async evaluateJavaScript<T = unknown>(script: string): Promise<T> {\n return ThrowNotImplemented('evaluateJavaScript');\n }\n\n // @deprecated\n async getElementsInfo() {\n return ThrowNotImplemented('getElementsInfo');\n }\n\n async getElementsNodeTree() {\n return ThrowNotImplemented('getElementsNodeTree');\n }\n\n async getXpathsByPoint(point: Point) {\n return ThrowNotImplemented('getXpathsByPoint');\n }\n\n async getElementInfoByXpath(xpath: string) {\n return ThrowNotImplemented('getElementInfoByXpath');\n }\n\n async size() {\n return {\n ...this.uiContext.shotSize\n };\n }\n\n async screenshotBase64() {\n const screenshot = this.uiContext.screenshot;\n if (typeof screenshot === 'object' && 'base64' in screenshot) {\n return (screenshot as { base64: string }).base64;\n }\n return screenshot as unknown as string;\n }\n\n async url() {\n return Promise.resolve('https://static_page_without_url');\n }\n\n async scrollUntilTop(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilTop');\n }\n\n async scrollUntilBottom(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilBottom');\n }\n\n async scrollUntilLeft(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilLeft');\n }\n\n async scrollUntilRight(startingPoint?: Point) {\n return ThrowNotImplemented('scrollUntilRight');\n }\n\n async scrollUp(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollUp');\n }\n\n async scrollDown(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollDown');\n }\n\n async scrollLeft(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollLeft');\n }\n\n async scrollRight(distance?: number, startingPoint?: Point) {\n return ThrowNotImplemented('scrollRight');\n }\n\n async clearInput() {\n return ThrowNotImplemented('clearInput');\n }\n\n mouse = {\n click: ThrowNotImplemented.bind(null, 'mouse.click'),\n wheel: ThrowNotImplemented.bind(null, 'mouse.wheel'),\n move: ThrowNotImplemented.bind(null, 'mouse.move'),\n drag: ThrowNotImplemented.bind(null, 'mouse.drag'),\n };\n\n keyboard = {\n type: ThrowNotImplemented.bind(null, 'keyboard.type'),\n press: ThrowNotImplemented.bind(null, 'keyboard.press'),\n };\n\n async destroy(): Promise<void> {\n //\n }\n\n\n updateContext(newContext: StaticPageUIContext): void {\n this.uiContext = newContext;\n }\n}\n"],"names":["ThrowNotImplemented","methodName","Error","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","StaticPage","defineActionTap","param","defineActionRightClick","defineActionHover","defineActionInput","defineActionKeyboardPress","defineActionScroll","defineActionDragAndDrop","defineActionSwipe","script","point","xpath","screenshot","Promise","startingPoint","distance","newContext","uiContext"],"mappings":";;;;;;;;;;;;AAeA,MAAMA,sBAAsB,CAACC;IAC3B,MAAM,IAAIC,MACR,CAAC,YAAY,EAAED,WAAW,qEAAqE,EAAEE,uCAAuC,CAAC,CAAC;AAE9I;AAIe,MAAMC;IASnB,cAA8B;QAG5B,OAAO;YACLC,gBAAgB,OAAOC;gBACrBN,oBAAoB;YACtB;YACAO,uBAAuB,OAAOD;gBAC5BN,oBAAoB;YACtB;YACAQ,kBAAkB,OAAOF;gBACvBN,oBAAoB;YACtB;YACAS,kBAAkB,OAAOH;gBACvBN,oBAAoB;YACtB;YACAU,0BAA0B,OAAOJ;gBAC/BN,oBAAoB;YACtB;YACAW,mBAAmB,OAAOL;gBACxBN,oBAAoB;YACtB;YACAY,wBAAwB,OAAON;gBAC7BN,oBAAoB;YACtB;YACAa,kBAAkB,OAAOP;gBACvBN,oBAAoB;YACtB;SACD;IACH;IAEA,MAAM,mBAAgCc,MAAc,EAAc;QAChE,OAAOd,oBAAoB;IAC7B;IAGA,MAAM,kBAAkB;QACtB,OAAOA,oBAAoB;IAC7B;IAEA,MAAM,sBAAsB;QAC1B,OAAOA,oBAAoB;IAC7B;IAEA,MAAM,iBAAiBe,KAAY,EAAE;QACnC,OAAOf,oBAAoB;IAC7B;IAEA,MAAM,sBAAsBgB,KAAa,EAAE;QACzC,OAAOhB,oBAAoB;IAC7B;IAEA,MAAM,OAAO;QACX,OAAO;YACL,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ;QAC5B;IACF;IAEA,MAAM,mBAAmB;QACvB,MAAMiB,aAAa,IAAI,CAAC,SAAS,CAAC,UAAU;QAC5C,IAAI,AAAsB,YAAtB,OAAOA,cAA2B,YAAYA,YAChD,OAAQA,WAAkC,MAAM;QAElD,OAAOA;IACT;IAEA,MAAM,MAAM;QACV,OAAOC,QAAQ,OAAO,CAAC;IACzB;IAEA,MAAM,eAAeC,aAAqB,EAAE;QAC1C,OAAOnB,oBAAoB;IAC7B;IAEA,MAAM,kBAAkBmB,aAAqB,EAAE;QAC7C,OAAOnB,oBAAoB;IAC7B;IAEA,MAAM,gBAAgBmB,aAAqB,EAAE;QAC3C,OAAOnB,oBAAoB;IAC7B;IAEA,MAAM,iBAAiBmB,aAAqB,EAAE;QAC5C,OAAOnB,oBAAoB;IAC7B;IAEA,MAAM,SAASoB,QAAiB,EAAED,aAAqB,EAAE;QACvD,OAAOnB,oBAAoB;IAC7B;IAEA,MAAM,WAAWoB,QAAiB,EAAED,aAAqB,EAAE;QACzD,OAAOnB,oBAAoB;IAC7B;IAEA,MAAM,WAAWoB,QAAiB,EAAED,aAAqB,EAAE;QACzD,OAAOnB,oBAAoB;IAC7B;IAEA,MAAM,YAAYoB,QAAiB,EAAED,aAAqB,EAAE;QAC1D,OAAOnB,oBAAoB;IAC7B;IAEA,MAAM,aAAa;QACjB,OAAOA,oBAAoB;IAC7B;IAcA,MAAM,UAAyB,CAE/B;IAGA,cAAcqB,UAA+B,EAAQ;QACnD,IAAI,CAAC,SAAS,GAAGA;IACnB;IAjIA,YAAYC,SAA8B,CAAE;QAJ5C,wCAAgB;QAEhB,uBAAQ,aAAR;QAgHA,gCAAQ;YACN,OAAOtB,oBAAoB,IAAI,CAAC,MAAM;YACtC,OAAOA,oBAAoB,IAAI,CAAC,MAAM;YACtC,MAAMA,oBAAoB,IAAI,CAAC,MAAM;YACrC,MAAMA,oBAAoB,IAAI,CAAC,MAAM;QACvC;QAEA,mCAAW;YACT,MAAMA,oBAAoB,IAAI,CAAC,MAAM;YACrC,OAAOA,oBAAoB,IAAI,CAAC,MAAM;QACxC;QAvHE,IAAI,CAAC,SAAS,GAAGsB;IACnB;AAgIF"}
@@ -1,5 +1,3 @@
1
- import { getDebug } from "@midscene/shared/logger";
2
- import { commonContextParser } from "@midscene/core/agent";
3
1
  function _define_property(obj, key, value) {
4
2
  if (key in obj) Object.defineProperty(obj, key, {
5
3
  value: value,
@@ -33,13 +31,6 @@ class WebElementInfoImpl {
33
31
  this.isVisible = isVisible;
34
32
  }
35
33
  }
36
- getDebug('web:parse-context');
37
- async function WebPageContextParser(page, _opt) {
38
- const basicContext = await commonContextParser(page, {
39
- uploadServerUrl: _opt.uploadServerUrl
40
- });
41
- return basicContext;
42
- }
43
34
  const limitOpenNewTabScript = `
44
35
  if (!window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__) {
45
36
  window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__ = true;
@@ -63,6 +54,6 @@ if (!window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__) {
63
54
  }, true);
64
55
  }
65
56
  `;
66
- export { WebElementInfoImpl, WebPageContextParser, limitOpenNewTabScript };
57
+ export { WebElementInfoImpl, limitOpenNewTabScript };
67
58
 
68
59
  //# sourceMappingURL=web-element.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-element.mjs","sources":["../../src/web-element.ts"],"sourcesContent":["import type {\n AgentOpt,\n DeviceAction,\n Rect,\n UIContext,\n WebElementInfo,\n} from '@midscene/core';\nimport type { AbstractInterface } from '@midscene/core/device';\nimport { getDebug } from '@midscene/shared/logger';\nimport { _keyDefinitions } from '@midscene/shared/us-keyboard-layout';\n\nimport { commonContextParser } from '@midscene/core/agent';\nimport type { NodeType } from '@midscene/shared/constants';\nimport type ChromeExtensionProxyPage from './chrome-extension/page';\nimport type { PlaywrightWebPage } from './playwright';\nimport type { PuppeteerWebPage } from './puppeteer';\nimport type { StaticPage } from './static';\nexport type { WebElementInfo };\n\nexport type WebPageAgentOpt = AgentOpt & WebPageOpt;\nexport type WebPageOpt = {\n waitForNavigationTimeout?: number;\n waitForNetworkIdleTimeout?: number;\n forceSameTabNavigation?: boolean /* if limit the new tab to the current page, default true */;\n enableTouchEventsInActionSpace?: boolean;\n /**\n * Force Chrome to render select elements using base-select appearance instead of OS-native rendering.\n * This makes select elements visible in screenshots captured by Playwright/Puppeteer.\n *\n * Reference: https://developer.chrome.com/blog/a-customizable-select\n *\n * When enabled, adds a style tag with `select { appearance: base-select !important; }` to the page.\n */\n forceChromeSelectRendering?: boolean;\n beforeInvokeAction?: () => Promise<void>;\n afterInvokeAction?: () => Promise<void>;\n customActions?: DeviceAction<any>[];\n};\n\nexport type WebPage =\n | PlaywrightWebPage\n | PuppeteerWebPage\n | StaticPage\n | ChromeExtensionProxyPage;\n\nexport class WebElementInfoImpl implements WebElementInfo {\n content: string;\n\n rect: Rect;\n\n center: [number, number];\n\n id: string;\n\n indexId: number;\n\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n\n xpaths?: string[];\n\n isVisible: boolean;\n\n constructor({\n content,\n rect,\n id,\n attributes,\n indexId,\n xpaths,\n isVisible,\n }: {\n content: string;\n rect: Rect;\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n indexId: number;\n xpaths?: string[];\n isVisible: boolean;\n }) {\n this.content = content;\n this.rect = rect;\n this.center = [\n Math.floor(rect.left + rect.width / 2),\n Math.floor(rect.top + rect.height / 2),\n ];\n this.id = id;\n this.attributes = attributes;\n this.indexId = indexId;\n this.xpaths = xpaths;\n this.isVisible = isVisible;\n }\n}\n\nconst debug = getDebug('web:parse-context');\nexport async function WebPageContextParser(\n page: AbstractInterface,\n _opt: { uploadServerUrl?: string },\n): Promise<UIContext> {\n const basicContext = await commonContextParser(page, {\n uploadServerUrl: _opt.uploadServerUrl,\n });\n\n // debug('will traverse element tree');\n // const tree = (await page.getElementsNodeTree?.()) || {\n // node: null,\n // children: [],\n // };\n // // const webTree = traverseTree(tree!, (elementInfo) => {\n // // const { rect, id, content, attributes, indexId, isVisible } = elementInfo;\n // // return new WebElementInfoImpl({\n // // rect,\n // // id,\n // // content,\n // // attributes,\n // // indexId,\n // // isVisible,\n // // });\n // // });\n // debug('traverse element tree end');\n\n return basicContext;\n}\n\nexport const limitOpenNewTabScript = `\nif (!window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__) {\n window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__ = true;\n\n // Intercept the window.open method (only once)\n window.open = function(url) {\n console.log('Blocked window.open:', url);\n window.location.href = url;\n return null;\n };\n\n // Block all a tag clicks with target=\"_blank\" (only once)\n document.addEventListener('click', function(e) {\n const target = e.target.closest('a');\n if (target && target.target === '_blank') {\n e.preventDefault();\n console.log('Blocked new tab:', target.href);\n window.location.href = target.href;\n target.removeAttribute('target');\n }\n }, true);\n}\n`;\n"],"names":["WebElementInfoImpl","content","rect","id","attributes","indexId","xpaths","isVisible","Math","getDebug","WebPageContextParser","page","_opt","basicContext","commonContextParser","limitOpenNewTabScript"],"mappings":";;;;;;;;;;;;AA6CO,MAAMA;IAoBX,YAAY,EACVC,OAAO,EACPC,IAAI,EACJC,EAAE,EACFC,UAAU,EACVC,OAAO,EACPC,MAAM,EACNC,SAAS,EAYV,CAAE;QAtCH;QAEA;QAEA;QAEA;QAEA;QAEA;QAKA;QAEA;QAsBE,IAAI,CAAC,OAAO,GAAGN;QACf,IAAI,CAAC,IAAI,GAAGC;QACZ,IAAI,CAAC,MAAM,GAAG;YACZM,KAAK,KAAK,CAACN,KAAK,IAAI,GAAGA,KAAK,KAAK,GAAG;YACpCM,KAAK,KAAK,CAACN,KAAK,GAAG,GAAGA,KAAK,MAAM,GAAG;SACrC;QACD,IAAI,CAAC,EAAE,GAAGC;QACV,IAAI,CAAC,UAAU,GAAGC;QAClB,IAAI,CAAC,OAAO,GAAGC;QACf,IAAI,CAAC,MAAM,GAAGC;QACd,IAAI,CAAC,SAAS,GAAGC;IACnB;AACF;AAEcE,SAAS;AAChB,eAAeC,qBACpBC,IAAuB,EACvBC,IAAkC;IAElC,MAAMC,eAAe,MAAMC,oBAAoBH,MAAM;QACnD,iBAAiBC,KAAK,eAAe;IACvC;IAoBA,OAAOC;AACT;AAEO,MAAME,wBAAwB,CAAC;;;;;;;;;;;;;;;;;;;;;;AAsBtC,CAAC"}
1
+ {"version":3,"file":"web-element.mjs","sources":["../../src/web-element.ts"],"sourcesContent":["import type {\n AgentOpt,\n DeviceAction,\n Rect,\n WebElementInfo,\n} from '@midscene/core';\nimport { _keyDefinitions } from '@midscene/shared/us-keyboard-layout';\n\nimport type { NodeType } from '@midscene/shared/constants';\nexport type { WebElementInfo };\n\nexport type WebPageAgentOpt = AgentOpt & WebPageOpt;\nexport type WebPageOpt = {\n waitForNavigationTimeout?: number;\n waitForNetworkIdleTimeout?: number;\n forceSameTabNavigation?: boolean /* if limit the new tab to the current page, default true */;\n enableTouchEventsInActionSpace?: boolean;\n /**\n * Force Chrome to render select elements using base-select appearance instead of OS-native rendering.\n * This makes select elements visible in screenshots captured by Playwright/Puppeteer.\n *\n * Reference: https://developer.chrome.com/blog/a-customizable-select\n *\n * When enabled, adds a style tag with `select { appearance: base-select !important; }` to the page.\n */\n forceChromeSelectRendering?: boolean;\n beforeInvokeAction?: () => Promise<void>;\n afterInvokeAction?: () => Promise<void>;\n customActions?: DeviceAction<any>[];\n};\n\nexport class WebElementInfoImpl implements WebElementInfo {\n content: string;\n\n rect: Rect;\n\n center: [number, number];\n\n id: string;\n\n indexId: number;\n\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n\n xpaths?: string[];\n\n isVisible: boolean;\n\n constructor({\n content,\n rect,\n id,\n attributes,\n indexId,\n xpaths,\n isVisible,\n }: {\n content: string;\n rect: Rect;\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n indexId: number;\n xpaths?: string[];\n isVisible: boolean;\n }) {\n this.content = content;\n this.rect = rect;\n this.center = [\n Math.floor(rect.left + rect.width / 2),\n Math.floor(rect.top + rect.height / 2),\n ];\n this.id = id;\n this.attributes = attributes;\n this.indexId = indexId;\n this.xpaths = xpaths;\n this.isVisible = isVisible;\n }\n}\n\nexport const limitOpenNewTabScript = `\nif (!window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__) {\n window.__MIDSCENE_NEW_TAB_INTERCEPTOR_INITIALIZED__ = true;\n\n // Intercept the window.open method (only once)\n window.open = function(url) {\n console.log('Blocked window.open:', url);\n window.location.href = url;\n return null;\n };\n\n // Block all a tag clicks with target=\"_blank\" (only once)\n document.addEventListener('click', function(e) {\n const target = e.target.closest('a');\n if (target && target.target === '_blank') {\n e.preventDefault();\n console.log('Blocked new tab:', target.href);\n window.location.href = target.href;\n target.removeAttribute('target');\n }\n }, true);\n}\n`;\n"],"names":["WebElementInfoImpl","content","rect","id","attributes","indexId","xpaths","isVisible","Math","limitOpenNewTabScript"],"mappings":";;;;;;;;;;AA+BO,MAAMA;IAoBX,YAAY,EACVC,OAAO,EACPC,IAAI,EACJC,EAAE,EACFC,UAAU,EACVC,OAAO,EACPC,MAAM,EACNC,SAAS,EAYV,CAAE;QAtCH;QAEA;QAEA;QAEA;QAEA;QAEA;QAKA;QAEA;QAsBE,IAAI,CAAC,OAAO,GAAGN;QACf,IAAI,CAAC,IAAI,GAAGC;QACZ,IAAI,CAAC,MAAM,GAAG;YACZM,KAAK,KAAK,CAACN,KAAK,IAAI,GAAGA,KAAK,KAAK,GAAG;YACpCM,KAAK,KAAK,CAACN,KAAK,GAAG,GAAGA,KAAK,MAAM,GAAG;SACrC;QACD,IAAI,CAAC,EAAE,GAAGC;QACV,IAAI,CAAC,UAAU,GAAGC;QAClB,IAAI,CAAC,OAAO,GAAGC;QACf,IAAI,CAAC,MAAM,GAAGC;QACd,IAAI,CAAC,SAAS,GAAGC;IACnB;AACF;AAEO,MAAME,wBAAwB,CAAC;;;;;;;;;;;;;;;;;;;;;;AAsBtC,CAAC"}
package/dist/lib/bin.js CHANGED
@@ -26,13 +26,14 @@ const external_cors_namespaceObject = require("cors");
26
26
  var external_cors_default = /*#__PURE__*/ __webpack_require__.n(external_cors_namespaceObject);
27
27
  const index_js_namespaceObject = require("./static/index.js");
28
28
  require("dotenv/config");
29
+ const core_namespaceObject = require("@midscene/core");
29
30
  async function startServer() {
30
31
  const page = new index_js_namespaceObject.StaticPage({
31
- size: {
32
+ shotSize: {
32
33
  width: 800,
33
34
  height: 600
34
35
  },
35
- screenshotBase64: ''
36
+ screenshot: core_namespaceObject.ScreenshotItem.create('')
36
37
  });
37
38
  const agent = new index_js_namespaceObject.StaticPageAgent(page);
38
39
  const server = new playground_namespaceObject.PlaygroundServer(agent);
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","../../src/bin.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))","import { PlaygroundServer } from '@midscene/playground';\nimport cors from 'cors';\nimport { StaticPage, StaticPageAgent } from './static';\nimport 'dotenv/config';\n\nasync function startServer() {\n // Create page and agent instances with minimal valid data\n // Use screenshotBase64 field for empty screenshot\n const page = new StaticPage({\n size: { width: 800, height: 600 },\n screenshotBase64: '',\n });\n const agent = new StaticPageAgent(page);\n\n // Create server with agent only\n const server = new PlaygroundServer(agent);\n\n // Register CORS middleware\n server.app.use(\n cors({\n origin: '*',\n credentials: true,\n }),\n );\n\n await server.launch();\n console.log(\n `Midscene playground server is running on http://localhost:${server.port}`,\n );\n}\n\nstartServer().catch(console.error);\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","startServer","page","StaticPage","agent","StaticPageAgent","server","PlaygroundServer","cors","console"],"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;;;;;;;;ACKlF,eAAeC;IAGb,MAAMC,OAAO,IAAIC,yBAAAA,UAAUA,CAAC;QAC1B,MAAM;YAAE,OAAO;YAAK,QAAQ;QAAI;QAChC,kBAAkB;IACpB;IACA,MAAMC,QAAQ,IAAIC,yBAAAA,eAAeA,CAACH;IAGlC,MAAMI,SAAS,IAAIC,2BAAAA,gBAAgBA,CAACH;IAGpCE,OAAO,GAAG,CAAC,GAAG,CACZE,wBAAK;QACH,QAAQ;QACR,aAAa;IACf;IAGF,MAAMF,OAAO,MAAM;IACnBG,QAAQ,GAAG,CACT,CAAC,0DAA0D,EAAEH,OAAO,IAAI,EAAE;AAE9E;AAEAL,cAAc,KAAK,CAACQ,QAAQ,KAAK"}
1
+ {"version":3,"file":"bin.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","../../src/bin.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))","import { PlaygroundServer } from '@midscene/playground';\nimport cors from 'cors';\nimport { StaticPage, StaticPageAgent } from './static';\nimport 'dotenv/config';\nimport { ScreenshotItem } from '@midscene/core';\n\nasync function startServer() {\n // Create page and agent instances with minimal valid data\n // Use screenshotBase64 field for empty screenshot\n const page = new StaticPage({\n shotSize: { width: 800, height: 600 },\n screenshot: ScreenshotItem.create(''),\n });\n const agent = new StaticPageAgent(page);\n\n // Create server with agent only\n const server = new PlaygroundServer(agent);\n\n // Register CORS middleware\n server.app.use(\n cors({\n origin: '*',\n credentials: true,\n }),\n );\n\n await server.launch();\n console.log(\n `Midscene playground server is running on http://localhost:${server.port}`,\n );\n}\n\nstartServer().catch(console.error);\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","startServer","page","StaticPage","ScreenshotItem","agent","StaticPageAgent","server","PlaygroundServer","cors","console"],"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;;;;;;;;;ACMlF,eAAeC;IAGb,MAAMC,OAAO,IAAIC,yBAAAA,UAAUA,CAAC;QAC1B,UAAU;YAAE,OAAO;YAAK,QAAQ;QAAI;QACpC,YAAYC,qBAAAA,cAAAA,CAAAA,MAAqB,CAAC;IACpC;IACA,MAAMC,QAAQ,IAAIC,yBAAAA,eAAeA,CAACJ;IAGlC,MAAMK,SAAS,IAAIC,2BAAAA,gBAAgBA,CAACH;IAGpCE,OAAO,GAAG,CAAC,GAAG,CACZE,wBAAK;QACH,QAAQ;QACR,aAAa;IACf;IAGF,MAAMF,OAAO,MAAM;IACnBG,QAAQ,GAAG,CACT,CAAC,0DAA0D,EAAEH,OAAO,IAAI,EAAE;AAE9E;AAEAN,cAAc,KAAK,CAACS,QAAQ,KAAK"}
@@ -67,7 +67,6 @@ const getBridgePageInCliSide = (options)=>{
67
67
  if ('toJSON' === prop) return ()=>({
68
68
  interfaceType: external_common_js_namespaceObject.BridgePageType
69
69
  });
70
- if ('getContext' === prop) return;
71
70
  if ('interfaceType' === prop) return external_common_js_namespaceObject.BridgePageType;
72
71
  if ('actionSpace' === prop) return ()=>(0, external_web_page_js_namespaceObject.commonWebActionsForWebPage)(proxyPage);
73
72
  if (Object.keys(page).includes(prop)) return page[prop];
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-mode/agent-cli-side.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/bridge-mode/agent-cli-side.ts"],"sourcesContent":["__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 { Agent, type AgentOpt } from '@midscene/core/agent';\nimport { assert } from '@midscene/shared/utils';\nimport { commonWebActionsForWebPage } from '../web-page';\nimport type { KeyboardAction, MouseAction } from '../web-page';\nimport {\n type BridgeConnectTabOptions,\n BridgeEvent,\n BridgePageType,\n DefaultBridgeServerHost,\n DefaultBridgeServerPort,\n KeyboardEvent,\n MouseEvent,\n getBridgeServerHost,\n} from './common';\nimport { BridgeServer } from './io-server';\nimport type { ExtensionBridgePageBrowserSide } from './page-browser-side';\n\ninterface ChromeExtensionPageCliSide extends ExtensionBridgePageBrowserSide {\n showStatusMessage: (message: string) => Promise<void>;\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n// actually, this is a proxy to the page in browser side\nexport const getBridgePageInCliSide = (options?: {\n host?: string;\n port?: number;\n timeout?: number | false;\n closeConflictServer?: boolean;\n}): ChromeExtensionPageCliSide => {\n const host = options?.host || DefaultBridgeServerHost;\n const port = options?.port || DefaultBridgeServerPort;\n const server = new BridgeServer(\n host,\n port,\n undefined,\n undefined,\n options?.closeConflictServer,\n );\n server.listen({\n timeout: options?.timeout,\n });\n const bridgeCaller = (method: string, timeout?: number) => {\n return async (...args: any[]) => {\n const response = await server.call(method, args, timeout);\n return response;\n };\n };\n const page = {\n showStatusMessage: async (message: string) => {\n await server.call(BridgeEvent.UpdateAgentStatus, [message]);\n },\n };\n\n const proxyPage = new Proxy(page, {\n get(target, prop, receiver) {\n assert(typeof prop === 'string', 'prop must be a string');\n\n if (prop === 'toJSON') {\n return () => {\n return {\n interfaceType: BridgePageType,\n };\n };\n }\n\n if (prop === 'getContext') {\n return undefined;\n }\n\n if (prop === 'interfaceType') {\n return BridgePageType;\n }\n\n if (prop === 'actionSpace') {\n return () => commonWebActionsForWebPage(proxyPage);\n }\n\n if (Object.keys(page).includes(prop)) {\n return page[prop as keyof typeof page];\n }\n\n if (prop === 'mouse') {\n const mouse: MouseAction = {\n click: bridgeCaller(MouseEvent.Click),\n wheel: bridgeCaller(MouseEvent.Wheel),\n move: bridgeCaller(MouseEvent.Move),\n drag: bridgeCaller(MouseEvent.Drag),\n };\n return mouse;\n }\n\n if (prop === 'keyboard') {\n const keyboard: KeyboardAction = {\n type: bridgeCaller(KeyboardEvent.Type),\n press: bridgeCaller(KeyboardEvent.Press),\n };\n return keyboard;\n }\n\n if (prop === 'destroy') {\n return async (...args: any[]) => {\n try {\n const caller = bridgeCaller('destroy');\n await caller(...args);\n } catch (e) {\n // console.error('error calling destroy', e);\n }\n return server.close();\n };\n }\n\n // Special handling for methods that support timeout in options\n if (prop === 'connectNewTabWithUrl') {\n return async (url: string, options?: BridgeConnectTabOptions) => {\n const timeout = options?.timeout;\n const caller = bridgeCaller(prop, timeout);\n return await caller(url, options);\n };\n }\n\n if (prop === 'connectCurrentTab') {\n return async (options?: BridgeConnectTabOptions) => {\n const timeout = options?.timeout;\n const caller = bridgeCaller(prop, timeout);\n return await caller(options);\n };\n }\n\n return bridgeCaller(prop);\n },\n }) as ChromeExtensionPageCliSide;\n\n return proxyPage;\n};\n\nexport class AgentOverChromeBridge extends Agent<ChromeExtensionPageCliSide> {\n private destroyAfterDisconnectFlag?: boolean;\n\n constructor(\n opts?: AgentOpt & {\n /**\n * Enable remote access to the bridge server.\n * - false (default): Only localhost can connect (most secure)\n * - true: Allow remote machines to connect (binds to 0.0.0.0)\n */\n allowRemoteAccess?: boolean;\n /**\n * Custom host to bind the bridge server to.\n * Overrides allowRemoteAccess if specified.\n */\n host?: string;\n /**\n * Custom port for the bridge server.\n * @default 3766\n */\n port?: number;\n closeNewTabsAfterDisconnect?: boolean;\n serverListeningTimeout?: number | false;\n closeConflictServer?: boolean;\n },\n ) {\n const host = getBridgeServerHost({\n host: opts?.host,\n allowRemoteAccess: opts?.allowRemoteAccess,\n });\n const page = getBridgePageInCliSide({\n host,\n port: opts?.port,\n timeout: opts?.serverListeningTimeout,\n closeConflictServer: opts?.closeConflictServer,\n });\n const originalOnTaskStartTip = opts?.onTaskStartTip;\n super(\n page,\n Object.assign(opts || {}, {\n onTaskStartTip: (tip: string) => {\n this.page.showStatusMessage(tip);\n if (originalOnTaskStartTip) {\n originalOnTaskStartTip?.call(this, tip);\n }\n },\n }),\n );\n this.destroyAfterDisconnectFlag = opts?.closeNewTabsAfterDisconnect;\n }\n\n async setDestroyOptionsAfterConnect() {\n if (this.destroyAfterDisconnectFlag) {\n this.page.setDestroyOptions({\n closeTab: true,\n });\n }\n }\n\n async connectNewTabWithUrl(url: string, options?: BridgeConnectTabOptions) {\n await this.page.connectNewTabWithUrl(url, options);\n await sleep(500);\n await this.setDestroyOptionsAfterConnect();\n }\n\n async getBrowserTabList() {\n return await this.page.getBrowserTabList();\n }\n\n async setActiveTabId(tabId: string) {\n return await this.page.setActiveTabId(Number.parseInt(tabId));\n }\n\n async connectCurrentTab(options?: BridgeConnectTabOptions) {\n await this.page.connectCurrentTab(options);\n await sleep(500);\n await this.setDestroyOptionsAfterConnect();\n }\n\n async aiAct(prompt: string, options?: any) {\n if (options) {\n console.warn(\n 'the `options` parameter of aiAct is not supported in cli side',\n );\n }\n return await super.aiAct(prompt);\n }\n\n async destroy(closeNewTabsAfterDisconnect?: boolean) {\n if (typeof closeNewTabsAfterDisconnect === 'boolean') {\n await this.page.setDestroyOptions({\n closeTab: closeNewTabsAfterDisconnect,\n });\n }\n await super.destroy();\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","sleep","ms","Promise","resolve","setTimeout","getBridgePageInCliSide","options","host","DefaultBridgeServerHost","port","DefaultBridgeServerPort","server","BridgeServer","undefined","bridgeCaller","method","timeout","args","response","page","message","BridgeEvent","proxyPage","Proxy","target","receiver","assert","BridgePageType","commonWebActionsForWebPage","mouse","MouseEvent","keyboard","KeyboardEvent","caller","e","url","AgentOverChromeBridge","Agent","tabId","Number","prompt","console","closeNewTabsAfterDisconnect","opts","getBridgeServerHost","originalOnTaskStartTip","tip"],"mappings":"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"}
1
+ {"version":3,"file":"bridge-mode/agent-cli-side.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/bridge-mode/agent-cli-side.ts"],"sourcesContent":["__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 { Agent, type AgentOpt } from '@midscene/core/agent';\nimport { assert } from '@midscene/shared/utils';\nimport { commonWebActionsForWebPage } from '../web-page';\nimport type { KeyboardAction, MouseAction } from '../web-page';\nimport {\n type BridgeConnectTabOptions,\n BridgeEvent,\n BridgePageType,\n DefaultBridgeServerHost,\n DefaultBridgeServerPort,\n KeyboardEvent,\n MouseEvent,\n getBridgeServerHost,\n} from './common';\nimport { BridgeServer } from './io-server';\nimport type { ExtensionBridgePageBrowserSide } from './page-browser-side';\n\ninterface ChromeExtensionPageCliSide extends ExtensionBridgePageBrowserSide {\n showStatusMessage: (message: string) => Promise<void>;\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n// actually, this is a proxy to the page in browser side\nexport const getBridgePageInCliSide = (options?: {\n host?: string;\n port?: number;\n timeout?: number | false;\n closeConflictServer?: boolean;\n}): ChromeExtensionPageCliSide => {\n const host = options?.host || DefaultBridgeServerHost;\n const port = options?.port || DefaultBridgeServerPort;\n const server = new BridgeServer(\n host,\n port,\n undefined,\n undefined,\n options?.closeConflictServer,\n );\n server.listen({\n timeout: options?.timeout,\n });\n const bridgeCaller = (method: string, timeout?: number) => {\n return async (...args: any[]) => {\n const response = await server.call(method, args, timeout);\n return response;\n };\n };\n const page = {\n showStatusMessage: async (message: string) => {\n await server.call(BridgeEvent.UpdateAgentStatus, [message]);\n },\n };\n\n const proxyPage = new Proxy(page, {\n get(target, prop, receiver) {\n assert(typeof prop === 'string', 'prop must be a string');\n\n if (prop === 'toJSON') {\n return () => {\n return {\n interfaceType: BridgePageType,\n };\n };\n }\n\n if (prop === 'interfaceType') {\n return BridgePageType;\n }\n\n if (prop === 'actionSpace') {\n return () => commonWebActionsForWebPage(proxyPage);\n }\n\n if (Object.keys(page).includes(prop)) {\n return page[prop as keyof typeof page];\n }\n\n if (prop === 'mouse') {\n const mouse: MouseAction = {\n click: bridgeCaller(MouseEvent.Click),\n wheel: bridgeCaller(MouseEvent.Wheel),\n move: bridgeCaller(MouseEvent.Move),\n drag: bridgeCaller(MouseEvent.Drag),\n };\n return mouse;\n }\n\n if (prop === 'keyboard') {\n const keyboard: KeyboardAction = {\n type: bridgeCaller(KeyboardEvent.Type),\n press: bridgeCaller(KeyboardEvent.Press),\n };\n return keyboard;\n }\n\n if (prop === 'destroy') {\n return async (...args: any[]) => {\n try {\n const caller = bridgeCaller('destroy');\n await caller(...args);\n } catch (e) {\n // console.error('error calling destroy', e);\n }\n return server.close();\n };\n }\n\n // Special handling for methods that support timeout in options\n if (prop === 'connectNewTabWithUrl') {\n return async (url: string, options?: BridgeConnectTabOptions) => {\n const timeout = options?.timeout;\n const caller = bridgeCaller(prop, timeout);\n return await caller(url, options);\n };\n }\n\n if (prop === 'connectCurrentTab') {\n return async (options?: BridgeConnectTabOptions) => {\n const timeout = options?.timeout;\n const caller = bridgeCaller(prop, timeout);\n return await caller(options);\n };\n }\n\n return bridgeCaller(prop);\n },\n }) as ChromeExtensionPageCliSide;\n\n return proxyPage;\n};\n\nexport class AgentOverChromeBridge extends Agent<ChromeExtensionPageCliSide> {\n private destroyAfterDisconnectFlag?: boolean;\n\n constructor(\n opts?: AgentOpt & {\n /**\n * Enable remote access to the bridge server.\n * - false (default): Only localhost can connect (most secure)\n * - true: Allow remote machines to connect (binds to 0.0.0.0)\n */\n allowRemoteAccess?: boolean;\n /**\n * Custom host to bind the bridge server to.\n * Overrides allowRemoteAccess if specified.\n */\n host?: string;\n /**\n * Custom port for the bridge server.\n * @default 3766\n */\n port?: number;\n closeNewTabsAfterDisconnect?: boolean;\n serverListeningTimeout?: number | false;\n closeConflictServer?: boolean;\n },\n ) {\n const host = getBridgeServerHost({\n host: opts?.host,\n allowRemoteAccess: opts?.allowRemoteAccess,\n });\n const page = getBridgePageInCliSide({\n host,\n port: opts?.port,\n timeout: opts?.serverListeningTimeout,\n closeConflictServer: opts?.closeConflictServer,\n });\n const originalOnTaskStartTip = opts?.onTaskStartTip;\n super(\n page,\n Object.assign(opts || {}, {\n onTaskStartTip: (tip: string) => {\n this.page.showStatusMessage(tip);\n if (originalOnTaskStartTip) {\n originalOnTaskStartTip?.call(this, tip);\n }\n },\n }),\n );\n this.destroyAfterDisconnectFlag = opts?.closeNewTabsAfterDisconnect;\n }\n\n async setDestroyOptionsAfterConnect() {\n if (this.destroyAfterDisconnectFlag) {\n this.page.setDestroyOptions({\n closeTab: true,\n });\n }\n }\n\n async connectNewTabWithUrl(url: string, options?: BridgeConnectTabOptions) {\n await this.page.connectNewTabWithUrl(url, options);\n await sleep(500);\n await this.setDestroyOptionsAfterConnect();\n }\n\n async getBrowserTabList() {\n return await this.page.getBrowserTabList();\n }\n\n async setActiveTabId(tabId: string) {\n return await this.page.setActiveTabId(Number.parseInt(tabId));\n }\n\n async connectCurrentTab(options?: BridgeConnectTabOptions) {\n await this.page.connectCurrentTab(options);\n await sleep(500);\n await this.setDestroyOptionsAfterConnect();\n }\n\n async aiAct(prompt: string, options?: any) {\n if (options) {\n console.warn(\n 'the `options` parameter of aiAct is not supported in cli side',\n );\n }\n return await super.aiAct(prompt);\n }\n\n async destroy(closeNewTabsAfterDisconnect?: boolean) {\n if (typeof closeNewTabsAfterDisconnect === 'boolean') {\n await this.page.setDestroyOptions({\n closeTab: closeNewTabsAfterDisconnect,\n });\n }\n await super.destroy();\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","sleep","ms","Promise","resolve","setTimeout","getBridgePageInCliSide","options","host","DefaultBridgeServerHost","port","DefaultBridgeServerPort","server","BridgeServer","undefined","bridgeCaller","method","timeout","args","response","page","message","BridgeEvent","proxyPage","Proxy","target","receiver","assert","BridgePageType","commonWebActionsForWebPage","mouse","MouseEvent","keyboard","KeyboardEvent","caller","e","url","AgentOverChromeBridge","Agent","tabId","Number","prompt","console","closeNewTabsAfterDisconnect","opts","getBridgeServerHost","originalOnTaskStartTip","tip"],"mappings":"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"}
@@ -51,7 +51,7 @@ class BridgeClient {
51
51
  ]
52
52
  } : {},
53
53
  query: {
54
- version: "1.4.5"
54
+ version: "1.4.7"
55
55
  }
56
56
  });
57
57
  const timeout = setTimeout(()=>{
@@ -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.4.5, browser-side version v${clientVersion}`);
107
+ (0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v1.4.7, 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.4.5"
132
+ version: "1.4.7"
133
133
  };
134
134
  socket.emit(external_common_js_namespaceObject.BridgeEvent.Connected, payload);
135
135
  Promise.resolve().then(()=>{
@@ -100,7 +100,7 @@ class ExtensionBridgePageBrowserSide extends page_js_default() {
100
100
  throw new Error('Connection denied by user');
101
101
  }
102
102
  }
103
- this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.4.5`, 'log');
103
+ this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.4.7`, 'log');
104
104
  }
105
105
  async connect() {
106
106
  return await this.setupBridgeClient();
@@ -197,8 +197,7 @@ class ChromeExtensionProxyPage {
197
197
  tree,
198
198
  size: {
199
199
  width: document.documentElement.clientWidth,
200
- height: document.documentElement.clientHeight,
201
- dpr: window.devicePixelRatio
200
+ height: document.documentElement.clientHeight
202
201
  }
203
202
  };
204
203
  };
@@ -286,7 +285,7 @@ class ChromeExtensionProxyPage {
286
285
  const xpaths = (0, cache_helper_js_namespaceObject.sanitizeXpaths)(feature.xpaths);
287
286
  for (const xpath of xpaths)try {
288
287
  const elementInfo = await this.getElementInfoByXpath(xpath);
289
- if (elementInfo?.rect) return (0, cache_helper_js_namespaceObject.buildRectFromElementInfo)(elementInfo, this.viewportSize?.dpr);
288
+ if (elementInfo?.rect) return (0, cache_helper_js_namespaceObject.buildRectFromElementInfo)(elementInfo);
290
289
  } catch (error) {
291
290
  debug('rectMatchesCacheFeature failed for xpath %s: %O', xpath, error);
292
291
  }
@@ -301,13 +300,10 @@ class ChromeExtensionProxyPage {
301
300
  children: []
302
301
  };
303
302
  }
304
- async getContext() {
305
- return await (0, external_web_element_js_namespaceObject.WebPageContextParser)(this, {});
306
- }
307
303
  async size() {
308
304
  if (this.viewportSize) return this.viewportSize;
309
305
  const result = await this.sendCommandToDebugger('Runtime.evaluate', {
310
- expression: '({width: window.innerWidth, height: window.innerHeight, dpr: window.devicePixelRatio})',
306
+ expression: '({width: window.innerWidth, height: window.innerHeight})',
311
307
  returnByValue: true
312
308
  });
313
309
  const sizeInfo = result.result.value;