Skip to content

Commit

Permalink
Add browser.profile setting and fix Firefox addArguments bug (#226)
Browse files Browse the repository at this point in the history
This PR adds a new browser.profile JSON config setting which can be used like this:

{
  "benchmarks": [
    {
      "url": "mybench.html",
      "browser": {
        "name": "firefox",
        "profile": "/Users/<username>/Library/Application Support/Firefox/Profiles/<profile-name>"
      }
    }
  ]
}

It also fixes a bug where addArguments was not being applied to Firefox, even though it was documented that it was supported.

For Chrome, it was previously supported and documented to use "addArguments": ["user-data-dir=<path>"] to achieve this same effect, but I found that the equivalent for Firefox ("-profile=<path>") caused Selenium to timeout trying to connect to the process. I wasn't able to figure out exactly why this was happening, but I did notice a dedicated setProfile method just for Firefox, which does work. So by adding the browser.profile setting, we now have a way to call this special API, plus the user doesn't need to remember the user-data-dir flag in Chrome.

Fixes #222

Also threw in a fix to tests relating to chromedriver having updated to Chrome 94 while GitHub Actions is still on Chrome 93.
  • Loading branch information
aomarks authored Sep 27, 2021
1 parent 19fc355 commit 724dbd5
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 14 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ jobs:
cache: npm

- run: npm ci
# TODO(aomarks) The latest chromedriver has updated to 94, but GitHub
# Actions hasn't updated yet. Pin to the earlier verison of chromedriver
# until GitHub Actions updated.
- run: npm install chromedriver@^93.0.0
- run: npm run build

- run: npm test
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ project adheres to [Semantic Versioning](http://semver.org/).
- Fix bug where log files would be created with '\' backslash names instead of
nested directories.

- Fix bug where `browser.addArguments` JSON config setting did not work for
Firefox.

- Add `browser.profile` JSON config setting that sets the browser profile
directory. Currently supported in Chrome and Firefox.

- Upgrade dependencies.

## [0.5.9] 2021-04-22
Expand Down
67 changes: 53 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -538,26 +538,65 @@ However, in some cases it may be useful to use an existing browser profile, for
example if the webpage you are benchmarking requires being signed into an
account.

In Chrome, you can use the `user-data-dir` flag to launch the browser using an
existing profile directory. You may also need to remove the `use-mock-keychain`
default argument if you encounter authentication problems. You can find out the
current binary path, profile location, and arguments of a running Chrome session
by visiting the `chrome://version` URL.
In Chrome and Firefox, use the `profile` JSON config option to specify an
existing profile to use. Other browsers do not yet support this option.

NOTE: If there is an existing Chrome process using the profile, you must
first terminate it. You also need to close all open tabs, or disable the
"Continue where you left off" startup setting, because tachometer does not
expect to find any existing tabs.
#### Chrome

To find your current profile location in Chrome, visit `chrome://version` and
look for "Profile Path".

If there is an existing Chrome process using this profile, you must first
terminate it. You also need to close all open tabs, or disable the "Continue
where you left off" startup setting, because tachometer does not expect to find
any existing tabs.

You may also need to remove the `use-mock-keychain` default argument if you
encounter authentication problems.

For example, using the standard location of the default user profile on macOS:

```json
{
"name": "chrome",
"addArguments": [
"user-data-dir=/Users/<username>/Library/Application Support/Google/Chrome"
],
"removeArguments": ["use-mock-keychain"]
"benchmarks": [
{
"url": "mybench.html",
"browser": {
"name": "chrome",
"profile": "/Users/<username>/Library/Application Support/Google/Chrome",
"removeArguments": ["use-mock-keychain"]
}
}
]
}
```

#### Firefox

To find your current profile location in Firefox, visit `about:support` and look
for "Profile Folder" or "Profile Directory".

Note when using the `profile` option in Firefox, the profile directory is copied
to a temporary location.

<!-- TODO(aomarks) Send a PR to selenium-webdriver to fix this stat error. -->

You may encounter a `no such file or directory, stat '.../lock'` error, due to a
bug in `selenium-webdriver`. Deleting this `lock` file should resolve the error.

For example, using the standard location of user profiles on macOS:

```json
{
"benchmarks": [
{
"url": "mybench.html",
"browser": {
"name": "firefox",
"profile": "/Users/<username>/Library/Application Support/Firefox/Profiles/<profile-name>"
}
}
]
}
```

Expand Down
8 changes: 8 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
],
"type": "string"
},
"profile": {
"description": "Path to a profile directory to use instead of the default temporary fresh\none.",
"type": "string"
},
"remoteUrl": {
"description": "A remote WebDriver server HTTP address to launch the browser from.",
"type": "string"
Expand Down Expand Up @@ -291,6 +295,10 @@
"description": "Advanced preferences that are usually set from the about:config page\nin Firefox (see\nhttps://support.mozilla.org/en-US/kb/about-config-editor-firefox).",
"type": "object"
},
"profile": {
"description": "Path to a profile directory to use instead of the default temporary fresh\none.",
"type": "string"
},
"remoteUrl": {
"description": "A remote WebDriver server HTTP address to launch the browser from.",
"type": "string"
Expand Down
16 changes: 16 additions & 0 deletions src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ export interface BrowserConfig {
preferences?: {[name: string]: string | number | boolean};
/** Trace browser performance logs configuration */
trace?: TraceConfig;
/** Path to profile directory to use instead of the default fresh one. */
profile?: string;
}

/**
Expand Down Expand Up @@ -105,6 +107,7 @@ export function browserSignature(config: BrowserConfig): string {
config.removeArguments ?? [],
config.cpuThrottlingRate ?? 1,
config.preferences ?? {},
config.profile ?? '',
]);
}

Expand Down Expand Up @@ -243,6 +246,9 @@ function chromeOpts(config: BrowserConfig): chrome.Options {
}
const {width, height} = config.windowSize;
opts.addArguments(`--window-size=${width},${height}`);
if (config.profile) {
opts.addArguments(`user-data-dir=${config.profile}`);
}
return opts;
}

Expand All @@ -262,6 +268,16 @@ function firefoxOpts(config: BrowserConfig): firefox.Options {
const {width, height} = config.windowSize;
opts.addArguments(`-width=${width}`);
opts.addArguments(`-height=${height}`);
if (config.addArguments) {
opts.addArguments(...config.addArguments);
}
if (config.profile) {
// Note there is also a `-profile` flag for Firefox that could be set with
// `addArguments`, but using that causes Selenium to timeout trying to
// connect to the browser process. This `setProfile` method creates a
// temporary copy of the profile.
opts.setProfile(config.profile);
}
return opts;
}

Expand Down
15 changes: 15 additions & 0 deletions src/configfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ interface ChromeConfig extends BrowserConfigBase {
* Optional config to turn on performance tracing.
*/
trace?: TraceConfig | true;

/**
* Path to a profile directory to use instead of the default temporary fresh
* one.
*/
profile?: string;
}

/**
Expand Down Expand Up @@ -285,6 +291,12 @@ interface FirefoxConfig extends BrowserConfigBase {
* https://support.mozilla.org/en-US/kb/about-config-editor-firefox).
*/
preferences?: {[name: string]: string | number | boolean};

/**
* Path to a profile directory to use instead of the default temporary fresh
* one.
*/
profile?: string;
}

interface SafariConfig extends BrowserConfigBase {
Expand Down Expand Up @@ -526,6 +538,9 @@ function parseBrowserObject(config: BrowserConfigs): BrowserConfig {
};
}
}
if ('profile' in config && config.profile !== undefined) {
parsed.profile = config.profile;
}
return parsed;
}

Expand Down

0 comments on commit 724dbd5

Please sign in to comment.