@midscene/web 1.0.1-beta-20251202152706.0 → 1.0.1-beta-20251203073716.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ class BridgeClient {
17
17
  this.socket = io(this.endpoint, {
18
18
  reconnection: false,
19
19
  query: {
20
- version: "1.0.1-beta-20251202152706.0"
20
+ version: "1.0.1-beta-20251203073716.0"
21
21
  }
22
22
  });
23
23
  const timeout = setTimeout(()=>{
@@ -75,7 +75,7 @@ class BridgeServer {
75
75
  logMsg('one client connected');
76
76
  this.socket = socket;
77
77
  const clientVersion = socket.handshake.query.version;
78
- logMsg(`Bridge connected, cli-side version v1.0.1-beta-20251202152706.0, browser-side version v${clientVersion}`);
78
+ logMsg(`Bridge connected, cli-side version v1.0.1-beta-20251203073716.0, browser-side version v${clientVersion}`);
79
79
  socket.on(BridgeEvent.CallResponse, (params)=>{
80
80
  const id = params.id;
81
81
  const response = params.response;
@@ -100,7 +100,7 @@ class BridgeServer {
100
100
  setTimeout(()=>{
101
101
  this.onConnect?.();
102
102
  const payload = {
103
- version: "1.0.1-beta-20251202152706.0"
103
+ version: "1.0.1-beta-20251203073716.0"
104
104
  };
105
105
  socket.emit(BridgeEvent.Connected, payload);
106
106
  Promise.resolve().then(()=>{
@@ -46,7 +46,7 @@ class ExtensionBridgePageBrowserSide extends page {
46
46
  }
47
47
  }, ()=>this.destroy());
48
48
  await this.bridgeClient.connect();
49
- this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.0.1-beta-20251202152706.0`, 'log');
49
+ this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.0.1-beta-20251203073716.0`, 'log');
50
50
  }
51
51
  async connect() {
52
52
  return await this.setupBridgeClient();
@@ -9,6 +9,24 @@ const defaultViewportWidth = 1440;
9
9
  const defaultViewportHeight = 768;
10
10
  const defaultViewportScale = 'darwin' === process.platform ? 2 : 1;
11
11
  const defaultWaitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
12
+ const DANGEROUS_ARGS = [
13
+ '--no-sandbox',
14
+ '--disable-setuid-sandbox',
15
+ '--disable-web-security',
16
+ '--ignore-certificate-errors',
17
+ '--disable-features=IsolateOrigins',
18
+ '--disable-site-isolation-trials',
19
+ '--allow-running-insecure-content'
20
+ ];
21
+ function validateChromeArgs(args, baseArgs) {
22
+ const newArgs = args.filter((arg)=>!baseArgs.some((baseArg)=>{
23
+ const argFlag = arg.split('=')[0];
24
+ const baseFlag = baseArg.split('=')[0];
25
+ return argFlag === baseFlag;
26
+ }));
27
+ const dangerousArgs = newArgs.filter((arg)=>DANGEROUS_ARGS.some((dangerous)=>arg.startsWith(dangerous)));
28
+ if (dangerousArgs.length > 0) console.warn(`Warning: Dangerous Chrome arguments detected: ${dangerousArgs.join(', ')}.\nThese arguments may reduce browser security. Use only in controlled testing environments.`);
29
+ }
12
30
  const launcherDebug = getDebug('puppeteer:launcher');
13
31
  async function launchPuppeteerPage(target, preference, browser) {
14
32
  assert(target.url, 'url is required');
@@ -45,7 +63,7 @@ async function launchPuppeteerPage(target, preference, browser) {
45
63
  preferMaximizedWindow = preferMaximizedWindow && !!headed;
46
64
  if (headed && '1' === process.env.CI) console.warn('you are probably running headed mode in CI, this will usually fail.');
47
65
  const isWindows = 'win32' === process.platform;
48
- const args = [
66
+ const baseArgs = [
49
67
  ...isWindows ? [] : [
50
68
  '--no-sandbox',
51
69
  '--disable-setuid-sandbox'
@@ -56,6 +74,15 @@ async function launchPuppeteerPage(target, preference, browser) {
56
74
  `--user-agent="${ua}"`,
57
75
  preferMaximizedWindow ? '--start-maximized' : `--window-size=${width},${height + 200}`
58
76
  ];
77
+ let args = baseArgs;
78
+ if (target.chromeArgs && target.chromeArgs.length > 0) {
79
+ validateChromeArgs(target.chromeArgs, baseArgs);
80
+ args = [
81
+ ...baseArgs,
82
+ ...target.chromeArgs
83
+ ];
84
+ launcherDebug('Merging custom Chrome arguments', target.chromeArgs, 'Final args', args);
85
+ }
59
86
  launcherDebug('launching browser with viewport, headed', headed, 'viewport', viewportConfig, 'args', args, 'preference', preference);
60
87
  let browserInstance = browser;
61
88
  if (!browserInstance) {
@@ -110,9 +137,7 @@ async function launchPuppeteerPage(target, preference, browser) {
110
137
  async function puppeteerAgentForTarget(target, preference, browser) {
111
138
  const { page, freeFn } = await launchPuppeteerPage(target, preference, browser);
112
139
  const agent = new PuppeteerAgent(page, {
113
- autoPrintReportMsg: false,
114
- testId: preference?.testId,
115
- cache: preference?.cache,
140
+ ...preference,
116
141
  aiActionContext: target.aiActionContext,
117
142
  forceSameTabNavigation: void 0 !== target.forceSameTabNavigation ? target.forceSameTabNavigation : true
118
143
  });
@@ -1 +1 @@
1
- {"version":3,"file":"puppeteer/agent-launcher.mjs","sources":["../../../src/puppeteer/agent-launcher.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nimport { PuppeteerAgent } from '@/puppeteer/index';\nimport type { Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';\nimport { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from '@midscene/shared/constants';\nimport puppeteer, { type Browser } from 'puppeteer';\n\nexport const defaultUA =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';\nexport const defaultViewportWidth = 1440;\nexport const defaultViewportHeight = 768;\nexport const defaultViewportScale = process.platform === 'darwin' ? 2 : 1;\nexport const defaultWaitForNetworkIdleTimeout =\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n\ninterface FreeFn {\n name: string;\n fn: () => void;\n}\n\nconst launcherDebug = getDebug('puppeteer:launcher');\n\nexport async function launchPuppeteerPage(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n },\n browser?: Browser,\n) {\n assert(target.url, 'url is required');\n const freeFn: FreeFn[] = [];\n\n // prepare the environment\n const ua = target.userAgent || defaultUA;\n let width = defaultViewportWidth;\n let preferMaximizedWindow = true;\n if (target.viewportWidth) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportWidth === 'number',\n 'viewportWidth must be a number',\n );\n width = Number.parseInt(target.viewportWidth as unknown as string, 10);\n assert(width > 0, `viewportWidth must be greater than 0, but got ${width}`);\n }\n let height = defaultViewportHeight;\n if (target.viewportHeight) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportHeight === 'number',\n 'viewportHeight must be a number',\n );\n height = Number.parseInt(target.viewportHeight as unknown as string, 10);\n assert(\n height > 0,\n `viewportHeight must be greater than 0, but got ${height}`,\n );\n }\n let dpr = defaultViewportScale;\n if (target.viewportScale) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportScale === 'number',\n 'viewportScale must be a number',\n );\n dpr = Number.parseInt(target.viewportScale as unknown as string, 10);\n assert(dpr > 0, `viewportScale must be greater than 0, but got ${dpr}`);\n }\n const viewportConfig = {\n width,\n height,\n deviceScaleFactor: dpr,\n };\n\n const headed = preference?.headed || preference?.keepWindow;\n\n // only maximize window in headed mode\n preferMaximizedWindow = preferMaximizedWindow && !!headed;\n\n // launch the browser\n if (headed && process.env.CI === '1') {\n console.warn(\n 'you are probably running headed mode in CI, this will usually fail.',\n );\n }\n // do not use 'no-sandbox' on windows https://www.perplexity.ai/search/how-to-solve-this-with-nodejs-dMHpdCypRa..JA8TkQzbeQ\n const isWindows = process.platform === 'win32';\n const args = [\n ...(isWindows ? [] : ['--no-sandbox', '--disable-setuid-sandbox']),\n '--disable-features=HttpsFirstBalancedModeAutoEnable',\n '--disable-features=PasswordLeakDetection',\n '--disable-save-password-bubble',\n `--user-agent=\"${ua}\"`,\n preferMaximizedWindow\n ? '--start-maximized'\n : `--window-size=${width},${height + 200}`, // add 200px for the address bar\n ];\n\n launcherDebug(\n 'launching browser with viewport, headed',\n headed,\n 'viewport',\n viewportConfig,\n 'args',\n args,\n 'preference',\n preference,\n );\n let browserInstance = browser;\n if (!browserInstance) {\n browserInstance = await puppeteer.launch({\n headless: !preference?.headed,\n defaultViewport: viewportConfig,\n args,\n acceptInsecureCerts: target.acceptInsecureCerts,\n });\n freeFn.push({\n name: 'puppeteer_browser',\n fn: () => {\n if (!preference?.keepWindow) {\n if (isWindows) {\n setTimeout(() => {\n browserInstance?.close();\n }, 800);\n } else {\n browserInstance?.close();\n }\n }\n },\n });\n }\n const page = await browserInstance.newPage();\n // await page.setUserAgent(ua);\n // await page.setViewport(viewportConfig);\n\n if (target.cookie) {\n const cookieFileContent = readFileSync(target.cookie, 'utf-8');\n await browserInstance.setCookie(...JSON.parse(cookieFileContent));\n }\n\n if (ua) {\n await page.setUserAgent(ua);\n }\n\n if (viewportConfig) {\n await page.setViewport(viewportConfig);\n }\n\n const waitForNetworkIdleTimeout =\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : defaultWaitForNetworkIdleTimeout;\n\n try {\n launcherDebug('goto', target.url);\n await page.goto(target.url);\n if (waitForNetworkIdleTimeout > 0) {\n launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);\n await page.waitForNetworkIdle({\n timeout: waitForNetworkIdleTimeout,\n });\n }\n } catch (e) {\n if (\n typeof target.waitForNetworkIdle?.continueOnNetworkIdleError ===\n 'boolean' &&\n !target.waitForNetworkIdle?.continueOnNetworkIdleError\n ) {\n const newError = new Error(`failed to wait for network idle: ${e}`, {\n cause: e,\n });\n throw newError;\n }\n const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;\n console.warn(newMessage);\n }\n\n return { page, freeFn };\n}\n\nexport async function puppeteerAgentForTarget(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n testId?: string;\n cache?: Cache;\n },\n browser?: Browser,\n) {\n const { page, freeFn } = await launchPuppeteerPage(\n target,\n preference,\n browser,\n );\n\n // prepare Midscene agent\n const agent = new PuppeteerAgent(page, {\n autoPrintReportMsg: false,\n testId: preference?.testId,\n cache: preference?.cache,\n aiActionContext: target.aiActionContext,\n forceSameTabNavigation:\n typeof target.forceSameTabNavigation !== 'undefined'\n ? target.forceSameTabNavigation\n : true, // true for default in yaml script\n });\n\n freeFn.push({\n name: 'midscene_puppeteer_agent',\n fn: () => agent.destroy(),\n });\n\n return { agent, freeFn };\n}\n"],"names":["defaultUA","defaultViewportWidth","defaultViewportHeight","defaultViewportScale","process","defaultWaitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","launcherDebug","getDebug","launchPuppeteerPage","target","preference","browser","assert","freeFn","ua","width","preferMaximizedWindow","Number","height","dpr","viewportConfig","headed","console","isWindows","args","browserInstance","puppeteer","setTimeout","page","cookieFileContent","readFileSync","JSON","waitForNetworkIdleTimeout","e","newError","Error","newMessage","puppeteerAgentForTarget","agent","PuppeteerAgent"],"mappings":"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"}
1
+ {"version":3,"file":"puppeteer/agent-launcher.mjs","sources":["../../../src/puppeteer/agent-launcher.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nimport { PuppeteerAgent } from '@/puppeteer/index';\nimport type { AgentOpt, Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';\nimport { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from '@midscene/shared/constants';\nimport puppeteer, { type Browser } from 'puppeteer';\n\nexport const defaultUA =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';\nexport const defaultViewportWidth = 1440;\nexport const defaultViewportHeight = 768;\nexport const defaultViewportScale = process.platform === 'darwin' ? 2 : 1;\nexport const defaultWaitForNetworkIdleTimeout =\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n\n/**\n * Chrome arguments that may reduce browser security.\n * These should only be used in controlled testing environments.\n *\n * Security implications:\n * - `--no-sandbox`: Disables Chrome's sandbox security model\n * - `--disable-setuid-sandbox`: Disables setuid sandbox on Linux\n * - `--disable-web-security`: Allows cross-origin requests without CORS\n * - `--ignore-certificate-errors`: Ignores SSL/TLS certificate errors\n * - `--disable-features=IsolateOrigins`: Disables origin isolation\n * - `--disable-site-isolation-trials`: Disables site isolation\n * - `--allow-running-insecure-content`: Allows mixed HTTP/HTTPS content\n */\nconst DANGEROUS_ARGS = [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-web-security',\n '--ignore-certificate-errors',\n '--disable-features=IsolateOrigins',\n '--disable-site-isolation-trials',\n '--allow-running-insecure-content',\n] as const;\n\n/**\n * Validates Chrome launch arguments for security concerns.\n * Emits a warning if dangerous arguments are detected.\n *\n * This function filters out arguments that are already present in baseArgs\n * to avoid warning about platform-specific defaults (e.g., --no-sandbox on non-Windows).\n *\n * @param args - Chrome launch arguments to validate\n * @param baseArgs - Base Chrome arguments already configured\n *\n * @example\n * ```typescript\n * // Will show warning for --disable-web-security\n * validateChromeArgs(['--disable-web-security', '--headless'], ['--no-sandbox']);\n *\n * // Will NOT show warning for --no-sandbox (already in baseArgs)\n * validateChromeArgs(['--no-sandbox'], ['--no-sandbox', '--headless']);\n * ```\n */\nfunction validateChromeArgs(args: string[], baseArgs: string[]): void {\n // Filter out arguments that are already in baseArgs\n const newArgs = args.filter(\n (arg) =>\n !baseArgs.some((baseArg) => {\n // Check if arg starts with the same flag as baseArg (before '=' if present)\n const argFlag = arg.split('=')[0];\n const baseFlag = baseArg.split('=')[0];\n return argFlag === baseFlag;\n }),\n );\n\n const dangerousArgs = newArgs.filter((arg) =>\n DANGEROUS_ARGS.some((dangerous) => arg.startsWith(dangerous)),\n );\n\n if (dangerousArgs.length > 0) {\n console.warn(\n `Warning: Dangerous Chrome arguments detected: ${dangerousArgs.join(', ')}.\\nThese arguments may reduce browser security. Use only in controlled testing environments.`,\n );\n }\n}\n\ninterface FreeFn {\n name: string;\n fn: () => void;\n}\n\nconst launcherDebug = getDebug('puppeteer:launcher');\n\nexport async function launchPuppeteerPage(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n },\n browser?: Browser,\n) {\n assert(target.url, 'url is required');\n const freeFn: FreeFn[] = [];\n\n // prepare the environment\n const ua = target.userAgent || defaultUA;\n let width = defaultViewportWidth;\n let preferMaximizedWindow = true;\n if (target.viewportWidth) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportWidth === 'number',\n 'viewportWidth must be a number',\n );\n width = Number.parseInt(target.viewportWidth as unknown as string, 10);\n assert(width > 0, `viewportWidth must be greater than 0, but got ${width}`);\n }\n let height = defaultViewportHeight;\n if (target.viewportHeight) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportHeight === 'number',\n 'viewportHeight must be a number',\n );\n height = Number.parseInt(target.viewportHeight as unknown as string, 10);\n assert(\n height > 0,\n `viewportHeight must be greater than 0, but got ${height}`,\n );\n }\n let dpr = defaultViewportScale;\n if (target.viewportScale) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportScale === 'number',\n 'viewportScale must be a number',\n );\n dpr = Number.parseInt(target.viewportScale as unknown as string, 10);\n assert(dpr > 0, `viewportScale must be greater than 0, but got ${dpr}`);\n }\n const viewportConfig = {\n width,\n height,\n deviceScaleFactor: dpr,\n };\n\n const headed = preference?.headed || preference?.keepWindow;\n\n // only maximize window in headed mode\n preferMaximizedWindow = preferMaximizedWindow && !!headed;\n\n // launch the browser\n if (headed && process.env.CI === '1') {\n console.warn(\n 'you are probably running headed mode in CI, this will usually fail.',\n );\n }\n // do not use 'no-sandbox' on windows https://www.perplexity.ai/search/how-to-solve-this-with-nodejs-dMHpdCypRa..JA8TkQzbeQ\n const isWindows = process.platform === 'win32';\n\n const baseArgs = [\n ...(isWindows ? [] : ['--no-sandbox', '--disable-setuid-sandbox']),\n '--disable-features=HttpsFirstBalancedModeAutoEnable',\n '--disable-features=PasswordLeakDetection',\n '--disable-save-password-bubble',\n `--user-agent=\"${ua}\"`,\n preferMaximizedWindow\n ? '--start-maximized'\n : `--window-size=${width},${height + 200}`, // add 200px for the address bar\n ];\n\n // Merge custom Chrome arguments\n let args = baseArgs;\n if (target.chromeArgs && target.chromeArgs.length > 0) {\n validateChromeArgs(target.chromeArgs, baseArgs);\n\n // Custom args come after base args, allowing them to override defaults\n args = [...baseArgs, ...target.chromeArgs];\n launcherDebug(\n 'Merging custom Chrome arguments',\n target.chromeArgs,\n 'Final args',\n args,\n );\n }\n\n launcherDebug(\n 'launching browser with viewport, headed',\n headed,\n 'viewport',\n viewportConfig,\n 'args',\n args,\n 'preference',\n preference,\n );\n let browserInstance = browser;\n if (!browserInstance) {\n browserInstance = await puppeteer.launch({\n headless: !preference?.headed,\n defaultViewport: viewportConfig,\n args,\n acceptInsecureCerts: target.acceptInsecureCerts,\n });\n freeFn.push({\n name: 'puppeteer_browser',\n fn: () => {\n if (!preference?.keepWindow) {\n if (isWindows) {\n setTimeout(() => {\n browserInstance?.close();\n }, 800);\n } else {\n browserInstance?.close();\n }\n }\n },\n });\n }\n const page = await browserInstance.newPage();\n\n if (target.cookie) {\n const cookieFileContent = readFileSync(target.cookie, 'utf-8');\n await browserInstance.setCookie(...JSON.parse(cookieFileContent));\n }\n\n if (ua) {\n await page.setUserAgent(ua);\n }\n\n if (viewportConfig) {\n await page.setViewport(viewportConfig);\n }\n\n const waitForNetworkIdleTimeout =\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : defaultWaitForNetworkIdleTimeout;\n\n try {\n launcherDebug('goto', target.url);\n await page.goto(target.url);\n if (waitForNetworkIdleTimeout > 0) {\n launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);\n await page.waitForNetworkIdle({\n timeout: waitForNetworkIdleTimeout,\n });\n }\n } catch (e) {\n if (\n typeof target.waitForNetworkIdle?.continueOnNetworkIdleError ===\n 'boolean' &&\n !target.waitForNetworkIdle?.continueOnNetworkIdleError\n ) {\n const newError = new Error(`failed to wait for network idle: ${e}`, {\n cause: e,\n });\n throw newError;\n }\n const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;\n console.warn(newMessage);\n }\n\n return { page, freeFn };\n}\n\nexport async function puppeteerAgentForTarget(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n } & Partial<\n Pick<\n AgentOpt,\n | 'testId'\n | 'groupName'\n | 'groupDescription'\n | 'generateReport'\n | 'autoPrintReportMsg'\n | 'reportFileName'\n | 'replanningCycleLimit'\n | 'cache'\n | 'aiActionContext'\n >\n >,\n browser?: Browser,\n) {\n const { page, freeFn } = await launchPuppeteerPage(\n target,\n preference,\n browser,\n );\n\n // prepare Midscene agent\n const agent = new PuppeteerAgent(page, {\n ...preference,\n aiActionContext: target.aiActionContext,\n forceSameTabNavigation:\n typeof target.forceSameTabNavigation !== 'undefined'\n ? target.forceSameTabNavigation\n : true, // true for default in yaml script\n });\n\n freeFn.push({\n name: 'midscene_puppeteer_agent',\n fn: () => agent.destroy(),\n });\n\n return { agent, freeFn };\n}\n"],"names":["defaultUA","defaultViewportWidth","defaultViewportHeight","defaultViewportScale","process","defaultWaitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","DANGEROUS_ARGS","validateChromeArgs","args","baseArgs","newArgs","arg","baseArg","argFlag","baseFlag","dangerousArgs","dangerous","console","launcherDebug","getDebug","launchPuppeteerPage","target","preference","browser","assert","freeFn","ua","width","preferMaximizedWindow","Number","height","dpr","viewportConfig","headed","isWindows","browserInstance","puppeteer","setTimeout","page","cookieFileContent","readFileSync","JSON","waitForNetworkIdleTimeout","e","newError","Error","newMessage","puppeteerAgentForTarget","agent","PuppeteerAgent"],"mappings":"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"}
@@ -45,7 +45,7 @@ class BridgeClient {
45
45
  this.socket = (0, external_socket_io_client_namespaceObject.io)(this.endpoint, {
46
46
  reconnection: false,
47
47
  query: {
48
- version: "1.0.1-beta-20251202152706.0"
48
+ version: "1.0.1-beta-20251203073716.0"
49
49
  }
50
50
  });
51
51
  const timeout = setTimeout(()=>{
@@ -104,7 +104,7 @@ class BridgeServer {
104
104
  (0, shared_utils_namespaceObject.logMsg)('one client connected');
105
105
  this.socket = socket;
106
106
  const clientVersion = socket.handshake.query.version;
107
- (0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v1.0.1-beta-20251202152706.0, browser-side version v${clientVersion}`);
107
+ (0, shared_utils_namespaceObject.logMsg)(`Bridge connected, cli-side version v1.0.1-beta-20251203073716.0, browser-side version v${clientVersion}`);
108
108
  socket.on(external_common_js_namespaceObject.BridgeEvent.CallResponse, (params)=>{
109
109
  const id = params.id;
110
110
  const response = params.response;
@@ -129,7 +129,7 @@ class BridgeServer {
129
129
  setTimeout(()=>{
130
130
  this.onConnect?.();
131
131
  const payload = {
132
- version: "1.0.1-beta-20251202152706.0"
132
+ version: "1.0.1-beta-20251203073716.0"
133
133
  };
134
134
  socket.emit(external_common_js_namespaceObject.BridgeEvent.Connected, payload);
135
135
  Promise.resolve().then(()=>{
@@ -84,7 +84,7 @@ class ExtensionBridgePageBrowserSide extends page_js_default() {
84
84
  }
85
85
  }, ()=>this.destroy());
86
86
  await this.bridgeClient.connect();
87
- this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.0.1-beta-20251202152706.0`, 'log');
87
+ this.onLogMessage(`Bridge connected, cli-side version v${this.bridgeClient.serverVersion}, browser-side version v1.0.1-beta-20251203073716.0`, 'log');
88
88
  }
89
89
  async connect() {
90
90
  return await this.setupBridgeClient();
@@ -53,6 +53,24 @@ const defaultViewportWidth = 1440;
53
53
  const defaultViewportHeight = 768;
54
54
  const defaultViewportScale = 'darwin' === process.platform ? 2 : 1;
55
55
  const defaultWaitForNetworkIdleTimeout = constants_namespaceObject.DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
56
+ const DANGEROUS_ARGS = [
57
+ '--no-sandbox',
58
+ '--disable-setuid-sandbox',
59
+ '--disable-web-security',
60
+ '--ignore-certificate-errors',
61
+ '--disable-features=IsolateOrigins',
62
+ '--disable-site-isolation-trials',
63
+ '--allow-running-insecure-content'
64
+ ];
65
+ function validateChromeArgs(args, baseArgs) {
66
+ const newArgs = args.filter((arg)=>!baseArgs.some((baseArg)=>{
67
+ const argFlag = arg.split('=')[0];
68
+ const baseFlag = baseArg.split('=')[0];
69
+ return argFlag === baseFlag;
70
+ }));
71
+ const dangerousArgs = newArgs.filter((arg)=>DANGEROUS_ARGS.some((dangerous)=>arg.startsWith(dangerous)));
72
+ if (dangerousArgs.length > 0) console.warn(`Warning: Dangerous Chrome arguments detected: ${dangerousArgs.join(', ')}.\nThese arguments may reduce browser security. Use only in controlled testing environments.`);
73
+ }
56
74
  const launcherDebug = (0, logger_namespaceObject.getDebug)('puppeteer:launcher');
57
75
  async function launchPuppeteerPage(target, preference, browser) {
58
76
  (0, utils_namespaceObject.assert)(target.url, 'url is required');
@@ -89,7 +107,7 @@ async function launchPuppeteerPage(target, preference, browser) {
89
107
  preferMaximizedWindow = preferMaximizedWindow && !!headed;
90
108
  if (headed && '1' === process.env.CI) console.warn('you are probably running headed mode in CI, this will usually fail.');
91
109
  const isWindows = 'win32' === process.platform;
92
- const args = [
110
+ const baseArgs = [
93
111
  ...isWindows ? [] : [
94
112
  '--no-sandbox',
95
113
  '--disable-setuid-sandbox'
@@ -100,6 +118,15 @@ async function launchPuppeteerPage(target, preference, browser) {
100
118
  `--user-agent="${ua}"`,
101
119
  preferMaximizedWindow ? '--start-maximized' : `--window-size=${width},${height + 200}`
102
120
  ];
121
+ let args = baseArgs;
122
+ if (target.chromeArgs && target.chromeArgs.length > 0) {
123
+ validateChromeArgs(target.chromeArgs, baseArgs);
124
+ args = [
125
+ ...baseArgs,
126
+ ...target.chromeArgs
127
+ ];
128
+ launcherDebug('Merging custom Chrome arguments', target.chromeArgs, 'Final args', args);
129
+ }
103
130
  launcherDebug('launching browser with viewport, headed', headed, 'viewport', viewportConfig, 'args', args, 'preference', preference);
104
131
  let browserInstance = browser;
105
132
  if (!browserInstance) {
@@ -154,9 +181,7 @@ async function launchPuppeteerPage(target, preference, browser) {
154
181
  async function puppeteerAgentForTarget(target, preference, browser) {
155
182
  const { page, freeFn } = await launchPuppeteerPage(target, preference, browser);
156
183
  const agent = new external_index_js_namespaceObject.PuppeteerAgent(page, {
157
- autoPrintReportMsg: false,
158
- testId: preference?.testId,
159
- cache: preference?.cache,
184
+ ...preference,
160
185
  aiActionContext: target.aiActionContext,
161
186
  forceSameTabNavigation: void 0 !== target.forceSameTabNavigation ? target.forceSameTabNavigation : true
162
187
  });
@@ -1 +1 @@
1
- {"version":3,"file":"puppeteer/agent-launcher.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/puppeteer/agent-launcher.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { readFileSync } from 'node:fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nimport { PuppeteerAgent } from '@/puppeteer/index';\nimport type { Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';\nimport { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from '@midscene/shared/constants';\nimport puppeteer, { type Browser } from 'puppeteer';\n\nexport const defaultUA =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';\nexport const defaultViewportWidth = 1440;\nexport const defaultViewportHeight = 768;\nexport const defaultViewportScale = process.platform === 'darwin' ? 2 : 1;\nexport const defaultWaitForNetworkIdleTimeout =\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n\ninterface FreeFn {\n name: string;\n fn: () => void;\n}\n\nconst launcherDebug = getDebug('puppeteer:launcher');\n\nexport async function launchPuppeteerPage(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n },\n browser?: Browser,\n) {\n assert(target.url, 'url is required');\n const freeFn: FreeFn[] = [];\n\n // prepare the environment\n const ua = target.userAgent || defaultUA;\n let width = defaultViewportWidth;\n let preferMaximizedWindow = true;\n if (target.viewportWidth) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportWidth === 'number',\n 'viewportWidth must be a number',\n );\n width = Number.parseInt(target.viewportWidth as unknown as string, 10);\n assert(width > 0, `viewportWidth must be greater than 0, but got ${width}`);\n }\n let height = defaultViewportHeight;\n if (target.viewportHeight) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportHeight === 'number',\n 'viewportHeight must be a number',\n );\n height = Number.parseInt(target.viewportHeight as unknown as string, 10);\n assert(\n height > 0,\n `viewportHeight must be greater than 0, but got ${height}`,\n );\n }\n let dpr = defaultViewportScale;\n if (target.viewportScale) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportScale === 'number',\n 'viewportScale must be a number',\n );\n dpr = Number.parseInt(target.viewportScale as unknown as string, 10);\n assert(dpr > 0, `viewportScale must be greater than 0, but got ${dpr}`);\n }\n const viewportConfig = {\n width,\n height,\n deviceScaleFactor: dpr,\n };\n\n const headed = preference?.headed || preference?.keepWindow;\n\n // only maximize window in headed mode\n preferMaximizedWindow = preferMaximizedWindow && !!headed;\n\n // launch the browser\n if (headed && process.env.CI === '1') {\n console.warn(\n 'you are probably running headed mode in CI, this will usually fail.',\n );\n }\n // do not use 'no-sandbox' on windows https://www.perplexity.ai/search/how-to-solve-this-with-nodejs-dMHpdCypRa..JA8TkQzbeQ\n const isWindows = process.platform === 'win32';\n const args = [\n ...(isWindows ? [] : ['--no-sandbox', '--disable-setuid-sandbox']),\n '--disable-features=HttpsFirstBalancedModeAutoEnable',\n '--disable-features=PasswordLeakDetection',\n '--disable-save-password-bubble',\n `--user-agent=\"${ua}\"`,\n preferMaximizedWindow\n ? '--start-maximized'\n : `--window-size=${width},${height + 200}`, // add 200px for the address bar\n ];\n\n launcherDebug(\n 'launching browser with viewport, headed',\n headed,\n 'viewport',\n viewportConfig,\n 'args',\n args,\n 'preference',\n preference,\n );\n let browserInstance = browser;\n if (!browserInstance) {\n browserInstance = await puppeteer.launch({\n headless: !preference?.headed,\n defaultViewport: viewportConfig,\n args,\n acceptInsecureCerts: target.acceptInsecureCerts,\n });\n freeFn.push({\n name: 'puppeteer_browser',\n fn: () => {\n if (!preference?.keepWindow) {\n if (isWindows) {\n setTimeout(() => {\n browserInstance?.close();\n }, 800);\n } else {\n browserInstance?.close();\n }\n }\n },\n });\n }\n const page = await browserInstance.newPage();\n // await page.setUserAgent(ua);\n // await page.setViewport(viewportConfig);\n\n if (target.cookie) {\n const cookieFileContent = readFileSync(target.cookie, 'utf-8');\n await browserInstance.setCookie(...JSON.parse(cookieFileContent));\n }\n\n if (ua) {\n await page.setUserAgent(ua);\n }\n\n if (viewportConfig) {\n await page.setViewport(viewportConfig);\n }\n\n const waitForNetworkIdleTimeout =\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : defaultWaitForNetworkIdleTimeout;\n\n try {\n launcherDebug('goto', target.url);\n await page.goto(target.url);\n if (waitForNetworkIdleTimeout > 0) {\n launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);\n await page.waitForNetworkIdle({\n timeout: waitForNetworkIdleTimeout,\n });\n }\n } catch (e) {\n if (\n typeof target.waitForNetworkIdle?.continueOnNetworkIdleError ===\n 'boolean' &&\n !target.waitForNetworkIdle?.continueOnNetworkIdleError\n ) {\n const newError = new Error(`failed to wait for network idle: ${e}`, {\n cause: e,\n });\n throw newError;\n }\n const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;\n console.warn(newMessage);\n }\n\n return { page, freeFn };\n}\n\nexport async function puppeteerAgentForTarget(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n testId?: string;\n cache?: Cache;\n },\n browser?: Browser,\n) {\n const { page, freeFn } = await launchPuppeteerPage(\n target,\n preference,\n browser,\n );\n\n // prepare Midscene agent\n const agent = new PuppeteerAgent(page, {\n autoPrintReportMsg: false,\n testId: preference?.testId,\n cache: preference?.cache,\n aiActionContext: target.aiActionContext,\n forceSameTabNavigation:\n typeof target.forceSameTabNavigation !== 'undefined'\n ? target.forceSameTabNavigation\n : true, // true for default in yaml script\n });\n\n freeFn.push({\n name: 'midscene_puppeteer_agent',\n fn: () => agent.destroy(),\n });\n\n return { agent, freeFn };\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","defaultUA","defaultViewportWidth","defaultViewportHeight","defaultViewportScale","process","defaultWaitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","launcherDebug","getDebug","launchPuppeteerPage","target","preference","browser","assert","freeFn","ua","width","preferMaximizedWindow","Number","height","dpr","viewportConfig","headed","console","isWindows","args","browserInstance","puppeteer","setTimeout","page","cookieFileContent","readFileSync","JSON","waitForNetworkIdleTimeout","e","newError","Error","newMessage","puppeteerAgentForTarget","agent","PuppeteerAgent"],"mappings":"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"}
1
+ {"version":3,"file":"puppeteer/agent-launcher.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/puppeteer/agent-launcher.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { readFileSync } from 'node:fs';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nimport { PuppeteerAgent } from '@/puppeteer/index';\nimport type { AgentOpt, Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';\nimport { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from '@midscene/shared/constants';\nimport puppeteer, { type Browser } from 'puppeteer';\n\nexport const defaultUA =\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36';\nexport const defaultViewportWidth = 1440;\nexport const defaultViewportHeight = 768;\nexport const defaultViewportScale = process.platform === 'darwin' ? 2 : 1;\nexport const defaultWaitForNetworkIdleTimeout =\n DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;\n\n/**\n * Chrome arguments that may reduce browser security.\n * These should only be used in controlled testing environments.\n *\n * Security implications:\n * - `--no-sandbox`: Disables Chrome's sandbox security model\n * - `--disable-setuid-sandbox`: Disables setuid sandbox on Linux\n * - `--disable-web-security`: Allows cross-origin requests without CORS\n * - `--ignore-certificate-errors`: Ignores SSL/TLS certificate errors\n * - `--disable-features=IsolateOrigins`: Disables origin isolation\n * - `--disable-site-isolation-trials`: Disables site isolation\n * - `--allow-running-insecure-content`: Allows mixed HTTP/HTTPS content\n */\nconst DANGEROUS_ARGS = [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-web-security',\n '--ignore-certificate-errors',\n '--disable-features=IsolateOrigins',\n '--disable-site-isolation-trials',\n '--allow-running-insecure-content',\n] as const;\n\n/**\n * Validates Chrome launch arguments for security concerns.\n * Emits a warning if dangerous arguments are detected.\n *\n * This function filters out arguments that are already present in baseArgs\n * to avoid warning about platform-specific defaults (e.g., --no-sandbox on non-Windows).\n *\n * @param args - Chrome launch arguments to validate\n * @param baseArgs - Base Chrome arguments already configured\n *\n * @example\n * ```typescript\n * // Will show warning for --disable-web-security\n * validateChromeArgs(['--disable-web-security', '--headless'], ['--no-sandbox']);\n *\n * // Will NOT show warning for --no-sandbox (already in baseArgs)\n * validateChromeArgs(['--no-sandbox'], ['--no-sandbox', '--headless']);\n * ```\n */\nfunction validateChromeArgs(args: string[], baseArgs: string[]): void {\n // Filter out arguments that are already in baseArgs\n const newArgs = args.filter(\n (arg) =>\n !baseArgs.some((baseArg) => {\n // Check if arg starts with the same flag as baseArg (before '=' if present)\n const argFlag = arg.split('=')[0];\n const baseFlag = baseArg.split('=')[0];\n return argFlag === baseFlag;\n }),\n );\n\n const dangerousArgs = newArgs.filter((arg) =>\n DANGEROUS_ARGS.some((dangerous) => arg.startsWith(dangerous)),\n );\n\n if (dangerousArgs.length > 0) {\n console.warn(\n `Warning: Dangerous Chrome arguments detected: ${dangerousArgs.join(', ')}.\\nThese arguments may reduce browser security. Use only in controlled testing environments.`,\n );\n }\n}\n\ninterface FreeFn {\n name: string;\n fn: () => void;\n}\n\nconst launcherDebug = getDebug('puppeteer:launcher');\n\nexport async function launchPuppeteerPage(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n },\n browser?: Browser,\n) {\n assert(target.url, 'url is required');\n const freeFn: FreeFn[] = [];\n\n // prepare the environment\n const ua = target.userAgent || defaultUA;\n let width = defaultViewportWidth;\n let preferMaximizedWindow = true;\n if (target.viewportWidth) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportWidth === 'number',\n 'viewportWidth must be a number',\n );\n width = Number.parseInt(target.viewportWidth as unknown as string, 10);\n assert(width > 0, `viewportWidth must be greater than 0, but got ${width}`);\n }\n let height = defaultViewportHeight;\n if (target.viewportHeight) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportHeight === 'number',\n 'viewportHeight must be a number',\n );\n height = Number.parseInt(target.viewportHeight as unknown as string, 10);\n assert(\n height > 0,\n `viewportHeight must be greater than 0, but got ${height}`,\n );\n }\n let dpr = defaultViewportScale;\n if (target.viewportScale) {\n preferMaximizedWindow = false;\n assert(\n typeof target.viewportScale === 'number',\n 'viewportScale must be a number',\n );\n dpr = Number.parseInt(target.viewportScale as unknown as string, 10);\n assert(dpr > 0, `viewportScale must be greater than 0, but got ${dpr}`);\n }\n const viewportConfig = {\n width,\n height,\n deviceScaleFactor: dpr,\n };\n\n const headed = preference?.headed || preference?.keepWindow;\n\n // only maximize window in headed mode\n preferMaximizedWindow = preferMaximizedWindow && !!headed;\n\n // launch the browser\n if (headed && process.env.CI === '1') {\n console.warn(\n 'you are probably running headed mode in CI, this will usually fail.',\n );\n }\n // do not use 'no-sandbox' on windows https://www.perplexity.ai/search/how-to-solve-this-with-nodejs-dMHpdCypRa..JA8TkQzbeQ\n const isWindows = process.platform === 'win32';\n\n const baseArgs = [\n ...(isWindows ? [] : ['--no-sandbox', '--disable-setuid-sandbox']),\n '--disable-features=HttpsFirstBalancedModeAutoEnable',\n '--disable-features=PasswordLeakDetection',\n '--disable-save-password-bubble',\n `--user-agent=\"${ua}\"`,\n preferMaximizedWindow\n ? '--start-maximized'\n : `--window-size=${width},${height + 200}`, // add 200px for the address bar\n ];\n\n // Merge custom Chrome arguments\n let args = baseArgs;\n if (target.chromeArgs && target.chromeArgs.length > 0) {\n validateChromeArgs(target.chromeArgs, baseArgs);\n\n // Custom args come after base args, allowing them to override defaults\n args = [...baseArgs, ...target.chromeArgs];\n launcherDebug(\n 'Merging custom Chrome arguments',\n target.chromeArgs,\n 'Final args',\n args,\n );\n }\n\n launcherDebug(\n 'launching browser with viewport, headed',\n headed,\n 'viewport',\n viewportConfig,\n 'args',\n args,\n 'preference',\n preference,\n );\n let browserInstance = browser;\n if (!browserInstance) {\n browserInstance = await puppeteer.launch({\n headless: !preference?.headed,\n defaultViewport: viewportConfig,\n args,\n acceptInsecureCerts: target.acceptInsecureCerts,\n });\n freeFn.push({\n name: 'puppeteer_browser',\n fn: () => {\n if (!preference?.keepWindow) {\n if (isWindows) {\n setTimeout(() => {\n browserInstance?.close();\n }, 800);\n } else {\n browserInstance?.close();\n }\n }\n },\n });\n }\n const page = await browserInstance.newPage();\n\n if (target.cookie) {\n const cookieFileContent = readFileSync(target.cookie, 'utf-8');\n await browserInstance.setCookie(...JSON.parse(cookieFileContent));\n }\n\n if (ua) {\n await page.setUserAgent(ua);\n }\n\n if (viewportConfig) {\n await page.setViewport(viewportConfig);\n }\n\n const waitForNetworkIdleTimeout =\n typeof target.waitForNetworkIdle?.timeout === 'number'\n ? target.waitForNetworkIdle.timeout\n : defaultWaitForNetworkIdleTimeout;\n\n try {\n launcherDebug('goto', target.url);\n await page.goto(target.url);\n if (waitForNetworkIdleTimeout > 0) {\n launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);\n await page.waitForNetworkIdle({\n timeout: waitForNetworkIdleTimeout,\n });\n }\n } catch (e) {\n if (\n typeof target.waitForNetworkIdle?.continueOnNetworkIdleError ===\n 'boolean' &&\n !target.waitForNetworkIdle?.continueOnNetworkIdleError\n ) {\n const newError = new Error(`failed to wait for network idle: ${e}`, {\n cause: e,\n });\n throw newError;\n }\n const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;\n console.warn(newMessage);\n }\n\n return { page, freeFn };\n}\n\nexport async function puppeteerAgentForTarget(\n target: MidsceneYamlScriptWebEnv,\n preference?: {\n headed?: boolean;\n keepWindow?: boolean;\n } & Partial<\n Pick<\n AgentOpt,\n | 'testId'\n | 'groupName'\n | 'groupDescription'\n | 'generateReport'\n | 'autoPrintReportMsg'\n | 'reportFileName'\n | 'replanningCycleLimit'\n | 'cache'\n | 'aiActionContext'\n >\n >,\n browser?: Browser,\n) {\n const { page, freeFn } = await launchPuppeteerPage(\n target,\n preference,\n browser,\n );\n\n // prepare Midscene agent\n const agent = new PuppeteerAgent(page, {\n ...preference,\n aiActionContext: target.aiActionContext,\n forceSameTabNavigation:\n typeof target.forceSameTabNavigation !== 'undefined'\n ? target.forceSameTabNavigation\n : true, // true for default in yaml script\n });\n\n freeFn.push({\n name: 'midscene_puppeteer_agent',\n fn: () => agent.destroy(),\n });\n\n return { agent, freeFn };\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","defaultUA","defaultViewportWidth","defaultViewportHeight","defaultViewportScale","process","defaultWaitForNetworkIdleTimeout","DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT","DANGEROUS_ARGS","validateChromeArgs","args","baseArgs","newArgs","arg","baseArg","argFlag","baseFlag","dangerousArgs","dangerous","console","launcherDebug","getDebug","launchPuppeteerPage","target","preference","browser","assert","freeFn","ua","width","preferMaximizedWindow","Number","height","dpr","viewportConfig","headed","isWindows","browserInstance","puppeteer","setTimeout","page","cookieFileContent","readFileSync","JSON","waitForNetworkIdleTimeout","e","newError","Error","newMessage","puppeteerAgentForTarget","agent","PuppeteerAgent"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { PuppeteerAgent } from './index';
2
- import type { Cache, MidsceneYamlScriptWebEnv } from '@midscene/core';
2
+ import type { AgentOpt, MidsceneYamlScriptWebEnv } from '@midscene/core';
3
3
  import { type Browser } from 'puppeteer';
4
4
  export declare const defaultUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36";
5
5
  export declare const defaultViewportWidth = 1440;
@@ -20,9 +20,7 @@ export declare function launchPuppeteerPage(target: MidsceneYamlScriptWebEnv, pr
20
20
  export declare function puppeteerAgentForTarget(target: MidsceneYamlScriptWebEnv, preference?: {
21
21
  headed?: boolean;
22
22
  keepWindow?: boolean;
23
- testId?: string;
24
- cache?: Cache;
25
- }, browser?: Browser): Promise<{
23
+ } & Partial<Pick<AgentOpt, 'testId' | 'groupName' | 'groupDescription' | 'generateReport' | 'autoPrintReportMsg' | 'reportFileName' | 'replanningCycleLimit' | 'cache' | 'aiActionContext'>>, browser?: Browser): Promise<{
26
24
  agent: PuppeteerAgent;
27
25
  freeFn: FreeFn[];
28
26
  }>;
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "Browser use",
9
9
  "Android use"
10
10
  ],
11
- "version": "1.0.1-beta-20251202152706.0",
11
+ "version": "1.0.1-beta-20251203073716.0",
12
12
  "repository": "https://github.com/web-infra-dev/midscene",
13
13
  "homepage": "https://midscenejs.com/",
14
14
  "main": "./dist/lib/index.js",
@@ -103,9 +103,9 @@
103
103
  "http-server": "14.1.1",
104
104
  "socket.io": "^4.8.1",
105
105
  "socket.io-client": "4.8.1",
106
- "@midscene/core": "1.0.1-beta-20251202152706.0",
107
- "@midscene/shared": "1.0.1-beta-20251202152706.0",
108
- "@midscene/playground": "1.0.1-beta-20251202152706.0"
106
+ "@midscene/core": "1.0.1-beta-20251203073716.0",
107
+ "@midscene/shared": "1.0.1-beta-20251203073716.0",
108
+ "@midscene/playground": "1.0.1-beta-20251203073716.0"
109
109
  },
110
110
  "devDependencies": {
111
111
  "@playwright/test": "^1.44.1",