@agent-infra/browser 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-browser.d.ts +5 -0
- package/dist/base-browser.d.ts.map +1 -1
- package/dist/base-browser.js +12 -0
- package/dist/base-browser.js.map +1 -1
- package/dist/base-browser.mjs +12 -0
- package/dist/base-browser.mjs.map +1 -1
- package/dist/browser-finder/chrome-paths.d.ts +10 -0
- package/dist/browser-finder/chrome-paths.d.ts.map +1 -0
- package/dist/browser-finder/chrome-paths.js +160 -0
- package/dist/browser-finder/chrome-paths.js.map +1 -0
- package/dist/browser-finder/chrome-paths.mjs +118 -0
- package/dist/browser-finder/chrome-paths.mjs.map +1 -0
- package/dist/browser-finder/firefox-paths.d.ts +2 -0
- package/dist/browser-finder/firefox-paths.d.ts.map +1 -0
- package/dist/browser-finder/firefox-paths.js +132 -0
- package/dist/browser-finder/firefox-paths.js.map +1 -0
- package/dist/browser-finder/firefox-paths.mjs +90 -0
- package/dist/browser-finder/firefox-paths.mjs.map +1 -0
- package/dist/browser-finder/index.d.ts +15 -0
- package/dist/browser-finder/index.d.ts.map +1 -0
- package/dist/browser-finder/index.js +151 -0
- package/dist/browser-finder/index.js.map +1 -0
- package/dist/browser-finder/index.mjs +119 -0
- package/dist/browser-finder/index.mjs.map +1 -0
- package/dist/browser-finder/index.test.d.ts +2 -0
- package/dist/browser-finder/index.test.d.ts.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/local-browser.d.ts +2 -6
- package/dist/local-browser.d.ts.map +1 -1
- package/dist/local-browser.js +42 -19
- package/dist/local-browser.js.map +1 -1
- package/dist/local-browser.mjs +42 -19
- package/dist/local-browser.mjs.map +1 -1
- package/dist/remote-browser.d.ts +3 -4
- package/dist/remote-browser.d.ts.map +1 -1
- package/dist/remote-browser.js +3 -4
- package/dist/remote-browser.js.map +1 -1
- package/dist/remote-browser.mjs +3 -4
- package/dist/remote-browser.mjs.map +1 -1
- package/dist/types.d.ts +28 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -15
- package/dist/types.mjs +0 -3
- package/package.json +5 -2
- package/dist/browser-finder.d.ts +0 -59
- package/dist/browser-finder.d.ts.map +0 -1
- package/dist/browser-finder.js +0 -148
- package/dist/browser-finder.js.map +0 -1
- package/dist/browser-finder.mjs +0 -116
- package/dist/browser-finder.mjs.map +0 -1
- package/dist/browser-finder.test.d.ts +0 -2
- package/dist/browser-finder.test.d.ts.map +0 -1
package/dist/base-browser.d.ts
CHANGED
|
@@ -36,6 +36,11 @@ export declare abstract class BaseBrowser implements BrowserInterface {
|
|
|
36
36
|
* @param {BaseBrowserOptions} [options] - Configuration options
|
|
37
37
|
*/
|
|
38
38
|
constructor(options?: BaseBrowserOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Check if the browser instance is active and responding
|
|
41
|
+
* @returns {Promise<boolean>} True if browser is active, false otherwise
|
|
42
|
+
*/
|
|
43
|
+
isBrowserAlive(): Promise<boolean>;
|
|
39
44
|
/**
|
|
40
45
|
* Get the underlying Puppeteer browser instance
|
|
41
46
|
* @throws Error if browser is not launched
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-browser.d.ts","sourceRoot":"","sources":["../src/base-browser.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAiB,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,IAAI,EACL,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,8BAAsB,WAAY,YAAW,gBAAgB;IAC3D;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAQ;IAEnD;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEzC;;;OAGG;gBACS,OAAO,CAAC,EAAE,kBAAkB;IAKxC;;;;;OAKG;IACH,UAAU,IAAI,SAAS,CAAC,OAAO;IAO/B;;;;OAIG;cACa,iBAAiB;IAwBjC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAEvD;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B;;;;;;;;OAQG;IACG,iBAAiB,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,CAAC,EACxC,OAAO,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,GACtC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAkCpB;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"base-browser.d.ts","sourceRoot":"","sources":["../src/base-browser.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAiB,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,IAAI,EACL,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,8BAAsB,WAAY,YAAW,gBAAgB;IAC3D;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAQ;IAEnD;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAEzC;;;OAGG;gBACS,OAAO,CAAC,EAAE,kBAAkB;IAKxC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAiBxC;;;;;OAKG;IACH,UAAU,IAAI,SAAS,CAAC,OAAO;IAO/B;;;;OAIG;cACa,iBAAiB;IAwBjC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAEvD;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B;;;;;;;;OAQG;IACG,iBAAiB,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,CAAC,EACxC,OAAO,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,GACtC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAkCpB;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC;;;;;OAKG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAuCrC"}
|
package/dist/base-browser.js
CHANGED
|
@@ -42,6 +42,18 @@ function _define_property(obj, key, value) {
|
|
|
42
42
|
return obj;
|
|
43
43
|
}
|
|
44
44
|
class BaseBrowser {
|
|
45
|
+
async isBrowserAlive() {
|
|
46
|
+
if (!this.browser) return false;
|
|
47
|
+
try {
|
|
48
|
+
const version = await this.browser.version();
|
|
49
|
+
this.logger.info('Browser version:', version);
|
|
50
|
+
return true;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
this.logger.warn('Browser instance is no longer active:', error);
|
|
53
|
+
this.browser = null;
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
45
57
|
getBrowser() {
|
|
46
58
|
if (!this.browser) throw new Error('Browser not launched');
|
|
47
59
|
return this.browser;
|
package/dist/base-browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-browser.js","sources":["webpack://@agent-infra/browser/./src/base-browser.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/*\n * Copyright (c) 2025 Bytedance, Inc. and its affiliates.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport * as puppeteer from 'puppeteer-core';\nimport { Logger, defaultLogger } from '@agent-infra/logger';\nimport {\n BrowserInterface,\n EvaluateOnNewPageOptions,\n LaunchOptions,\n Page,\n} from './types';\n\n/**\n * Configuration options for the BaseBrowser class\n * @interface BaseBrowserOptions\n * @property {Logger} [logger] - Custom logger instance to use for browser logging\n */\nexport interface BaseBrowserOptions {\n logger?: Logger;\n}\n\n/**\n * Abstract base class that implements common browser automation functionality\n * Provides a foundation for specific browser implementations with shared capabilities\n * @abstract\n * @implements {BrowserInterface}\n */\nexport abstract class BaseBrowser implements BrowserInterface {\n /**\n * The underlying Puppeteer browser instance\n * @protected\n */\n protected browser: puppeteer.Browser | null = null;\n\n /**\n * Logger instance for browser-related logging\n * @protected\n */\n protected logger: Logger;\n\n /**\n * Reference to the currently active browser page\n * @protected\n */\n protected activePage: Page | null = null;\n\n /**\n * Creates an instance of BaseBrowser\n * @param {BaseBrowserOptions} [options] - Configuration options\n */\n constructor(options?: BaseBrowserOptions) {\n this.logger = options?.logger ?? defaultLogger;\n this.logger.info('Browser Options:', options);\n }\n\n /**\n * Get the underlying Puppeteer browser instance\n * @throws Error if browser is not launched\n\n * @returns {puppeteer.Browser} Puppeteer browser instance\n */\n getBrowser(): puppeteer.Browser {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n return this.browser;\n }\n\n /**\n * Sets up listeners for browser page events\n * Tracks page creation and updates active page reference\n * @protected\n */\n protected async setupPageListener() {\n if (!this.browser) return;\n\n this.browser.on('targetcreated', async (target) => {\n const page = await target.page();\n if (page) {\n this.logger.info('New page created:', await page.url());\n this.activePage = page;\n\n page.once('close', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n\n page.once('error', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n }\n });\n }\n\n /**\n * Launches the browser with specified options\n * @abstract\n * @param {LaunchOptions} [options] - Browser launch configuration options\n * @returns {Promise<void>} Promise that resolves when browser is launched\n */\n abstract launch(options?: LaunchOptions): Promise<void>;\n\n /**\n * Closes the browser instance and cleans up resources\n * @returns {Promise<void>} Promise that resolves when browser is closed\n * @throws {Error} If browser fails to close properly\n */\n async close(): Promise<void> {\n this.logger.info('Closing browser');\n try {\n await this.browser?.close();\n this.browser = null;\n this.logger.success('Browser closed successfully');\n } catch (error) {\n this.logger.error('Failed to close browser:', error);\n throw error;\n }\n }\n\n /**\n * Creates a new page, navigates to the specified URL, executes a function in the page context, and returns the result\n * This method is inspired and modified from https://github.com/egoist/local-web-search/blob/04608ed09aa103e2fff6402c72ca12edfb692d19/src/browser.ts#L74\n * @template T - Type of parameters passed to the page function\n * @template R - Return type of the page function\n * @param {EvaluateOnNewPageOptions<T, R>} options - Configuration options for the page evaluation\n * @returns {Promise<R | null>} Promise resolving to the result of the page function or null\n * @throws {Error} If page creation or evaluation fails\n */\n async evaluateOnNewPage<T extends any[], R>(\n options: EvaluateOnNewPageOptions<T, R>,\n ): Promise<R | null> {\n const {\n url,\n pageFunction,\n pageFunctionParams,\n beforePageLoad,\n afterPageLoad,\n beforeSendResult,\n waitForOptions,\n } = options;\n const page = await this.browser!.newPage();\n try {\n await beforePageLoad?.(page);\n await page.goto(url, {\n waitUntil: 'networkidle2',\n ...waitForOptions,\n });\n await afterPageLoad?.(page);\n const _window = await page.evaluateHandle(() => window);\n const result = await page.evaluate(\n pageFunction,\n _window,\n ...pageFunctionParams,\n );\n await beforeSendResult?.(page, result);\n await _window.dispose();\n await page.close();\n return result;\n } catch (error) {\n await page.close();\n throw error;\n }\n }\n\n /**\n * Creates a new browser page\n * @returns {Promise<Page>} Promise resolving to the newly created page\n * @throws {Error} If browser is not launched or page creation fails\n */\n async createPage(): Promise<Page> {\n if (!this.browser) {\n this.logger.error('No active browser');\n throw new Error('Browser not launched');\n }\n const page = await this.browser.newPage();\n return page;\n }\n\n /**\n * Gets the currently active page or finds an active page if none is currently tracked\n * If no active pages exist, creates a new page\n * @returns {Promise<Page>} Promise resolving to the active page\n * @throws {Error} If browser is not launched or no active page can be found/created\n */\n async getActivePage(): Promise<Page> {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n\n // If activePage exists and is still available, return directly\n if (this.activePage) {\n try {\n // Verify that the page is still available\n await this.activePage.evaluate(() => document.readyState);\n return this.activePage;\n } catch (e) {\n this.logger.warn('Active page no longer available:', e);\n this.activePage = null;\n }\n }\n\n // Get all pages and find the last active page\n const pages = await this.browser.pages();\n\n if (pages.length === 0) {\n this.activePage = await this.createPage();\n return this.activePage;\n }\n\n // Find the last responding page\n for (let i = pages.length - 1; i >= 0; i--) {\n const page = pages[i];\n try {\n await page.evaluate(() => document.readyState);\n this.activePage = page;\n return page;\n } catch (e) {\n continue;\n }\n }\n\n throw new Error('No active page found');\n }\n}\n"],"names":["BaseBrowser","Error","target","page","_this_browser","error","options","url","pageFunction","pageFunctionParams","beforePageLoad","afterPageLoad","beforeSendResult","waitForOptions","_window","window","result","document","e","pages","i","defaultLogger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base-browser.js","sources":["webpack://@agent-infra/browser/./src/base-browser.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/*\n * Copyright (c) 2025 Bytedance, Inc. and its affiliates.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport * as puppeteer from 'puppeteer-core';\nimport { Logger, defaultLogger } from '@agent-infra/logger';\nimport {\n BrowserInterface,\n EvaluateOnNewPageOptions,\n LaunchOptions,\n Page,\n} from './types';\n\n/**\n * Configuration options for the BaseBrowser class\n * @interface BaseBrowserOptions\n * @property {Logger} [logger] - Custom logger instance to use for browser logging\n */\nexport interface BaseBrowserOptions {\n logger?: Logger;\n}\n\n/**\n * Abstract base class that implements common browser automation functionality\n * Provides a foundation for specific browser implementations with shared capabilities\n * @abstract\n * @implements {BrowserInterface}\n */\nexport abstract class BaseBrowser implements BrowserInterface {\n /**\n * The underlying Puppeteer browser instance\n * @protected\n */\n protected browser: puppeteer.Browser | null = null;\n\n /**\n * Logger instance for browser-related logging\n * @protected\n */\n protected logger: Logger;\n\n /**\n * Reference to the currently active browser page\n * @protected\n */\n protected activePage: Page | null = null;\n\n /**\n * Creates an instance of BaseBrowser\n * @param {BaseBrowserOptions} [options] - Configuration options\n */\n constructor(options?: BaseBrowserOptions) {\n this.logger = options?.logger ?? defaultLogger;\n this.logger.info('Browser Options:', options);\n }\n\n /**\n * Check if the browser instance is active and responding\n * @returns {Promise<boolean>} True if browser is active, false otherwise\n */\n async isBrowserAlive(): Promise<boolean> {\n if (!this.browser) {\n return false;\n }\n\n try {\n // Try to get browser version to check if it's still responding\n const version = await this.browser.version();\n this.logger.info('Browser version:', version);\n return true;\n } catch (error) {\n this.logger.warn('Browser instance is no longer active:', error);\n this.browser = null;\n return false;\n }\n }\n\n /**\n * Get the underlying Puppeteer browser instance\n * @throws Error if browser is not launched\n\n * @returns {puppeteer.Browser} Puppeteer browser instance\n */\n getBrowser(): puppeteer.Browser {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n return this.browser;\n }\n\n /**\n * Sets up listeners for browser page events\n * Tracks page creation and updates active page reference\n * @protected\n */\n protected async setupPageListener() {\n if (!this.browser) return;\n\n this.browser.on('targetcreated', async (target) => {\n const page = await target.page();\n if (page) {\n this.logger.info('New page created:', await page.url());\n this.activePage = page;\n\n page.once('close', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n\n page.once('error', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n }\n });\n }\n\n /**\n * Launches the browser with specified options\n * @abstract\n * @param {LaunchOptions} [options] - Browser launch configuration options\n * @returns {Promise<void>} Promise that resolves when browser is launched\n */\n abstract launch(options?: LaunchOptions): Promise<void>;\n\n /**\n * Closes the browser instance and cleans up resources\n * @returns {Promise<void>} Promise that resolves when browser is closed\n * @throws {Error} If browser fails to close properly\n */\n async close(): Promise<void> {\n this.logger.info('Closing browser');\n try {\n await this.browser?.close();\n this.browser = null;\n this.logger.success('Browser closed successfully');\n } catch (error) {\n this.logger.error('Failed to close browser:', error);\n throw error;\n }\n }\n\n /**\n * Creates a new page, navigates to the specified URL, executes a function in the page context, and returns the result\n * This method is inspired and modified from https://github.com/egoist/local-web-search/blob/04608ed09aa103e2fff6402c72ca12edfb692d19/src/browser.ts#L74\n * @template T - Type of parameters passed to the page function\n * @template R - Return type of the page function\n * @param {EvaluateOnNewPageOptions<T, R>} options - Configuration options for the page evaluation\n * @returns {Promise<R | null>} Promise resolving to the result of the page function or null\n * @throws {Error} If page creation or evaluation fails\n */\n async evaluateOnNewPage<T extends any[], R>(\n options: EvaluateOnNewPageOptions<T, R>,\n ): Promise<R | null> {\n const {\n url,\n pageFunction,\n pageFunctionParams,\n beforePageLoad,\n afterPageLoad,\n beforeSendResult,\n waitForOptions,\n } = options;\n const page = await this.browser!.newPage();\n try {\n await beforePageLoad?.(page);\n await page.goto(url, {\n waitUntil: 'networkidle2',\n ...waitForOptions,\n });\n await afterPageLoad?.(page);\n const _window = await page.evaluateHandle(() => window);\n const result = await page.evaluate(\n pageFunction,\n _window,\n ...pageFunctionParams,\n );\n await beforeSendResult?.(page, result);\n await _window.dispose();\n await page.close();\n return result;\n } catch (error) {\n await page.close();\n throw error;\n }\n }\n\n /**\n * Creates a new browser page\n * @returns {Promise<Page>} Promise resolving to the newly created page\n * @throws {Error} If browser is not launched or page creation fails\n */\n async createPage(): Promise<Page> {\n if (!this.browser) {\n this.logger.error('No active browser');\n throw new Error('Browser not launched');\n }\n\n const page = await this.browser.newPage();\n return page;\n }\n\n /**\n * Gets the currently active page or finds an active page if none is currently tracked\n * If no active pages exist, creates a new page\n * @returns {Promise<Page>} Promise resolving to the active page\n * @throws {Error} If browser is not launched or no active page can be found/created\n */\n async getActivePage(): Promise<Page> {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n\n // If activePage exists and is still available, return directly\n if (this.activePage) {\n try {\n // Verify that the page is still available\n await this.activePage.evaluate(() => document.readyState);\n return this.activePage;\n } catch (e) {\n this.logger.warn('Active page no longer available:', e);\n this.activePage = null;\n }\n }\n\n // Get all pages and find the last active page\n const pages = await this.browser.pages();\n\n if (pages.length === 0) {\n this.activePage = await this.createPage();\n return this.activePage;\n }\n\n // Find the last responding page\n for (let i = pages.length - 1; i >= 0; i--) {\n const page = pages[i];\n try {\n await page.evaluate(() => document.readyState);\n this.activePage = page;\n return page;\n } catch (e) {\n continue;\n }\n }\n\n throw new Error('No active page found');\n }\n}\n"],"names":["BaseBrowser","version","error","Error","target","page","_this_browser","options","url","pageFunction","pageFunctionParams","beforePageLoad","afterPageLoad","beforeSendResult","waitForOptions","_window","window","result","document","e","pages","i","defaultLogger"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIC;;;;;;;;;;AAyBM,MAAeA;IAgCpB,MAAM,iBAAmC;QACvC,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,OAAO;QAGT,IAAI;YAEF,MAAMC,UAAU,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO;YAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoBA;YACrC,OAAO;QACT,EAAE,OAAOC,OAAO;YACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyCA;YAC1D,IAAI,CAAC,OAAO,GAAG;YACf,OAAO;QACT;IACF;IAQA,aAAgC;QAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAIC,MAAM;QAElB,OAAO,IAAI,CAAC,OAAO;IACrB;IAOA,MAAgB,oBAAoB;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QAEnB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,iBAAiB,OAAOC;YACtC,MAAMC,OAAO,MAAMD,OAAO,IAAI;YAC9B,IAAIC,MAAM;gBACR,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,MAAMA,KAAK,GAAG;gBACpD,IAAI,CAAC,UAAU,GAAGA;gBAElBA,KAAK,IAAI,CAAC,SAAS;oBACjB,IAAI,IAAI,CAAC,UAAU,KAAKA,MACtB,IAAI,CAAC,UAAU,GAAG;gBAEtB;gBAEAA,KAAK,IAAI,CAAC,SAAS;oBACjB,IAAI,IAAI,CAAC,UAAU,KAAKA,MACtB,IAAI,CAAC,UAAU,GAAG;gBAEtB;YACF;QACF;IACF;IAeA,MAAM,QAAuB;QAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QACjB,IAAI;gBACIC;YAAN,OAAkB,SAAZA,CAAAA,gBAAAA,IAAI,CAAC,OAAO,AAAD,KAAXA,AAAAA,KAAAA,MAAAA,gBAAAA,KAAAA,IAAAA,cAAc,KAAK,EAAC;YAC1B,IAAI,CAAC,OAAO,GAAG;YACf,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QACtB,EAAE,OAAOJ,OAAO;YACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4BA;YAC9C,MAAMA;QACR;IACF;IAWA,MAAM,kBACJK,OAAuC,EACpB;QACnB,MAAM,EACJC,GAAG,EACHC,YAAY,EACZC,kBAAkB,EAClBC,cAAc,EACdC,aAAa,EACbC,gBAAgB,EAChBC,cAAc,EACf,GAAGP;QACJ,MAAMF,OAAO,MAAM,IAAI,CAAC,OAAO,CAAE,OAAO;QACxC,IAAI;YACF,MAAMM,CAAAA,QAAAA,iBAAAA,KAAAA,IAAAA,eAAiBN,KAAI;YAC3B,MAAMA,KAAK,IAAI,CAACG,KAAK;gBACnB,WAAW;gBACX,GAAGM,cAAc;YACnB;YACA,MAAMF,CAAAA,QAAAA,gBAAAA,KAAAA,IAAAA,cAAgBP,KAAI;YAC1B,MAAMU,UAAU,MAAMV,KAAK,cAAc,CAAC,IAAMW;YAChD,MAAMC,SAAS,MAAMZ,KAAK,QAAQ,CAChCI,cACAM,YACGL;YAEL,MAAMG,CAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,iBAAmBR,MAAMY,OAAM;YACrC,MAAMF,QAAQ,OAAO;YACrB,MAAMV,KAAK,KAAK;YAChB,OAAOY;QACT,EAAE,OAAOf,OAAO;YACd,MAAMG,KAAK,KAAK;YAChB,MAAMH;QACR;IACF;IAOA,MAAM,aAA4B;QAChC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAClB,MAAM,IAAIC,MAAM;QAClB;QAEA,MAAME,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO;QACvC,OAAOA;IACT;IAQA,MAAM,gBAA+B;QACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAIF,MAAM;QAIlB,IAAI,IAAI,CAAC,UAAU,EACjB,IAAI;YAEF,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAMe,SAAS,UAAU;YACxD,OAAO,IAAI,CAAC,UAAU;QACxB,EAAE,OAAOC,GAAG;YACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoCA;YACrD,IAAI,CAAC,UAAU,GAAG;QACpB;QAIF,MAAMC,QAAQ,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK;QAEtC,IAAIA,AAAiB,MAAjBA,MAAM,MAAM,EAAQ;YACtB,IAAI,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU;YACvC,OAAO,IAAI,CAAC,UAAU;QACxB;QAGA,IAAK,IAAIC,IAAID,MAAM,MAAM,GAAG,GAAGC,KAAK,GAAGA,IAAK;YAC1C,MAAMhB,OAAOe,KAAK,CAACC,EAAE;YACrB,IAAI;gBACF,MAAMhB,KAAK,QAAQ,CAAC,IAAMa,SAAS,UAAU;gBAC7C,IAAI,CAAC,UAAU,GAAGb;gBAClB,OAAOA;YACT,EAAE,OAAOc,GAAG;gBACV;YACF;QACF;QAEA,MAAM,IAAIhB,MAAM;IAClB;IArMA,YAAYI,OAA4B,CAAE;QAlB1C,uBAAU,WAAoC;QAM9C,uBAAU,UAAV;QAMA,uBAAU,cAA0B;QAOlC,IAAI,CAAC,MAAM,GAAGA,AAAAA,CAAAA,QAAAA,UAAAA,KAAAA,IAAAA,QAAS,MAAM,AAAD,KAAKe,uBAAAA,aAAaA;QAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoBf;IACvC;AAmMF"}
|
package/dist/base-browser.mjs
CHANGED
|
@@ -14,6 +14,18 @@ function _define_property(obj, key, value) {
|
|
|
14
14
|
return obj;
|
|
15
15
|
}
|
|
16
16
|
class BaseBrowser {
|
|
17
|
+
async isBrowserAlive() {
|
|
18
|
+
if (!this.browser) return false;
|
|
19
|
+
try {
|
|
20
|
+
const version = await this.browser.version();
|
|
21
|
+
this.logger.info('Browser version:', version);
|
|
22
|
+
return true;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
this.logger.warn('Browser instance is no longer active:', error);
|
|
25
|
+
this.browser = null;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
17
29
|
getBrowser() {
|
|
18
30
|
if (!this.browser) throw new Error('Browser not launched');
|
|
19
31
|
return this.browser;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-browser.mjs","sources":["webpack://@agent-infra/browser/./src/base-browser.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/*\n * Copyright (c) 2025 Bytedance, Inc. and its affiliates.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport * as puppeteer from 'puppeteer-core';\nimport { Logger, defaultLogger } from '@agent-infra/logger';\nimport {\n BrowserInterface,\n EvaluateOnNewPageOptions,\n LaunchOptions,\n Page,\n} from './types';\n\n/**\n * Configuration options for the BaseBrowser class\n * @interface BaseBrowserOptions\n * @property {Logger} [logger] - Custom logger instance to use for browser logging\n */\nexport interface BaseBrowserOptions {\n logger?: Logger;\n}\n\n/**\n * Abstract base class that implements common browser automation functionality\n * Provides a foundation for specific browser implementations with shared capabilities\n * @abstract\n * @implements {BrowserInterface}\n */\nexport abstract class BaseBrowser implements BrowserInterface {\n /**\n * The underlying Puppeteer browser instance\n * @protected\n */\n protected browser: puppeteer.Browser | null = null;\n\n /**\n * Logger instance for browser-related logging\n * @protected\n */\n protected logger: Logger;\n\n /**\n * Reference to the currently active browser page\n * @protected\n */\n protected activePage: Page | null = null;\n\n /**\n * Creates an instance of BaseBrowser\n * @param {BaseBrowserOptions} [options] - Configuration options\n */\n constructor(options?: BaseBrowserOptions) {\n this.logger = options?.logger ?? defaultLogger;\n this.logger.info('Browser Options:', options);\n }\n\n /**\n * Get the underlying Puppeteer browser instance\n * @throws Error if browser is not launched\n\n * @returns {puppeteer.Browser} Puppeteer browser instance\n */\n getBrowser(): puppeteer.Browser {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n return this.browser;\n }\n\n /**\n * Sets up listeners for browser page events\n * Tracks page creation and updates active page reference\n * @protected\n */\n protected async setupPageListener() {\n if (!this.browser) return;\n\n this.browser.on('targetcreated', async (target) => {\n const page = await target.page();\n if (page) {\n this.logger.info('New page created:', await page.url());\n this.activePage = page;\n\n page.once('close', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n\n page.once('error', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n }\n });\n }\n\n /**\n * Launches the browser with specified options\n * @abstract\n * @param {LaunchOptions} [options] - Browser launch configuration options\n * @returns {Promise<void>} Promise that resolves when browser is launched\n */\n abstract launch(options?: LaunchOptions): Promise<void>;\n\n /**\n * Closes the browser instance and cleans up resources\n * @returns {Promise<void>} Promise that resolves when browser is closed\n * @throws {Error} If browser fails to close properly\n */\n async close(): Promise<void> {\n this.logger.info('Closing browser');\n try {\n await this.browser?.close();\n this.browser = null;\n this.logger.success('Browser closed successfully');\n } catch (error) {\n this.logger.error('Failed to close browser:', error);\n throw error;\n }\n }\n\n /**\n * Creates a new page, navigates to the specified URL, executes a function in the page context, and returns the result\n * This method is inspired and modified from https://github.com/egoist/local-web-search/blob/04608ed09aa103e2fff6402c72ca12edfb692d19/src/browser.ts#L74\n * @template T - Type of parameters passed to the page function\n * @template R - Return type of the page function\n * @param {EvaluateOnNewPageOptions<T, R>} options - Configuration options for the page evaluation\n * @returns {Promise<R | null>} Promise resolving to the result of the page function or null\n * @throws {Error} If page creation or evaluation fails\n */\n async evaluateOnNewPage<T extends any[], R>(\n options: EvaluateOnNewPageOptions<T, R>,\n ): Promise<R | null> {\n const {\n url,\n pageFunction,\n pageFunctionParams,\n beforePageLoad,\n afterPageLoad,\n beforeSendResult,\n waitForOptions,\n } = options;\n const page = await this.browser!.newPage();\n try {\n await beforePageLoad?.(page);\n await page.goto(url, {\n waitUntil: 'networkidle2',\n ...waitForOptions,\n });\n await afterPageLoad?.(page);\n const _window = await page.evaluateHandle(() => window);\n const result = await page.evaluate(\n pageFunction,\n _window,\n ...pageFunctionParams,\n );\n await beforeSendResult?.(page, result);\n await _window.dispose();\n await page.close();\n return result;\n } catch (error) {\n await page.close();\n throw error;\n }\n }\n\n /**\n * Creates a new browser page\n * @returns {Promise<Page>} Promise resolving to the newly created page\n * @throws {Error} If browser is not launched or page creation fails\n */\n async createPage(): Promise<Page> {\n if (!this.browser) {\n this.logger.error('No active browser');\n throw new Error('Browser not launched');\n }\n const page = await this.browser.newPage();\n return page;\n }\n\n /**\n * Gets the currently active page or finds an active page if none is currently tracked\n * If no active pages exist, creates a new page\n * @returns {Promise<Page>} Promise resolving to the active page\n * @throws {Error} If browser is not launched or no active page can be found/created\n */\n async getActivePage(): Promise<Page> {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n\n // If activePage exists and is still available, return directly\n if (this.activePage) {\n try {\n // Verify that the page is still available\n await this.activePage.evaluate(() => document.readyState);\n return this.activePage;\n } catch (e) {\n this.logger.warn('Active page no longer available:', e);\n this.activePage = null;\n }\n }\n\n // Get all pages and find the last active page\n const pages = await this.browser.pages();\n\n if (pages.length === 0) {\n this.activePage = await this.createPage();\n return this.activePage;\n }\n\n // Find the last responding page\n for (let i = pages.length - 1; i >= 0; i--) {\n const page = pages[i];\n try {\n await page.evaluate(() => document.readyState);\n this.activePage = page;\n return page;\n } catch (e) {\n continue;\n }\n }\n\n throw new Error('No active page found');\n }\n}\n"],"names":["BaseBrowser","Error","target","page","_this_browser","error","options","url","pageFunction","pageFunctionParams","beforePageLoad","afterPageLoad","beforeSendResult","waitForOptions","_window","window","result","document","e","pages","i","defaultLogger"],"mappings":";;;;;AAIC;;;;;;;;;;AAyBM,MAAeA;IAkCpB,aAAgC;QAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAIC,MAAM;QAElB,OAAO,IAAI,CAAC,OAAO;IACrB;IAOA,MAAgB,oBAAoB;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QAEnB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,iBAAiB,OAAOC;YACtC,MAAMC,OAAO,MAAMD,OAAO,IAAI;YAC9B,IAAIC,MAAM;gBACR,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,MAAMA,KAAK,GAAG;gBACpD,IAAI,CAAC,UAAU,GAAGA;gBAElBA,KAAK,IAAI,CAAC,SAAS;oBACjB,IAAI,IAAI,CAAC,UAAU,KAAKA,MACtB,IAAI,CAAC,UAAU,GAAG;gBAEtB;gBAEAA,KAAK,IAAI,CAAC,SAAS;oBACjB,IAAI,IAAI,CAAC,UAAU,KAAKA,MACtB,IAAI,CAAC,UAAU,GAAG;gBAEtB;YACF;QACF;IACF;IAeA,MAAM,QAAuB;QAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QACjB,IAAI;gBACIC;YAAN,OAAkB,SAAZA,CAAAA,gBAAAA,IAAI,CAAC,OAAO,AAAD,KAAXA,AAAAA,KAAAA,MAAAA,gBAAAA,KAAAA,IAAAA,cAAc,KAAK,EAAC;YAC1B,IAAI,CAAC,OAAO,GAAG;YACf,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QACtB,EAAE,OAAOC,OAAO;YACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4BA;YAC9C,MAAMA;QACR;IACF;IAWA,MAAM,kBACJC,OAAuC,EACpB;QACnB,MAAM,EACJC,GAAG,EACHC,YAAY,EACZC,kBAAkB,EAClBC,cAAc,EACdC,aAAa,EACbC,gBAAgB,EAChBC,cAAc,EACf,GAAGP;QACJ,MAAMH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAE,OAAO;QACxC,IAAI;YACF,MAAMO,CAAAA,QAAAA,iBAAAA,KAAAA,IAAAA,eAAiBP,KAAI;YAC3B,MAAMA,KAAK,IAAI,CAACI,KAAK;gBACnB,WAAW;gBACX,GAAGM,cAAc;YACnB;YACA,MAAMF,CAAAA,QAAAA,gBAAAA,KAAAA,IAAAA,cAAgBR,KAAI;YAC1B,MAAMW,UAAU,MAAMX,KAAK,cAAc,CAAC,IAAMY;YAChD,MAAMC,SAAS,MAAMb,KAAK,QAAQ,CAChCK,cACAM,YACGL;YAEL,MAAMG,CAAAA,QAAAA,mBAAAA,KAAAA,IAAAA,iBAAmBT,MAAMa,OAAM;YACrC,MAAMF,QAAQ,OAAO;YACrB,MAAMX,KAAK,KAAK;YAChB,OAAOa;QACT,EAAE,OAAOX,OAAO;YACd,MAAMF,KAAK,KAAK;YAChB,MAAME;QACR;IACF;IAOA,MAAM,aAA4B;QAChC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAClB,MAAM,IAAIJ,MAAM;QAClB;QACA,MAAME,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO;QACvC,OAAOA;IACT;IAQA,MAAM,gBAA+B;QACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EACf,MAAM,IAAIF,MAAM;QAIlB,IAAI,IAAI,CAAC,UAAU,EACjB,IAAI;YAEF,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAMgB,SAAS,UAAU;YACxD,OAAO,IAAI,CAAC,UAAU;QACxB,EAAE,OAAOC,GAAG;YACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoCA;YACrD,IAAI,CAAC,UAAU,GAAG;QACpB;QAIF,MAAMC,QAAQ,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK;QAEtC,IAAIA,AAAiB,MAAjBA,MAAM,MAAM,EAAQ;YACtB,IAAI,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU;YACvC,OAAO,IAAI,CAAC,UAAU;QACxB;QAGA,IAAK,IAAIC,IAAID,MAAM,MAAM,GAAG,GAAGC,KAAK,GAAGA,IAAK;YAC1C,MAAMjB,OAAOgB,KAAK,CAACC,EAAE;YACrB,IAAI;gBACF,MAAMjB,KAAK,QAAQ,CAAC,IAAMc,SAAS,UAAU;gBAC7C,IAAI,CAAC,UAAU,GAAGd;gBAClB,OAAOA;YACT,EAAE,OAAOe,GAAG;gBACV;YACF;QACF;QAEA,MAAM,IAAIjB,MAAM;IAClB;IA/KA,YAAYK,OAA4B,CAAE;QAlB1C,uBAAU,WAAoC;QAM9C,uBAAU,UAAV;QAMA,uBAAU,cAA0B;QAOlC,IAAI,CAAC,MAAM,GAAGA,AAAAA,CAAAA,QAAAA,UAAAA,KAAAA,IAAAA,QAAS,MAAM,AAAD,KAAKe,yDAAAA,aAAaA;QAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoBf;IACvC;AA6KF"}
|
|
1
|
+
{"version":3,"file":"base-browser.mjs","sources":["webpack://@agent-infra/browser/./src/base-browser.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/*\n * Copyright (c) 2025 Bytedance, Inc. and its affiliates.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport * as puppeteer from 'puppeteer-core';\nimport { Logger, defaultLogger } from '@agent-infra/logger';\nimport {\n BrowserInterface,\n EvaluateOnNewPageOptions,\n LaunchOptions,\n Page,\n} from './types';\n\n/**\n * Configuration options for the BaseBrowser class\n * @interface BaseBrowserOptions\n * @property {Logger} [logger] - Custom logger instance to use for browser logging\n */\nexport interface BaseBrowserOptions {\n logger?: Logger;\n}\n\n/**\n * Abstract base class that implements common browser automation functionality\n * Provides a foundation for specific browser implementations with shared capabilities\n * @abstract\n * @implements {BrowserInterface}\n */\nexport abstract class BaseBrowser implements BrowserInterface {\n /**\n * The underlying Puppeteer browser instance\n * @protected\n */\n protected browser: puppeteer.Browser | null = null;\n\n /**\n * Logger instance for browser-related logging\n * @protected\n */\n protected logger: Logger;\n\n /**\n * Reference to the currently active browser page\n * @protected\n */\n protected activePage: Page | null = null;\n\n /**\n * Creates an instance of BaseBrowser\n * @param {BaseBrowserOptions} [options] - Configuration options\n */\n constructor(options?: BaseBrowserOptions) {\n this.logger = options?.logger ?? defaultLogger;\n this.logger.info('Browser Options:', options);\n }\n\n /**\n * Check if the browser instance is active and responding\n * @returns {Promise<boolean>} True if browser is active, false otherwise\n */\n async isBrowserAlive(): Promise<boolean> {\n if (!this.browser) {\n return false;\n }\n\n try {\n // Try to get browser version to check if it's still responding\n const version = await this.browser.version();\n this.logger.info('Browser version:', version);\n return true;\n } catch (error) {\n this.logger.warn('Browser instance is no longer active:', error);\n this.browser = null;\n return false;\n }\n }\n\n /**\n * Get the underlying Puppeteer browser instance\n * @throws Error if browser is not launched\n\n * @returns {puppeteer.Browser} Puppeteer browser instance\n */\n getBrowser(): puppeteer.Browser {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n return this.browser;\n }\n\n /**\n * Sets up listeners for browser page events\n * Tracks page creation and updates active page reference\n * @protected\n */\n protected async setupPageListener() {\n if (!this.browser) return;\n\n this.browser.on('targetcreated', async (target) => {\n const page = await target.page();\n if (page) {\n this.logger.info('New page created:', await page.url());\n this.activePage = page;\n\n page.once('close', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n\n page.once('error', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n }\n });\n }\n\n /**\n * Launches the browser with specified options\n * @abstract\n * @param {LaunchOptions} [options] - Browser launch configuration options\n * @returns {Promise<void>} Promise that resolves when browser is launched\n */\n abstract launch(options?: LaunchOptions): Promise<void>;\n\n /**\n * Closes the browser instance and cleans up resources\n * @returns {Promise<void>} Promise that resolves when browser is closed\n * @throws {Error} If browser fails to close properly\n */\n async close(): Promise<void> {\n this.logger.info('Closing browser');\n try {\n await this.browser?.close();\n this.browser = null;\n this.logger.success('Browser closed successfully');\n } catch (error) {\n this.logger.error('Failed to close browser:', error);\n throw error;\n }\n }\n\n /**\n * Creates a new page, navigates to the specified URL, executes a function in the page context, and returns the result\n * This method is inspired and modified from https://github.com/egoist/local-web-search/blob/04608ed09aa103e2fff6402c72ca12edfb692d19/src/browser.ts#L74\n * @template T - Type of parameters passed to the page function\n * @template R - Return type of the page function\n * @param {EvaluateOnNewPageOptions<T, R>} options - Configuration options for the page evaluation\n * @returns {Promise<R | null>} Promise resolving to the result of the page function or null\n * @throws {Error} If page creation or evaluation fails\n */\n async evaluateOnNewPage<T extends any[], R>(\n options: EvaluateOnNewPageOptions<T, R>,\n ): Promise<R | null> {\n const {\n url,\n pageFunction,\n pageFunctionParams,\n beforePageLoad,\n afterPageLoad,\n beforeSendResult,\n waitForOptions,\n } = options;\n const page = await this.browser!.newPage();\n try {\n await beforePageLoad?.(page);\n await page.goto(url, {\n waitUntil: 'networkidle2',\n ...waitForOptions,\n });\n await afterPageLoad?.(page);\n const _window = await page.evaluateHandle(() => window);\n const result = await page.evaluate(\n pageFunction,\n _window,\n ...pageFunctionParams,\n );\n await beforeSendResult?.(page, result);\n await _window.dispose();\n await page.close();\n return result;\n } catch (error) {\n await page.close();\n throw error;\n }\n }\n\n /**\n * Creates a new browser page\n * @returns {Promise<Page>} Promise resolving to the newly created page\n * @throws {Error} If browser is not launched or page creation fails\n */\n async createPage(): Promise<Page> {\n if (!this.browser) {\n this.logger.error('No active browser');\n throw new Error('Browser not launched');\n }\n\n const page = await this.browser.newPage();\n return page;\n }\n\n /**\n * Gets the currently active page or finds an active page if none is currently tracked\n * If no active pages exist, creates a new page\n * @returns {Promise<Page>} Promise resolving to the active page\n * @throws {Error} If browser is not launched or no active page can be found/created\n */\n async getActivePage(): Promise<Page> {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n\n // If activePage exists and is still available, return directly\n if (this.activePage) {\n try {\n // Verify that the page is still available\n await this.activePage.evaluate(() => document.readyState);\n return this.activePage;\n } catch (e) {\n this.logger.warn('Active page no longer available:', e);\n this.activePage = null;\n }\n }\n\n // Get all pages and find the last active page\n const pages = await this.browser.pages();\n\n if (pages.length === 0) {\n this.activePage = await this.createPage();\n return this.activePage;\n }\n\n // Find the last responding page\n for (let i = pages.length - 1; i >= 0; i--) {\n const page = pages[i];\n try {\n await page.evaluate(() => document.readyState);\n this.activePage = page;\n return page;\n } catch (e) {\n continue;\n }\n }\n\n throw new Error('No active page found');\n }\n}\n"],"names":["BaseBrowser","version","error","Error","target","page","_this_browser","options","url","pageFunction","pageFunctionParams","beforePageLoad","afterPageLoad","beforeSendResult","waitForOptions","_window","window","result","document","e","pages","i","defaultLogger"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The following code is modified based on
|
|
3
|
+
* https://github.com/shirshak55/edge-paths/blob/master/index.ts
|
|
4
|
+
*
|
|
5
|
+
* MIT Licensed
|
|
6
|
+
* Copyright (c) 2020 Shirshak
|
|
7
|
+
* https://github.com/shirshak55/edge-paths/blob/master/LICENSE
|
|
8
|
+
*/
|
|
9
|
+
export declare function getAnyChromeStable(): string;
|
|
10
|
+
//# sourceMappingURL=chrome-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome-paths.d.ts","sourceRoot":"","sources":["../../src/browser-finder/chrome-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiJH,wBAAgB,kBAAkB,IAAI,MAAM,CAwB3C"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
var __webpack_require__ = {};
|
|
7
|
+
(()=>{
|
|
8
|
+
__webpack_require__.n = (module)=>{
|
|
9
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
10
|
+
__webpack_require__.d(getter, {
|
|
11
|
+
a: getter
|
|
12
|
+
});
|
|
13
|
+
return getter;
|
|
14
|
+
};
|
|
15
|
+
})();
|
|
16
|
+
(()=>{
|
|
17
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
18
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: definition[key]
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
(()=>{
|
|
25
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
26
|
+
})();
|
|
27
|
+
(()=>{
|
|
28
|
+
__webpack_require__.r = function(exports1) {
|
|
29
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
30
|
+
value: 'Module'
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
33
|
+
value: true
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
var __webpack_exports__ = {};
|
|
38
|
+
__webpack_require__.r(__webpack_exports__);
|
|
39
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
40
|
+
getAnyChromeStable: ()=>getAnyChromeStable
|
|
41
|
+
});
|
|
42
|
+
const external_fs_namespaceObject = require("fs");
|
|
43
|
+
const external_path_namespaceObject = require("path");
|
|
44
|
+
const external_which_namespaceObject = require("which");
|
|
45
|
+
var external_which_default = /*#__PURE__*/ __webpack_require__.n(external_which_namespaceObject);
|
|
46
|
+
const platform = process.platform;
|
|
47
|
+
function getChromeOnLinux(list) {
|
|
48
|
+
try {
|
|
49
|
+
for (const name of list){
|
|
50
|
+
const path = external_which_default().sync(name);
|
|
51
|
+
return path;
|
|
52
|
+
}
|
|
53
|
+
} catch (e) {}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
function getChromeOnWindows(name) {
|
|
57
|
+
const suffix = `${external_path_namespaceObject.sep}Google${external_path_namespaceObject.sep}${name}${external_path_namespaceObject.sep}Application${external_path_namespaceObject.sep}chrome.exe`;
|
|
58
|
+
const prefixes = [
|
|
59
|
+
process.env.LOCALAPPDATA,
|
|
60
|
+
process.env.PROGRAMFILES,
|
|
61
|
+
process.env['PROGRAMFILES(X86)']
|
|
62
|
+
].filter(Boolean);
|
|
63
|
+
for (const prefix of prefixes){
|
|
64
|
+
const chrome = (0, external_path_namespaceObject.join)(prefix, suffix);
|
|
65
|
+
if ((0, external_fs_namespaceObject.existsSync)(chrome)) return chrome;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
function getChromeOnDarwin(name) {
|
|
70
|
+
const suffix = `/Applications/${name}.app/Contents/MacOS/${name}`;
|
|
71
|
+
const prefixes = [
|
|
72
|
+
'',
|
|
73
|
+
process.env.HOME
|
|
74
|
+
].filter((item)=>void 0 !== item);
|
|
75
|
+
for (const prefix of prefixes){
|
|
76
|
+
const chromePath = (0, external_path_namespaceObject.join)(prefix, suffix);
|
|
77
|
+
if ((0, external_fs_namespaceObject.existsSync)(chromePath)) return chromePath;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const chromePaths = {
|
|
82
|
+
chrome: {
|
|
83
|
+
linux: ()=>getChromeOnLinux([
|
|
84
|
+
'google-chrome-stable',
|
|
85
|
+
'google-chrome'
|
|
86
|
+
]),
|
|
87
|
+
darwin: ()=>getChromeOnDarwin('Google Chrome'),
|
|
88
|
+
win32: ()=>getChromeOnWindows('Chrome')
|
|
89
|
+
},
|
|
90
|
+
beta: {
|
|
91
|
+
linux: ()=>getChromeOnLinux([
|
|
92
|
+
'google-chrome-beta'
|
|
93
|
+
]),
|
|
94
|
+
darwin: ()=>getChromeOnDarwin('Google Chrome Beta'),
|
|
95
|
+
win32: ()=>getChromeOnWindows('Chrome Beta')
|
|
96
|
+
},
|
|
97
|
+
dev: {
|
|
98
|
+
linux: ()=>getChromeOnLinux([
|
|
99
|
+
'google-chrome-dev'
|
|
100
|
+
]),
|
|
101
|
+
darwin: ()=>getChromeOnDarwin('Google Chrome Dev'),
|
|
102
|
+
win32: ()=>getChromeOnWindows('Chrome Dev')
|
|
103
|
+
},
|
|
104
|
+
canary: {
|
|
105
|
+
linux: ()=>getChromeOnLinux([
|
|
106
|
+
'chromium-browser',
|
|
107
|
+
'chromium'
|
|
108
|
+
]),
|
|
109
|
+
darwin: ()=>getChromeOnDarwin('Google Chrome Canary'),
|
|
110
|
+
win32: ()=>getChromeOnWindows('Chrome SxS')
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
function getChromePath() {
|
|
114
|
+
const chrome = chromePaths.chrome;
|
|
115
|
+
if (platform && Object.keys(chrome).includes(platform)) {
|
|
116
|
+
const pth = chrome[platform]();
|
|
117
|
+
if (pth) return pth;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function getChromeBetaPath() {
|
|
121
|
+
const beta = chromePaths.beta;
|
|
122
|
+
if (platform && Object.keys(beta).includes(platform)) {
|
|
123
|
+
const pth = beta[platform]();
|
|
124
|
+
if (pth) return pth;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function getChromeDevPath() {
|
|
128
|
+
const dev = chromePaths.dev;
|
|
129
|
+
if (platform && Object.keys(dev).includes(platform)) {
|
|
130
|
+
const pth = dev[platform]();
|
|
131
|
+
if (pth) return pth;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function getChromeCanaryPath() {
|
|
135
|
+
const canary = chromePaths.canary;
|
|
136
|
+
if (platform && Object.keys(canary).includes(platform)) {
|
|
137
|
+
const pth = canary[platform]();
|
|
138
|
+
if (pth) return pth;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function getAnyChromeStable() {
|
|
142
|
+
const chrome = getChromePath();
|
|
143
|
+
if (chrome) return chrome;
|
|
144
|
+
const beta = getChromeBetaPath();
|
|
145
|
+
if (beta) return beta;
|
|
146
|
+
const dev = getChromeDevPath();
|
|
147
|
+
if (dev) return dev;
|
|
148
|
+
const canary = getChromeCanaryPath();
|
|
149
|
+
if (canary) return canary;
|
|
150
|
+
const error = new Error('Unable to find any chrome browser.');
|
|
151
|
+
error.name = 'ChromePathsError';
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
var __webpack_export_target__ = exports;
|
|
155
|
+
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
156
|
+
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
|
|
157
|
+
value: true
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
//# sourceMappingURL=chrome-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-finder/chrome-paths.js","sources":["webpack://@agent-infra/browser/./src/browser-finder/chrome-paths.ts"],"sourcesContent":["/**\n * The following code is modified based on\n * https://github.com/shirshak55/edge-paths/blob/master/index.ts\n *\n * MIT Licensed\n * Copyright (c) 2020 Shirshak\n * https://github.com/shirshak55/edge-paths/blob/master/LICENSE\n */\n\n/**\n * Q: Why not use [find-chrome-bin](https://github.com/mbalabash/find-chrome-bin) or [chrome-finder](https://github.com/gwuhaolin/chrome-finder)?\n *\n * A: The `find-chrome-bin` or `chrome-finder` libraries execute `lsregister -dump` under Darwin (macOS),\n * which is a time-consuming operation (taking up to 6 seconds on my computer!).\n * Since this process is performed during the app's startup, such a delay is unacceptable.\n */\nimport { existsSync } from 'fs';\nimport { sep, join } from 'path';\nimport which from 'which';\n\nconst platform = process.platform;\n\nfunction getChromeOnLinux(\n list: (\n | 'google-chrome'\n | 'google-chrome-stable'\n | 'google-chrome-beta'\n | 'google-chrome-dev'\n | 'chromium-browser'\n | 'chromium'\n )[],\n): string | null {\n // TODO: scan desktop installation folders, the `grep` operation can be somewhat time-consuming.\n // https://github.com/mbalabash/find-chrome-bin/blob/main/src/linux/index.js\n try {\n for (const name of list) {\n const path = which.sync(name);\n return path;\n }\n } catch (e) {}\n\n return null;\n}\n\nfunction getChromeOnWindows(\n name: 'Chrome' | 'Chrome Beta' | 'Chrome Dev' | 'Chrome SxS',\n): string | null {\n const suffix = `${sep}Google${sep}${name}${sep}Application${sep}chrome.exe`;\n\n const prefixes = [\n process.env.LOCALAPPDATA,\n process.env.PROGRAMFILES,\n process.env['PROGRAMFILES(X86)'],\n ].filter(Boolean);\n\n for (const prefix of prefixes) {\n const chrome = join(prefix!, suffix);\n if (existsSync(chrome)) {\n return chrome;\n }\n }\n\n return null;\n}\n\nfunction getChromeOnDarwin(\n name:\n | 'Google Chrome'\n | 'Google Chrome Beta'\n | 'Google Chrome Dev'\n | 'Google Chrome Canary',\n): string | null {\n const suffix = `/Applications/${name}.app/Contents/MacOS/${name}`;\n const prefixes = ['', process.env.HOME].filter((item) => item !== undefined);\n\n for (const prefix of prefixes) {\n const chromePath = join(prefix, suffix);\n if (existsSync(chromePath)) {\n return chromePath;\n }\n }\n\n return null;\n}\n\nconst chromePaths = {\n chrome: {\n linux: () => getChromeOnLinux(['google-chrome-stable', 'google-chrome']),\n darwin: () => getChromeOnDarwin('Google Chrome'),\n win32: () => getChromeOnWindows('Chrome'),\n },\n beta: {\n linux: () => getChromeOnLinux(['google-chrome-beta']),\n darwin: () => getChromeOnDarwin('Google Chrome Beta'),\n win32: () => getChromeOnWindows('Chrome Beta'),\n },\n dev: {\n linux: () => getChromeOnLinux(['google-chrome-dev']),\n darwin: () => getChromeOnDarwin('Google Chrome Dev'),\n win32: () => getChromeOnWindows('Chrome Dev'),\n },\n canary: {\n linux: () => getChromeOnLinux(['chromium-browser', 'chromium']),\n darwin: () => getChromeOnDarwin('Google Chrome Canary'),\n win32: () => getChromeOnWindows('Chrome SxS'),\n },\n};\n\nfunction getChromePath() {\n const chrome = chromePaths.chrome;\n\n if (platform && Object.keys(chrome).includes(platform)) {\n const pth = chrome[platform as keyof typeof chrome]();\n if (pth) {\n return pth;\n }\n }\n}\n\nfunction getChromeBetaPath() {\n const beta = chromePaths.beta;\n\n if (platform && Object.keys(beta).includes(platform)) {\n const pth = beta[platform as keyof typeof beta]();\n if (pth) {\n return pth;\n }\n }\n}\n\nfunction getChromeDevPath() {\n const dev = chromePaths.dev;\n\n if (platform && Object.keys(dev).includes(platform)) {\n const pth = dev[platform as keyof typeof dev]();\n if (pth) {\n return pth;\n }\n }\n}\n\nfunction getChromeCanaryPath() {\n const canary = chromePaths.canary;\n\n if (platform && Object.keys(canary).includes(platform)) {\n const pth = canary[platform as keyof typeof canary]();\n if (pth) {\n return pth;\n }\n }\n}\n\nexport function getAnyChromeStable(): string {\n const chrome = getChromePath();\n if (chrome) {\n return chrome;\n }\n\n const beta = getChromeBetaPath();\n if (beta) {\n return beta;\n }\n\n const dev = getChromeDevPath();\n if (dev) {\n return dev;\n }\n\n const canary = getChromeCanaryPath();\n if (canary) {\n return canary;\n }\n\n const error = new Error('Unable to find any chrome browser.');\n error.name = 'ChromePathsError';\n throw error;\n}\n"],"names":["platform","process","getChromeOnLinux","list","name","path","which","e","getChromeOnWindows","suffix","sep","prefixes","Boolean","prefix","chrome","join","existsSync","getChromeOnDarwin","item","undefined","chromePath","chromePaths","getChromePath","Object","pth","getChromeBetaPath","beta","getChromeDevPath","dev","getChromeCanaryPath","canary","getAnyChromeStable","error","Error"],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import * as __WEBPACK_EXTERNAL_MODULE_fs__ from "fs";
|
|
6
|
+
import * as __WEBPACK_EXTERNAL_MODULE_path__ from "path";
|
|
7
|
+
import * as __WEBPACK_EXTERNAL_MODULE_which__ from "which";
|
|
8
|
+
const platform = process.platform;
|
|
9
|
+
function getChromeOnLinux(list) {
|
|
10
|
+
try {
|
|
11
|
+
for (const name of list){
|
|
12
|
+
const path = __WEBPACK_EXTERNAL_MODULE_which__["default"].sync(name);
|
|
13
|
+
return path;
|
|
14
|
+
}
|
|
15
|
+
} catch (e) {}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
function getChromeOnWindows(name) {
|
|
19
|
+
const suffix = `${__WEBPACK_EXTERNAL_MODULE_path__.sep}Google${__WEBPACK_EXTERNAL_MODULE_path__.sep}${name}${__WEBPACK_EXTERNAL_MODULE_path__.sep}Application${__WEBPACK_EXTERNAL_MODULE_path__.sep}chrome.exe`;
|
|
20
|
+
const prefixes = [
|
|
21
|
+
process.env.LOCALAPPDATA,
|
|
22
|
+
process.env.PROGRAMFILES,
|
|
23
|
+
process.env['PROGRAMFILES(X86)']
|
|
24
|
+
].filter(Boolean);
|
|
25
|
+
for (const prefix of prefixes){
|
|
26
|
+
const chrome = (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(prefix, suffix);
|
|
27
|
+
if ((0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)(chrome)) return chrome;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function getChromeOnDarwin(name) {
|
|
32
|
+
const suffix = `/Applications/${name}.app/Contents/MacOS/${name}`;
|
|
33
|
+
const prefixes = [
|
|
34
|
+
'',
|
|
35
|
+
process.env.HOME
|
|
36
|
+
].filter((item)=>void 0 !== item);
|
|
37
|
+
for (const prefix of prefixes){
|
|
38
|
+
const chromePath = (0, __WEBPACK_EXTERNAL_MODULE_path__.join)(prefix, suffix);
|
|
39
|
+
if ((0, __WEBPACK_EXTERNAL_MODULE_fs__.existsSync)(chromePath)) return chromePath;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const chromePaths = {
|
|
44
|
+
chrome: {
|
|
45
|
+
linux: ()=>getChromeOnLinux([
|
|
46
|
+
'google-chrome-stable',
|
|
47
|
+
'google-chrome'
|
|
48
|
+
]),
|
|
49
|
+
darwin: ()=>getChromeOnDarwin('Google Chrome'),
|
|
50
|
+
win32: ()=>getChromeOnWindows('Chrome')
|
|
51
|
+
},
|
|
52
|
+
beta: {
|
|
53
|
+
linux: ()=>getChromeOnLinux([
|
|
54
|
+
'google-chrome-beta'
|
|
55
|
+
]),
|
|
56
|
+
darwin: ()=>getChromeOnDarwin('Google Chrome Beta'),
|
|
57
|
+
win32: ()=>getChromeOnWindows('Chrome Beta')
|
|
58
|
+
},
|
|
59
|
+
dev: {
|
|
60
|
+
linux: ()=>getChromeOnLinux([
|
|
61
|
+
'google-chrome-dev'
|
|
62
|
+
]),
|
|
63
|
+
darwin: ()=>getChromeOnDarwin('Google Chrome Dev'),
|
|
64
|
+
win32: ()=>getChromeOnWindows('Chrome Dev')
|
|
65
|
+
},
|
|
66
|
+
canary: {
|
|
67
|
+
linux: ()=>getChromeOnLinux([
|
|
68
|
+
'chromium-browser',
|
|
69
|
+
'chromium'
|
|
70
|
+
]),
|
|
71
|
+
darwin: ()=>getChromeOnDarwin('Google Chrome Canary'),
|
|
72
|
+
win32: ()=>getChromeOnWindows('Chrome SxS')
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
function getChromePath() {
|
|
76
|
+
const chrome = chromePaths.chrome;
|
|
77
|
+
if (platform && Object.keys(chrome).includes(platform)) {
|
|
78
|
+
const pth = chrome[platform]();
|
|
79
|
+
if (pth) return pth;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function getChromeBetaPath() {
|
|
83
|
+
const beta = chromePaths.beta;
|
|
84
|
+
if (platform && Object.keys(beta).includes(platform)) {
|
|
85
|
+
const pth = beta[platform]();
|
|
86
|
+
if (pth) return pth;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function getChromeDevPath() {
|
|
90
|
+
const dev = chromePaths.dev;
|
|
91
|
+
if (platform && Object.keys(dev).includes(platform)) {
|
|
92
|
+
const pth = dev[platform]();
|
|
93
|
+
if (pth) return pth;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function getChromeCanaryPath() {
|
|
97
|
+
const canary = chromePaths.canary;
|
|
98
|
+
if (platform && Object.keys(canary).includes(platform)) {
|
|
99
|
+
const pth = canary[platform]();
|
|
100
|
+
if (pth) return pth;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function getAnyChromeStable() {
|
|
104
|
+
const chrome = getChromePath();
|
|
105
|
+
if (chrome) return chrome;
|
|
106
|
+
const beta = getChromeBetaPath();
|
|
107
|
+
if (beta) return beta;
|
|
108
|
+
const dev = getChromeDevPath();
|
|
109
|
+
if (dev) return dev;
|
|
110
|
+
const canary = getChromeCanaryPath();
|
|
111
|
+
if (canary) return canary;
|
|
112
|
+
const error = new Error('Unable to find any chrome browser.');
|
|
113
|
+
error.name = 'ChromePathsError';
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
export { getAnyChromeStable };
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=chrome-paths.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-finder/chrome-paths.mjs","sources":["webpack://@agent-infra/browser/./src/browser-finder/chrome-paths.ts"],"sourcesContent":["/**\n * The following code is modified based on\n * https://github.com/shirshak55/edge-paths/blob/master/index.ts\n *\n * MIT Licensed\n * Copyright (c) 2020 Shirshak\n * https://github.com/shirshak55/edge-paths/blob/master/LICENSE\n */\n\n/**\n * Q: Why not use [find-chrome-bin](https://github.com/mbalabash/find-chrome-bin) or [chrome-finder](https://github.com/gwuhaolin/chrome-finder)?\n *\n * A: The `find-chrome-bin` or `chrome-finder` libraries execute `lsregister -dump` under Darwin (macOS),\n * which is a time-consuming operation (taking up to 6 seconds on my computer!).\n * Since this process is performed during the app's startup, such a delay is unacceptable.\n */\nimport { existsSync } from 'fs';\nimport { sep, join } from 'path';\nimport which from 'which';\n\nconst platform = process.platform;\n\nfunction getChromeOnLinux(\n list: (\n | 'google-chrome'\n | 'google-chrome-stable'\n | 'google-chrome-beta'\n | 'google-chrome-dev'\n | 'chromium-browser'\n | 'chromium'\n )[],\n): string | null {\n // TODO: scan desktop installation folders, the `grep` operation can be somewhat time-consuming.\n // https://github.com/mbalabash/find-chrome-bin/blob/main/src/linux/index.js\n try {\n for (const name of list) {\n const path = which.sync(name);\n return path;\n }\n } catch (e) {}\n\n return null;\n}\n\nfunction getChromeOnWindows(\n name: 'Chrome' | 'Chrome Beta' | 'Chrome Dev' | 'Chrome SxS',\n): string | null {\n const suffix = `${sep}Google${sep}${name}${sep}Application${sep}chrome.exe`;\n\n const prefixes = [\n process.env.LOCALAPPDATA,\n process.env.PROGRAMFILES,\n process.env['PROGRAMFILES(X86)'],\n ].filter(Boolean);\n\n for (const prefix of prefixes) {\n const chrome = join(prefix!, suffix);\n if (existsSync(chrome)) {\n return chrome;\n }\n }\n\n return null;\n}\n\nfunction getChromeOnDarwin(\n name:\n | 'Google Chrome'\n | 'Google Chrome Beta'\n | 'Google Chrome Dev'\n | 'Google Chrome Canary',\n): string | null {\n const suffix = `/Applications/${name}.app/Contents/MacOS/${name}`;\n const prefixes = ['', process.env.HOME].filter((item) => item !== undefined);\n\n for (const prefix of prefixes) {\n const chromePath = join(prefix, suffix);\n if (existsSync(chromePath)) {\n return chromePath;\n }\n }\n\n return null;\n}\n\nconst chromePaths = {\n chrome: {\n linux: () => getChromeOnLinux(['google-chrome-stable', 'google-chrome']),\n darwin: () => getChromeOnDarwin('Google Chrome'),\n win32: () => getChromeOnWindows('Chrome'),\n },\n beta: {\n linux: () => getChromeOnLinux(['google-chrome-beta']),\n darwin: () => getChromeOnDarwin('Google Chrome Beta'),\n win32: () => getChromeOnWindows('Chrome Beta'),\n },\n dev: {\n linux: () => getChromeOnLinux(['google-chrome-dev']),\n darwin: () => getChromeOnDarwin('Google Chrome Dev'),\n win32: () => getChromeOnWindows('Chrome Dev'),\n },\n canary: {\n linux: () => getChromeOnLinux(['chromium-browser', 'chromium']),\n darwin: () => getChromeOnDarwin('Google Chrome Canary'),\n win32: () => getChromeOnWindows('Chrome SxS'),\n },\n};\n\nfunction getChromePath() {\n const chrome = chromePaths.chrome;\n\n if (platform && Object.keys(chrome).includes(platform)) {\n const pth = chrome[platform as keyof typeof chrome]();\n if (pth) {\n return pth;\n }\n }\n}\n\nfunction getChromeBetaPath() {\n const beta = chromePaths.beta;\n\n if (platform && Object.keys(beta).includes(platform)) {\n const pth = beta[platform as keyof typeof beta]();\n if (pth) {\n return pth;\n }\n }\n}\n\nfunction getChromeDevPath() {\n const dev = chromePaths.dev;\n\n if (platform && Object.keys(dev).includes(platform)) {\n const pth = dev[platform as keyof typeof dev]();\n if (pth) {\n return pth;\n }\n }\n}\n\nfunction getChromeCanaryPath() {\n const canary = chromePaths.canary;\n\n if (platform && Object.keys(canary).includes(platform)) {\n const pth = canary[platform as keyof typeof canary]();\n if (pth) {\n return pth;\n }\n }\n}\n\nexport function getAnyChromeStable(): string {\n const chrome = getChromePath();\n if (chrome) {\n return chrome;\n }\n\n const beta = getChromeBetaPath();\n if (beta) {\n return beta;\n }\n\n const dev = getChromeDevPath();\n if (dev) {\n return dev;\n }\n\n const canary = getChromeCanaryPath();\n if (canary) {\n return canary;\n }\n\n const error = new Error('Unable to find any chrome browser.');\n error.name = 'ChromePathsError';\n throw error;\n}\n"],"names":["platform","process","getChromeOnLinux","list","name","path","which","e","getChromeOnWindows","suffix","sep","prefixes","Boolean","prefix","chrome","join","existsSync","getChromeOnDarwin","item","undefined","chromePath","chromePaths","getChromePath","Object","pth","getChromeBetaPath","beta","getChromeDevPath","dev","getChromeCanaryPath","canary","getAnyChromeStable","error","Error"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firefox-paths.d.ts","sourceRoot":"","sources":["../../src/browser-finder/firefox-paths.ts"],"names":[],"mappings":"AA8GA,wBAAgB,mBAAmB,IAAI,MAAM,CAmB5C"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
var __webpack_require__ = {};
|
|
7
|
+
(()=>{
|
|
8
|
+
__webpack_require__.n = (module)=>{
|
|
9
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
10
|
+
__webpack_require__.d(getter, {
|
|
11
|
+
a: getter
|
|
12
|
+
});
|
|
13
|
+
return getter;
|
|
14
|
+
};
|
|
15
|
+
})();
|
|
16
|
+
(()=>{
|
|
17
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
18
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: definition[key]
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
(()=>{
|
|
25
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
26
|
+
})();
|
|
27
|
+
(()=>{
|
|
28
|
+
__webpack_require__.r = function(exports1) {
|
|
29
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
30
|
+
value: 'Module'
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
33
|
+
value: true
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
var __webpack_exports__ = {};
|
|
38
|
+
__webpack_require__.r(__webpack_exports__);
|
|
39
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
40
|
+
getAnyFirefoxStable: ()=>getAnyFirefoxStable
|
|
41
|
+
});
|
|
42
|
+
const external_fs_namespaceObject = require("fs");
|
|
43
|
+
const external_path_namespaceObject = require("path");
|
|
44
|
+
const external_which_namespaceObject = require("which");
|
|
45
|
+
var external_which_default = /*#__PURE__*/ __webpack_require__.n(external_which_namespaceObject);
|
|
46
|
+
const platform = process.platform;
|
|
47
|
+
function getFirefoxOnLinux(name) {
|
|
48
|
+
try {
|
|
49
|
+
const path = external_which_default().sync(name);
|
|
50
|
+
return path;
|
|
51
|
+
} catch (e) {}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function getFirefoxOnWindows(name) {
|
|
55
|
+
const suffix = `${external_path_namespaceObject.sep}${name}${external_path_namespaceObject.sep}firefox.exe`;
|
|
56
|
+
const prefixes = [
|
|
57
|
+
process.env.LOCALAPPDATA,
|
|
58
|
+
process.env.PROGRAMFILES,
|
|
59
|
+
process.env['PROGRAMFILES(X86)']
|
|
60
|
+
].filter(Boolean);
|
|
61
|
+
for (const prefix of prefixes){
|
|
62
|
+
const firefoxPath = (0, external_path_namespaceObject.join)(prefix, suffix);
|
|
63
|
+
if ((0, external_fs_namespaceObject.existsSync)(firefoxPath)) return firefoxPath;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
function getFireFoxOnDarwin(name) {
|
|
68
|
+
const suffix = `/Applications/${name}.app/Contents/MacOS/firefox`;
|
|
69
|
+
const prefixes = [
|
|
70
|
+
'',
|
|
71
|
+
process.env.HOME
|
|
72
|
+
].filter((item)=>void 0 !== item);
|
|
73
|
+
for (const prefix of prefixes){
|
|
74
|
+
const firefoxPath = (0, external_path_namespaceObject.join)(prefix, suffix);
|
|
75
|
+
if ((0, external_fs_namespaceObject.existsSync)(firefoxPath)) return firefoxPath;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const firefoxPaths = {
|
|
80
|
+
firefox: {
|
|
81
|
+
linux: ()=>getFirefoxOnLinux('firefox'),
|
|
82
|
+
darwin: ()=>getFireFoxOnDarwin('Firefox'),
|
|
83
|
+
win32: ()=>getFirefoxOnWindows('Mozilla Firefox')
|
|
84
|
+
},
|
|
85
|
+
dev: {
|
|
86
|
+
darwin: ()=>getFireFoxOnDarwin('Firefox Developer Edition'),
|
|
87
|
+
win32: ()=>getFirefoxOnWindows('Firefox Developer Edition')
|
|
88
|
+
},
|
|
89
|
+
nightly: {
|
|
90
|
+
darwin: ()=>getFireFoxOnDarwin('Firefox Nightly'),
|
|
91
|
+
win32: ()=>getFirefoxOnWindows('Firefox Nightly')
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
function getFirefoxPath() {
|
|
95
|
+
const firefox = firefoxPaths.firefox;
|
|
96
|
+
if (platform && Object.keys(firefox).includes(platform)) {
|
|
97
|
+
const pth = firefox[platform]();
|
|
98
|
+
if (pth) return pth;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function getFirefoxDevPath() {
|
|
102
|
+
const dev = firefoxPaths.dev;
|
|
103
|
+
if (platform && Object.keys(dev).includes(platform)) {
|
|
104
|
+
const pth = dev[platform]();
|
|
105
|
+
if (pth) return pth;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function getFirefoxNightlyPath() {
|
|
109
|
+
const nightly = firefoxPaths.nightly;
|
|
110
|
+
if (platform && Object.keys(nightly).includes(platform)) {
|
|
111
|
+
const pth = nightly[platform]();
|
|
112
|
+
if (pth) return pth;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function getAnyFirefoxStable() {
|
|
116
|
+
const firefox = getFirefoxPath();
|
|
117
|
+
if (firefox) return firefox;
|
|
118
|
+
const dev = getFirefoxDevPath();
|
|
119
|
+
if (dev) return dev;
|
|
120
|
+
const canary = getFirefoxNightlyPath();
|
|
121
|
+
if (canary) return canary;
|
|
122
|
+
const error = new Error('Unable to find any firefox browser.');
|
|
123
|
+
error.name = 'FirefoxPathsError';
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
var __webpack_export_target__ = exports;
|
|
127
|
+
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
128
|
+
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
|
|
129
|
+
value: true
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
//# sourceMappingURL=firefox-paths.js.map
|