@godscene/web 1.7.11

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 (129) hide show
  1. package/README.md +7 -0
  2. package/bin/midscene-playground +3 -0
  3. package/bin/midscene-web +2 -0
  4. package/dist/es/bin.mjs +14 -0
  5. package/dist/es/bridge-mode/agent-cli-side.mjs +135 -0
  6. package/dist/es/bridge-mode/browser.mjs +2 -0
  7. package/dist/es/bridge-mode/common.mjs +41 -0
  8. package/dist/es/bridge-mode/index.mjs +4 -0
  9. package/dist/es/bridge-mode/io-client.mjs +99 -0
  10. package/dist/es/bridge-mode/io-server.mjs +218 -0
  11. package/dist/es/bridge-mode/page-browser-side.mjs +119 -0
  12. package/dist/es/cdp-proxy-constants.mjs +7 -0
  13. package/dist/es/cdp-proxy-manager.mjs +217 -0
  14. package/dist/es/cdp-proxy.mjs +151 -0
  15. package/dist/es/cdp-target-store.mjs +26 -0
  16. package/dist/es/chrome-extension/agent.mjs +8 -0
  17. package/dist/es/chrome-extension/cdpInput.mjs +172 -0
  18. package/dist/es/chrome-extension/cdpInput.mjs.LICENSE.txt +5 -0
  19. package/dist/es/chrome-extension/dynamic-scripts.mjs +36 -0
  20. package/dist/es/chrome-extension/index.mjs +5 -0
  21. package/dist/es/chrome-extension/page.mjs +733 -0
  22. package/dist/es/cli-options.mjs +97 -0
  23. package/dist/es/cli.mjs +26 -0
  24. package/dist/es/common/cache-helper.mjs +26 -0
  25. package/dist/es/common/viewport.mjs +36 -0
  26. package/dist/es/index.mjs +8 -0
  27. package/dist/es/mcp-server.mjs +33 -0
  28. package/dist/es/mcp-tools-cdp.mjs +164 -0
  29. package/dist/es/mcp-tools-puppeteer.mjs +246 -0
  30. package/dist/es/mcp-tools.mjs +81 -0
  31. package/dist/es/platform.mjs +37 -0
  32. package/dist/es/playwright/ai-fixture.mjs +364 -0
  33. package/dist/es/playwright/index.mjs +36 -0
  34. package/dist/es/playwright/page.mjs +42 -0
  35. package/dist/es/playwright/reporter/index.mjs +178 -0
  36. package/dist/es/puppeteer/agent-launcher.mjs +172 -0
  37. package/dist/es/puppeteer/base-page.mjs +830 -0
  38. package/dist/es/puppeteer/index.mjs +35 -0
  39. package/dist/es/puppeteer/page.mjs +7 -0
  40. package/dist/es/static/index.mjs +3 -0
  41. package/dist/es/static/static-agent.mjs +10 -0
  42. package/dist/es/static/static-page.mjs +123 -0
  43. package/dist/es/utils.mjs +6 -0
  44. package/dist/es/web-element.mjs +57 -0
  45. package/dist/es/web-page.mjs +272 -0
  46. package/dist/lib/bin.js +20 -0
  47. package/dist/lib/bridge-mode/agent-cli-side.js +172 -0
  48. package/dist/lib/bridge-mode/browser.js +36 -0
  49. package/dist/lib/bridge-mode/common.js +105 -0
  50. package/dist/lib/bridge-mode/index.js +44 -0
  51. package/dist/lib/bridge-mode/io-client.js +133 -0
  52. package/dist/lib/bridge-mode/io-server.js +255 -0
  53. package/dist/lib/bridge-mode/page-browser-side.js +163 -0
  54. package/dist/lib/cdp-proxy-constants.js +50 -0
  55. package/dist/lib/cdp-proxy-manager.js +273 -0
  56. package/dist/lib/cdp-proxy.js +179 -0
  57. package/dist/lib/cdp-target-store.js +66 -0
  58. package/dist/lib/chrome-extension/agent.js +42 -0
  59. package/dist/lib/chrome-extension/cdpInput.js +206 -0
  60. package/dist/lib/chrome-extension/cdpInput.js.LICENSE.txt +5 -0
  61. package/dist/lib/chrome-extension/dynamic-scripts.js +86 -0
  62. package/dist/lib/chrome-extension/index.js +58 -0
  63. package/dist/lib/chrome-extension/page.js +767 -0
  64. package/dist/lib/cli-options.js +131 -0
  65. package/dist/lib/cli.js +54 -0
  66. package/dist/lib/common/cache-helper.js +66 -0
  67. package/dist/lib/common/viewport.js +88 -0
  68. package/dist/lib/index.js +66 -0
  69. package/dist/lib/mcp-server.js +73 -0
  70. package/dist/lib/mcp-tools-cdp.js +208 -0
  71. package/dist/lib/mcp-tools-puppeteer.js +296 -0
  72. package/dist/lib/mcp-tools.js +115 -0
  73. package/dist/lib/platform.js +71 -0
  74. package/dist/lib/playwright/ai-fixture.js +401 -0
  75. package/dist/lib/playwright/index.js +89 -0
  76. package/dist/lib/playwright/page.js +76 -0
  77. package/dist/lib/playwright/reporter/index.js +212 -0
  78. package/dist/lib/puppeteer/agent-launcher.js +240 -0
  79. package/dist/lib/puppeteer/base-page.js +876 -0
  80. package/dist/lib/puppeteer/index.js +85 -0
  81. package/dist/lib/puppeteer/page.js +41 -0
  82. package/dist/lib/static/index.js +50 -0
  83. package/dist/lib/static/static-agent.js +44 -0
  84. package/dist/lib/static/static-page.js +157 -0
  85. package/dist/lib/utils.js +38 -0
  86. package/dist/lib/web-element.js +94 -0
  87. package/dist/lib/web-page.js +322 -0
  88. package/dist/types/bin.d.ts +1 -0
  89. package/dist/types/bridge-mode/agent-cli-side.d.ts +49 -0
  90. package/dist/types/bridge-mode/browser.d.ts +2 -0
  91. package/dist/types/bridge-mode/common.d.ts +74 -0
  92. package/dist/types/bridge-mode/index.d.ts +4 -0
  93. package/dist/types/bridge-mode/io-client.d.ts +10 -0
  94. package/dist/types/bridge-mode/io-server.d.ts +27 -0
  95. package/dist/types/bridge-mode/page-browser-side.d.ts +21 -0
  96. package/dist/types/cdp-proxy-constants.d.ts +4 -0
  97. package/dist/types/cdp-proxy-manager.d.ts +53 -0
  98. package/dist/types/cdp-proxy.d.ts +37 -0
  99. package/dist/types/cdp-target-store.d.ts +26 -0
  100. package/dist/types/chrome-extension/agent.d.ts +4 -0
  101. package/dist/types/chrome-extension/cdpInput.d.ts +52 -0
  102. package/dist/types/chrome-extension/dynamic-scripts.d.ts +3 -0
  103. package/dist/types/chrome-extension/index.d.ts +5 -0
  104. package/dist/types/chrome-extension/page.d.ts +120 -0
  105. package/dist/types/cli-options.d.ts +8 -0
  106. package/dist/types/cli.d.ts +1 -0
  107. package/dist/types/common/cache-helper.d.ts +20 -0
  108. package/dist/types/common/viewport.d.ts +17 -0
  109. package/dist/types/index.d.ts +9 -0
  110. package/dist/types/mcp-server.d.ts +26 -0
  111. package/dist/types/mcp-tools-cdp.d.ts +23 -0
  112. package/dist/types/mcp-tools-puppeteer.d.ts +23 -0
  113. package/dist/types/mcp-tools.d.ts +14 -0
  114. package/dist/types/platform.d.ts +10 -0
  115. package/dist/types/playwright/ai-fixture.d.ts +133 -0
  116. package/dist/types/playwright/index.d.ts +13 -0
  117. package/dist/types/playwright/page.d.ts +11 -0
  118. package/dist/types/playwright/reporter/index.d.ts +28 -0
  119. package/dist/types/puppeteer/agent-launcher.d.ts +59 -0
  120. package/dist/types/puppeteer/base-page.d.ts +123 -0
  121. package/dist/types/puppeteer/index.d.ts +11 -0
  122. package/dist/types/puppeteer/page.d.ts +6 -0
  123. package/dist/types/static/index.d.ts +2 -0
  124. package/dist/types/static/static-agent.d.ts +5 -0
  125. package/dist/types/static/static-page.d.ts +46 -0
  126. package/dist/types/utils.d.ts +6 -0
  127. package/dist/types/web-element.d.ts +48 -0
  128. package/dist/types/web-page.d.ts +69 -0
  129. package/package.json +173 -0
@@ -0,0 +1,178 @@
1
+ import { copyFileSync, cpSync, existsSync, mkdirSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { getReportFileName, printReportMsg } from "@godscene/core/agent";
4
+ import { ReportMergingTool, isDirectoryModeReport } from "@godscene/core/report";
5
+ import { getMidsceneRunSubDir } from "@godscene/shared/common";
6
+ import { logMsg, replaceIllegalPathCharsAndSpace } from "@godscene/shared/utils";
7
+ function _define_property(obj, key, value) {
8
+ if (key in obj) Object.defineProperty(obj, key, {
9
+ value: value,
10
+ enumerable: true,
11
+ configurable: true,
12
+ writable: true
13
+ });
14
+ else obj[key] = value;
15
+ return obj;
16
+ }
17
+ class MidsceneReporter {
18
+ static getMode(reporterType) {
19
+ if (!reporterType) return 'merged';
20
+ if ('merged' !== reporterType && 'separate' !== reporterType) throw new Error(`Unknown reporter type in playwright config: ${reporterType}, only support 'merged' or 'separate'`);
21
+ return reporterType;
22
+ }
23
+ getSeparatedFilename(testTitle) {
24
+ if (!this.testTitleToFilename.has(testTitle)) {
25
+ const baseTag = `playwright-${replaceIllegalPathCharsAndSpace(testTitle)}`;
26
+ const generatedFilename = getReportFileName(baseTag);
27
+ this.testTitleToFilename.set(testTitle, generatedFilename);
28
+ }
29
+ return this.testTitleToFilename.get(testTitle);
30
+ }
31
+ getReportFilename(testTitle) {
32
+ if ('merged' === this.mode) {
33
+ if (!this.mergedFilename) this.mergedFilename = getReportFileName('playwright-merged');
34
+ return this.mergedFilename;
35
+ }
36
+ if ('separate' === this.mode) {
37
+ if (!testTitle) throw new Error('testTitle is required in separate mode');
38
+ return this.getSeparatedFilename(testTitle);
39
+ }
40
+ throw new Error(`Unknown mode: ${this.mode}`);
41
+ }
42
+ getReportPath(testTitle) {
43
+ const fileName = this.getReportFilename(testTitle);
44
+ if ('html-and-external-assets' === this.outputFormat) return join(getMidsceneRunSubDir('report'), fileName, 'index.html');
45
+ return join(getMidsceneRunSubDir('report'), `${fileName}.html`);
46
+ }
47
+ ensureOutputRoot() {
48
+ mkdirSync(getMidsceneRunSubDir('report'), {
49
+ recursive: true
50
+ });
51
+ }
52
+ copyReport(reportFilePath, targetPath) {
53
+ if (isDirectoryModeReport(reportFilePath)) {
54
+ const targetDir = dirname(targetPath);
55
+ mkdirSync(targetDir, {
56
+ recursive: true
57
+ });
58
+ cpSync(dirname(reportFilePath), targetDir, {
59
+ recursive: true,
60
+ force: true
61
+ });
62
+ return;
63
+ }
64
+ mkdirSync(dirname(targetPath), {
65
+ recursive: true
66
+ });
67
+ copyFileSync(reportFilePath, targetPath);
68
+ }
69
+ collectReportInfo(test, result) {
70
+ const reportAnnotations = test.annotations.filter((annotation)=>'MIDSCENE_DUMP_ANNOTATION' === annotation.type && annotation.description);
71
+ if (0 === reportAnnotations.length || !this.mode) return;
72
+ const retry = result.retry ? `(retry #${result.retry})` : '';
73
+ const testId = `${test.id}${retry}`;
74
+ const projectName = this.hasMultipleProjects ? test.parent?.project()?.name : void 0;
75
+ const projectSuffix = projectName ? ` [${projectName}]` : '';
76
+ const testTitle = `${test.title}${projectSuffix}${retry}`;
77
+ const reports = reportAnnotations.map((annotation)=>annotation.description).filter((reportFilePath)=>{
78
+ if (existsSync(reportFilePath)) return true;
79
+ logMsg(`Failed to read Midscene report file: ${reportFilePath}`, new Error('Report file does not exist'));
80
+ return false;
81
+ }).map((reportFilePath)=>({
82
+ reportFilePath,
83
+ reportAttributes: {
84
+ testDuration: result.duration,
85
+ testStatus: result.status,
86
+ testTitle,
87
+ testId,
88
+ testDescription: test.parent?.title || ''
89
+ }
90
+ }));
91
+ if (0 === reports.length) return;
92
+ this.reportsByTestId.set(testId, {
93
+ testTitle,
94
+ reports
95
+ });
96
+ }
97
+ finalizeMergedReport() {
98
+ this.ensureOutputRoot();
99
+ const tool = new ReportMergingTool();
100
+ let reportCount = 0;
101
+ for (const entry of this.reportsByTestId.values())for (const report of entry.reports){
102
+ tool.append(report);
103
+ reportCount += 1;
104
+ }
105
+ if (0 === reportCount) return;
106
+ const targetName = this.getReportFilename();
107
+ if (1 === reportCount) {
108
+ const firstReport = Array.from(this.reportsByTestId.values())[0]?.reports[0];
109
+ if (!firstReport) return;
110
+ if (firstReport.reportFilePath) {
111
+ const targetPath = this.getReportPath();
112
+ this.copyReport(firstReport.reportFilePath, targetPath);
113
+ printReportMsg(targetPath);
114
+ return;
115
+ }
116
+ const mergedReportPath = tool.mergeReports(targetName, {
117
+ overwrite: true
118
+ });
119
+ if (mergedReportPath) printReportMsg(mergedReportPath);
120
+ return;
121
+ }
122
+ const mergedReportPath = tool.mergeReports(targetName, {
123
+ overwrite: true
124
+ });
125
+ if (mergedReportPath) printReportMsg(mergedReportPath);
126
+ }
127
+ finalizeSeparateReports() {
128
+ this.ensureOutputRoot();
129
+ for (const entry of this.reportsByTestId.values()){
130
+ const targetName = this.getReportFilename(entry.testTitle);
131
+ if (1 === entry.reports.length) {
132
+ const firstReport = entry.reports[0];
133
+ if (firstReport.reportFilePath) {
134
+ const targetPath = this.getReportPath(entry.testTitle);
135
+ this.copyReport(firstReport.reportFilePath, targetPath);
136
+ printReportMsg(targetPath);
137
+ continue;
138
+ }
139
+ const tool = new ReportMergingTool();
140
+ tool.append(firstReport);
141
+ const reportPath = tool.mergeReports(targetName, {
142
+ overwrite: true
143
+ });
144
+ if (reportPath) printReportMsg(reportPath);
145
+ continue;
146
+ }
147
+ const tool = new ReportMergingTool();
148
+ for (const report of entry.reports)tool.append(report);
149
+ const reportPath = tool.mergeReports(targetName, {
150
+ overwrite: true
151
+ });
152
+ if (reportPath) printReportMsg(reportPath);
153
+ }
154
+ }
155
+ async onBegin(config, _suite) {
156
+ this.hasMultipleProjects = (config.projects?.length || 0) > 1;
157
+ }
158
+ onTestBegin(_test, _result) {}
159
+ onTestEnd(test, result) {
160
+ this.collectReportInfo(test, result);
161
+ }
162
+ async onEnd() {
163
+ if ('merged' === this.mode) return void this.finalizeMergedReport();
164
+ if ('separate' === this.mode) this.finalizeSeparateReports();
165
+ }
166
+ constructor(options = {}){
167
+ _define_property(this, "mergedFilename", void 0);
168
+ _define_property(this, "testTitleToFilename", new Map());
169
+ _define_property(this, "reportsByTestId", new Map());
170
+ _define_property(this, "mode", void 0);
171
+ _define_property(this, "outputFormat", void 0);
172
+ _define_property(this, "hasMultipleProjects", false);
173
+ this.mode = MidsceneReporter.getMode(options.type ?? 'merged');
174
+ this.outputFormat = options.outputFormat ?? 'single-html';
175
+ }
176
+ }
177
+ const reporter = MidsceneReporter;
178
+ export { reporter as default };
@@ -0,0 +1,172 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { getDebug } from "@godscene/shared/logger";
3
+ import { assert } from "@godscene/shared/utils";
4
+ import { defaultViewportHeight, defaultViewportWidth, resolveWebViewportSize } from "../common/viewport.mjs";
5
+ import { PuppeteerAgent } from "./index.mjs";
6
+ import { DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT } from "@godscene/shared/constants";
7
+ import puppeteer from "puppeteer";
8
+ 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';
9
+ const defaultViewportScale = 0;
10
+ const defaultWaitForNetworkIdleTimeout = DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
11
+ function resolveAiActionContext(target, preference) {
12
+ const data = preference?.aiActContext ?? preference?.aiActionContext ?? target.aiActionContext;
13
+ return data;
14
+ }
15
+ const DANGEROUS_ARGS = [
16
+ '--no-sandbox',
17
+ '--disable-setuid-sandbox',
18
+ '--disable-web-security',
19
+ '--ignore-certificate-errors',
20
+ '--disable-features=IsolateOrigins',
21
+ '--disable-site-isolation-trials',
22
+ '--allow-running-insecure-content'
23
+ ];
24
+ function validateChromeArgs(args, baseArgs) {
25
+ const newArgs = args.filter((arg)=>!baseArgs.some((baseArg)=>{
26
+ const argFlag = arg.split('=')[0];
27
+ const baseFlag = baseArg.split('=')[0];
28
+ return argFlag === baseFlag;
29
+ }));
30
+ const dangerousArgs = newArgs.filter((arg)=>DANGEROUS_ARGS.some((dangerous)=>arg.startsWith(dangerous)));
31
+ 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.`);
32
+ }
33
+ const launcherDebug = getDebug('puppeteer:launcher');
34
+ function buildChromeArgs(options) {
35
+ const isWindows = 'win32' === process.platform;
36
+ const sandboxArgs = isWindows ? [] : [
37
+ '--no-sandbox',
38
+ '--disable-setuid-sandbox'
39
+ ];
40
+ const featureArgs = [
41
+ '--disable-features=HttpsFirstBalancedModeAutoEnable',
42
+ '--disable-features=PasswordLeakDetection',
43
+ '--disable-save-password-bubble'
44
+ ];
45
+ const userAgentArg = options?.userAgent ? [
46
+ `--user-agent="${options.userAgent}"`
47
+ ] : [];
48
+ const windowSizeArg = options?.windowSize ? [
49
+ `--window-size=${options.windowSize.width},${options.windowSize.height}`
50
+ ] : [];
51
+ const baseArgs = [
52
+ ...sandboxArgs,
53
+ ...featureArgs,
54
+ ...userAgentArg,
55
+ ...windowSizeArg
56
+ ];
57
+ if (options?.chromeArgs?.length) {
58
+ validateChromeArgs(options.chromeArgs, baseArgs);
59
+ return [
60
+ ...baseArgs,
61
+ ...options.chromeArgs
62
+ ];
63
+ }
64
+ return baseArgs;
65
+ }
66
+ async function launchPuppeteerPage(target, preference, browser, existingPage) {
67
+ assert(target.url, 'url is required');
68
+ const freeFn = [];
69
+ const ua = target.userAgent || defaultUA;
70
+ const { width, height } = resolveWebViewportSize(target);
71
+ let dpr = defaultViewportScale;
72
+ if (void 0 !== target.deviceScaleFactor && null !== target.deviceScaleFactor) {
73
+ assert('number' == typeof target.deviceScaleFactor, 'deviceScaleFactor must be a number');
74
+ dpr = target.deviceScaleFactor;
75
+ assert(dpr > 0, `deviceScaleFactor must be > 0, but got ${dpr}`);
76
+ }
77
+ const viewportConfig = {
78
+ width,
79
+ height,
80
+ deviceScaleFactor: dpr
81
+ };
82
+ const headed = preference?.headed || preference?.keepWindow;
83
+ const defaultViewportConfig = headed ? null : viewportConfig;
84
+ if (headed && '1' === process.env.CI) console.warn('you are probably running headed mode in CI, this will usually fail.');
85
+ const browserUIHeight = 100;
86
+ const args = buildChromeArgs({
87
+ userAgent: ua,
88
+ windowSize: headed ? {
89
+ width,
90
+ height: height + browserUIHeight
91
+ } : void 0,
92
+ chromeArgs: target.chromeArgs
93
+ });
94
+ launcherDebug('launching browser with viewport, headed', headed, 'viewport', viewportConfig, 'args', args, 'preference', preference);
95
+ let page;
96
+ let browserInstance = browser;
97
+ if (existingPage) {
98
+ page = existingPage;
99
+ launcherDebug('reusing existing page for shared browser context');
100
+ if (!browserInstance) browserInstance = page.browser();
101
+ } else {
102
+ if (!browserInstance) {
103
+ browserInstance = await puppeteer.launch({
104
+ headless: !preference?.headed,
105
+ defaultViewport: defaultViewportConfig,
106
+ args,
107
+ acceptInsecureCerts: target.acceptInsecureCerts,
108
+ ignoreDefaultArgs: preference?.ignoreDefaultArgs
109
+ });
110
+ freeFn.push({
111
+ name: 'puppeteer_browser',
112
+ fn: ()=>{
113
+ if (!preference?.keepWindow) if ('win32' === process.platform) setTimeout(()=>{
114
+ browserInstance?.close();
115
+ }, 800);
116
+ else browserInstance?.close();
117
+ }
118
+ });
119
+ }
120
+ page = await browserInstance.newPage();
121
+ }
122
+ if (target.cookie) {
123
+ const cookieFileContent = readFileSync(target.cookie, 'utf-8');
124
+ await browserInstance.setCookie(...JSON.parse(cookieFileContent));
125
+ }
126
+ if (ua) await page.setUserAgent(ua);
127
+ if (viewportConfig) await page.setViewport(viewportConfig);
128
+ const waitForNetworkIdleTimeout = 'number' == typeof target.waitForNetworkIdle?.timeout ? target.waitForNetworkIdle.timeout : defaultWaitForNetworkIdleTimeout;
129
+ try {
130
+ launcherDebug('goto', target.url);
131
+ await page.goto(target.url);
132
+ if (waitForNetworkIdleTimeout > 0) {
133
+ launcherDebug('waitForNetworkIdle', waitForNetworkIdleTimeout);
134
+ await page.waitForNetworkIdle({
135
+ timeout: waitForNetworkIdleTimeout
136
+ });
137
+ }
138
+ } catch (e) {
139
+ if ('boolean' == typeof target.waitForNetworkIdle?.continueOnNetworkIdleError && !target.waitForNetworkIdle?.continueOnNetworkIdleError) {
140
+ const newError = new Error(`failed to wait for network idle: ${e}`, {
141
+ cause: e
142
+ });
143
+ throw newError;
144
+ }
145
+ const newMessage = `failed to wait for network idle after ${waitForNetworkIdleTimeout}ms, but the script will continue.`;
146
+ console.warn(newMessage);
147
+ }
148
+ return {
149
+ page,
150
+ freeFn
151
+ };
152
+ }
153
+ async function puppeteerAgentForTarget(target, preference, browser, existingPage) {
154
+ const { page, freeFn } = await launchPuppeteerPage(target, preference, browser, existingPage);
155
+ const aiActContext = resolveAiActionContext(target, preference);
156
+ const { aiActionContext, ...preferenceToUse } = preference ?? {};
157
+ const agent = new PuppeteerAgent(page, {
158
+ ...preferenceToUse,
159
+ aiActContext,
160
+ waitForNetworkIdleTimeout: 'number' == typeof target.waitForNetworkIdle?.timeout ? target.waitForNetworkIdle.timeout : void 0,
161
+ forceSameTabNavigation: void 0 !== target.forceSameTabNavigation ? target.forceSameTabNavigation : true
162
+ });
163
+ freeFn.push({
164
+ name: 'midscene_puppeteer_agent',
165
+ fn: ()=>agent.destroy()
166
+ });
167
+ return {
168
+ agent,
169
+ freeFn
170
+ };
171
+ }
172
+ export { buildChromeArgs, defaultUA, defaultViewportHeight, defaultViewportScale, defaultViewportWidth, defaultWaitForNetworkIdleTimeout, launchPuppeteerPage, puppeteerAgentForTarget, resolveAiActionContext };