browser-commander 0.9.1 → 0.10.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - fe688ac: Add `channel` and `executablePath` launch options for reusing an installed Chrome-family browser.
8
+
3
9
  ## 0.9.1
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -87,6 +87,19 @@ await commander.destroy();
87
87
  await browser.close();
88
88
  ```
89
89
 
90
+ To reuse an installed Chrome-family browser instead of downloading the
91
+ engine's bundled Chromium, select a browser channel or provide its executable
92
+ path. Both options are passed directly to Playwright or Puppeteer:
93
+
94
+ ```javascript
95
+ const { browser, page } = await launchBrowser({
96
+ engine: 'playwright',
97
+ channel: 'chrome',
98
+ // Or: executablePath: '/usr/bin/google-chrome',
99
+ headless: true,
100
+ });
101
+ ```
102
+
90
103
  ## Browser Commander Tests
91
104
 
92
105
  `browser-commander/tests` adds browser fixtures and scheduling helpers on top of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-commander",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "Universal browser automation library that supports both Playwright and Puppeteer with a unified API",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -0,0 +1,51 @@
1
+ function setBrowserSelectionOptions(options, { channel, executablePath }) {
2
+ if (channel !== undefined) {
3
+ options.channel = channel;
4
+ }
5
+ if (executablePath !== undefined) {
6
+ options.executablePath = executablePath;
7
+ }
8
+ return options;
9
+ }
10
+
11
+ export function buildPlaywrightLaunchOptions({
12
+ headless,
13
+ slowMo,
14
+ chromeArgs,
15
+ colorScheme,
16
+ channel,
17
+ executablePath,
18
+ }) {
19
+ const options = {
20
+ headless,
21
+ slowMo,
22
+ chromiumSandbox: true,
23
+ viewport: null,
24
+ args: chromeArgs,
25
+ ignoreDefaultArgs: ['--enable-automation'],
26
+ };
27
+
28
+ if (colorScheme !== undefined) {
29
+ options.colorScheme = colorScheme;
30
+ }
31
+
32
+ return setBrowserSelectionOptions(options, { channel, executablePath });
33
+ }
34
+
35
+ export function buildPuppeteerLaunchOptions({
36
+ headless,
37
+ chromeArgs,
38
+ userDataDir,
39
+ channel,
40
+ executablePath,
41
+ }) {
42
+ return setBrowserSelectionOptions(
43
+ {
44
+ headless,
45
+ defaultViewport: null,
46
+ args: ['--start-maximized', ...chromeArgs],
47
+ userDataDir,
48
+ },
49
+ { channel, executablePath }
50
+ );
51
+ }
@@ -3,6 +3,10 @@ import os from 'os';
3
3
  import { CHROME_ARGS } from '../core/constants.js';
4
4
  import { disableTranslateInPreferences } from '../core/preferences.js';
5
5
  import { emulateMedia } from './media.js';
6
+ import {
7
+ buildPlaywrightLaunchOptions,
8
+ buildPuppeteerLaunchOptions,
9
+ } from './launch-options.js';
6
10
 
7
11
  /**
8
12
  * Launch browser with default configuration
@@ -14,6 +18,8 @@ import { emulateMedia } from './media.js';
14
18
  * @param {boolean} options.verbose - Enable verbose logging (default: false)
15
19
  * @param {string[]} options.args - Custom Chrome arguments to append to the default CHROME_ARGS
16
20
  * @param {string|null} [options.colorScheme] - Emulate color scheme: 'light', 'dark', 'no-preference', or null to reset
21
+ * @param {string} [options.channel] - Installed browser channel, such as 'chrome', 'chrome-beta', or 'msedge'
22
+ * @param {string} [options.executablePath] - Explicit path to a Chrome or Chromium executable
17
23
  * @returns {Promise<Object>} - Object with browser and page
18
24
  */
19
25
  export async function launchBrowser(options = {}) {
@@ -25,6 +31,8 @@ export async function launchBrowser(options = {}) {
25
31
  verbose = false,
26
32
  args = [],
27
33
  colorScheme,
34
+ channel,
35
+ executablePath,
28
36
  } = options;
29
37
 
30
38
  // Combine default CHROME_ARGS with custom args
@@ -53,18 +61,14 @@ export async function launchBrowser(options = {}) {
53
61
 
54
62
  if (engine === 'playwright') {
55
63
  const { chromium } = await import('playwright');
56
- const contextOptions = {
64
+ const contextOptions = buildPlaywrightLaunchOptions({
57
65
  headless,
58
66
  slowMo,
59
- chromiumSandbox: true,
60
- viewport: null,
61
- args: chromeArgs,
62
- ignoreDefaultArgs: ['--enable-automation'],
63
- };
64
- // Playwright supports colorScheme as a context-level launch option
65
- if (colorScheme !== undefined) {
66
- contextOptions.colorScheme = colorScheme;
67
- }
67
+ chromeArgs,
68
+ colorScheme,
69
+ channel,
70
+ executablePath,
71
+ });
68
72
  browser = await chromium.launchPersistentContext(
69
73
  userDataDir,
70
74
  contextOptions
@@ -72,12 +76,15 @@ export async function launchBrowser(options = {}) {
72
76
  page = browser.pages()[0];
73
77
  } else {
74
78
  const puppeteer = await import('puppeteer');
75
- browser = await puppeteer.default.launch({
76
- headless,
77
- defaultViewport: null,
78
- args: ['--start-maximized', ...chromeArgs],
79
- userDataDir,
80
- });
79
+ browser = await puppeteer.default.launch(
80
+ buildPuppeteerLaunchOptions({
81
+ headless,
82
+ chromeArgs,
83
+ userDataDir,
84
+ channel,
85
+ executablePath,
86
+ })
87
+ );
81
88
  const pages = await browser.pages();
82
89
  page = pages[0];
83
90
  }
@@ -0,0 +1,53 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+
4
+ import {
5
+ buildPlaywrightLaunchOptions,
6
+ buildPuppeteerLaunchOptions,
7
+ } from '../../../src/browser/launch-options.js';
8
+
9
+ describe('browser launch options', () => {
10
+ it('forwards channel and executablePath to Playwright', () => {
11
+ const options = buildPlaywrightLaunchOptions({
12
+ headless: true,
13
+ slowMo: 25,
14
+ chromeArgs: ['--custom'],
15
+ channel: 'chrome-beta',
16
+ executablePath: '/opt/google/chrome-beta',
17
+ });
18
+
19
+ assert.equal(options.channel, 'chrome-beta');
20
+ assert.equal(options.executablePath, '/opt/google/chrome-beta');
21
+ });
22
+
23
+ it('forwards channel and executablePath to Puppeteer', () => {
24
+ const options = buildPuppeteerLaunchOptions({
25
+ headless: true,
26
+ chromeArgs: ['--custom'],
27
+ userDataDir: '/tmp/browser-commander-test',
28
+ channel: 'chrome',
29
+ executablePath: '/usr/bin/google-chrome',
30
+ });
31
+
32
+ assert.equal(options.channel, 'chrome');
33
+ assert.equal(options.executablePath, '/usr/bin/google-chrome');
34
+ });
35
+
36
+ it('omits browser selection options by default', () => {
37
+ const playwright = buildPlaywrightLaunchOptions({
38
+ headless: false,
39
+ slowMo: 150,
40
+ chromeArgs: [],
41
+ });
42
+ const puppeteer = buildPuppeteerLaunchOptions({
43
+ headless: false,
44
+ chromeArgs: [],
45
+ userDataDir: '/tmp/browser-commander-test',
46
+ });
47
+
48
+ assert.equal('channel' in playwright, false);
49
+ assert.equal('executablePath' in playwright, false);
50
+ assert.equal('channel' in puppeteer, false);
51
+ assert.equal('executablePath' in puppeteer, false);
52
+ });
53
+ });