Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly prepare Firefox profiles with required preferences for all scenarious #7684

Merged
merged 1 commit into from Nov 10, 2021

Conversation

whimboo
Copy link
Collaborator

@whimboo whimboo commented Oct 13, 2021

PR to fix issue #7615 by making sure that also temporary folders for the Firefox profile are properly prepared with required preferences.

@google-cla google-cla bot added the cla: yes label Oct 13, 2021
@whimboo whimboo force-pushed the firefox_preferences branch 2 times, most recently from 16ba01e to 04bec14 Compare October 13, 2021 12:00
@whimboo whimboo requested a review from jschfflr October 13, 2021 12:24
@whimboo
Copy link
Collaborator Author

whimboo commented Oct 13, 2021

@jschfflr let me know if this is something that would work for you. As already asked on the issue itself, I wonder if it would make sense to pass the userDataDir via the launch options. Or if this could be a follow-up given that it would also affect Chrome.

@whimboo whimboo requested a review from OrKoN October 13, 2021 12:25
@whimboo
Copy link
Collaborator Author

whimboo commented Oct 13, 2021

Here are the first results for this PR:
https://github.com/puppeteer/puppeteer/actions/runs/1337331528/attempts/1

I will trigger some more to make sure it also succeeds all the time in CI.

Copy link
Collaborator

@OrKoN OrKoN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks (let's let Jan to take a look as well)

Copy link
Collaborator Author

@whimboo whimboo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During an internal discussion two important points have been raised and need to be clarified first. Please see my inline comments.

src/node/Launcher.ts Outdated Show resolved Hide resolved
firefoxArguments.push(temporaryUserDataDir);
} else {
const prefs = this.defaultPreferences(extraPrefsFirefox);
await this.writePreferences(prefs, profilePath);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jschfflr what's the actual expected behavior for user profiles that exists but should be used once for Puppeteer. Right now we would overwrite all the preferences which is not ideal. Instead we could only write the user.js file, which values will automatically be copied into prefs.js, and maybe fail if that file already exists?

Otherwise creating a backup of the prefs.js would be an idea, but there might be cases when the clean-up doesn't really work and we might miss to restore it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an interesting case. Would firefox still work normally with the same user profile after the changes to users.js?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any preferences in user.js will be copied by Firefox to prefs.js and just removing user.js will not be enough to get it reverted. That means that all the changes will remain post Puppeteer.

Given that we tweak the profile for automation the user might indeed see differences in Firefox' behavior afterward. I see two options:

  1. Create a backup of prefs.js and restore it during teardown, which will not always work like in cases the user hits Ctrl+C. Also changes to prefs.js will trigger different behaviors for various components in Firefox, and can cause other files in the profile to get modified too.

  2. Create a copy of the user's profile in the temp folder and let Puppeteer remove it as usual.

Only with option 2 the users profile will be kept identical and no traces from a usage with Puppeteer will remain in the original profile. But note that this might also have side-effects if multiple tests require the same profile and in worst cases steps as done by a previous test.

With geckodriver we actually make use of option 2 and never modify the original profile.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually creating a temporary copy of the specified user profile causes some of the user-data-dir tests to fail because the expected path isn't the same anymore.

@jschfflr as it looks like this might be a larger refactoring because the newly created temp directory will not be accessible by the consumer, and the Browser class doesn't have a property.

What do you suggest? Shall we go with a backup of pref.js for now and delete both .js files after Puppeteer finished? It would at least copy the behavior as what is used for Chrome by using the real user data dir.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah damn, that's too bad. Let's go with your proposed solution then!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do. What would be a good place to actually reset the prefs.js and delete user.js? Is https://github.com/puppeteer/puppeteer/blob/main/src/node/BrowserRunner.ts#L100 the right place so that it's always executed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's probably the best place for it!

@jschfflr
Copy link
Contributor

The user profiles seem to be a tricky thing. I'm wondering what kind of usecases we want to support and how they can be implemented. From the top of my head, I guess the following situations should be considered:

  1. A Puppeteer user wants to store state - normal firefox will not be running with this user profile
  2. A Puppeteer user wants to pick up state that has been created through a previous session with normal firefox
  3. A Puppeteer user wants a normal firefox instance to pick up the state from a previous puppeteer run
  4. There is a back and forth between normal FF and Puppeteer using the same user profile
  5. What happens if normal FF and Puppeteer try to use the same user profile at the same time?

Let me know if there are other situations to take into account!

@whimboo
Copy link
Collaborator Author

whimboo commented Nov 2, 2021

2. A Puppeteer user wants to pick up state that has been created through a previous session with normal firefox

This might be the most important case IMHO given that the profile can be pre-configured with imported certificates, accepted cookies and others.

3. A Puppeteer user wants a normal firefox instance to pick up the state from a previous puppeteer run

I'm not sure about the benefits here and what they actually could make use of. I would consider this a rare case.

5. What happens if normal FF and Puppeteer try to use the same user profile at the same time?

It's not possible. The profile is locked once a Firefox instance is using it.

Let me know if there are other situations to take into account!

You got a pretty good listing. So I cannot think of something else right now.

@whimboo
Copy link
Collaborator Author

whimboo commented Nov 3, 2021

Today (I was out the last two weeks) I noticed that this broken behavior is also causing a nearly permanent failure (#7615) in our own CI. As such I would like to get it fixed sooner than later. @jschfflr if we can find a proper solution in the next days I would appreciate. Thanks.

@jschfflr
Copy link
Contributor

jschfflr commented Nov 3, 2021

Happy to get this through :)
What do you think about going with option 2

Create a copy of the user's profile in the temp folder and let Puppeteer remove it as usual.

to get us unblocked and then iterating on that to find a better solution going forward?

@whimboo
Copy link
Collaborator Author

whimboo commented Nov 3, 2021

Thank you for the quick reply. Yes, that sounds fine. I'll go ahead with option 2 and we can observe incoming issues in case that this new behavior causes trouble to users.

@whimboo
Copy link
Collaborator Author

whimboo commented Nov 8, 2021

@jschfflr I'm struggling a bit with the prefix of the commits. Is chore the right one to use? If not what shall I use for the commits? As I saw recently the changes for Firefox that I did not that long ago were not automatically mentioned in the changelog. Is there a manual process to request additions?

@whimboo whimboo force-pushed the firefox_preferences branch 4 times, most recently from 8b22617 to 80eb9ec Compare November 8, 2021 13:17
@OrKoN
Copy link
Collaborator

OrKoN commented Nov 8, 2021

Here is some guidance on the commits https://github.com/puppeteer/puppeteer/blob/main/CONTRIBUTING.md#commit-messages I think all commits in a PR get squashed though and only the final commit message matters. I am not sure if there is a manual process for generating the changelog now. cc @mathiasbynens

@whimboo whimboo force-pushed the firefox_preferences branch 2 times, most recently from 497a873 to a83bf6d Compare November 8, 2021 17:16
@whimboo
Copy link
Collaborator Author

whimboo commented Nov 8, 2021

Here is some guidance on the commits https://github.com/puppeteer/puppeteer/blob/main/CONTRIBUTING.md#commit-messages I think all commits in a PR get squashed though and only the final commit message matters. I am not sure if there is a manual process for generating the changelog now. cc @mathiasbynens

Thanks for pointing that out! I rebased my commits and updated the commit message prefixes appropriately. I would still like to see the commits pushed individually if possible.

The last three CI checks were all successful, so if that's the case again the PR would be ready for another review @jschfflr. Thanks in advance!

@OrKoN
Copy link
Collaborator

OrKoN commented Nov 10, 2021

I am not sure Jan would be able to review this any time soon. So let me take another look.

I am not sure it's possible to maintain individual commits as the squash merge is enforced for this repo.

Copy link
Collaborator

@OrKoN OrKoN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still LGTM

@whimboo
Copy link
Collaborator Author

whimboo commented Nov 10, 2021

Thanks for the review @OrKoN!

I didn't know that squash is enforced. So I will squash them all together and give it a proper commit message. I assume after this update you can land it, or do we have to wait for someone else for doing that?

@OrKoN
Copy link
Collaborator

OrKoN commented Nov 10, 2021

@whimboo yes, I can land it then

When using a custom Firefox profile for Puppeteer the modified
preferences as present in prefs.js need to be reset once the
profile is no longer needed by Puppeteer. If not done this could
cause side-effects when the profile is used next time outside
of Puppeteer.

As ride-along fix the "--foreground" argument for Firefox will
only be used on MacOS because that's the only supported platform.
@whimboo
Copy link
Collaborator Author

whimboo commented Nov 10, 2021

@OrKoN the commits have all been squashed and I force-pushed them. Also all the tests are still passing. So it looks like it's ready for landing.

@OrKoN OrKoN merged commit 790c7a0 into puppeteer:main Nov 10, 2021
@OrKoN
Copy link
Collaborator

OrKoN commented Nov 10, 2021

Merged!

@whimboo whimboo deleted the firefox_preferences branch November 10, 2021 12:32
@whimboo
Copy link
Collaborator Author

whimboo commented Nov 10, 2021

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants