Skip to content

Commit

Permalink
fix(firefox): back up user.js as well (#12943)
Browse files Browse the repository at this point in the history
  • Loading branch information
OrKoN authored Aug 13, 2024
1 parent 71afa01 commit 9feda9c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 28 deletions.
36 changes: 17 additions & 19 deletions packages/browsers/src/browser-data/firefox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export async function createProfile(options: ProfileOptions): Promise<void> {
recursive: true,
});
}
await writePreferences({
await syncPreferences({
preferences: {
...defaultProfilePreferences(options.preferences),
...options.preferences,
Expand Down Expand Up @@ -395,36 +395,34 @@ function defaultProfilePreferences(
return Object.assign(defaultPrefs, extraPrefs);
}

async function backupFile(input: string): Promise<void> {
if (!fs.existsSync(input)) {
return;
}
await fs.promises.copyFile(input, input + '.puppeteer');
}

/**
* Populates the user.js file with custom preferences as needed to allow
* Firefox's CDP support to properly function. These preferences will be
* Firefox's support to properly function. These preferences will be
* automatically copied over to prefs.js during startup of Firefox. To be
* able to restore the original values of preferences a backup of prefs.js
* will be created.
*
* @param prefs - List of preferences to add.
* @param profilePath - Firefox profile to write the preferences to.
*/
async function writePreferences(options: ProfileOptions): Promise<void> {
async function syncPreferences(options: ProfileOptions): Promise<void> {
const prefsPath = path.join(options.path, 'prefs.js');
const userPath = path.join(options.path, 'user.js');

const lines = Object.entries(options.preferences).map(([key, value]) => {
return `user_pref(${JSON.stringify(key)}, ${JSON.stringify(value)});`;
});

// Use allSettled to prevent corruption
// Use allSettled to prevent corruption.
const result = await Promise.allSettled([
fs.promises.writeFile(path.join(options.path, 'user.js'), lines.join('\n')),
// Create a backup of the preferences file if it already exitsts.
fs.promises.access(prefsPath, fs.constants.F_OK).then(
async () => {
await fs.promises.copyFile(
prefsPath,
path.join(options.path, 'prefs.js.puppeteer')
);
},
// Swallow only if file does not exist
() => {}
),
backupFile(userPath).then(async () => {
await fs.promises.writeFile(userPath, lines.join('\n'));
}),
backupFile(prefsPath),
]);
for (const command of result) {
if (command.status === 'rejected') {
Expand Down
26 changes: 17 additions & 9 deletions packages/puppeteer-core/src/node/FirefoxLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,23 @@ export class FirefoxLauncher extends BrowserLauncher {
}
} else {
try {
// When an existing user profile has been used remove the user
// preferences file and restore possibly backuped preferences.
await unlink(path.join(userDataDir, 'user.js'));

const prefsBackupPath = path.join(userDataDir, 'prefs.js.puppeteer');
if (fs.existsSync(prefsBackupPath)) {
const prefsPath = path.join(userDataDir, 'prefs.js');
await unlink(prefsPath);
await rename(prefsBackupPath, prefsPath);
const backupSuffix = '.puppeteer';
const backupFiles = ['prefs.js', 'user.js'];

const results = await Promise.allSettled(
backupFiles.map(async file => {
const prefsBackupPath = path.join(userDataDir, file + backupSuffix);
if (fs.existsSync(prefsBackupPath)) {
const prefsPath = path.join(userDataDir, file);
await unlink(prefsPath);
await rename(prefsBackupPath, prefsPath);
}
})
);
for (const result of results) {
if (result.status === 'rejected') {
throw result.reason;
}
}
} catch (error) {
debugError(error);
Expand Down
3 changes: 3 additions & 0 deletions test/src/launcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,10 @@ describe('Launcher specs', function () {
const userDataDir = await mkdtemp(TMP_FOLDER);

const prefsJSPath = path.join(userDataDir, 'prefs.js');
const userJSPath = path.join(userDataDir, 'user.js');
const prefsJSContent = 'user_pref("browser.warnOnQuit", true)';
await writeFile(prefsJSPath, prefsJSContent);
await writeFile(userJSPath, prefsJSContent);

const {context, close} = await launch({userDataDir});
try {
Expand All @@ -265,6 +267,7 @@ describe('Launcher specs', function () {
expect(fs.readdirSync(userDataDir).length).toBeGreaterThan(0);

expect(await readFile(prefsJSPath, 'utf8')).toBe(prefsJSContent);
expect(await readFile(userJSPath, 'utf8')).toBe(prefsJSContent);
} finally {
await close();
}
Expand Down

0 comments on commit 9feda9c

Please sign in to comment.