Skip to content

Commit 9d2df23

Browse files
committed
feat: Allow passing custom chromium preferences (#1)
1 parent 8b177d5 commit 9d2df23

File tree

5 files changed

+114
-17
lines changed

5 files changed

+114
-17
lines changed

package-lock.json

+43-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"parse-json": "7.1.1",
6363
"pino": "9.6.0",
6464
"promise-toolbox": "0.21.0",
65+
"set-value": "4.1.0",
6566
"source-map-support": "0.5.21",
6667
"strip-bom": "5.0.0",
6768
"strip-json-comments": "5.0.1",

src/cmd/run.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export default async function run(
5050
firefoxApkComponent,
5151
// Chromium CLI options.
5252
chromiumBinary,
53+
chromiumPref,
5354
chromiumProfile,
5455
},
5556
{
@@ -82,7 +83,12 @@ export default async function run(
8283

8384
// Create an alias for --pref since it has been transformed into an
8485
// object containing one or more preferences.
85-
const customPrefs = pref;
86+
const customPrefs = { ...pref };
87+
88+
// Create an alias for --chromium-pref since it has been transformed into an
89+
// object containing one or more preferences.
90+
const customChromiumPrefs = { ...chromiumPref };
91+
8692
const manifestData = await getValidatedManifest(sourceDir);
8793

8894
const profileDir = firefoxProfile || chromiumProfile;
@@ -190,6 +196,7 @@ export default async function run(
190196
...commonRunnerParams,
191197
chromiumBinary,
192198
chromiumProfile,
199+
customChromiumPrefs,
193200
};
194201

195202
const chromiumRunner = await createExtensionRunner({

src/extension-runners/chromium.js

+20
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
launch as defaultChromiumLaunch,
1212
} from 'chrome-launcher';
1313
import WebSocket, { WebSocketServer } from 'ws';
14+
import set from 'set-value';
1415

1516
import { createLogger } from '../util/logger.js';
1617
import { TempDir } from '../util/temp-dir.js';
@@ -29,6 +30,10 @@ export const DEFAULT_CHROME_FLAGS = ChromeLauncher.defaultFlags().filter(
2930
(flag) => !EXCLUDED_CHROME_FLAGS.includes(flag),
3031
);
3132

33+
const DEFAULT_PREFS = {
34+
'extensions.ui.developer_mode': true,
35+
};
36+
3237
/**
3338
* Implements an IExtensionRunner which manages a Chromium instance.
3439
*/
@@ -214,6 +219,7 @@ export class ChromiumExtensionRunner {
214219
userDataDir,
215220
// Ignore default flags to keep the extension enabled.
216221
ignoreDefaultFlags: true,
222+
prefs: this.getPrefs(),
217223
});
218224

219225
this.chromiumInstance.process.once('close', () => {
@@ -418,4 +424,18 @@ export class ChromiumExtensionRunner {
418424
}
419425
}
420426
}
427+
428+
/**
429+
* Returns a deep preferences object based on a set of flat preferences, like
430+
* "extensions.ui.developer_mode".
431+
*/
432+
getPrefs() {
433+
return Object.entries({
434+
...DEFAULT_PREFS,
435+
...(this.params.customChromiumPrefs || {}),
436+
}).reduce((prefs, [key, value]) => {
437+
set(prefs, key, value);
438+
return prefs;
439+
}, {});
440+
}
421441
}

tests/unit/test-extension-runners/test.chromium.js

+42-11
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ function prepareExtensionRunnerParams({ params } = {}) {
2828
};
2929
const runnerParams = {
3030
extensions: [
31-
{
32-
sourceDir: '/fake/sourceDir',
33-
manifestData: deepcopy(basicManifest),
34-
},
31+
{ sourceDir: '/fake/sourceDir', manifestData: deepcopy(basicManifest) },
3532
],
3633
keepProfileChanges: false,
3734
startUrl: undefined,
@@ -47,7 +44,7 @@ function prepareExtensionRunnerParams({ params } = {}) {
4744

4845
describe('util/extension-runners/chromium', async () => {
4946
it('uses the expected chrome flags', () => {
50-
// Flags from chrome-launcher v0.14.0
47+
// Flags from chrome-launcher v1.1.0
5148
const expectedFlags = [
5249
'--disable-features=Translate,OptimizationHints,MediaRouter,DialMediaRouteProvider,CalculateNativeWinOcclusion,InterestFeedContentSuggestions,CertificateTransparencyComponentUpdater,AutofillServerCommunication,PrivacySandboxSettings4',
5350
'--disable-component-extensions-with-background-pages',
@@ -372,9 +369,7 @@ describe('util/extension-runners/chromium', async () => {
372369
});
373370

374371
it('does use a random user-data-dir', async () => {
375-
const { params } = prepareExtensionRunnerParams({
376-
params: {},
377-
});
372+
const { params } = prepareExtensionRunnerParams({ params: {} });
378373

379374
const spy = sinon.spy(TempDir.prototype, 'path');
380375

@@ -394,9 +389,7 @@ describe('util/extension-runners/chromium', async () => {
394389
it('does pass a user-data-dir flag to chrome', async () =>
395390
withTempDir(async (tmpDir) => {
396391
const { params } = prepareExtensionRunnerParams({
397-
params: {
398-
chromiumProfile: tmpDir.path(),
399-
},
392+
params: { chromiumProfile: tmpDir.path() },
400393
});
401394

402395
const spy = sinon.spy(TempDir.prototype, 'path');
@@ -618,6 +611,44 @@ describe('util/extension-runners/chromium', async () => {
618611
}),
619612
);
620613

614+
it('does pass default prefs to chrome', async () => {
615+
const { params } = prepareExtensionRunnerParams();
616+
617+
const runnerInstance = new ChromiumExtensionRunner(params);
618+
await runnerInstance.run();
619+
620+
sinon.assert.calledOnce(params.chromiumLaunch);
621+
sinon.assert.calledWithMatch(params.chromiumLaunch, {
622+
prefs: { extensions: { ui: { developer_mode: true } } },
623+
});
624+
625+
await runnerInstance.exit();
626+
});
627+
628+
it('does pass custom prefs to chrome', async () => {
629+
const { params } = prepareExtensionRunnerParams({
630+
params: {
631+
customChromiumPrefs: {
632+
'download.default_directory': '/some/directory',
633+
'extensions.ui.developer_mode': false,
634+
},
635+
},
636+
});
637+
638+
const runnerInstance = new ChromiumExtensionRunner(params);
639+
await runnerInstance.run();
640+
641+
sinon.assert.calledOnce(params.chromiumLaunch);
642+
sinon.assert.calledWithMatch(params.chromiumLaunch, {
643+
prefs: {
644+
download: { default_directory: '/some/directory' },
645+
extensions: { ui: { developer_mode: false } },
646+
},
647+
});
648+
649+
await runnerInstance.exit();
650+
});
651+
621652
describe('reloadAllExtensions', () => {
622653
let runnerInstance;
623654
let wsClient;

0 commit comments

Comments
 (0)