@rpascene/web 0.30.8 → 0.30.9

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 (40) hide show
  1. package/README.md +2 -2
  2. package/dist/es/bin.mjs +1 -1
  3. package/dist/es/bin.mjs.map +1 -1
  4. package/dist/es/bridge-mode/common.mjs +1 -1
  5. package/dist/es/bridge-mode/common.mjs.map +1 -1
  6. package/dist/es/chrome-extension/page.mjs +12 -12
  7. package/dist/es/chrome-extension/page.mjs.map +1 -1
  8. package/dist/es/playwright/ai-fixture.mjs +9 -9
  9. package/dist/es/playwright/ai-fixture.mjs.map +1 -1
  10. package/dist/es/playwright/reporter/index.mjs +6 -6
  11. package/dist/es/playwright/reporter/index.mjs.map +1 -1
  12. package/dist/es/puppeteer/agent-launcher.mjs +1 -1
  13. package/dist/es/puppeteer/agent-launcher.mjs.map +1 -1
  14. package/dist/es/puppeteer/base-page.mjs +5 -5
  15. package/dist/es/puppeteer/base-page.mjs.map +1 -1
  16. package/dist/es/web-element.mjs +2 -2
  17. package/dist/es/web-element.mjs.map +1 -1
  18. package/dist/lib/bin.js +1 -1
  19. package/dist/lib/bin.js.map +1 -1
  20. package/dist/lib/bridge-mode/common.js +1 -1
  21. package/dist/lib/bridge-mode/common.js.map +1 -1
  22. package/dist/lib/chrome-extension/page.js +12 -12
  23. package/dist/lib/chrome-extension/page.js.map +1 -1
  24. package/dist/lib/playwright/ai-fixture.js +11 -11
  25. package/dist/lib/playwright/ai-fixture.js.map +1 -1
  26. package/dist/lib/playwright/reporter/index.js +6 -6
  27. package/dist/lib/playwright/reporter/index.js.map +1 -1
  28. package/dist/lib/puppeteer/agent-launcher.js +1 -1
  29. package/dist/lib/puppeteer/agent-launcher.js.map +1 -1
  30. package/dist/lib/puppeteer/base-page.js +5 -5
  31. package/dist/lib/puppeteer/base-page.js.map +1 -1
  32. package/dist/lib/web-element.js +2 -2
  33. package/dist/lib/web-element.js.map +1 -1
  34. package/dist/types/bridge-mode/agent-cli-side.d.ts +1 -1
  35. package/dist/types/bridge-mode/common.d.ts +1 -1
  36. package/dist/types/playwright/ai-fixture.d.ts +1 -1
  37. package/dist/types/playwright/reporter/index.d.ts +4 -4
  38. package/dist/types/puppeteer/agent-launcher.d.ts +3 -3
  39. package/dist/types/web-element.d.ts +1 -1
  40. package/package.json +23 -15
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  Automate UI actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML.
4
4
 
5
- See https://rpascenejs.com/ for details.
5
+ See https://midscenejs.com/ for details.
6
6
 
7
7
  ## License
8
8
 
9
- Rpascene is MIT licensed.
9
+ Midscene is MIT licensed.
package/dist/es/bin.mjs CHANGED
@@ -20,7 +20,7 @@ server.app.use(cors({
20
20
  credentials: true
21
21
  }));
22
22
  Promise.resolve().then(()=>server.launch()).then(()=>{
23
- console.log(`Rpascene playground server is running on http://localhost:${server.port}`);
23
+ console.log(`Midscene playground server is running on http://localhost:${server.port}`);
24
24
  });
25
25
 
26
26
  //# sourceMappingURL=bin.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"bin.mjs","sources":["webpack://@rpascene/web/./src/bin.ts"],"sourcesContent":["import { PlaygroundServer } from '@rpascene/playground';\nimport cors from 'cors';\nimport { StaticPage, StaticPageAgent } from './static';\nimport 'dotenv/config';\n\n// Create page and agent instances with minimal valid data\nconst page = new StaticPage({\n tree: {\n node: null,\n children: [],\n },\n size: { width: 800, height: 600 },\n screenshotBase64: '',\n});\nconst agent = new StaticPageAgent(page);\n\n// Create server with agent only\nconst server = new PlaygroundServer(agent);\n\n// Register CORS middleware\nserver.app.use(\n cors({\n origin: '*',\n credentials: true,\n }),\n);\n\nPromise.resolve()\n .then(() => server.launch())\n .then(() => {\n console.log(\n `Rpascene playground server is running on http://localhost:${server.port}`,\n );\n });\n"],"names":["page","StaticPage","agent","StaticPageAgent","server","PlaygroundServer","cors","Promise","console"],"mappings":";;;;AAMA,MAAMA,OAAO,IAAIC,WAAW;IAC1B,MAAM;QACJ,MAAM;QACN,UAAU,EAAE;IACd;IACA,MAAM;QAAE,OAAO;QAAK,QAAQ;IAAI;IAChC,kBAAkB;AACpB;AACA,MAAMC,QAAQ,IAAIC,gBAAgBH;AAGlC,MAAMI,SAAS,IAAIC,iBAAiBH;AAGpCE,OAAO,GAAG,CAAC,GAAG,CACZE,KAAK;IACH,QAAQ;IACR,aAAa;AACf;AAGFC,QAAQ,OAAO,GACZ,IAAI,CAAC,IAAMH,OAAO,MAAM,IACxB,IAAI,CAAC;IACJI,QAAQ,GAAG,CACT,CAAC,0DAA0D,EAAEJ,OAAO,IAAI,EAAE;AAE9E"}
1
+ {"version":3,"file":"bin.mjs","sources":["webpack://@rpascene/web/./src/bin.ts"],"sourcesContent":["import { PlaygroundServer } from '@rpascene/playground';\nimport cors from 'cors';\nimport { StaticPage, StaticPageAgent } from './static';\nimport 'dotenv/config';\n\n// Create page and agent instances with minimal valid data\nconst page = new StaticPage({\n tree: {\n node: null,\n children: [],\n },\n size: { width: 800, height: 600 },\n screenshotBase64: '',\n});\nconst agent = new StaticPageAgent(page);\n\n// Create server with agent only\nconst server = new PlaygroundServer(agent);\n\n// Register CORS middleware\nserver.app.use(\n cors({\n origin: '*',\n credentials: true,\n }),\n);\n\nPromise.resolve()\n .then(() => server.launch())\n .then(() => {\n console.log(\n `Midscene playground server is running on http://localhost:${server.port}`,\n );\n });\n"],"names":["page","StaticPage","agent","StaticPageAgent","server","PlaygroundServer","cors","Promise","console"],"mappings":";;;;AAMA,MAAMA,OAAO,IAAIC,WAAW;IAC1B,MAAM;QACJ,MAAM;QACN,UAAU,EAAE;IACd;IACA,MAAM;QAAE,OAAO;QAAK,QAAQ;IAAI;IAChC,kBAAkB;AACpB;AACA,MAAMC,QAAQ,IAAIC,gBAAgBH;AAGlC,MAAMI,SAAS,IAAIC,iBAAiBH;AAGpCE,OAAO,GAAG,CAAC,GAAG,CACZE,KAAK;IACH,QAAQ;IACR,aAAa;AACf;AAGFC,QAAQ,OAAO,GACZ,IAAI,CAAC,IAAMH,OAAO,MAAM,IACxB,IAAI,CAAC;IACJI,QAAQ,GAAG,CACT,CAAC,0DAA0D,EAAEJ,OAAO,IAAI,EAAE;AAE9E"}
@@ -15,7 +15,7 @@ var common_BridgeEvent = /*#__PURE__*/ function(BridgeEvent) {
15
15
  BridgeEvent["SetActiveTabId"] = "setActiveTabId";
16
16
  return BridgeEvent;
17
17
  }({});
18
- const BridgeSignalKill = 'RPASCENE_BRIDGE_SIGNAL_KILL';
18
+ const BridgeSignalKill = 'MIDSCENE_BRIDGE_SIGNAL_KILL';
19
19
  var common_MouseEvent = /*#__PURE__*/ function(MouseEvent) {
20
20
  MouseEvent["PREFIX"] = "mouse.";
21
21
  MouseEvent["Click"] = "mouse.click";
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-mode\\common.mjs","sources":["webpack://@rpascene/web/./src/bridge-mode/common.ts"],"sourcesContent":["export const DefaultBridgeServerPort = 3766;\nexport const DefaultLocalEndpoint = `http://127.0.0.1:${DefaultBridgeServerPort}`;\nexport const BridgeCallTimeout = 30000;\n\nexport enum BridgeEvent {\n Call = 'bridge-call',\n CallResponse = 'bridge-call-response',\n UpdateAgentStatus = 'bridge-update-agent-status',\n Message = 'bridge-message',\n Connected = 'bridge-connected',\n Refused = 'bridge-refused',\n ConnectNewTabWithUrl = 'connectNewTabWithUrl',\n ConnectCurrentTab = 'connectCurrentTab',\n GetBrowserTabList = 'getBrowserTabList',\n SetDestroyOptions = 'setDestroyOptions',\n SetActiveTabId = 'setActiveTabId',\n}\n\nexport const BridgeSignalKill = 'RPASCENE_BRIDGE_SIGNAL_KILL';\n\nexport interface BridgeConnectTabOptions {\n /**\n * If true, the page will always track the active tab.\n * @default true\n */\n forceSameTabNavigation?: boolean;\n}\n\nexport enum MouseEvent {\n PREFIX = 'mouse.',\n Click = 'mouse.click',\n Wheel = 'mouse.wheel',\n Move = 'mouse.move',\n Drag = 'mouse.drag',\n}\n\nexport enum KeyboardEvent {\n PREFIX = 'keyboard.',\n Type = 'keyboard.type',\n Press = 'keyboard.press',\n}\n\nexport const BridgePageType = 'page-over-chrome-extension-bridge';\n\nexport const BridgeErrorCodeNoClientConnected = 'no-client-connected';\n\nexport interface BridgeCall {\n method: string;\n args: any[];\n response: any;\n callTime: number;\n responseTime: number;\n callback: (error: Error | undefined, response: any) => void;\n error?: Error;\n}\n\nexport interface BridgeCallRequest {\n id: string;\n method: string;\n args: any[];\n}\n\nexport interface BridgeCallResponse {\n id: string;\n response: any;\n error?: any;\n}\n\nexport interface BridgeConnectedEventPayload {\n version: string;\n}\n"],"names":["DefaultBridgeServerPort","DefaultLocalEndpoint","BridgeCallTimeout","BridgeEvent","BridgeSignalKill","MouseEvent","KeyboardEvent","BridgePageType","BridgeErrorCodeNoClientConnected"],"mappings":"AAAO,MAAMA,0BAA0B;AAChC,MAAMC,uBAAuB,CAAC,iBAAiB,EAAED,yBAAyB;AAC1E,MAAME,oBAAoB;AAE1B,IAAKC,qBAAWA,WAAAA,GAAAA,SAAXA,WAAW;;;;;;;;;;;;WAAXA;;AAcL,MAAMC,mBAAmB;AAUzB,IAAKC,oBAAUA,WAAAA,GAAAA,SAAVA,UAAU;;;;;;WAAVA;;AAQL,IAAKC,uBAAaA,WAAAA,GAAAA,SAAbA,aAAa;;;;WAAbA;;AAML,MAAMC,iBAAiB;AAEvB,MAAMC,mCAAmC"}
1
+ {"version":3,"file":"bridge-mode\\common.mjs","sources":["webpack://@rpascene/web/./src/bridge-mode/common.ts"],"sourcesContent":["export const DefaultBridgeServerPort = 3766;\nexport const DefaultLocalEndpoint = `http://127.0.0.1:${DefaultBridgeServerPort}`;\nexport const BridgeCallTimeout = 30000;\n\nexport enum BridgeEvent {\n Call = 'bridge-call',\n CallResponse = 'bridge-call-response',\n UpdateAgentStatus = 'bridge-update-agent-status',\n Message = 'bridge-message',\n Connected = 'bridge-connected',\n Refused = 'bridge-refused',\n ConnectNewTabWithUrl = 'connectNewTabWithUrl',\n ConnectCurrentTab = 'connectCurrentTab',\n GetBrowserTabList = 'getBrowserTabList',\n SetDestroyOptions = 'setDestroyOptions',\n SetActiveTabId = 'setActiveTabId',\n}\n\nexport const BridgeSignalKill = 'MIDSCENE_BRIDGE_SIGNAL_KILL';\n\nexport interface BridgeConnectTabOptions {\n /**\n * If true, the page will always track the active tab.\n * @default true\n */\n forceSameTabNavigation?: boolean;\n}\n\nexport enum MouseEvent {\n PREFIX = 'mouse.',\n Click = 'mouse.click',\n Wheel = 'mouse.wheel',\n Move = 'mouse.move',\n Drag = 'mouse.drag',\n}\n\nexport enum KeyboardEvent {\n PREFIX = 'keyboard.',\n Type = 'keyboard.type',\n Press = 'keyboard.press',\n}\n\nexport const BridgePageType = 'page-over-chrome-extension-bridge';\n\nexport const BridgeErrorCodeNoClientConnected = 'no-client-connected';\n\nexport interface BridgeCall {\n method: string;\n args: any[];\n response: any;\n callTime: number;\n responseTime: number;\n callback: (error: Error | undefined, response: any) => void;\n error?: Error;\n}\n\nexport interface BridgeCallRequest {\n id: string;\n method: string;\n args: any[];\n}\n\nexport interface BridgeCallResponse {\n id: string;\n response: any;\n error?: any;\n}\n\nexport interface BridgeConnectedEventPayload {\n version: string;\n}\n"],"names":["DefaultBridgeServerPort","DefaultLocalEndpoint","BridgeCallTimeout","BridgeEvent","BridgeSignalKill","MouseEvent","KeyboardEvent","BridgePageType","BridgeErrorCodeNoClientConnected"],"mappings":"AAAO,MAAMA,0BAA0B;AAChC,MAAMC,uBAAuB,CAAC,iBAAiB,EAAED,yBAAyB;AAC1E,MAAME,oBAAoB;AAE1B,IAAKC,qBAAWA,WAAAA,GAAAA,SAAXA,WAAW;;;;;;;;;;;;WAAXA;;AAcL,MAAMC,mBAAmB;AAUzB,IAAKC,oBAAUA,WAAAA,GAAAA,SAAVA,UAAU;;;;;;WAAVA;;AAQL,IAAKC,uBAAaA,WAAAA,GAAAA,SAAbA,aAAa;;;;WAAbA;;AAML,MAAMC,iBAAiB;AAEvB,MAAMC,mCAAmC"}
@@ -61,7 +61,7 @@ class ChromeExtensionProxyPage {
61
61
  this.attachingDebugger = (async ()=>{
62
62
  const url = await this.url();
63
63
  let error = null;
64
- if (url.startsWith('chrome://')) throw new Error('Cannot attach debugger to chrome:// pages, please use Rpascene in a normal page with http://, https:// or file://');
64
+ if (url.startsWith('chrome://')) throw new Error('Cannot attach debugger to chrome:// pages, please use Midscene in a normal page with http://, https:// or file://');
65
65
  try {
66
66
  const currentTabId = await this.getTabIdOrConnectToCurrentTab();
67
67
  if (this.tabIdOfDebuggerAttached === currentTabId) return;
@@ -97,11 +97,11 @@ class ChromeExtensionProxyPage {
97
97
  }
98
98
  async showMousePointer(x, y) {
99
99
  const pointerScript = `(() => {
100
- if(typeof window.rpasceneWaterFlowAnimation !== 'undefined') {
101
- window.rpasceneWaterFlowAnimation.enable();
102
- window.rpasceneWaterFlowAnimation.showMousePointer(${x}, ${y});
100
+ if(typeof window.midsceneWaterFlowAnimation !== 'undefined') {
101
+ window.midsceneWaterFlowAnimation.enable();
102
+ window.midsceneWaterFlowAnimation.showMousePointer(${x}, ${y});
103
103
  } else {
104
- console.log('rpasceneWaterFlowAnimation is not defined');
104
+ console.log('midsceneWaterFlowAnimation is not defined');
105
105
  }
106
106
  })()`;
107
107
  await this.sendCommandToDebugger('Runtime.evaluate', {
@@ -111,8 +111,8 @@ class ChromeExtensionProxyPage {
111
111
  async hideMousePointer() {
112
112
  await this.sendCommandToDebugger('Runtime.evaluate', {
113
113
  expression: `(() => {
114
- if(typeof window.rpasceneWaterFlowAnimation !== 'undefined') {
115
- window.rpasceneWaterFlowAnimation.hideMousePointer();
114
+ if(typeof window.midsceneWaterFlowAnimation !== 'undefined') {
115
+ window.midsceneWaterFlowAnimation.hideMousePointer();
116
116
  }
117
117
  })()`
118
118
  });
@@ -177,8 +177,8 @@ class ChromeExtensionProxyPage {
177
177
  }
178
178
  });
179
179
  const expression = async ()=>{
180
- window.rpascene_element_inspector.setNodeHashCacheListOnWindow();
181
- const tree = await window.rpascene_element_inspector.webExtractNodeTree();
180
+ window.midscene_element_inspector.setNodeHashCacheListOnWindow();
181
+ const tree = await window.midscene_element_inspector.webExtractNodeTree();
182
182
  return {
183
183
  tree,
184
184
  size: {
@@ -235,7 +235,7 @@ class ChromeExtensionProxyPage {
235
235
  expression: script
236
236
  });
237
237
  const result = await this.sendCommandToDebugger('Runtime.evaluate', {
238
- expression: `window.rpascene_element_inspector.getXpathsById(${JSON.stringify(id)})`,
238
+ expression: `window.midscene_element_inspector.getXpathsById(${JSON.stringify(id)})`,
239
239
  returnByValue: true
240
240
  });
241
241
  return result.result.value;
@@ -246,7 +246,7 @@ class ChromeExtensionProxyPage {
246
246
  expression: script
247
247
  });
248
248
  const result = await this.sendCommandToDebugger('Runtime.evaluate', {
249
- expression: `window.rpascene_element_inspector.getXpathsByPoint({left: ${point.left}, top: ${point.top}}, ${isOrderSensitive})`,
249
+ expression: `window.midscene_element_inspector.getXpathsByPoint({left: ${point.left}, top: ${point.top}}, ${isOrderSensitive})`,
250
250
  returnByValue: true
251
251
  });
252
252
  return result.result.value;
@@ -257,7 +257,7 @@ class ChromeExtensionProxyPage {
257
257
  expression: script
258
258
  });
259
259
  const result = await this.sendCommandToDebugger('Runtime.evaluate', {
260
- expression: `window.rpascene_element_inspector.getElementInfoByXpath(${JSON.stringify(xpath)})`,
260
+ expression: `window.midscene_element_inspector.getElementInfoByXpath(${JSON.stringify(xpath)})`,
261
261
  returnByValue: true
262
262
  });
263
263
  return result.result.value;
@@ -1 +1 @@
1
- {"version":3,"file":"chrome-extension\\page.mjs","sources":["webpack://@rpascene/web/./src/chrome-extension/page.ts"],"sourcesContent":["/// <reference types=\"chrome\" />\n\n/*\n It is used to interact with the page tab from the chrome extension.\n The page must be active when interacting with it.\n*/\n\nimport { limitOpenNewTabScript } from '@/web-element';\nimport type { ElementTreeNode, Point, Size, UIContext } from '@rpascene/core';\nimport type { AbstractInterface, DeviceAction } from '@rpascene/core/device';\nimport type { ElementInfo } from '@rpascene/shared/extractor';\nimport { treeToList } from '@rpascene/shared/extractor';\nimport { createImgBase64ByFormat } from '@rpascene/shared/img';\nimport { assert } from '@rpascene/shared/utils';\nimport type { Protocol as CDPTypes } from 'devtools-protocol';\nimport { WebPageContextParser } from '../web-element';\nimport {\n type KeyInput,\n type MouseButton,\n commonWebActionsForWebPage,\n} from '../web-page';\nimport { CdpKeyboard } from './cdpInput';\nimport {\n getHtmlElementScript,\n injectStopWaterFlowAnimation,\n injectWaterFlowAnimation,\n} from './dynamic-scripts';\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// 浏览器插件接口\nexport default class ChromeExtensionProxyPage implements AbstractInterface {\n interfaceType = 'chrome-extension-proxy';\n\n public forceSameTabNavigation: boolean;\n\n private viewportSize?: Size;\n\n private activeTabId: number | null = null;\n\n private tabIdOfDebuggerAttached: number | null = null;\n\n private attachingDebugger: Promise<void> | null = null;\n\n private destroyed = false;\n\n private isMobileEmulation: boolean | null = null;\n\n public _continueWhenFailedToAttachDebugger = false;\n\n constructor(forceSameTabNavigation: boolean) {\n this.forceSameTabNavigation = forceSameTabNavigation;\n }\n\n actionSpace(): DeviceAction[] {\n return commonWebActionsForWebPage(this);\n }\n // 设置激活的tab\n public async setActiveTabId(tabId: number) {\n if (this.activeTabId) {\n throw new Error(\n `Active tab id is already set, which is ${this.activeTabId}, cannot set it to ${tabId}`,\n );\n }\n await chrome.tabs.update(tabId, { active: true });\n this.activeTabId = tabId;\n }\n // 获取激活的tabid\n public async getActiveTabId() {\n return this.activeTabId;\n }\n\n /**\n * Get a list of current tabs\n * @returns {Promise<Array<{id: number, title: string, url: string}>>}\n */\n public async getBrowserTabList(): Promise<\n { id: string; title: string; url: string; currentActiveTab: boolean }[]\n > {\n const tabs = await chrome.tabs.query({ currentWindow: true });\n return tabs\n .map((tab) => ({\n id: `${tab.id}`,\n title: tab.title,\n url: tab.url,\n currentActiveTab: tab.active,\n }))\n .filter((tab) => tab.id && tab.title && tab.url) as {\n id: string;\n title: string;\n url: string;\n currentActiveTab: boolean;\n }[];\n }\n // 获取或链接到tab\n public async getTabIdOrConnectToCurrentTab() {\n if (this.activeTabId) {\n // alway keep on the connected tab\n return this.activeTabId;\n }\n const tabId = await chrome.tabs\n .query({ active: true, currentWindow: true })\n .then((tabs) => tabs[0]?.id);\n this.activeTabId = tabId || 0;\n return this.activeTabId;\n }\n // 附加debugger\n private async attachDebugger() {\n assert(!this.destroyed, 'Page is destroyed');\n\n // If already attaching, wait for it to complete\n if (this.attachingDebugger) {\n await this.attachingDebugger;\n return;\n }\n\n // Create new attaching promise\n this.attachingDebugger = (async () => {\n const url = await this.url();\n let error: Error | null = null;\n if (url.startsWith('chrome://')) {\n throw new Error(\n 'Cannot attach debugger to chrome:// pages, please use Rpascene in a normal page with http://, https:// or file://',\n );\n }\n\n try {\n const currentTabId = await this.getTabIdOrConnectToCurrentTab();\n\n if (this.tabIdOfDebuggerAttached === currentTabId) {\n // already attached\n return;\n }\n if (\n this.tabIdOfDebuggerAttached &&\n this.tabIdOfDebuggerAttached !== currentTabId\n ) {\n // detach the previous tab\n console.log(\n 'detach the previous tab',\n this.tabIdOfDebuggerAttached,\n '->',\n currentTabId,\n );\n try {\n await this.detachDebugger(this.tabIdOfDebuggerAttached);\n } catch (error) {\n console.error('Failed to detach debugger', error);\n }\n }\n\n // detach any debugger attached to the tab\n console.log('attaching debugger', currentTabId);\n try {\n await chrome.debugger.attach({ tabId: currentTabId }, '1.3');\n } catch (e) {\n if (this._continueWhenFailedToAttachDebugger) {\n console.warn(\n 'Failed to attach debugger, but the script will continue as if the debugger is attached since the _continueWhenFailedToAttachDebugger is true',\n e,\n );\n } else {\n throw e;\n }\n }\n\n // wait util the debugger banner in Chrome appears\n await sleep(500);\n\n this.tabIdOfDebuggerAttached = currentTabId;\n\n await this.enableWaterFlowAnimation();\n } catch (e) {\n console.error('Failed to attach debugger', e);\n error = e as Error;\n } finally {\n this.attachingDebugger = null;\n }\n if (error) {\n throw error;\n }\n })();\n\n await this.attachingDebugger;\n }\n // 显示鼠标\n private async showMousePointer(x: number, y: number) {\n // update mouse pointer while redirecting\n const pointerScript = `(() => {\n if(typeof window.rpasceneWaterFlowAnimation !== 'undefined') {\n window.rpasceneWaterFlowAnimation.enable();\n window.rpasceneWaterFlowAnimation.showMousePointer(${x}, ${y});\n } else {\n console.log('rpasceneWaterFlowAnimation is not defined');\n }\n })()`;\n\n await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `${pointerScript}`,\n });\n }\n // 隐藏鼠标\n private async hideMousePointer() {\n await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `(() => {\n if(typeof window.rpasceneWaterFlowAnimation !== 'undefined') {\n window.rpasceneWaterFlowAnimation.hideMousePointer();\n }\n })()`,\n });\n }\n // 卸载debbgger\n private async detachDebugger(tabId?: number) {\n const tabIdToDetach = tabId || this.tabIdOfDebuggerAttached;\n console.log('detaching debugger', tabIdToDetach);\n if (!tabIdToDetach) {\n console.warn('No tab id to detach');\n return;\n }\n\n try {\n await this.disableWaterFlowAnimation(tabIdToDetach);\n await sleep(200); // wait for the animation to stop\n } catch (error) {\n console.warn('Failed to disable water flow animation', error);\n }\n\n try {\n await chrome.debugger.detach({ tabId: tabIdToDetach });\n } catch (error) {\n // maybe tab is closed ?\n console.warn('Failed to detach debugger', error);\n }\n this.tabIdOfDebuggerAttached = null;\n }\n // 开启动画\n private async enableWaterFlowAnimation() {\n // limit open page in new tab\n if (this.forceSameTabNavigation) {\n await chrome.debugger.sendCommand(\n { tabId: this.tabIdOfDebuggerAttached! },\n 'Runtime.evaluate',\n {\n expression: limitOpenNewTabScript,\n },\n );\n }\n\n const script = await injectWaterFlowAnimation();\n // we will call this function in sendCommandToDebugger, so we have to use the chrome.debugger.sendCommand\n await chrome.debugger.sendCommand(\n { tabId: this.tabIdOfDebuggerAttached! },\n 'Runtime.evaluate',\n {\n expression: script,\n },\n );\n }\n // 禁用动画\n private async disableWaterFlowAnimation(tabId: number) {\n const script = await injectStopWaterFlowAnimation();\n\n await chrome.debugger.sendCommand({ tabId }, 'Runtime.evaluate', {\n expression: script,\n });\n }\n // 向debugger发送命令\n private async sendCommandToDebugger<ResponseType = any, RequestType = any>(\n command: string,\n params: RequestType,\n ): Promise<ResponseType> {\n await this.attachDebugger();\n\n assert(this.tabIdOfDebuggerAttached, 'Debugger is not attached');\n\n // wo don't have to await it\n this.enableWaterFlowAnimation();\n return (await chrome.debugger.sendCommand(\n { tabId: this.tabIdOfDebuggerAttached! },\n command,\n params as any,\n )) as ResponseType;\n }\n // 通过CDP获取页面内容\n private async getPageContentByCDP() {\n // 获取节点树生成脚本\n\n // const script = await getHtmlElementScript();\n\n // check tab url\n // await this.sendCommandToDebugger<\n // CDPTypes.Runtime.EvaluateResponse,\n // CDPTypes.Runtime.EvaluateRequest\n // >('Runtime.evaluate', {\n // expression: script,\n // });\n\n // 所有的iframe中都需要注入\n await chrome.scripting.executeScript({\n files: ['./scripts/htmlElement.js'],\n world: \"MAIN\",\n target: {\n allFrames: true,\n tabId: this.tabIdOfDebuggerAttached!\n }\n })\n\n\n const expression = async () => {\n // 设置节点缓存\n (window as any).rpascene_element_inspector.setNodeHashCacheListOnWindow();\n // 生成节点树\n const tree = await (\n window as any\n ).rpascene_element_inspector.webExtractNodeTree();\n\n\n return {\n tree,\n size: {\n width: document.documentElement.clientWidth,\n height: document.documentElement.clientHeight,\n dpr: window.devicePixelRatio,\n },\n };\n };\n const returnValue = await this.sendCommandToDebugger<\n CDPTypes.Runtime.EvaluateResponse,\n CDPTypes.Runtime.EvaluateRequest\n >('Runtime.evaluate', {\n expression: `(${expression.toString()})()`,\n returnByValue: true,\n awaitPromise: true\n });\n\n if (!returnValue.result.value) {\n const errorDescription =\n returnValue.exceptionDetails?.exception?.description || '';\n if (!errorDescription) {\n console.error('returnValue from cdp', returnValue);\n }\n throw new Error(\n `Failed to get page content from page, error: ${errorDescription}`,\n );\n }\n\n return returnValue.result.value as {\n tree: ElementTreeNode<ElementInfo>;\n size: Size;\n };\n }\n // 执行js脚本\n public async evaluateJavaScript(script: string) {\n return this.sendCommandToDebugger('Runtime.evaluate', {\n expression: script,\n });\n }\n // 执行前等待网络请求加载完成\n async beforeInvokeAction(): Promise<void> {\n // current implementation is wait until domReadyState is complete\n try {\n await this.waitUntilNetworkIdle();\n } catch (error) {\n // console.warn('Failed to wait until network idle', error);\n }\n }\n // 等待页面加载完成\n private async waitUntilNetworkIdle() {\n const timeout = 10000;\n const startTime = Date.now();\n let lastReadyState = '';\n while (Date.now() - startTime < timeout) {\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: 'document.readyState',\n });\n lastReadyState = result.result.value;\n if (lastReadyState === 'complete') {\n await new Promise((resolve) => setTimeout(resolve, 300));\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, 300));\n }\n throw new Error(\n `Failed to wait until network idle, last readyState: ${lastReadyState}`,\n );\n }\n\n // 获取元素信息\n // @deprecated\n async getElementsInfo() {\n // 获取节点树\n const tree = await this.getElementsNodeTree();\n // 节点树转list\n return treeToList(tree);\n }\n // 通过id获取xpath列表\n async getXpathsById(id: string) {\n const script = await getHtmlElementScript();\n\n // check tab url\n await this.sendCommandToDebugger<\n CDPTypes.Runtime.EvaluateResponse,\n CDPTypes.Runtime.EvaluateRequest\n >('Runtime.evaluate', {\n expression: script,\n });\n\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `window.rpascene_element_inspector.getXpathsById(${JSON.stringify(id)})`,\n returnByValue: true,\n });\n return result.result.value;\n }\n // 通过point坐标获取xpath列表\n async getXpathsByPoint(point: Point, isOrderSensitive: boolean) {\n const script = await getHtmlElementScript();\n\n await this.sendCommandToDebugger<\n CDPTypes.Runtime.EvaluateResponse,\n CDPTypes.Runtime.EvaluateRequest\n >('Runtime.evaluate', {\n expression: script,\n });\n\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `window.rpascene_element_inspector.getXpathsByPoint({left: ${point.left}, top: ${point.top}}, ${isOrderSensitive})`,\n returnByValue: true,\n });\n return result.result.value;\n }\n // 通过xpath获取元素信息\n async getElementInfoByXpath(xpath: string) {\n const script = await getHtmlElementScript();\n\n // check tab url\n await this.sendCommandToDebugger<\n CDPTypes.Runtime.EvaluateResponse,\n CDPTypes.Runtime.EvaluateRequest\n >('Runtime.evaluate', {\n expression: script,\n });\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `window.rpascene_element_inspector.getElementInfoByXpath(${JSON.stringify(xpath)})`,\n returnByValue: true,\n });\n return result.result.value;\n }\n // 获取元素节点树\n async getElementsNodeTree() {\n await this.hideMousePointer();\n const content = await this.getPageContentByCDP();\n if (content?.size) {\n this.viewportSize = content.size;\n }\n\n return content?.tree || { node: null, children: [] };\n }\n // 获取上下文\n async getContext(): Promise<UIContext> {\n return await WebPageContextParser(this, {});\n }\n // 页面尺寸\n async size() {\n // if (this.viewportSize) return this.viewportSize;\n const content = await this.getPageContentByCDP();\n return content.size;\n }\n // 截图返回base64\n async screenshotBase64() {\n // screenshot by cdp\n await this.hideMousePointer();\n const format = 'jpeg';\n const base64 = await this.sendCommandToDebugger('Page.captureScreenshot', {\n format,\n quality: 90,\n });\n return createImgBase64ByFormat(format, base64.data);\n }\n // 页面url\n async url() {\n const tabId = await this.getTabIdOrConnectToCurrentTab();\n const url = await chrome.tabs.get(tabId).then((tab) => tab.url);\n return url || '';\n }\n // 滚动到顶部\n async scrollUntilTop(startingPoint?: Point) {\n if (startingPoint) {\n await this.mouse.move(startingPoint.left, startingPoint.top);\n }\n return this.mouse.wheel(0, -9999999);\n }\n // 滚动到底部\n async scrollUntilBottom(startingPoint?: Point) {\n if (startingPoint) {\n await this.mouse.move(startingPoint.left, startingPoint.top);\n }\n return this.mouse.wheel(0, 9999999);\n }\n // 滚动到左侧\n async scrollUntilLeft(startingPoint?: Point) {\n if (startingPoint) {\n await this.mouse.move(startingPoint.left, startingPoint.top);\n }\n return this.mouse.wheel(-9999999, 0);\n }\n // 滚动到右侧\n async scrollUntilRight(startingPoint?: Point) {\n if (startingPoint) {\n await this.mouse.move(startingPoint.left, startingPoint.top);\n }\n return this.mouse.wheel(9999999, 0);\n }\n // 向上滚动\n async scrollUp(distance?: number, startingPoint?: Point) {\n const { height } = await this.size();\n const scrollDistance = distance || height * 0.7;\n return this.mouse.wheel(\n 0,\n -scrollDistance,\n startingPoint?.left,\n startingPoint?.top,\n );\n }\n // 向下滚动\n async scrollDown(distance?: number, startingPoint?: Point) {\n const { height } = await this.size();\n const scrollDistance = distance || height * 0.7;\n return this.mouse.wheel(\n 0,\n scrollDistance,\n startingPoint?.left,\n startingPoint?.top,\n );\n }\n // 向左滚动\n async scrollLeft(distance?: number, startingPoint?: Point) {\n const { width } = await this.size();\n const scrollDistance = distance || width * 0.7;\n return this.mouse.wheel(\n -scrollDistance,\n 0,\n startingPoint?.left,\n startingPoint?.top,\n );\n }\n // 向右滚动\n async scrollRight(distance?: number, startingPoint?: Point) {\n const { width } = await this.size();\n const scrollDistance = distance || width * 0.7;\n return this.mouse.wheel(\n scrollDistance,\n 0,\n startingPoint?.left,\n startingPoint?.top,\n );\n }\n // 清空input框\n async clearInput(element: ElementInfo) {\n if (!element) {\n console.warn('No element to clear input');\n return;\n }\n\n await this.mouse.click(element.center[0], element.center[1]);\n\n await this.sendCommandToDebugger('Input.dispatchKeyEvent', {\n type: 'keyDown',\n commands: ['selectAll'],\n });\n\n await this.sendCommandToDebugger('Input.dispatchKeyEvent', {\n type: 'keyUp',\n commands: ['selectAll'],\n });\n\n await sleep(100);\n\n await this.keyboard.press({\n key: 'Backspace',\n });\n }\n\n private latestMouseX = 100;\n private latestMouseY = 100;\n // 鼠标\n mouse = {\n click: async (\n x: number,\n y: number,\n options?: { button?: MouseButton; count?: number },\n ) => {\n const { button = 'left', count = 1 } = options || {};\n await this.mouse.move(x, y);\n // detect if the page is in mobile emulation mode\n if (this.isMobileEmulation === null) {\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `(() => {\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\n })()`,\n returnByValue: true,\n });\n this.isMobileEmulation = result?.result?.value;\n }\n\n if (this.isMobileEmulation && button === 'left') {\n // in mobile emulation mode, directly inject click event\n const touchPoints = [{ x: Math.round(x), y: Math.round(y) }];\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchStart',\n touchPoints,\n modifiers: 0,\n });\n\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchEnd',\n touchPoints: [],\n modifiers: 0,\n });\n } else {\n for (let i = 0; i < count; i++) {\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mousePressed',\n x,\n y,\n button,\n clickCount: 1,\n });\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseReleased',\n x,\n y,\n button,\n clickCount: 1,\n });\n await sleep(50);\n }\n }\n },\n wheel: async (\n deltaX: number,\n deltaY: number,\n startX?: number,\n startY?: number,\n ) => {\n const finalX = startX || this.latestMouseX;\n const finalY = startY || this.latestMouseY;\n await this.showMousePointer(finalX, finalY);\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseWheel',\n x: finalX,\n y: finalY,\n deltaX,\n deltaY,\n });\n this.latestMouseX = finalX;\n this.latestMouseY = finalY;\n },\n move: async (x: number, y: number) => {\n await this.showMousePointer(x, y);\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseMoved',\n x,\n y,\n });\n this.latestMouseX = x;\n this.latestMouseY = y;\n },\n drag: async (\n from: { x: number; y: number },\n to: { x: number; y: number },\n ) => {\n await this.mouse.move(from.x, from.y);\n\n await sleep(200);\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mousePressed',\n x: from.x,\n y: from.y,\n button: 'left',\n clickCount: 1,\n });\n\n await sleep(300);\n\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseMoved',\n x: to.x,\n y: to.y,\n });\n\n await sleep(500);\n\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseReleased',\n x: to.x,\n y: to.y,\n button: 'left',\n clickCount: 1,\n });\n\n await sleep(200);\n\n await this.mouse.move(to.x, to.y);\n },\n };\n // 键盘\n keyboard = {\n type: async (text: string) => {\n const cdpKeyboard = new CdpKeyboard({\n send: this.sendCommandToDebugger.bind(this),\n });\n await cdpKeyboard.type(text, { delay: 0 });\n },\n press: async (\n action:\n | { key: KeyInput; command?: string }\n | { key: KeyInput; command?: string }[],\n ) => {\n const cdpKeyboard = new CdpKeyboard({\n send: this.sendCommandToDebugger.bind(this),\n });\n const keys = Array.isArray(action) ? action : [action];\n for (const k of keys) {\n const commands = k.command ? [k.command] : [];\n await cdpKeyboard.down(k.key, { commands });\n }\n for (const k of [...keys].reverse()) {\n await cdpKeyboard.up(k.key);\n }\n },\n };\n // 销毁debugger\n async destroy(): Promise<void> {\n this.activeTabId = null;\n await this.detachDebugger();\n this.destroyed = true;\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 await this.mouse.move(x, y);\n\n if (this.isMobileEmulation === null) {\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `(() => {\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\n })()`,\n returnByValue: true,\n });\n this.isMobileEmulation = result?.result?.value;\n }\n\n if (this.isMobileEmulation) {\n const touchPoints = [{ x: Math.round(x), y: Math.round(y) }];\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchStart',\n touchPoints,\n modifiers: 0,\n });\n await new Promise((res) => setTimeout(res, duration));\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchEnd',\n touchPoints: [],\n modifiers: 0,\n });\n } else {\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mousePressed',\n x,\n y,\n button: 'left',\n clickCount: 1,\n });\n await new Promise((res) => setTimeout(res, duration));\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseReleased',\n x,\n y,\n button: 'left',\n clickCount: 1,\n });\n }\n this.latestMouseX = x;\n this.latestMouseY = y;\n }\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 || 300;\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\n if (this.isMobileEmulation === null) {\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `(() => {\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\n })()`,\n returnByValue: true,\n });\n this.isMobileEmulation = result?.result?.value;\n }\n\n const steps = 30;\n const delay = duration / steps;\n\n if (this.isMobileEmulation) {\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchStart',\n touchPoints: [{ x: Math.round(from.x), y: Math.round(from.y) }],\n modifiers: 0,\n });\n\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 this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchMove',\n touchPoints: [{ x: Math.round(x), y: Math.round(y) }],\n modifiers: 0,\n });\n await new Promise((res) => setTimeout(res, delay));\n }\n\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchEnd',\n touchPoints: [],\n modifiers: 0,\n });\n } else {\n await this.mouse.move(from.x, from.y);\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mousePressed',\n x: from.x,\n y: from.y,\n button: 'left',\n clickCount: 1,\n });\n\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 this.mouse.move(x, y);\n await new Promise((res) => setTimeout(res, delay));\n }\n\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseReleased',\n x: to.x,\n y: to.y,\n button: 'left',\n clickCount: 1,\n });\n }\n\n this.latestMouseX = to.x;\n this.latestMouseY = to.y;\n }\n}\n"],"names":["sleep","ms","Promise","resolve","setTimeout","ChromeExtensionProxyPage","commonWebActionsForWebPage","tabId","Error","chrome","tabs","tab","_tabs_","assert","url","error","currentTabId","console","e","x","y","pointerScript","tabIdToDetach","limitOpenNewTabScript","script","injectWaterFlowAnimation","injectStopWaterFlowAnimation","command","params","expression","window","tree","document","returnValue","_returnValue_exceptionDetails_exception","errorDescription","timeout","startTime","Date","lastReadyState","result","treeToList","id","getHtmlElementScript","JSON","point","isOrderSensitive","xpath","content","WebPageContextParser","format","base64","createImgBase64ByFormat","startingPoint","distance","height","scrollDistance","width","element","duration","LONG_PRESS_THRESHOLD","MIN_PRESS_THRESHOLD","_result_result","touchPoints","Math","res","from","to","steps","delay","i","forceSameTabNavigation","options","button","count","deltaX","deltaY","startX","startY","finalX","finalY","text","cdpKeyboard","CdpKeyboard","action","keys","Array","k","commands"],"mappings":"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"}
1
+ {"version":3,"file":"chrome-extension\\page.mjs","sources":["webpack://@rpascene/web/./src/chrome-extension/page.ts"],"sourcesContent":["/// <reference types=\"chrome\" />\n\n/*\n It is used to interact with the page tab from the chrome extension.\n The page must be active when interacting with it.\n*/\n\nimport { limitOpenNewTabScript } from '@/web-element';\nimport type { ElementTreeNode, Point, Size, UIContext } from '@rpascene/core';\nimport type { AbstractInterface, DeviceAction } from '@rpascene/core/device';\nimport type { ElementInfo } from '@rpascene/shared/extractor';\nimport { treeToList } from '@rpascene/shared/extractor';\nimport { createImgBase64ByFormat } from '@rpascene/shared/img';\nimport { assert } from '@rpascene/shared/utils';\nimport type { Protocol as CDPTypes } from 'devtools-protocol';\nimport { WebPageContextParser } from '../web-element';\nimport {\n type KeyInput,\n type MouseButton,\n commonWebActionsForWebPage,\n} from '../web-page';\nimport { CdpKeyboard } from './cdpInput';\nimport {\n getHtmlElementScript,\n injectStopWaterFlowAnimation,\n injectWaterFlowAnimation,\n} from './dynamic-scripts';\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// 浏览器插件接口\nexport default class ChromeExtensionProxyPage implements AbstractInterface {\n interfaceType = 'chrome-extension-proxy';\n\n public forceSameTabNavigation: boolean;\n\n private viewportSize?: Size;\n\n private activeTabId: number | null = null;\n\n private tabIdOfDebuggerAttached: number | null = null;\n\n private attachingDebugger: Promise<void> | null = null;\n\n private destroyed = false;\n\n private isMobileEmulation: boolean | null = null;\n\n public _continueWhenFailedToAttachDebugger = false;\n\n constructor(forceSameTabNavigation: boolean) {\n this.forceSameTabNavigation = forceSameTabNavigation;\n }\n\n actionSpace(): DeviceAction[] {\n return commonWebActionsForWebPage(this);\n }\n // 设置激活的tab\n public async setActiveTabId(tabId: number) {\n if (this.activeTabId) {\n throw new Error(\n `Active tab id is already set, which is ${this.activeTabId}, cannot set it to ${tabId}`,\n );\n }\n await chrome.tabs.update(tabId, { active: true });\n this.activeTabId = tabId;\n }\n // 获取激活的tabid\n public async getActiveTabId() {\n return this.activeTabId;\n }\n\n /**\n * Get a list of current tabs\n * @returns {Promise<Array<{id: number, title: string, url: string}>>}\n */\n public async getBrowserTabList(): Promise<\n { id: string; title: string; url: string; currentActiveTab: boolean }[]\n > {\n const tabs = await chrome.tabs.query({ currentWindow: true });\n return tabs\n .map((tab) => ({\n id: `${tab.id}`,\n title: tab.title,\n url: tab.url,\n currentActiveTab: tab.active,\n }))\n .filter((tab) => tab.id && tab.title && tab.url) as {\n id: string;\n title: string;\n url: string;\n currentActiveTab: boolean;\n }[];\n }\n // 获取或链接到tab\n public async getTabIdOrConnectToCurrentTab() {\n if (this.activeTabId) {\n // alway keep on the connected tab\n return this.activeTabId;\n }\n const tabId = await chrome.tabs\n .query({ active: true, currentWindow: true })\n .then((tabs) => tabs[0]?.id);\n this.activeTabId = tabId || 0;\n return this.activeTabId;\n }\n // 附加debugger\n private async attachDebugger() {\n assert(!this.destroyed, 'Page is destroyed');\n\n // If already attaching, wait for it to complete\n if (this.attachingDebugger) {\n await this.attachingDebugger;\n return;\n }\n\n // Create new attaching promise\n this.attachingDebugger = (async () => {\n const url = await this.url();\n let error: Error | null = null;\n if (url.startsWith('chrome://')) {\n throw new Error(\n 'Cannot attach debugger to chrome:// pages, please use Midscene in a normal page with http://, https:// or file://',\n );\n }\n\n try {\n const currentTabId = await this.getTabIdOrConnectToCurrentTab();\n\n if (this.tabIdOfDebuggerAttached === currentTabId) {\n // already attached\n return;\n }\n if (\n this.tabIdOfDebuggerAttached &&\n this.tabIdOfDebuggerAttached !== currentTabId\n ) {\n // detach the previous tab\n console.log(\n 'detach the previous tab',\n this.tabIdOfDebuggerAttached,\n '->',\n currentTabId,\n );\n try {\n await this.detachDebugger(this.tabIdOfDebuggerAttached);\n } catch (error) {\n console.error('Failed to detach debugger', error);\n }\n }\n\n // detach any debugger attached to the tab\n console.log('attaching debugger', currentTabId);\n try {\n await chrome.debugger.attach({ tabId: currentTabId }, '1.3');\n } catch (e) {\n if (this._continueWhenFailedToAttachDebugger) {\n console.warn(\n 'Failed to attach debugger, but the script will continue as if the debugger is attached since the _continueWhenFailedToAttachDebugger is true',\n e,\n );\n } else {\n throw e;\n }\n }\n\n // wait util the debugger banner in Chrome appears\n await sleep(500);\n\n this.tabIdOfDebuggerAttached = currentTabId;\n\n await this.enableWaterFlowAnimation();\n } catch (e) {\n console.error('Failed to attach debugger', e);\n error = e as Error;\n } finally {\n this.attachingDebugger = null;\n }\n if (error) {\n throw error;\n }\n })();\n\n await this.attachingDebugger;\n }\n // 显示鼠标\n private async showMousePointer(x: number, y: number) {\n // update mouse pointer while redirecting\n const pointerScript = `(() => {\n if(typeof window.midsceneWaterFlowAnimation !== 'undefined') {\n window.midsceneWaterFlowAnimation.enable();\n window.midsceneWaterFlowAnimation.showMousePointer(${x}, ${y});\n } else {\n console.log('midsceneWaterFlowAnimation is not defined');\n }\n })()`;\n\n await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `${pointerScript}`,\n });\n }\n // 隐藏鼠标\n private async hideMousePointer() {\n await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `(() => {\n if(typeof window.midsceneWaterFlowAnimation !== 'undefined') {\n window.midsceneWaterFlowAnimation.hideMousePointer();\n }\n })()`,\n });\n }\n // 卸载debbgger\n private async detachDebugger(tabId?: number) {\n const tabIdToDetach = tabId || this.tabIdOfDebuggerAttached;\n console.log('detaching debugger', tabIdToDetach);\n if (!tabIdToDetach) {\n console.warn('No tab id to detach');\n return;\n }\n\n try {\n await this.disableWaterFlowAnimation(tabIdToDetach);\n await sleep(200); // wait for the animation to stop\n } catch (error) {\n console.warn('Failed to disable water flow animation', error);\n }\n\n try {\n await chrome.debugger.detach({ tabId: tabIdToDetach });\n } catch (error) {\n // maybe tab is closed ?\n console.warn('Failed to detach debugger', error);\n }\n this.tabIdOfDebuggerAttached = null;\n }\n // 开启动画\n private async enableWaterFlowAnimation() {\n // limit open page in new tab\n if (this.forceSameTabNavigation) {\n await chrome.debugger.sendCommand(\n { tabId: this.tabIdOfDebuggerAttached! },\n 'Runtime.evaluate',\n {\n expression: limitOpenNewTabScript,\n },\n );\n }\n\n const script = await injectWaterFlowAnimation();\n // we will call this function in sendCommandToDebugger, so we have to use the chrome.debugger.sendCommand\n await chrome.debugger.sendCommand(\n { tabId: this.tabIdOfDebuggerAttached! },\n 'Runtime.evaluate',\n {\n expression: script,\n },\n );\n }\n // 禁用动画\n private async disableWaterFlowAnimation(tabId: number) {\n const script = await injectStopWaterFlowAnimation();\n\n await chrome.debugger.sendCommand({ tabId }, 'Runtime.evaluate', {\n expression: script,\n });\n }\n // 向debugger发送命令\n private async sendCommandToDebugger<ResponseType = any, RequestType = any>(\n command: string,\n params: RequestType,\n ): Promise<ResponseType> {\n await this.attachDebugger();\n\n assert(this.tabIdOfDebuggerAttached, 'Debugger is not attached');\n\n // wo don't have to await it\n this.enableWaterFlowAnimation();\n return (await chrome.debugger.sendCommand(\n { tabId: this.tabIdOfDebuggerAttached! },\n command,\n params as any,\n )) as ResponseType;\n }\n // 通过CDP获取页面内容\n private async getPageContentByCDP() {\n // 获取节点树生成脚本\n\n // const script = await getHtmlElementScript();\n\n // check tab url\n // await this.sendCommandToDebugger<\n // CDPTypes.Runtime.EvaluateResponse,\n // CDPTypes.Runtime.EvaluateRequest\n // >('Runtime.evaluate', {\n // expression: script,\n // });\n\n // 所有的iframe中都需要注入\n await chrome.scripting.executeScript({\n files: ['./scripts/htmlElement.js'],\n world: \"MAIN\",\n target: {\n allFrames: true,\n tabId: this.tabIdOfDebuggerAttached!\n }\n })\n\n\n const expression = async () => {\n // 设置节点缓存\n (window as any).midscene_element_inspector.setNodeHashCacheListOnWindow();\n // 生成节点树\n const tree = await (\n window as any\n ).midscene_element_inspector.webExtractNodeTree();\n\n\n return {\n tree,\n size: {\n width: document.documentElement.clientWidth,\n height: document.documentElement.clientHeight,\n dpr: window.devicePixelRatio,\n },\n };\n };\n const returnValue = await this.sendCommandToDebugger<\n CDPTypes.Runtime.EvaluateResponse,\n CDPTypes.Runtime.EvaluateRequest\n >('Runtime.evaluate', {\n expression: `(${expression.toString()})()`,\n returnByValue: true,\n awaitPromise: true\n });\n\n if (!returnValue.result.value) {\n const errorDescription =\n returnValue.exceptionDetails?.exception?.description || '';\n if (!errorDescription) {\n console.error('returnValue from cdp', returnValue);\n }\n throw new Error(\n `Failed to get page content from page, error: ${errorDescription}`,\n );\n }\n\n return returnValue.result.value as {\n tree: ElementTreeNode<ElementInfo>;\n size: Size;\n };\n }\n // 执行js脚本\n public async evaluateJavaScript(script: string) {\n return this.sendCommandToDebugger('Runtime.evaluate', {\n expression: script,\n });\n }\n // 执行前等待网络请求加载完成\n async beforeInvokeAction(): Promise<void> {\n // current implementation is wait until domReadyState is complete\n try {\n await this.waitUntilNetworkIdle();\n } catch (error) {\n // console.warn('Failed to wait until network idle', error);\n }\n }\n // 等待页面加载完成\n private async waitUntilNetworkIdle() {\n const timeout = 10000;\n const startTime = Date.now();\n let lastReadyState = '';\n while (Date.now() - startTime < timeout) {\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: 'document.readyState',\n });\n lastReadyState = result.result.value;\n if (lastReadyState === 'complete') {\n await new Promise((resolve) => setTimeout(resolve, 300));\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, 300));\n }\n throw new Error(\n `Failed to wait until network idle, last readyState: ${lastReadyState}`,\n );\n }\n\n // 获取元素信息\n // @deprecated\n async getElementsInfo() {\n // 获取节点树\n const tree = await this.getElementsNodeTree();\n // 节点树转list\n return treeToList(tree);\n }\n // 通过id获取xpath列表\n async getXpathsById(id: string) {\n const script = await getHtmlElementScript();\n\n // check tab url\n await this.sendCommandToDebugger<\n CDPTypes.Runtime.EvaluateResponse,\n CDPTypes.Runtime.EvaluateRequest\n >('Runtime.evaluate', {\n expression: script,\n });\n\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `window.midscene_element_inspector.getXpathsById(${JSON.stringify(id)})`,\n returnByValue: true,\n });\n return result.result.value;\n }\n // 通过point坐标获取xpath列表\n async getXpathsByPoint(point: Point, isOrderSensitive: boolean) {\n const script = await getHtmlElementScript();\n\n await this.sendCommandToDebugger<\n CDPTypes.Runtime.EvaluateResponse,\n CDPTypes.Runtime.EvaluateRequest\n >('Runtime.evaluate', {\n expression: script,\n });\n\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `window.midscene_element_inspector.getXpathsByPoint({left: ${point.left}, top: ${point.top}}, ${isOrderSensitive})`,\n returnByValue: true,\n });\n return result.result.value;\n }\n // 通过xpath获取元素信息\n async getElementInfoByXpath(xpath: string) {\n const script = await getHtmlElementScript();\n\n // check tab url\n await this.sendCommandToDebugger<\n CDPTypes.Runtime.EvaluateResponse,\n CDPTypes.Runtime.EvaluateRequest\n >('Runtime.evaluate', {\n expression: script,\n });\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `window.midscene_element_inspector.getElementInfoByXpath(${JSON.stringify(xpath)})`,\n returnByValue: true,\n });\n return result.result.value;\n }\n // 获取元素节点树\n async getElementsNodeTree() {\n await this.hideMousePointer();\n const content = await this.getPageContentByCDP();\n if (content?.size) {\n this.viewportSize = content.size;\n }\n\n return content?.tree || { node: null, children: [] };\n }\n // 获取上下文\n async getContext(): Promise<UIContext> {\n return await WebPageContextParser(this, {});\n }\n // 页面尺寸\n async size() {\n // if (this.viewportSize) return this.viewportSize;\n const content = await this.getPageContentByCDP();\n return content.size;\n }\n // 截图返回base64\n async screenshotBase64() {\n // screenshot by cdp\n await this.hideMousePointer();\n const format = 'jpeg';\n const base64 = await this.sendCommandToDebugger('Page.captureScreenshot', {\n format,\n quality: 90,\n });\n return createImgBase64ByFormat(format, base64.data);\n }\n // 页面url\n async url() {\n const tabId = await this.getTabIdOrConnectToCurrentTab();\n const url = await chrome.tabs.get(tabId).then((tab) => tab.url);\n return url || '';\n }\n // 滚动到顶部\n async scrollUntilTop(startingPoint?: Point) {\n if (startingPoint) {\n await this.mouse.move(startingPoint.left, startingPoint.top);\n }\n return this.mouse.wheel(0, -9999999);\n }\n // 滚动到底部\n async scrollUntilBottom(startingPoint?: Point) {\n if (startingPoint) {\n await this.mouse.move(startingPoint.left, startingPoint.top);\n }\n return this.mouse.wheel(0, 9999999);\n }\n // 滚动到左侧\n async scrollUntilLeft(startingPoint?: Point) {\n if (startingPoint) {\n await this.mouse.move(startingPoint.left, startingPoint.top);\n }\n return this.mouse.wheel(-9999999, 0);\n }\n // 滚动到右侧\n async scrollUntilRight(startingPoint?: Point) {\n if (startingPoint) {\n await this.mouse.move(startingPoint.left, startingPoint.top);\n }\n return this.mouse.wheel(9999999, 0);\n }\n // 向上滚动\n async scrollUp(distance?: number, startingPoint?: Point) {\n const { height } = await this.size();\n const scrollDistance = distance || height * 0.7;\n return this.mouse.wheel(\n 0,\n -scrollDistance,\n startingPoint?.left,\n startingPoint?.top,\n );\n }\n // 向下滚动\n async scrollDown(distance?: number, startingPoint?: Point) {\n const { height } = await this.size();\n const scrollDistance = distance || height * 0.7;\n return this.mouse.wheel(\n 0,\n scrollDistance,\n startingPoint?.left,\n startingPoint?.top,\n );\n }\n // 向左滚动\n async scrollLeft(distance?: number, startingPoint?: Point) {\n const { width } = await this.size();\n const scrollDistance = distance || width * 0.7;\n return this.mouse.wheel(\n -scrollDistance,\n 0,\n startingPoint?.left,\n startingPoint?.top,\n );\n }\n // 向右滚动\n async scrollRight(distance?: number, startingPoint?: Point) {\n const { width } = await this.size();\n const scrollDistance = distance || width * 0.7;\n return this.mouse.wheel(\n scrollDistance,\n 0,\n startingPoint?.left,\n startingPoint?.top,\n );\n }\n // 清空input框\n async clearInput(element: ElementInfo) {\n if (!element) {\n console.warn('No element to clear input');\n return;\n }\n\n await this.mouse.click(element.center[0], element.center[1]);\n\n await this.sendCommandToDebugger('Input.dispatchKeyEvent', {\n type: 'keyDown',\n commands: ['selectAll'],\n });\n\n await this.sendCommandToDebugger('Input.dispatchKeyEvent', {\n type: 'keyUp',\n commands: ['selectAll'],\n });\n\n await sleep(100);\n\n await this.keyboard.press({\n key: 'Backspace',\n });\n }\n\n private latestMouseX = 100;\n private latestMouseY = 100;\n // 鼠标\n mouse = {\n click: async (\n x: number,\n y: number,\n options?: { button?: MouseButton; count?: number },\n ) => {\n const { button = 'left', count = 1 } = options || {};\n await this.mouse.move(x, y);\n // detect if the page is in mobile emulation mode\n if (this.isMobileEmulation === null) {\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `(() => {\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\n })()`,\n returnByValue: true,\n });\n this.isMobileEmulation = result?.result?.value;\n }\n\n if (this.isMobileEmulation && button === 'left') {\n // in mobile emulation mode, directly inject click event\n const touchPoints = [{ x: Math.round(x), y: Math.round(y) }];\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchStart',\n touchPoints,\n modifiers: 0,\n });\n\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchEnd',\n touchPoints: [],\n modifiers: 0,\n });\n } else {\n for (let i = 0; i < count; i++) {\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mousePressed',\n x,\n y,\n button,\n clickCount: 1,\n });\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseReleased',\n x,\n y,\n button,\n clickCount: 1,\n });\n await sleep(50);\n }\n }\n },\n wheel: async (\n deltaX: number,\n deltaY: number,\n startX?: number,\n startY?: number,\n ) => {\n const finalX = startX || this.latestMouseX;\n const finalY = startY || this.latestMouseY;\n await this.showMousePointer(finalX, finalY);\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseWheel',\n x: finalX,\n y: finalY,\n deltaX,\n deltaY,\n });\n this.latestMouseX = finalX;\n this.latestMouseY = finalY;\n },\n move: async (x: number, y: number) => {\n await this.showMousePointer(x, y);\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseMoved',\n x,\n y,\n });\n this.latestMouseX = x;\n this.latestMouseY = y;\n },\n drag: async (\n from: { x: number; y: number },\n to: { x: number; y: number },\n ) => {\n await this.mouse.move(from.x, from.y);\n\n await sleep(200);\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mousePressed',\n x: from.x,\n y: from.y,\n button: 'left',\n clickCount: 1,\n });\n\n await sleep(300);\n\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseMoved',\n x: to.x,\n y: to.y,\n });\n\n await sleep(500);\n\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseReleased',\n x: to.x,\n y: to.y,\n button: 'left',\n clickCount: 1,\n });\n\n await sleep(200);\n\n await this.mouse.move(to.x, to.y);\n },\n };\n // 键盘\n keyboard = {\n type: async (text: string) => {\n const cdpKeyboard = new CdpKeyboard({\n send: this.sendCommandToDebugger.bind(this),\n });\n await cdpKeyboard.type(text, { delay: 0 });\n },\n press: async (\n action:\n | { key: KeyInput; command?: string }\n | { key: KeyInput; command?: string }[],\n ) => {\n const cdpKeyboard = new CdpKeyboard({\n send: this.sendCommandToDebugger.bind(this),\n });\n const keys = Array.isArray(action) ? action : [action];\n for (const k of keys) {\n const commands = k.command ? [k.command] : [];\n await cdpKeyboard.down(k.key, { commands });\n }\n for (const k of [...keys].reverse()) {\n await cdpKeyboard.up(k.key);\n }\n },\n };\n // 销毁debugger\n async destroy(): Promise<void> {\n this.activeTabId = null;\n await this.detachDebugger();\n this.destroyed = true;\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 await this.mouse.move(x, y);\n\n if (this.isMobileEmulation === null) {\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `(() => {\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\n })()`,\n returnByValue: true,\n });\n this.isMobileEmulation = result?.result?.value;\n }\n\n if (this.isMobileEmulation) {\n const touchPoints = [{ x: Math.round(x), y: Math.round(y) }];\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchStart',\n touchPoints,\n modifiers: 0,\n });\n await new Promise((res) => setTimeout(res, duration));\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchEnd',\n touchPoints: [],\n modifiers: 0,\n });\n } else {\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mousePressed',\n x,\n y,\n button: 'left',\n clickCount: 1,\n });\n await new Promise((res) => setTimeout(res, duration));\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseReleased',\n x,\n y,\n button: 'left',\n clickCount: 1,\n });\n }\n this.latestMouseX = x;\n this.latestMouseY = y;\n }\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 || 300;\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\n if (this.isMobileEmulation === null) {\n const result = await this.sendCommandToDebugger('Runtime.evaluate', {\n expression: `(() => {\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\n })()`,\n returnByValue: true,\n });\n this.isMobileEmulation = result?.result?.value;\n }\n\n const steps = 30;\n const delay = duration / steps;\n\n if (this.isMobileEmulation) {\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchStart',\n touchPoints: [{ x: Math.round(from.x), y: Math.round(from.y) }],\n modifiers: 0,\n });\n\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 this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchMove',\n touchPoints: [{ x: Math.round(x), y: Math.round(y) }],\n modifiers: 0,\n });\n await new Promise((res) => setTimeout(res, delay));\n }\n\n await this.sendCommandToDebugger('Input.dispatchTouchEvent', {\n type: 'touchEnd',\n touchPoints: [],\n modifiers: 0,\n });\n } else {\n await this.mouse.move(from.x, from.y);\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mousePressed',\n x: from.x,\n y: from.y,\n button: 'left',\n clickCount: 1,\n });\n\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 this.mouse.move(x, y);\n await new Promise((res) => setTimeout(res, delay));\n }\n\n await this.sendCommandToDebugger('Input.dispatchMouseEvent', {\n type: 'mouseReleased',\n x: to.x,\n y: to.y,\n button: 'left',\n clickCount: 1,\n });\n }\n\n this.latestMouseX = to.x;\n this.latestMouseY = to.y;\n }\n}\n"],"names":["sleep","ms","Promise","resolve","setTimeout","ChromeExtensionProxyPage","commonWebActionsForWebPage","tabId","Error","chrome","tabs","tab","_tabs_","assert","url","error","currentTabId","console","e","x","y","pointerScript","tabIdToDetach","limitOpenNewTabScript","script","injectWaterFlowAnimation","injectStopWaterFlowAnimation","command","params","expression","window","tree","document","returnValue","_returnValue_exceptionDetails_exception","errorDescription","timeout","startTime","Date","lastReadyState","result","treeToList","id","getHtmlElementScript","JSON","point","isOrderSensitive","xpath","content","WebPageContextParser","format","base64","createImgBase64ByFormat","startingPoint","distance","height","scrollDistance","width","element","duration","LONG_PRESS_THRESHOLD","MIN_PRESS_THRESHOLD","_result_result","touchPoints","Math","res","from","to","steps","delay","i","forceSameTabNavigation","options","button","count","deltaX","deltaY","startX","startY","finalX","finalY","text","cdpKeyboard","CdpKeyboard","action","keys","Array","k","commands"],"mappings":";;;;;;;AAKA;;;;;;;;;;AAuBA,SAASA,MAAMC,EAAU;IACvB,OAAO,IAAIC,QAAQ,CAACC,UAAYC,WAAWD,SAASF;AACtD;AAGe,MAAMI;IAuBnB,cAA8B;QAC5B,OAAOC,2BAA2B,IAAI;IACxC;IAEA,MAAa,eAAeC,KAAa,EAAE;QACzC,IAAI,IAAI,CAAC,WAAW,EAClB,MAAM,IAAIC,MACR,CAAC,uCAAuC,EAAE,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAED,OAAO;QAG3F,MAAME,OAAO,IAAI,CAAC,MAAM,CAACF,OAAO;YAAE,QAAQ;QAAK;QAC/C,IAAI,CAAC,WAAW,GAAGA;IACrB;IAEA,MAAa,iBAAiB;QAC5B,OAAO,IAAI,CAAC,WAAW;IACzB;IAMA,MAAa,oBAEX;QACA,MAAMG,OAAO,MAAMD,OAAO,IAAI,CAAC,KAAK,CAAC;YAAE,eAAe;QAAK;QAC3D,OAAOC,KACJ,GAAG,CAAC,CAACC,MAAS;gBACb,IAAI,GAAGA,IAAI,EAAE,EAAE;gBACf,OAAOA,IAAI,KAAK;gBAChB,KAAKA,IAAI,GAAG;gBACZ,kBAAkBA,IAAI,MAAM;YAC9B,IACC,MAAM,CAAC,CAACA,MAAQA,IAAI,EAAE,IAAIA,IAAI,KAAK,IAAIA,IAAI,GAAG;IAMnD;IAEA,MAAa,gCAAgC;QAC3C,IAAI,IAAI,CAAC,WAAW,EAElB,OAAO,IAAI,CAAC,WAAW;QAEzB,MAAMJ,QAAQ,MAAME,OAAO,IAAI,CAC5B,KAAK,CAAC;YAAE,QAAQ;YAAM,eAAe;QAAK,GAC1C,IAAI,CAAC,CAACC;gBAASE;2BAAAA,CAAAA,SAAAA,IAAI,CAAC,EAAE,AAAD,IAANA,KAAAA,IAAAA,OAAS,EAAE;;QAC7B,IAAI,CAAC,WAAW,GAAGL,SAAS;QAC5B,OAAO,IAAI,CAAC,WAAW;IACzB;IAEA,MAAc,iBAAiB;QAC7BM,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE;QAGxB,IAAI,IAAI,CAAC,iBAAiB,EAAE,YAC1B,MAAM,IAAI,CAAC,iBAAiB;QAK9B,IAAI,CAAC,iBAAiB,GAAI;YACxB,MAAMC,MAAM,MAAM,IAAI,CAAC,GAAG;YAC1B,IAAIC,QAAsB;YAC1B,IAAID,IAAI,UAAU,CAAC,cACjB,MAAM,IAAIN,MACR;YAIJ,IAAI;gBACF,MAAMQ,eAAe,MAAM,IAAI,CAAC,6BAA6B;gBAE7D,IAAI,IAAI,CAAC,uBAAuB,KAAKA,cAEnC;gBAEF,IACE,IAAI,CAAC,uBAAuB,IAC5B,IAAI,CAAC,uBAAuB,KAAKA,cACjC;oBAEAC,QAAQ,GAAG,CACT,2BACA,IAAI,CAAC,uBAAuB,EAC5B,MACAD;oBAEF,IAAI;wBACF,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,uBAAuB;oBACxD,EAAE,OAAOD,OAAO;wBACdE,QAAQ,KAAK,CAAC,6BAA6BF;oBAC7C;gBACF;gBAGAE,QAAQ,GAAG,CAAC,sBAAsBD;gBAClC,IAAI;oBACF,MAAMP,OAAO,QAAQ,CAAC,MAAM,CAAC;wBAAE,OAAOO;oBAAa,GAAG;gBACxD,EAAE,OAAOE,GAAG;oBACV,IAAI,IAAI,CAAC,mCAAmC,EAC1CD,QAAQ,IAAI,CACV,gJACAC;yBAGF,MAAMA;gBAEV;gBAGA,MAAMlB,MAAM;gBAEZ,IAAI,CAAC,uBAAuB,GAAGgB;gBAE/B,MAAM,IAAI,CAAC,wBAAwB;YACrC,EAAE,OAAOE,GAAG;gBACVD,QAAQ,KAAK,CAAC,6BAA6BC;gBAC3CH,QAAQG;YACV,SAAU;gBACR,IAAI,CAAC,iBAAiB,GAAG;YAC3B;YACA,IAAIH,OACF,MAAMA;QAEV;QAEA,MAAM,IAAI,CAAC,iBAAiB;IAC9B;IAEA,MAAc,iBAAiBI,CAAS,EAAEC,CAAS,EAAE;QAEnD,MAAMC,gBAAgB,CAAC;;;2DAGgC,EAAEF,EAAE,EAAE,EAAEC,EAAE;;;;QAI7D,CAAC;QAEL,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;YACnD,YAAY,GAAGC,eAAe;QAChC;IACF;IAEA,MAAc,mBAAmB;QAC/B,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;YACnD,YAAY,CAAC;;;;UAIT,CAAC;QACP;IACF;IAEA,MAAc,eAAed,KAAc,EAAE;QAC3C,MAAMe,gBAAgBf,SAAS,IAAI,CAAC,uBAAuB;QAC3DU,QAAQ,GAAG,CAAC,sBAAsBK;QAClC,IAAI,CAACA,eAAe,YAClBL,QAAQ,IAAI,CAAC;QAIf,IAAI;YACF,MAAM,IAAI,CAAC,yBAAyB,CAACK;YACrC,MAAMtB,MAAM;QACd,EAAE,OAAOe,OAAO;YACdE,QAAQ,IAAI,CAAC,0CAA0CF;QACzD;QAEA,IAAI;YACF,MAAMN,OAAO,QAAQ,CAAC,MAAM,CAAC;gBAAE,OAAOa;YAAc;QACtD,EAAE,OAAOP,OAAO;YAEdE,QAAQ,IAAI,CAAC,6BAA6BF;QAC5C;QACA,IAAI,CAAC,uBAAuB,GAAG;IACjC;IAEA,MAAc,2BAA2B;QAEvC,IAAI,IAAI,CAAC,sBAAsB,EAC7B,MAAMN,OAAO,QAAQ,CAAC,WAAW,CAC/B;YAAE,OAAO,IAAI,CAAC,uBAAuB;QAAE,GACvC,oBACA;YACE,YAAYc;QACd;QAIJ,MAAMC,SAAS,MAAMC;QAErB,MAAMhB,OAAO,QAAQ,CAAC,WAAW,CAC/B;YAAE,OAAO,IAAI,CAAC,uBAAuB;QAAE,GACvC,oBACA;YACE,YAAYe;QACd;IAEJ;IAEA,MAAc,0BAA0BjB,KAAa,EAAE;QACrD,MAAMiB,SAAS,MAAME;QAErB,MAAMjB,OAAO,QAAQ,CAAC,WAAW,CAAC;YAAEF;QAAM,GAAG,oBAAoB;YAC/D,YAAYiB;QACd;IACF;IAEA,MAAc,sBACZG,OAAe,EACfC,MAAmB,EACI;QACvB,MAAM,IAAI,CAAC,cAAc;QAEzBf,OAAO,IAAI,CAAC,uBAAuB,EAAE;QAGrC,IAAI,CAAC,wBAAwB;QAC7B,OAAQ,MAAMJ,OAAO,QAAQ,CAAC,WAAW,CACvC;YAAE,OAAO,IAAI,CAAC,uBAAuB;QAAE,GACvCkB,SACAC;IAEJ;IAEA,MAAc,sBAAsB;QAclC,MAAMnB,OAAO,SAAS,CAAC,aAAa,CAAC;YACnC,OAAO;gBAAC;aAA2B;YACnC,OAAO;YACP,QAAQ;gBACN,WAAW;gBACX,OAAO,IAAI,CAAC,uBAAuB;YACrC;QACF;QAGA,MAAMoB,aAAa;YAEhBC,OAAe,0BAA0B,CAAC,4BAA4B;YAEvE,MAAMC,OAAO,MACXD,OACA,0BAA0B,CAAC,kBAAkB;YAG/C,OAAO;gBACLC;gBACA,MAAM;oBACJ,OAAOC,SAAS,eAAe,CAAC,WAAW;oBAC3C,QAAQA,SAAS,eAAe,CAAC,YAAY;oBAC7C,KAAKF,OAAO,gBAAgB;gBAC9B;YACF;QACF;QACA,MAAMG,cAAc,MAAM,IAAI,CAAC,qBAAqB,CAGlD,oBAAoB;YACpB,YAAY,CAAC,CAAC,EAAEJ,WAAW,QAAQ,GAAG,GAAG,CAAC;YAC1C,eAAe;YACf,cAAc;QAChB;QAEA,IAAI,CAACI,YAAY,MAAM,CAAC,KAAK,EAAE;gBAE3BC,yCAAAA;YADF,MAAMC,mBACJD,AAAAA,SAAAA,CAAAA,gCAAAA,YAAY,gBAAgB,AAAD,IAA3BA,KAAAA,IAAAA,QAAAA,CAAAA,0CAAAA,8BAA8B,SAAS,AAAD,IAAtCA,KAAAA,IAAAA,wCAAyC,WAAW,AAAD,KAAK;YAC1D,IAAI,CAACC,kBACHlB,QAAQ,KAAK,CAAC,wBAAwBgB;YAExC,MAAM,IAAIzB,MACR,CAAC,6CAA6C,EAAE2B,kBAAkB;QAEtE;QAEA,OAAOF,YAAY,MAAM,CAAC,KAAK;IAIjC;IAEA,MAAa,mBAAmBT,MAAc,EAAE;QAC9C,OAAO,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;YACpD,YAAYA;QACd;IACF;IAEA,MAAM,qBAAoC;QAExC,IAAI;YACF,MAAM,IAAI,CAAC,oBAAoB;QACjC,EAAE,OAAOT,OAAO,CAEhB;IACF;IAEA,MAAc,uBAAuB;QACnC,MAAMqB,UAAU;QAChB,MAAMC,YAAYC,KAAK,GAAG;QAC1B,IAAIC,iBAAiB;QACrB,MAAOD,KAAK,GAAG,KAAKD,YAAYD,QAAS;YACvC,MAAMI,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;gBAClE,YAAY;YACd;YACAD,iBAAiBC,OAAO,MAAM,CAAC,KAAK;YACpC,IAAID,AAAmB,eAAnBA,gBAA+B,YACjC,MAAM,IAAIrC,QAAQ,CAACC,UAAYC,WAAWD,SAAS;YAGrD,MAAM,IAAID,QAAQ,CAACC,UAAYC,WAAWD,SAAS;QACrD;QACA,MAAM,IAAIK,MACR,CAAC,oDAAoD,EAAE+B,gBAAgB;IAE3E;IAIA,MAAM,kBAAkB;QAEtB,MAAMR,OAAO,MAAM,IAAI,CAAC,mBAAmB;QAE3C,OAAOU,WAAWV;IACpB;IAEA,MAAM,cAAcW,EAAU,EAAE;QAC9B,MAAMlB,SAAS,MAAMmB;QAGrB,MAAM,IAAI,CAAC,qBAAqB,CAG9B,oBAAoB;YACpB,YAAYnB;QACd;QAEA,MAAMgB,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;YAClE,YAAY,CAAC,gDAAgD,EAAEI,KAAK,SAAS,CAACF,IAAI,CAAC,CAAC;YACpF,eAAe;QACjB;QACA,OAAOF,OAAO,MAAM,CAAC,KAAK;IAC5B;IAEA,MAAM,iBAAiBK,KAAY,EAAEC,gBAAyB,EAAE;QAC9D,MAAMtB,SAAS,MAAMmB;QAErB,MAAM,IAAI,CAAC,qBAAqB,CAG9B,oBAAoB;YACpB,YAAYnB;QACd;QAEA,MAAMgB,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;YAClE,YAAY,CAAC,0DAA0D,EAAEK,MAAM,IAAI,CAAC,OAAO,EAAEA,MAAM,GAAG,CAAC,GAAG,EAAEC,iBAAiB,CAAC,CAAC;YAC/H,eAAe;QACjB;QACA,OAAON,OAAO,MAAM,CAAC,KAAK;IAC5B;IAEA,MAAM,sBAAsBO,KAAa,EAAE;QACzC,MAAMvB,SAAS,MAAMmB;QAGrB,MAAM,IAAI,CAAC,qBAAqB,CAG9B,oBAAoB;YACpB,YAAYnB;QACd;QACA,MAAMgB,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;YAClE,YAAY,CAAC,wDAAwD,EAAEI,KAAK,SAAS,CAACG,OAAO,CAAC,CAAC;YAC/F,eAAe;QACjB;QACA,OAAOP,OAAO,MAAM,CAAC,KAAK;IAC5B;IAEA,MAAM,sBAAsB;QAC1B,MAAM,IAAI,CAAC,gBAAgB;QAC3B,MAAMQ,UAAU,MAAM,IAAI,CAAC,mBAAmB;QAC9C,IAAIA,QAAAA,UAAAA,KAAAA,IAAAA,QAAS,IAAI,EACf,IAAI,CAAC,YAAY,GAAGA,QAAQ,IAAI;QAGlC,OAAOA,AAAAA,CAAAA,QAAAA,UAAAA,KAAAA,IAAAA,QAAS,IAAI,AAAD,KAAK;YAAE,MAAM;YAAM,UAAU,EAAE;QAAC;IACrD;IAEA,MAAM,aAAiC;QACrC,OAAO,MAAMC,qBAAqB,IAAI,EAAE,CAAC;IAC3C;IAEA,MAAM,OAAO;QAEX,MAAMD,UAAU,MAAM,IAAI,CAAC,mBAAmB;QAC9C,OAAOA,QAAQ,IAAI;IACrB;IAEA,MAAM,mBAAmB;QAEvB,MAAM,IAAI,CAAC,gBAAgB;QAC3B,MAAME,SAAS;QACf,MAAMC,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,0BAA0B;YACxED;YACA,SAAS;QACX;QACA,OAAOE,wBAAwBF,QAAQC,OAAO,IAAI;IACpD;IAEA,MAAM,MAAM;QACV,MAAM5C,QAAQ,MAAM,IAAI,CAAC,6BAA6B;QACtD,MAAMO,MAAM,MAAML,OAAO,IAAI,CAAC,GAAG,CAACF,OAAO,IAAI,CAAC,CAACI,MAAQA,IAAI,GAAG;QAC9D,OAAOG,OAAO;IAChB;IAEA,MAAM,eAAeuC,aAAqB,EAAE;QAC1C,IAAIA,eACF,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACA,cAAc,IAAI,EAAEA,cAAc,GAAG;QAE7D,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG;IAC7B;IAEA,MAAM,kBAAkBA,aAAqB,EAAE;QAC7C,IAAIA,eACF,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACA,cAAc,IAAI,EAAEA,cAAc,GAAG;QAE7D,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG;IAC7B;IAEA,MAAM,gBAAgBA,aAAqB,EAAE;QAC3C,IAAIA,eACF,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACA,cAAc,IAAI,EAAEA,cAAc,GAAG;QAE7D,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU;IACpC;IAEA,MAAM,iBAAiBA,aAAqB,EAAE;QAC5C,IAAIA,eACF,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACA,cAAc,IAAI,EAAEA,cAAc,GAAG;QAE7D,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS;IACnC;IAEA,MAAM,SAASC,QAAiB,EAAED,aAAqB,EAAE;QACvD,MAAM,EAAEE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI;QAClC,MAAMC,iBAAiBF,YAAYC,AAAS,MAATA;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CACrB,GACA,CAACC,gBACDH,QAAAA,gBAAAA,KAAAA,IAAAA,cAAe,IAAI,EACnBA,QAAAA,gBAAAA,KAAAA,IAAAA,cAAe,GAAG;IAEtB;IAEA,MAAM,WAAWC,QAAiB,EAAED,aAAqB,EAAE;QACzD,MAAM,EAAEE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI;QAClC,MAAMC,iBAAiBF,YAAYC,AAAS,MAATA;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CACrB,GACAC,gBACAH,QAAAA,gBAAAA,KAAAA,IAAAA,cAAe,IAAI,EACnBA,QAAAA,gBAAAA,KAAAA,IAAAA,cAAe,GAAG;IAEtB;IAEA,MAAM,WAAWC,QAAiB,EAAED,aAAqB,EAAE;QACzD,MAAM,EAAEI,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI;QACjC,MAAMD,iBAAiBF,YAAYG,AAAQ,MAARA;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CACrB,CAACD,gBACD,GACAH,QAAAA,gBAAAA,KAAAA,IAAAA,cAAe,IAAI,EACnBA,QAAAA,gBAAAA,KAAAA,IAAAA,cAAe,GAAG;IAEtB;IAEA,MAAM,YAAYC,QAAiB,EAAED,aAAqB,EAAE;QAC1D,MAAM,EAAEI,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI;QACjC,MAAMD,iBAAiBF,YAAYG,AAAQ,MAARA;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CACrBD,gBACA,GACAH,QAAAA,gBAAAA,KAAAA,IAAAA,cAAe,IAAI,EACnBA,QAAAA,gBAAAA,KAAAA,IAAAA,cAAe,GAAG;IAEtB;IAEA,MAAM,WAAWK,OAAoB,EAAE;QACrC,IAAI,CAACA,SAAS,YACZzC,QAAQ,IAAI,CAAC;QAIf,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAACyC,QAAQ,MAAM,CAAC,EAAE,EAAEA,QAAQ,MAAM,CAAC,EAAE;QAE3D,MAAM,IAAI,CAAC,qBAAqB,CAAC,0BAA0B;YACzD,MAAM;YACN,UAAU;gBAAC;aAAY;QACzB;QAEA,MAAM,IAAI,CAAC,qBAAqB,CAAC,0BAA0B;YACzD,MAAM;YACN,UAAU;gBAAC;aAAY;QACzB;QAEA,MAAM1D,MAAM;QAEZ,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YACxB,KAAK;QACP;IACF;IAwJA,MAAM,UAAyB;QAC7B,IAAI,CAAC,WAAW,GAAG;QACnB,MAAM,IAAI,CAAC,cAAc;QACzB,IAAI,CAAC,SAAS,GAAG;IACnB;IAEA,MAAM,UAAUmB,CAAS,EAAEC,CAAS,EAAEuC,QAAiB,EAAE;QACvDA,WAAWA,YAAY;QACvB,MAAMC,uBAAuB;QAC7B,MAAMC,sBAAsB;QAC5B,IAAIF,WAAWC,sBACbD,WAAWC;QAEb,IAAID,WAAWE,qBACbF,WAAWE;QAEb,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC1C,GAAGC;QAEzB,IAAI,AAA2B,SAA3B,IAAI,CAAC,iBAAiB,EAAW;gBAOV0C;YANzB,MAAMtB,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;gBAClE,YAAY,CAAC;;YAET,CAAC;gBACL,eAAe;YACjB;YACA,IAAI,CAAC,iBAAiB,GAAGsB,QAAAA,SAAAA,KAAAA,IAAAA,QAAAA,CAAAA,iBAAAA,OAAQ,MAAM,AAAD,IAAbA,KAAAA,IAAAA,eAAgB,KAAK;QAChD;QAEA,IAAI,IAAI,CAAC,iBAAiB,EAAE;YAC1B,MAAMC,cAAc;gBAAC;oBAAE,GAAGC,KAAK,KAAK,CAAC7C;oBAAI,GAAG6C,KAAK,KAAK,CAAC5C;gBAAG;aAAE;YAC5D,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;gBAC3D,MAAM;gBACN2C;gBACA,WAAW;YACb;YACA,MAAM,IAAI7D,QAAQ,CAAC+D,MAAQ7D,WAAW6D,KAAKN;YAC3C,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;gBAC3D,MAAM;gBACN,aAAa,EAAE;gBACf,WAAW;YACb;QACF,OAAO;YACL,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;gBAC3D,MAAM;gBACNxC;gBACAC;gBACA,QAAQ;gBACR,YAAY;YACd;YACA,MAAM,IAAIlB,QAAQ,CAAC+D,MAAQ7D,WAAW6D,KAAKN;YAC3C,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;gBAC3D,MAAM;gBACNxC;gBACAC;gBACA,QAAQ;gBACR,YAAY;YACd;QACF;QACA,IAAI,CAAC,YAAY,GAAGD;QACpB,IAAI,CAAC,YAAY,GAAGC;IACtB;IAEA,MAAM,MACJ8C,IAA8B,EAC9BC,EAA4B,EAC5BR,QAAiB,EACjB;QACA,MAAMC,uBAAuB;QAC7B,MAAMC,sBAAsB;QAC5BF,WAAWA,YAAY;QACvB,IAAIA,WAAWE,qBACbF,WAAWE;QAEb,IAAIF,WAAWC,sBACbD,WAAWC;QAGb,IAAI,AAA2B,SAA3B,IAAI,CAAC,iBAAiB,EAAW;gBAOVE;YANzB,MAAMtB,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;gBAClE,YAAY,CAAC;;YAET,CAAC;gBACL,eAAe;YACjB;YACA,IAAI,CAAC,iBAAiB,GAAGsB,QAAAA,SAAAA,KAAAA,IAAAA,QAAAA,CAAAA,iBAAAA,OAAQ,MAAM,AAAD,IAAbA,KAAAA,IAAAA,eAAgB,KAAK;QAChD;QAEA,MAAMM,QAAQ;QACd,MAAMC,QAAQV,WAAWS;QAEzB,IAAI,IAAI,CAAC,iBAAiB,EAAE;YAC1B,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;gBAC3D,MAAM;gBACN,aAAa;oBAAC;wBAAE,GAAGJ,KAAK,KAAK,CAACE,KAAK,CAAC;wBAAG,GAAGF,KAAK,KAAK,CAACE,KAAK,CAAC;oBAAE;iBAAE;gBAC/D,WAAW;YACb;YAEA,IAAK,IAAII,IAAI,GAAGA,KAAKF,OAAOE,IAAK;gBAC/B,MAAMnD,IAAI+C,KAAK,CAAC,GAAIC,AAAAA,CAAAA,GAAG,CAAC,GAAGD,KAAK,CAAC,AAAD,IAAMI,CAAAA,IAAIF,KAAI;gBAC9C,MAAMhD,IAAI8C,KAAK,CAAC,GAAIC,AAAAA,CAAAA,GAAG,CAAC,GAAGD,KAAK,CAAC,AAAD,IAAMI,CAAAA,IAAIF,KAAI;gBAC9C,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;oBAC3D,MAAM;oBACN,aAAa;wBAAC;4BAAE,GAAGJ,KAAK,KAAK,CAAC7C;4BAAI,GAAG6C,KAAK,KAAK,CAAC5C;wBAAG;qBAAE;oBACrD,WAAW;gBACb;gBACA,MAAM,IAAIlB,QAAQ,CAAC+D,MAAQ7D,WAAW6D,KAAKI;YAC7C;YAEA,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;gBAC3D,MAAM;gBACN,aAAa,EAAE;gBACf,WAAW;YACb;QACF,OAAO;YACL,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACH,KAAK,CAAC,EAAEA,KAAK,CAAC;YACpC,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;gBAC3D,MAAM;gBACN,GAAGA,KAAK,CAAC;gBACT,GAAGA,KAAK,CAAC;gBACT,QAAQ;gBACR,YAAY;YACd;YAEA,IAAK,IAAII,IAAI,GAAGA,KAAKF,OAAOE,IAAK;gBAC/B,MAAMnD,IAAI+C,KAAK,CAAC,GAAIC,AAAAA,CAAAA,GAAG,CAAC,GAAGD,KAAK,CAAC,AAAD,IAAMI,CAAAA,IAAIF,KAAI;gBAC9C,MAAMhD,IAAI8C,KAAK,CAAC,GAAIC,AAAAA,CAAAA,GAAG,CAAC,GAAGD,KAAK,CAAC,AAAD,IAAMI,CAAAA,IAAIF,KAAI;gBAC9C,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACjD,GAAGC;gBACzB,MAAM,IAAIlB,QAAQ,CAAC+D,MAAQ7D,WAAW6D,KAAKI;YAC7C;YAEA,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;gBAC3D,MAAM;gBACN,GAAGF,GAAG,CAAC;gBACP,GAAGA,GAAG,CAAC;gBACP,QAAQ;gBACR,YAAY;YACd;QACF;QAEA,IAAI,CAAC,YAAY,GAAGA,GAAG,CAAC;QACxB,IAAI,CAAC,YAAY,GAAGA,GAAG,CAAC;IAC1B;IAvzBA,YAAYI,sBAA+B,CAAE;QAlB7C,wCAAgB;QAEhB,uBAAO,0BAAP;QAEA,uBAAQ,gBAAR;QAEA,uBAAQ,eAA6B;QAErC,uBAAQ,2BAAyC;QAEjD,uBAAQ,qBAA0C;QAElD,uBAAQ,aAAY;QAEpB,uBAAQ,qBAAoC;QAE5C,uBAAO,uCAAsC;QAshB7C,uBAAQ,gBAAe;QACvB,uBAAQ,gBAAe;QAEvB,gCAAQ;YACN,OAAO,OACLpD,GACAC,GACAoD;gBAEA,MAAM,EAAEC,SAAS,MAAM,EAAEC,QAAQ,CAAC,EAAE,GAAGF,WAAW,CAAC;gBACnD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACrD,GAAGC;gBAEzB,IAAI,AAA2B,SAA3B,IAAI,CAAC,iBAAiB,EAAW;wBAOV0C;oBANzB,MAAMtB,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB;wBAClE,YAAY,CAAC;;cAET,CAAC;wBACL,eAAe;oBACjB;oBACA,IAAI,CAAC,iBAAiB,GAAGsB,QAAAA,SAAAA,KAAAA,IAAAA,QAAAA,CAAAA,iBAAAA,OAAQ,MAAM,AAAD,IAAbA,KAAAA,IAAAA,eAAgB,KAAK;gBAChD;gBAEA,IAAI,IAAI,CAAC,iBAAiB,IAAIW,AAAW,WAAXA,QAAmB;oBAE/C,MAAMV,cAAc;wBAAC;4BAAE,GAAGC,KAAK,KAAK,CAAC7C;4BAAI,GAAG6C,KAAK,KAAK,CAAC5C;wBAAG;qBAAE;oBAC5D,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;wBAC3D,MAAM;wBACN2C;wBACA,WAAW;oBACb;oBAEA,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;wBAC3D,MAAM;wBACN,aAAa,EAAE;wBACf,WAAW;oBACb;gBACF,OACE,IAAK,IAAIO,IAAI,GAAGA,IAAII,OAAOJ,IAAK;oBAC9B,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;wBAC3D,MAAM;wBACNnD;wBACAC;wBACAqD;wBACA,YAAY;oBACd;oBACA,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;wBAC3D,MAAM;wBACNtD;wBACAC;wBACAqD;wBACA,YAAY;oBACd;oBACA,MAAMzE,MAAM;gBACd;YAEJ;YACA,OAAO,OACL2E,QACAC,QACAC,QACAC;gBAEA,MAAMC,SAASF,UAAU,IAAI,CAAC,YAAY;gBAC1C,MAAMG,SAASF,UAAU,IAAI,CAAC,YAAY;gBAC1C,MAAM,IAAI,CAAC,gBAAgB,CAACC,QAAQC;gBACpC,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;oBAC3D,MAAM;oBACN,GAAGD;oBACH,GAAGC;oBACHL;oBACAC;gBACF;gBACA,IAAI,CAAC,YAAY,GAAGG;gBACpB,IAAI,CAAC,YAAY,GAAGC;YACtB;YACA,MAAM,OAAO7D,GAAWC;gBACtB,MAAM,IAAI,CAAC,gBAAgB,CAACD,GAAGC;gBAC/B,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;oBAC3D,MAAM;oBACND;oBACAC;gBACF;gBACA,IAAI,CAAC,YAAY,GAAGD;gBACpB,IAAI,CAAC,YAAY,GAAGC;YACtB;YACA,MAAM,OACJ8C,MACAC;gBAEA,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACD,KAAK,CAAC,EAAEA,KAAK,CAAC;gBAEpC,MAAMlE,MAAM;gBACZ,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;oBAC3D,MAAM;oBACN,GAAGkE,KAAK,CAAC;oBACT,GAAGA,KAAK,CAAC;oBACT,QAAQ;oBACR,YAAY;gBACd;gBAEA,MAAMlE,MAAM;gBAEZ,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;oBAC3D,MAAM;oBACN,GAAGmE,GAAG,CAAC;oBACP,GAAGA,GAAG,CAAC;gBACT;gBAEA,MAAMnE,MAAM;gBAEZ,MAAM,IAAI,CAAC,qBAAqB,CAAC,4BAA4B;oBAC3D,MAAM;oBACN,GAAGmE,GAAG,CAAC;oBACP,GAAGA,GAAG,CAAC;oBACP,QAAQ;oBACR,YAAY;gBACd;gBAEA,MAAMnE,MAAM;gBAEZ,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAACmE,GAAG,CAAC,EAAEA,GAAG,CAAC;YAClC;QACF;QAEA,mCAAW;YACT,MAAM,OAAOc;gBACX,MAAMC,cAAc,IAAIC,YAAY;oBAClC,MAAM,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI;gBAC5C;gBACA,MAAMD,YAAY,IAAI,CAACD,MAAM;oBAAE,OAAO;gBAAE;YAC1C;YACA,OAAO,OACLG;gBAIA,MAAMF,cAAc,IAAIC,YAAY;oBAClC,MAAM,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI;gBAC5C;gBACA,MAAME,OAAOC,MAAM,OAAO,CAACF,UAAUA,SAAS;oBAACA;iBAAO;gBACtD,KAAK,MAAMG,KAAKF,KAAM;oBACpB,MAAMG,WAAWD,EAAE,OAAO,GAAG;wBAACA,EAAE,OAAO;qBAAC,GAAG,EAAE;oBAC7C,MAAML,YAAY,IAAI,CAACK,EAAE,GAAG,EAAE;wBAAEC;oBAAS;gBAC3C;gBACA,KAAK,MAAMD,KAAK;uBAAIF;iBAAK,CAAC,OAAO,GAC/B,MAAMH,YAAY,EAAE,CAACK,EAAE,GAAG;YAE9B;QACF;QAvqBE,IAAI,CAAC,sBAAsB,GAAGhB;IAChC;AAszBF"}
@@ -31,8 +31,8 @@ const groupAndCaseForTest = (testInfo)=>{
31
31
  title: replaceIllegalPathCharsAndSpace(taskTitleWithRetry)
32
32
  };
33
33
  };
34
- const rpasceneAgentKeyId = '_rpasceneAgentId';
35
- const rpasceneDumpAnnotationId = 'RPASCENE_DUMP_ANNOTATION';
34
+ const midsceneAgentKeyId = '_midsceneAgentId';
35
+ const midsceneDumpAnnotationId = 'MIDSCENE_DUMP_ANNOTATION';
36
36
  const PlaywrightAiFixture = (options)=>{
37
37
  const { forceSameTabNavigation = true, waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT, waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT, cache } = options ?? {};
38
38
  const processTestCacheConfig = (testInfo)=>{
@@ -41,10 +41,10 @@ const PlaywrightAiFixture = (options)=>{
41
41
  };
42
42
  const pageAgentMap = {};
43
43
  const createOrReuseAgentForPage = (page, testInfo, opts)=>{
44
- let idForPage = page[rpasceneAgentKeyId];
44
+ let idForPage = page[midsceneAgentKeyId];
45
45
  if (!idForPage) {
46
46
  idForPage = uuid();
47
- page[rpasceneAgentKeyId] = idForPage;
47
+ page[midsceneAgentKeyId] = idForPage;
48
48
  const { testId } = testInfo;
49
49
  const { file, title } = groupAndCaseForTest(testInfo);
50
50
  const cacheConfig = processTestCacheConfig(testInfo);
@@ -80,7 +80,7 @@ const PlaywrightAiFixture = (options)=>{
80
80
  debugPage(`waitForNetworkIdle timeout: ${waitForNetworkIdleTimeout}`);
81
81
  await agent.waitForNetworkIdle(waitForNetworkIdleTimeout);
82
82
  } catch (error) {
83
- console.warn('[rpascene:warning] Waiting for network idle has timed out, but Rpascene will continue execution. Please check https://rpascenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout');
83
+ console.warn('[midscene:warning] Waiting for 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');
84
84
  }
85
85
  try {
86
86
  const result = await agent[aiActionType](taskPrompt, ...args || []);
@@ -92,14 +92,14 @@ const PlaywrightAiFixture = (options)=>{
92
92
  }));
93
93
  }
94
94
  const updateDumpAnnotation = (test, dump)=>{
95
- const tempFileName = `rpascene-dump-${test.testId || uuid()}-${Date.now()}.json`;
95
+ const tempFileName = `midscene-dump-${test.testId || uuid()}-${Date.now()}.json`;
96
96
  const tempFilePath = join(tmpdir(), tempFileName);
97
97
  writeFileSync(tempFilePath, dump, 'utf-8');
98
98
  debugPage(`Dump written to temp file: ${tempFilePath}`);
99
- const currentAnnotation = test.annotations.find((item)=>item.type === rpasceneDumpAnnotationId);
99
+ const currentAnnotation = test.annotations.find((item)=>item.type === midsceneDumpAnnotationId);
100
100
  if (currentAnnotation) currentAnnotation.description = tempFilePath;
101
101
  else test.annotations.push({
102
- type: rpasceneDumpAnnotationId,
102
+ type: midsceneDumpAnnotationId,
103
103
  description: tempFilePath
104
104
  });
105
105
  };
@@ -320,6 +320,6 @@ const PlaywrightAiFixture = (options)=>{
320
320
  }
321
321
  };
322
322
  };
323
- export { PlaywrightAiFixture, rpasceneDumpAnnotationId };
323
+ export { PlaywrightAiFixture, midsceneDumpAnnotationId };
324
324
 
325
325
  //# sourceMappingURL=ai-fixture.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"playwright\\ai-fixture.mjs","sources":["webpack://@rpascene/web/./src/playwright/ai-fixture.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { PlaywrightAgent, type PlaywrightWebPage } from '@/playwright/index';\nimport type { WebPageAgentOpt } from '@/web-element';\nimport type { Cache } from '@rpascene/core';\nimport type { AgentOpt, Agent as PageAgent } from '@rpascene/core/agent';\nimport { processCacheConfig } from '@rpascene/core/utils';\nimport {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@rpascene/shared/constants';\nimport { getDebug } from '@rpascene/shared/logger';\nimport { uuid } from '@rpascene/shared/utils';\nimport { replaceIllegalPathCharsAndSpace } from '@rpascene/shared/utils';\nimport { type TestInfo, type TestType, test } from '@playwright/test';\nimport type { Page as OriginPlaywrightPage } from 'playwright';\nexport type APITestType = Pick<TestType<any, any>, 'step'>;\n\nconst debugPage = getDebug('web:playwright:ai-fixture');\n\nconst groupAndCaseForTest = (testInfo: TestInfo) => {\n let taskFile: string;\n let taskTitle: string;\n const titlePath = [...testInfo.titlePath];\n\n if (titlePath.length > 1) {\n taskFile = titlePath.shift() || 'unnamed';\n taskTitle = titlePath.join('__');\n } else if (titlePath.length === 1) {\n taskTitle = titlePath[0];\n taskFile = `${taskTitle}`;\n } else {\n taskTitle = 'unnamed';\n taskFile = 'unnamed';\n }\n\n const taskTitleWithRetry = `${taskTitle}${testInfo.retry ? `(retry #${testInfo.retry})` : ''}`;\n\n return {\n file: taskFile,\n id: replaceIllegalPathCharsAndSpace(`${taskFile}(${taskTitle})`),\n title: replaceIllegalPathCharsAndSpace(taskTitleWithRetry),\n };\n};\n\nconst rpasceneAgentKeyId = '_rpasceneAgentId';\nexport const rpasceneDumpAnnotationId = 'RPASCENE_DUMP_ANNOTATION';\n\ntype PlaywrightCacheConfig = {\n strategy?: 'read-only' | 'read-write' | 'write-only';\n id?: string;\n};\ntype PlaywrightCache = false | true | PlaywrightCacheConfig;\n\nexport const PlaywrightAiFixture = (options?: {\n forceSameTabNavigation?: boolean;\n waitForNetworkIdleTimeout?: number;\n waitForNavigationTimeout?: number;\n cache?: PlaywrightCache;\n}) => {\n const {\n forceSameTabNavigation = true,\n waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n cache,\n } = options ?? {};\n\n // Helper function to process cache configuration and auto-generate ID from test info\n const processTestCacheConfig = (testInfo: TestInfo): Cache | undefined => {\n // Generate ID from test info\n const { id } = groupAndCaseForTest(testInfo);\n\n // Use shared processCacheConfig with generated ID as fallback\n return processCacheConfig(cache as Cache, id);\n };\n\n const pageAgentMap: Record<string, PageAgent<PlaywrightWebPage>> = {};\n const createOrReuseAgentForPage = (\n page: OriginPlaywrightPage,\n testInfo: TestInfo, // { testId: string; taskFile: string; taskTitle: string },\n opts?: WebPageAgentOpt,\n ) => {\n let idForPage = (page as any)[rpasceneAgentKeyId];\n if (!idForPage) {\n idForPage = uuid();\n (page as any)[rpasceneAgentKeyId] = idForPage;\n const { testId } = testInfo;\n const { file, title } = groupAndCaseForTest(testInfo);\n const cacheConfig = processTestCacheConfig(testInfo);\n\n pageAgentMap[idForPage] = new PlaywrightAgent(page, {\n testId: `playwright-${testId}-${idForPage}`,\n forceSameTabNavigation,\n cache: cacheConfig,\n groupName: title,\n groupDescription: file,\n generateReport: false, // we will generate it in the reporter\n ...opts,\n });\n\n pageAgentMap[idForPage].onDumpUpdate = (dump: string) => {\n updateDumpAnnotation(testInfo, dump);\n };\n\n page.on('close', () => {\n debugPage('page closed');\n pageAgentMap[idForPage].destroy();\n delete pageAgentMap[idForPage];\n });\n }\n\n return pageAgentMap[idForPage];\n };\n\n async function generateAiFunction(options: {\n page: OriginPlaywrightPage;\n testInfo: TestInfo;\n use: any;\n aiActionType:\n | 'ai'\n | 'aiAction'\n | 'aiHover'\n | 'aiInput'\n | 'aiKeyboardPress'\n | 'aiScroll'\n | 'aiTap'\n | 'aiRightClick'\n | 'aiDoubleClick'\n | 'aiQuery'\n | 'aiAssert'\n | 'aiWaitFor'\n | 'aiLocate'\n | 'aiNumber'\n | 'aiString'\n | 'aiBoolean'\n | 'aiAsk'\n | 'runYaml'\n | 'setAIActionContext'\n | 'evaluateJavaScript'\n | 'logScreenshot'\n | 'freezePageContext'\n | 'unfreezePageContext';\n }) {\n const { page, testInfo, use, aiActionType } = options;\n const agent = createOrReuseAgentForPage(page, testInfo, {\n waitForNavigationTimeout,\n waitForNetworkIdleTimeout,\n }) as PlaywrightAgent;\n\n await use(async (taskPrompt: string, ...args: any[]) => {\n return new Promise((resolve, reject) => {\n test.step(`ai-${aiActionType} - ${JSON.stringify(taskPrompt)}`, async () => {\n try {\n debugPage(\n `waitForNetworkIdle timeout: ${waitForNetworkIdleTimeout}`,\n );\n await agent.waitForNetworkIdle(waitForNetworkIdleTimeout);\n } catch (error) {\n console.warn(\n '[rpascene:warning] Waiting for network idle has timed out, but Rpascene will continue execution. Please check https://rpascenejs.com/faq.html#customize-the-network-timeout for more information on customizing the network timeout',\n );\n }\n try {\n type AgentMethod = (\n prompt: string,\n ...restArgs: any[]\n ) => Promise<any>;\n const result = await (agent[aiActionType] as AgentMethod)(\n taskPrompt,\n ...(args || []),\n );\n resolve(result);\n } catch (error) {\n reject(error);\n }\n });\n });\n });\n }\n\n const updateDumpAnnotation = (test: TestInfo, dump: string) => {\n // Write dump to temporary file\n const tempFileName = `rpascene-dump-${test.testId || uuid()}-${Date.now()}.json`;\n const tempFilePath = join(tmpdir(), tempFileName);\n\n writeFileSync(tempFilePath, dump, 'utf-8');\n debugPage(`Dump written to temp file: ${tempFilePath}`);\n\n // Store only the file path in annotation\n const currentAnnotation = test.annotations.find((item) => {\n return item.type === rpasceneDumpAnnotationId;\n });\n if (currentAnnotation) {\n // Store file path instead of dump content\n currentAnnotation.description = tempFilePath;\n } else {\n test.annotations.push({\n type: rpasceneDumpAnnotationId,\n description: tempFilePath,\n });\n }\n };\n\n return {\n agentForPage: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await use(\n async (\n propsPage?: OriginPlaywrightPage | undefined,\n opts?: AgentOpt,\n ) => {\n const cacheConfig = processTestCacheConfig(testInfo);\n\n // Handle cache configuration priority:\n // 1. If user provides cache in opts, use it (but auto-generate ID if missing)\n // 2. Otherwise use fixture's cache config\n let finalCacheConfig = cacheConfig;\n if (opts?.cache !== undefined) {\n const userCache = opts.cache;\n if (userCache === false) {\n finalCacheConfig = false;\n } else if (userCache === true) {\n // Auto-generate ID for user's cache: true\n const { id } = groupAndCaseForTest(testInfo);\n finalCacheConfig = { id };\n } else if (typeof userCache === 'object') {\n if (!userCache.id) {\n // Auto-generate ID for user's cache object without ID\n const { id } = groupAndCaseForTest(testInfo);\n finalCacheConfig = { ...userCache, id };\n } else {\n finalCacheConfig = userCache;\n }\n }\n }\n\n const agent = createOrReuseAgentForPage(propsPage || page, testInfo, {\n waitForNavigationTimeout,\n waitForNetworkIdleTimeout,\n cache: finalCacheConfig,\n ...opts,\n });\n return agent;\n },\n );\n },\n ai: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'ai',\n });\n },\n aiAction: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAction',\n });\n },\n aiTap: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiTap',\n });\n },\n aiRightClick: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiRightClick',\n });\n },\n aiDoubleClick: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiDoubleClick',\n });\n },\n aiHover: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiHover',\n });\n },\n aiInput: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiInput',\n });\n },\n aiKeyboardPress: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiKeyboardPress',\n });\n },\n aiScroll: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiScroll',\n });\n },\n aiQuery: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiQuery',\n });\n },\n aiAssert: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAssert',\n });\n },\n aiWaitFor: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiWaitFor',\n });\n },\n aiLocate: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiLocate',\n });\n },\n aiNumber: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiNumber',\n });\n },\n aiString: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiString',\n });\n },\n aiBoolean: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiBoolean',\n });\n },\n aiAsk: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAsk',\n });\n },\n runYaml: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'runYaml',\n });\n },\n setAIActionContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'setAIActionContext',\n });\n },\n evaluateJavaScript: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'evaluateJavaScript',\n });\n },\n logScreenshot: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'logScreenshot',\n });\n },\n freezePageContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'freezePageContext',\n });\n },\n unfreezePageContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'unfreezePageContext',\n });\n },\n };\n};\n\nexport type PlayWrightAiFixtureType = {\n agentForPage: (\n page?: any,\n opts?: any,\n ) => Promise<PageAgent<PlaywrightWebPage>>;\n ai: <T = any>(prompt: string) => Promise<T>;\n aiAction: (taskPrompt: string) => ReturnType<PageAgent['aiAction']>;\n aiTap: (\n ...args: Parameters<PageAgent['aiTap']>\n ) => ReturnType<PageAgent['aiTap']>;\n aiRightClick: (\n ...args: Parameters<PageAgent['aiRightClick']>\n ) => ReturnType<PageAgent['aiRightClick']>;\n aiDoubleClick: (\n ...args: Parameters<PageAgent['aiDoubleClick']>\n ) => ReturnType<PageAgent['aiDoubleClick']>;\n aiHover: (\n ...args: Parameters<PageAgent['aiHover']>\n ) => ReturnType<PageAgent['aiHover']>;\n aiInput: (\n ...args: Parameters<PageAgent['aiInput']>\n ) => ReturnType<PageAgent['aiInput']>;\n aiKeyboardPress: (\n ...args: Parameters<PageAgent['aiKeyboardPress']>\n ) => ReturnType<PageAgent['aiKeyboardPress']>;\n aiScroll: (\n ...args: Parameters<PageAgent['aiScroll']>\n ) => ReturnType<PageAgent['aiScroll']>;\n aiQuery: <T = any>(...args: Parameters<PageAgent['aiQuery']>) => Promise<T>;\n aiAssert: (\n ...args: Parameters<PageAgent['aiAssert']>\n ) => ReturnType<PageAgent['aiAssert']>;\n aiWaitFor: (...args: Parameters<PageAgent['aiWaitFor']>) => Promise<void>;\n aiLocate: (\n ...args: Parameters<PageAgent['aiLocate']>\n ) => ReturnType<PageAgent['aiLocate']>;\n aiNumber: (\n ...args: Parameters<PageAgent['aiNumber']>\n ) => ReturnType<PageAgent['aiNumber']>;\n aiString: (\n ...args: Parameters<PageAgent['aiString']>\n ) => ReturnType<PageAgent['aiString']>;\n aiBoolean: (\n ...args: Parameters<PageAgent['aiBoolean']>\n ) => ReturnType<PageAgent['aiBoolean']>;\n aiAsk: (\n ...args: Parameters<PageAgent['aiAsk']>\n ) => ReturnType<PageAgent['aiAsk']>;\n runYaml: (\n ...args: Parameters<PageAgent['runYaml']>\n ) => ReturnType<PageAgent['runYaml']>;\n setAIActionContext: (\n ...args: Parameters<PageAgent['setAIActionContext']>\n ) => ReturnType<PageAgent['setAIActionContext']>;\n evaluateJavaScript: (\n ...args: Parameters<PageAgent['evaluateJavaScript']>\n ) => ReturnType<PageAgent['evaluateJavaScript']>;\n logScreenshot: (\n ...args: Parameters<PageAgent['logScreenshot']>\n ) => ReturnType<PageAgent['logScreenshot']>;\n freezePageContext: (\n ...args: Parameters<PageAgent['freezePageContext']>\n ) => ReturnType<PageAgent['freezePageContext']>;\n unfreezePageContext: (\n ...args: Parameters<PageAgent['unfreezePageContext']>\n ) => ReturnType<PageAgent['unfreezePageContext']>;\n};\n"],"names":["debugPage","getDebug","groupAndCaseForTest","testInfo","taskFile","taskTitle","titlePath","taskTitleWithRetry","replaceIllegalPathCharsAndSpace","rpasceneAgentKeyId","rpasceneDumpAnnotationId","PlaywrightAiFixture","options","forceSameTabNavigation","waitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","waitForNavigationTimeout","DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT","cache","processTestCacheConfig","id","processCacheConfig","pageAgentMap","createOrReuseAgentForPage","page","opts","idForPage","uuid","testId","file","title","cacheConfig","PlaywrightAgent","dump","updateDumpAnnotation","generateAiFunction","use","aiActionType","agent","taskPrompt","args","Promise","resolve","reject","test","JSON","error","console","result","tempFileName","Date","tempFilePath","join","tmpdir","writeFileSync","currentAnnotation","item","propsPage","finalCacheConfig","undefined","userCache"],"mappings":"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BACA,cAAc;YAChB;QACF;QACA,WAAW,OACT,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,OAAO,OACL,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,SAAS,OACP,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,oBAAoB,OAClB,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,oBAAoB,OAClB,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,eAAe,OACb,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,mBAAmB,OACjB,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,qBAAqB,OACnB,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;IACF;AACF"}
1
+ {"version":3,"file":"playwright\\ai-fixture.mjs","sources":["webpack://@rpascene/web/./src/playwright/ai-fixture.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { PlaywrightAgent, type PlaywrightWebPage } from '@/playwright/index';\nimport type { WebPageAgentOpt } from '@/web-element';\nimport type { Cache } from '@rpascene/core';\nimport type { AgentOpt, Agent as PageAgent } from '@rpascene/core/agent';\nimport { processCacheConfig } from '@rpascene/core/utils';\nimport {\n DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n} from '@rpascene/shared/constants';\nimport { getDebug } from '@rpascene/shared/logger';\nimport { uuid } from '@rpascene/shared/utils';\nimport { replaceIllegalPathCharsAndSpace } from '@rpascene/shared/utils';\nimport { type TestInfo, type TestType, test } from '@playwright/test';\nimport type { Page as OriginPlaywrightPage } from 'playwright';\nexport type APITestType = Pick<TestType<any, any>, 'step'>;\n\nconst debugPage = getDebug('web:playwright:ai-fixture');\n\nconst groupAndCaseForTest = (testInfo: TestInfo) => {\n let taskFile: string;\n let taskTitle: string;\n const titlePath = [...testInfo.titlePath];\n\n if (titlePath.length > 1) {\n taskFile = titlePath.shift() || 'unnamed';\n taskTitle = titlePath.join('__');\n } else if (titlePath.length === 1) {\n taskTitle = titlePath[0];\n taskFile = `${taskTitle}`;\n } else {\n taskTitle = 'unnamed';\n taskFile = 'unnamed';\n }\n\n const taskTitleWithRetry = `${taskTitle}${testInfo.retry ? `(retry #${testInfo.retry})` : ''}`;\n\n return {\n file: taskFile,\n id: replaceIllegalPathCharsAndSpace(`${taskFile}(${taskTitle})`),\n title: replaceIllegalPathCharsAndSpace(taskTitleWithRetry),\n };\n};\n\nconst midsceneAgentKeyId = '_midsceneAgentId';\nexport const midsceneDumpAnnotationId = 'MIDSCENE_DUMP_ANNOTATION';\n\ntype PlaywrightCacheConfig = {\n strategy?: 'read-only' | 'read-write' | 'write-only';\n id?: string;\n};\ntype PlaywrightCache = false | true | PlaywrightCacheConfig;\n\nexport const PlaywrightAiFixture = (options?: {\n forceSameTabNavigation?: boolean;\n waitForNetworkIdleTimeout?: number;\n waitForNavigationTimeout?: number;\n cache?: PlaywrightCache;\n}) => {\n const {\n forceSameTabNavigation = true,\n waitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT,\n waitForNavigationTimeout = DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT,\n cache,\n } = options ?? {};\n\n // Helper function to process cache configuration and auto-generate ID from test info\n const processTestCacheConfig = (testInfo: TestInfo): Cache | undefined => {\n // Generate ID from test info\n const { id } = groupAndCaseForTest(testInfo);\n\n // Use shared processCacheConfig with generated ID as fallback\n return processCacheConfig(cache as Cache, id);\n };\n\n const pageAgentMap: Record<string, PageAgent<PlaywrightWebPage>> = {};\n const createOrReuseAgentForPage = (\n page: OriginPlaywrightPage,\n testInfo: TestInfo, // { testId: string; taskFile: string; taskTitle: string },\n opts?: WebPageAgentOpt,\n ) => {\n let idForPage = (page as any)[midsceneAgentKeyId];\n if (!idForPage) {\n idForPage = uuid();\n (page as any)[midsceneAgentKeyId] = idForPage;\n const { testId } = testInfo;\n const { file, title } = groupAndCaseForTest(testInfo);\n const cacheConfig = processTestCacheConfig(testInfo);\n\n pageAgentMap[idForPage] = new PlaywrightAgent(page, {\n testId: `playwright-${testId}-${idForPage}`,\n forceSameTabNavigation,\n cache: cacheConfig,\n groupName: title,\n groupDescription: file,\n generateReport: false, // we will generate it in the reporter\n ...opts,\n });\n\n pageAgentMap[idForPage].onDumpUpdate = (dump: string) => {\n updateDumpAnnotation(testInfo, dump);\n };\n\n page.on('close', () => {\n debugPage('page closed');\n pageAgentMap[idForPage].destroy();\n delete pageAgentMap[idForPage];\n });\n }\n\n return pageAgentMap[idForPage];\n };\n\n async function generateAiFunction(options: {\n page: OriginPlaywrightPage;\n testInfo: TestInfo;\n use: any;\n aiActionType:\n | 'ai'\n | 'aiAction'\n | 'aiHover'\n | 'aiInput'\n | 'aiKeyboardPress'\n | 'aiScroll'\n | 'aiTap'\n | 'aiRightClick'\n | 'aiDoubleClick'\n | 'aiQuery'\n | 'aiAssert'\n | 'aiWaitFor'\n | 'aiLocate'\n | 'aiNumber'\n | 'aiString'\n | 'aiBoolean'\n | 'aiAsk'\n | 'runYaml'\n | 'setAIActionContext'\n | 'evaluateJavaScript'\n | 'logScreenshot'\n | 'freezePageContext'\n | 'unfreezePageContext';\n }) {\n const { page, testInfo, use, aiActionType } = options;\n const agent = createOrReuseAgentForPage(page, testInfo, {\n waitForNavigationTimeout,\n waitForNetworkIdleTimeout,\n }) as PlaywrightAgent;\n\n await use(async (taskPrompt: string, ...args: any[]) => {\n return new Promise((resolve, reject) => {\n test.step(`ai-${aiActionType} - ${JSON.stringify(taskPrompt)}`, async () => {\n try {\n debugPage(\n `waitForNetworkIdle timeout: ${waitForNetworkIdleTimeout}`,\n );\n await agent.waitForNetworkIdle(waitForNetworkIdleTimeout);\n } catch (error) {\n console.warn(\n '[midscene:warning] Waiting for 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 try {\n type AgentMethod = (\n prompt: string,\n ...restArgs: any[]\n ) => Promise<any>;\n const result = await (agent[aiActionType] as AgentMethod)(\n taskPrompt,\n ...(args || []),\n );\n resolve(result);\n } catch (error) {\n reject(error);\n }\n });\n });\n });\n }\n\n const updateDumpAnnotation = (test: TestInfo, dump: string) => {\n // Write dump to temporary file\n const tempFileName = `midscene-dump-${test.testId || uuid()}-${Date.now()}.json`;\n const tempFilePath = join(tmpdir(), tempFileName);\n\n writeFileSync(tempFilePath, dump, 'utf-8');\n debugPage(`Dump written to temp file: ${tempFilePath}`);\n\n // Store only the file path in annotation\n const currentAnnotation = test.annotations.find((item) => {\n return item.type === midsceneDumpAnnotationId;\n });\n if (currentAnnotation) {\n // Store file path instead of dump content\n currentAnnotation.description = tempFilePath;\n } else {\n test.annotations.push({\n type: midsceneDumpAnnotationId,\n description: tempFilePath,\n });\n }\n };\n\n return {\n agentForPage: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await use(\n async (\n propsPage?: OriginPlaywrightPage | undefined,\n opts?: AgentOpt,\n ) => {\n const cacheConfig = processTestCacheConfig(testInfo);\n\n // Handle cache configuration priority:\n // 1. If user provides cache in opts, use it (but auto-generate ID if missing)\n // 2. Otherwise use fixture's cache config\n let finalCacheConfig = cacheConfig;\n if (opts?.cache !== undefined) {\n const userCache = opts.cache;\n if (userCache === false) {\n finalCacheConfig = false;\n } else if (userCache === true) {\n // Auto-generate ID for user's cache: true\n const { id } = groupAndCaseForTest(testInfo);\n finalCacheConfig = { id };\n } else if (typeof userCache === 'object') {\n if (!userCache.id) {\n // Auto-generate ID for user's cache object without ID\n const { id } = groupAndCaseForTest(testInfo);\n finalCacheConfig = { ...userCache, id };\n } else {\n finalCacheConfig = userCache;\n }\n }\n }\n\n const agent = createOrReuseAgentForPage(propsPage || page, testInfo, {\n waitForNavigationTimeout,\n waitForNetworkIdleTimeout,\n cache: finalCacheConfig,\n ...opts,\n });\n return agent;\n },\n );\n },\n ai: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'ai',\n });\n },\n aiAction: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAction',\n });\n },\n aiTap: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiTap',\n });\n },\n aiRightClick: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiRightClick',\n });\n },\n aiDoubleClick: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiDoubleClick',\n });\n },\n aiHover: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiHover',\n });\n },\n aiInput: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiInput',\n });\n },\n aiKeyboardPress: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiKeyboardPress',\n });\n },\n aiScroll: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiScroll',\n });\n },\n aiQuery: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiQuery',\n });\n },\n aiAssert: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAssert',\n });\n },\n aiWaitFor: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiWaitFor',\n });\n },\n aiLocate: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiLocate',\n });\n },\n aiNumber: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiNumber',\n });\n },\n aiString: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiString',\n });\n },\n aiBoolean: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiBoolean',\n });\n },\n aiAsk: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'aiAsk',\n });\n },\n runYaml: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'runYaml',\n });\n },\n setAIActionContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'setAIActionContext',\n });\n },\n evaluateJavaScript: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'evaluateJavaScript',\n });\n },\n logScreenshot: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'logScreenshot',\n });\n },\n freezePageContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'freezePageContext',\n });\n },\n unfreezePageContext: async (\n { page }: { page: OriginPlaywrightPage },\n use: any,\n testInfo: TestInfo,\n ) => {\n await generateAiFunction({\n page,\n testInfo,\n use,\n aiActionType: 'unfreezePageContext',\n });\n },\n };\n};\n\nexport type PlayWrightAiFixtureType = {\n agentForPage: (\n page?: any,\n opts?: any,\n ) => Promise<PageAgent<PlaywrightWebPage>>;\n ai: <T = any>(prompt: string) => Promise<T>;\n aiAction: (taskPrompt: string) => ReturnType<PageAgent['aiAction']>;\n aiTap: (\n ...args: Parameters<PageAgent['aiTap']>\n ) => ReturnType<PageAgent['aiTap']>;\n aiRightClick: (\n ...args: Parameters<PageAgent['aiRightClick']>\n ) => ReturnType<PageAgent['aiRightClick']>;\n aiDoubleClick: (\n ...args: Parameters<PageAgent['aiDoubleClick']>\n ) => ReturnType<PageAgent['aiDoubleClick']>;\n aiHover: (\n ...args: Parameters<PageAgent['aiHover']>\n ) => ReturnType<PageAgent['aiHover']>;\n aiInput: (\n ...args: Parameters<PageAgent['aiInput']>\n ) => ReturnType<PageAgent['aiInput']>;\n aiKeyboardPress: (\n ...args: Parameters<PageAgent['aiKeyboardPress']>\n ) => ReturnType<PageAgent['aiKeyboardPress']>;\n aiScroll: (\n ...args: Parameters<PageAgent['aiScroll']>\n ) => ReturnType<PageAgent['aiScroll']>;\n aiQuery: <T = any>(...args: Parameters<PageAgent['aiQuery']>) => Promise<T>;\n aiAssert: (\n ...args: Parameters<PageAgent['aiAssert']>\n ) => ReturnType<PageAgent['aiAssert']>;\n aiWaitFor: (...args: Parameters<PageAgent['aiWaitFor']>) => Promise<void>;\n aiLocate: (\n ...args: Parameters<PageAgent['aiLocate']>\n ) => ReturnType<PageAgent['aiLocate']>;\n aiNumber: (\n ...args: Parameters<PageAgent['aiNumber']>\n ) => ReturnType<PageAgent['aiNumber']>;\n aiString: (\n ...args: Parameters<PageAgent['aiString']>\n ) => ReturnType<PageAgent['aiString']>;\n aiBoolean: (\n ...args: Parameters<PageAgent['aiBoolean']>\n ) => ReturnType<PageAgent['aiBoolean']>;\n aiAsk: (\n ...args: Parameters<PageAgent['aiAsk']>\n ) => ReturnType<PageAgent['aiAsk']>;\n runYaml: (\n ...args: Parameters<PageAgent['runYaml']>\n ) => ReturnType<PageAgent['runYaml']>;\n setAIActionContext: (\n ...args: Parameters<PageAgent['setAIActionContext']>\n ) => ReturnType<PageAgent['setAIActionContext']>;\n evaluateJavaScript: (\n ...args: Parameters<PageAgent['evaluateJavaScript']>\n ) => ReturnType<PageAgent['evaluateJavaScript']>;\n logScreenshot: (\n ...args: Parameters<PageAgent['logScreenshot']>\n ) => ReturnType<PageAgent['logScreenshot']>;\n freezePageContext: (\n ...args: Parameters<PageAgent['freezePageContext']>\n ) => ReturnType<PageAgent['freezePageContext']>;\n unfreezePageContext: (\n ...args: Parameters<PageAgent['unfreezePageContext']>\n ) => ReturnType<PageAgent['unfreezePageContext']>;\n};\n"],"names":["debugPage","getDebug","groupAndCaseForTest","testInfo","taskFile","taskTitle","titlePath","taskTitleWithRetry","replaceIllegalPathCharsAndSpace","midsceneAgentKeyId","midsceneDumpAnnotationId","PlaywrightAiFixture","options","forceSameTabNavigation","waitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","waitForNavigationTimeout","DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT","cache","processTestCacheConfig","id","processCacheConfig","pageAgentMap","createOrReuseAgentForPage","page","opts","idForPage","uuid","testId","file","title","cacheConfig","PlaywrightAgent","dump","updateDumpAnnotation","generateAiFunction","use","aiActionType","agent","taskPrompt","args","Promise","resolve","reject","test","JSON","error","console","result","tempFileName","Date","tempFilePath","join","tmpdir","writeFileSync","currentAnnotation","item","propsPage","finalCacheConfig","undefined","userCache"],"mappings":"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BACA,cAAc;YAChB;QACF;QACA,WAAW,OACT,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,OAAO,OACL,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,SAAS,OACP,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,oBAAoB,OAClB,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,oBAAoB,OAClB,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,eAAe,OACb,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,mBAAmB,OACjB,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;QACA,qBAAqB,OACnB,EAAEZ,IAAI,EAAkC,EACxCY,KACAjC;YAEA,MAAMgC,mBAAmB;gBACvBX;gBACArB;gBACAiC;gBACA,cAAc;YAChB;QACF;IACF;AACF"}
@@ -12,7 +12,7 @@ function _define_property(obj, key, value) {
12
12
  else obj[key] = value;
13
13
  return obj;
14
14
  }
15
- class RpasceneReporter {
15
+ class MidsceneReporter {
16
16
  static getMode(reporterType) {
17
17
  if (!reporterType) return 'merged';
18
18
  if ('merged' !== reporterType && 'separate' !== reporterType) throw new Error(`Unknown reporter type in playwright config: ${reporterType}, only support 'merged' or 'separate'`);
@@ -47,14 +47,14 @@ class RpasceneReporter {
47
47
  async onBegin(config, suite) {}
48
48
  onTestBegin(_test, _result) {}
49
49
  onTestEnd(test, result) {
50
- const dumpAnnotation = test.annotations.find((annotation)=>'RPASCENE_DUMP_ANNOTATION' === annotation.type);
50
+ const dumpAnnotation = test.annotations.find((annotation)=>'MIDSCENE_DUMP_ANNOTATION' === annotation.type);
51
51
  if (!(null == dumpAnnotation ? void 0 : dumpAnnotation.description)) return;
52
52
  const tempFilePath = dumpAnnotation.description;
53
53
  let dumpString;
54
54
  try {
55
55
  dumpString = readFileSync(tempFilePath, 'utf-8');
56
56
  } catch (error) {
57
- console.error(`Failed to read Rpascene dump file: ${tempFilePath}`, error);
57
+ console.error(`Failed to read Midscene dump file: ${tempFilePath}`, error);
58
58
  return;
59
59
  }
60
60
  const retry = result.retry ? `(retry #${result.retry})` : '';
@@ -74,17 +74,17 @@ class RpasceneReporter {
74
74
  force: true
75
75
  });
76
76
  } catch (error) {
77
- console.warn(`Failed to delete Rpascene temp file: ${tempFilePath}`, error);
77
+ console.warn(`Failed to delete Midscene temp file: ${tempFilePath}`, error);
78
78
  }
79
79
  }
80
80
  constructor(options = {}){
81
81
  _define_property(this, "mergedFilename", void 0);
82
82
  _define_property(this, "testTitleToFilename", new Map());
83
83
  _define_property(this, "mode", void 0);
84
- this.mode = RpasceneReporter.getMode(options.type ?? 'merged');
84
+ this.mode = MidsceneReporter.getMode(options.type ?? 'merged');
85
85
  }
86
86
  }
87
- const reporter = RpasceneReporter;
87
+ const reporter = MidsceneReporter;
88
88
  export { reporter as default };
89
89
 
90
90
  //# sourceMappingURL=index.mjs.map