-
Notifications
You must be signed in to change notification settings - Fork 188
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
New: Add flag to use default user profile instead #48
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks very much for the contribution anton! :)
chrome-launcher.ts
Outdated
`--remote-debugging-port=${this.port}`, | ||
let flags = DEFAULT_FLAGS.concat([`--remote-debugging-port=${this.port}`]); | ||
|
||
if (!this.defaultProfile) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's also update the logic for conditionally creating/destroying the tmp directory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still using a tmp directory for the logs and the pid file. If I don't use one, should I write those files into the default profile? It can get messy because then I'll have to guess the path of the default profile and delete each file individually.
README.md
Outdated
@@ -50,6 +50,10 @@ npm install chrome-launcher | |||
// * Otherwise, a detected Chrome (stable) will be used | |||
chromePath: string; | |||
|
|||
// (optional) Uses the default Chrome profile instead of creating a new one | |||
// Default: false | |||
defaultProfile: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to 🚲 🏠 on name, it's not super clear that this will currently ignore whatever is set as userDataDir
some potential others
forceDefaultProfile
ignoreUserDataDir
overrideUserDataDirWithDefault
alternatively, we could make this the behavior when false
is explicitly passed to userDataDir
and just document that it results in the default profile being used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like forceDefaultProfile
.
alternatively, we could make this the behavior when
false
is explicitly passed touserDataDir
and just document that it results in the default profile being used?
Do you want me to add this behavior on top of the current one or instead of the new parameter? userDataDir
will probably be a cleaner API for the user, but I was looking into the code and I had to change where the pid
files were created, etc. It was starting to get a bit too complicated so I preferred to wait for feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want me to add this behavior on top of the current one or instead of the new parameter?
My personal preference would probably be the boolean approach instead of the new flag. I agree it's a cleaner API for consumers. OTOH, forceDefaultProfile
is fairly explicit while userDataDir: false
is a little more opaque even if the logic tracks of "do not pass in --user-data-dir".
userDataDir will probably be a cleaner API for the user, but I was looking into the code and I had to start changing where the pid files were created, etc. It was starting to get a bit too complicated so I preferred to wait for feedback.
Hmmm, I suppose there's not a clear and obvious alternative for where else to stick the pid file process.cwd()
might be ok but permissions and litter could get messy. Keeping the tmp directory for now seems ok to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OTOH,
forceDefaultProfile
is fairly explicit whileuserDataDir: false
is a little more opaque even if the logic tracks of "do not pass in --user-data-dir".
Been trying to do this and there are some things to take into account. The main problem is "what happens if the users puts true
instead of a path
or false
? Also I need to update the logic in a couple places to validate that userDataDir
is a string
instead of boolean
, otherwise TypeScript will complain.
This is my current code in the constructor:
if (typeof this.opts.userDataDir === 'boolean') {
if (!this.opts.userDataDir) {
this.forceDefaultProfile = true;
} else {
throw new Error('userDataDir has to be false or a path');
}
} else {
this.forceDefaultProfile = defaults(this.opts.forceDefaultProfile, false);
}
}
What do you think? Should I just add the forceDefaultProfile
parameter or continue down this path?
@patrickhulce I've created a new PR that just changes the property to |
I really like the ergonomics of lemme take the temperature of some other folks before having you go down the rabbit hole if I'm alone in preferring this over #49 :) @brendankenny @samccone any preferences on this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
userDataDir: false
looks good to me.
Can we drop forceDefaultProfile
as an external option at the same time? It would be nice to avoid options interfering with each other if possible, and it seems like it's not necessary(?).
chrome-launcher.ts
Outdated
@@ -337,7 +350,9 @@ export class Launcher { | |||
delete this.errFile; | |||
} | |||
|
|||
this.rimraf(this.userDataDir, () => resolve()); | |||
if (typeof this.userDataDir === 'string') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just check this.forceDefaultProfile
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to do that check or otherwise TypeScript will complain it can be Boolean
or string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well we can always keep userDataDir a string inside this class, it's just boolean|string
in this.opts
chrome-launcher.ts
Outdated
|
||
if (typeof this.opts.userDataDir === 'boolean') { | ||
if (!this.opts.userDataDir) { | ||
this.forceDefaultProfile = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bikeshed: if it's a private property only, something like useDefaultProfile
is another possible name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
chrome-launcher.ts
Outdated
if (!this.opts.userDataDir) { | ||
this.forceDefaultProfile = true; | ||
} else { | ||
throw new Error('userDataDir has to be false or a path'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe userDataDir must be false or a path
Sure, I'll close the other PR and update this one. |
OK, I've updated the PR with @brendankenny's feedback. Once everyone is OK I'll squash the commits. Let me know if there is something else you want me to do here! |
README.md
Outdated
@@ -50,9 +50,10 @@ npm install chrome-launcher | |||
// * Otherwise, a detected Chrome (stable) will be used | |||
chromePath: string; | |||
|
|||
// (optional) Chrome profile path to use | |||
// (optional) Chrome profile path to use, if set to `false` then the default profile will be used. | |||
// This is the same as setting `forceDefaultProfile` to `true` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's remove this now that forceDefaultProfile
isn't an option anymore
chrome-launcher.ts
Outdated
@@ -33,6 +33,7 @@ export interface Options { | |||
handleSIGINT?: boolean; | |||
chromePath?: string; | |||
userDataDir?: string; | |||
forceDefaultProfile?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this now since we're using useDefaultProfile
for the same purpose?
chrome-launcher.ts
Outdated
@@ -337,7 +350,9 @@ export class Launcher { | |||
delete this.errFile; | |||
} | |||
|
|||
this.rimraf(this.userDataDir, () => resolve()); | |||
if (typeof this.userDataDir === 'string') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well we can always keep userDataDir a string inside this class, it's just boolean|string
in this.opts
chrome-launcher.ts
Outdated
throw new Error('userDataDir must be false or a path'); | ||
} | ||
} else { | ||
this.useDefaultProfile = defaults(this.opts.forceDefaultProfile, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this now? I guess we could explicitly set this.useDefaultProfile
to false now that forceDefaultProfile is gone
9151a2f
to
a56fe92
Compare
I'll take a look at the tests on Monday. Thanks for the feedback! |
@patrickhulce I've updated the tests. Had to add a new Let me know if I should change something else. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because I've moved that part to the constructor
hmm, I think placement of that was actually intentional, so that merely constructing ChromeLauncher wouldn't have any side effects (like creating a tmp directory) until instance.launch()
was called.
Sorry to make this harder :)
I'm just setting the value of Do you still want me to change it? |
doesn't the |
You are right, I thought the magic was happening in this.fs.openSync Will change it and try to make it DRY |
e7d26ac
to
3563c51
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm % nits! thanks for pushing through on this @molant!
chrome-launcher.ts
Outdated
`--remote-debugging-port=${this.port}`, | ||
let flags = DEFAULT_FLAGS.concat([`--remote-debugging-port=${this.port}`]); | ||
|
||
if (!this.useDefaultProfile) { | ||
// Place Chrome profile in a custom location we'll rm -rf later |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's maybe move this line of the comment down to where we create it with a bit of explanation on the new logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
yarn.lock
Outdated
@@ -1,1494 +1,1494 @@ | |||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this just seems like noise without any new deps, would you mind reverting this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would you mind adding a test for this?
e.g. a new one in the style of this test:
chrome-launcher/test/chrome-launcher-test.ts
Lines 106 to 124 in b08cd10
it('removes --disable-extensions from flags on enableExtensions', async () => { | |
const spawnStub = stub().returns({pid: 'some_pid'}); | |
const chromeInstance = new Launcher( | |
{enableExtensions: true}, | |
{fs: fsMock as any, rimraf: spy() as any, spawn: spawnStub as any}); | |
stub(chromeInstance, 'waitUntilReady').returns(Promise.resolve()); | |
chromeInstance.prepare(); | |
try { | |
await chromeInstance.launch(); | |
} catch (err) { | |
return Promise.reject(err); | |
} | |
const chromeFlags = spawnStub.getCall(0).args[1] as string[]; | |
assert.ok(!chromeFlags.includes('--disable-extensions')); | |
}); |
could just check that there's no
--user-data-dir
in the flags when userDataDir
is false
chrome-launcher.ts
Outdated
@@ -153,7 +155,18 @@ export class Launcher { | |||
throw new Error(`Platform ${platform} is not supported`); | |||
} | |||
|
|||
this.userDataDir = this.opts.userDataDir || this.makeTmpDir(); | |||
if (typeof this.opts.userDataDir === 'boolean') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe set this.useDefaultProfile
in the profile?
Then in the constructor it would just be something like
if (typeof this.opts.userDataDir === 'boolean') {
if (!this.opts.userDataDir) {
this.useDefaultProfile = true;
} else {
throw new Error('userDataDir must be false or a path');
}
} else {
this.useDefaultProfile = false;
}
That would immediately thrown on an invalid true
for userDataDir
, and it means that this line could just be
this.userDataDir = this.opts.userDataDir || this.makeTmpDir();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that might be too clever for the typescript compiler, I guess. To go with @patrickhulce's suggestion to keep this.userDataDir
an optional string, in the constructor could do
if (typeof this.opts.userDataDir === 'boolean') {
if (!this.opts.userDataDir) {
this.useDefaultProfile = true;
this.userDataDir = undefined;
} else {
throw new Error('userDataDir must be false or a path');
}
} else {
this.useDefaultProfile = false;
this.userDataDir = this.opts.userDataDir;
}
the compiler seems to understand this.opts.userDataDir
would then be string|undefined
by the last line there.
Then here in prepare()
it would just be
this.userDataDir = this.userDataDir || this.makeTmpDir();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used your latest comment for the change.
f1d1cda
to
fe5d8fb
Compare
Done |
@brendankenny @patrickhulce let me know if you want me to change anything else! |
@brendankenny @patrickhulce ping. Anything else I should do to get this merged? Thanks! |
shipped in 0.9.0 |
Thank you all! |
Could you provide any examples of use into documentation? |
Add a new property
defaultProfile
to use the default user's profile in Chrome instead of creating a new one. By default this value isfalse
so it doesn't change the current behavior.Close #47