-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Improve automated webdriver setup documentation #11128
Conversation
packages/wdio-types/src/Options.ts
Outdated
@@ -43,24 +43,31 @@ export interface Connection { | |||
/** | |||
* Protocol to use when communicating with the Selenium standalone server (or driver). | |||
* | |||
* If you specify a value other than the default, the webdriver won't be started automatically. |
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.
Reference:
webdriverio/packages/wdio-utils/src/driver/utils.ts
Lines 257 to 265 in aa35c29
export function definesRemoteDriver(options: Pick<Options.WebDriver, 'user' | 'key' | 'protocol' | 'hostname' | 'port' | 'path'>) { | |
return Boolean( | |
(options.protocol && options.protocol !== DEFAULT_PROTOCOL) || | |
(options.hostname && options.hostname !== DEFAULT_HOSTNAME) || | |
Boolean(options.port) || | |
(options.path && options.path !== DEFAULT_PATH) || | |
Boolean(options.user && options.key) | |
) | |
} |
and
webdriverio/packages/wdio-utils/src/driver/manager.ts
Lines 52 to 53 in aa35c29
// - we are not about to run a cloud session | |
!definesRemoteDriver(options) && |
Applies for all other documentation updates in this file.
* @default 'localhost' | ||
*/ | ||
hostname?: string | ||
/** | ||
* Port your WebDriver server is on. | ||
* | ||
* @default 4444 |
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.
Ref:
webdriverio/packages/webdriver/src/constants.ts
Lines 20 to 25 in aa35c29
/** | |
* port of automation driver | |
*/ | |
port: { | |
type: 'number' | |
}, |
website/docs/Capabilities.md
Outdated
|
||
:::caution | ||
|
||
If you set a driver binary, the browser won't be downloaded automatically. You'll need to have the corresponding browser already installed or specify a binary path as previously shown. |
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.
Ref:
webdriverio/packages/wdio-utils/src/driver/manager.ts
Lines 56 to 57 in aa35c29
// - driver options don't define a binary path | |
!getDriverOptions(cap).binary |
and
webdriverio/packages/wdio-utils/src/driver/utils.ts
Lines 161 to 170 in aa35c29
export function getDriverOptions (caps: Capabilities.Capabilities) { | |
return ( | |
caps['wdio:chromedriverOptions'] || | |
caps['wdio:geckodriverOptions'] || | |
caps['wdio:edgedriverOptions'] || | |
// Safaridriver does not have any options as it already | |
// is installed on macOS | |
{} | |
) | |
} |
Applies for all other :::caution
entries on this file.
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 mentioned before already when we document binary
for within the common driver options:
binary
Path to a custom driver binary. If set WebdriverIO won't attempt to download a driver but will use the one provided by this path. Make sure the driver is compatible with the browser you are using.
I think repeating this for all browser again isn't ideal.
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.
Oh, I missed that! OK, I'm going to remove this in favor of promoting that to a :::caution
so it gets more prominency.
website/docs/Capabilities.md
Outdated
|
||
:::caution | ||
|
||
WebdriverIO won't automatically download Microsoft Edge. Only Chrome and Firefox are supported. |
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.
Ref:
webdriverio/packages/wdio-utils/src/driver/manager.ts
Lines 118 to 120 in aa35c29
if (isEdge(cap.browserName)) { | |
// not yet implemented | |
return Promise.resolve() |
website/docs/Capabilities.md
Outdated
|
||
WebdriverIO won't automatically download Microsoft Edge. Only Chrome and Firefox are supported. | ||
|
||
If you set a browser binary and omit the browser version and driver binary, WebdriverIO will auto-determine the driver version to download based on the automatically detected Microsoft Edge installation. In some environments, the detected browser may be different from the specified binary. Therefore, it's recommended to always specify the browser version when specifying a browser binary and omitting the driver binary. |
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.
Ref:
webdriverio/packages/wdio-utils/src/driver/manager.ts
Lines 101 to 102 in aa35c29
if (isEdge(cap.browserName)) { | |
return setupEdgedriver(cacheDir, cap.browserVersion) |
and
webdriverio/packages/wdio-utils/src/driver/utils.ts
Lines 245 to 247 in aa35c29
export function setupEdgedriver (cacheDir: string, driverVersion?: string) { | |
return downloadEdgedriver(driverVersion, cacheDir) | |
} |
and
webdriverio-community/node-edgedriver@7f2fc5d5b/src/install.ts:25-30
website/docs/Capabilities.md
Outdated
``` | ||
|
||
:::info | ||
|
||
WebdriverIO won't automatically download Safari driver as it is already installed on macOS. |
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.
Ref:
webdriverio/packages/wdio-utils/src/driver/utils.ts
Lines 161 to 170 in aa35c29
export function getDriverOptions (caps: Capabilities.Capabilities) { | |
return ( | |
caps['wdio:chromedriverOptions'] || | |
caps['wdio:geckodriverOptions'] || | |
caps['wdio:edgedriverOptions'] || | |
// Safaridriver does not have any options as it already | |
// is installed on macOS | |
{} | |
) | |
} |
website/docs/Capabilities.md
Outdated
browserVersion: '116' // or '116.0.5845.96', 'stable', 'dev', 'canary', 'beta' | ||
browserVersion: '116.0.5845.96' // or 'stable', 'latest', 'dev', 'canary', 'beta' |
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.
You can't use 116
. Ref:
webdriverio/packages/wdio-utils/src/driver/utils.ts
Lines 138 to 150 in aa35c29
const tag = browserName === Browser.CHROME | |
? caps.browserVersion || ChromeReleaseChannel.STABLE | |
: caps.browserVersion || 'latest' | |
const buildId = await resolveBuildId(browserName, platform, tag) | |
const installOptions: InstallOptions & { unpack?: true } = { | |
unpack: true, | |
cacheDir, | |
platform, | |
buildId, | |
browser: browserName, | |
downloadProgressCallback: (downloadedBytes, totalBytes) => downloadProgressCallback(`${browserName} (${buildId})`, downloadedBytes, totalBytes) | |
} | |
const isCombinationAvailable = await canDownload(installOptions) |
and running:
await (async () => {
const { canDownload, detectBrowserPlatform, resolveBuildId } = await import('@puppeteer/browsers')
const browser = 'chrome'
const platform = detectBrowserPlatform()
const results = []
for (const tag of ['116', '116.0.5845.96', 'stable', 'latest', 'dev', 'canary', 'beta']) {
const buildId = await resolveBuildId(browser, platform, tag)
const result = await canDownload({
browser,
platform,
buildId,
})
results.push(`${tag}: ${result}`)
}
return results
})()
returns
[
'116: false',
'116.0.5845.96: true',
'stable: true',
'latest: true',
'dev: true',
'canary: true',
'beta: 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.
This actually works for me:
[
'116: true',
'116.0.5845.96: true',
'stable: true',
'latest: true',
'dev: true',
'canary: true',
'beta: 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.
I ran the code using @puppeteer/browsers
version 1.4.6
(used here) that's why I got a different result from you.
Running it with @puppeteer/browsers
version 1.7.0
(used here) I get the same result as you. Will revert.
That being said, using just the major version with firefox
does not work, even with @puppeteer/browsers
version 1.7.0
:
await (async () => {
const { canDownload, detectBrowserPlatform, resolveBuildId } = await import('@puppeteer/browsers')
const browser = 'firefox'
const platform = detectBrowserPlatform()
const results = []
for (const tag of ['119', '119.0a1', 'latest']) {
const buildId = await resolveBuildId(browser, platform, tag)
const result = await canDownload({
browser,
platform,
buildId,
})
results.push(`${tag}: ${result}`)
}
return results
})()
I get:
[
'119: false',
'119.0a1: true',
'latest: true'
]
packages/wdio-types/src/Options.ts
Outdated
@@ -43,24 +43,31 @@ export interface Connection { | |||
/** | |||
* Protocol to use when communicating with the Selenium standalone server (or driver). | |||
* | |||
* If you specify a value other than the default, the webdriver won't be started automatically. |
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 think we should mention this in a separate section here: https://webdriver.io/docs/driverbinaries rather than as part of the comment.
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.
Sounds good, I'll add a bit more information there then.
packages/webdriver/README.md
Outdated
@@ -103,25 +103,34 @@ Options: *trace* | *debug* | *info* | *warn* | *error* | *silent* | |||
### protocol | |||
Protocol to use when communicating with the Selenium standalone server (or driver). | |||
|
|||
If you specify a value other than the default, the webdriver won't be started automatically. |
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.
same
packages/webdriver/README.md
Outdated
Type: `Number`<br /> | ||
Default: *4444* | ||
Default: `null` |
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.
The default value is not null
, it is not defined
Default: `null` |
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.
Yes, I was aware. I was just following the standard set by the other parameters:
webdriverio/packages/webdriver/README.md
Lines 128 to 132 in b79e085
### queryParams | |
Query parameters that are propagated to the driver server. | |
Type: `Object` | |
Default: `null` |
webdriverio/packages/webdriver/src/constants.ts
Lines 40 to 45 in b79e085
/** | |
* A key-value store of query parameters to be added to every selenium request | |
*/ | |
queryParams: { | |
type: 'object' | |
}, |
I will update the documentation to indicate undefined
instead.
website/docs/Capabilities.md
Outdated
browserVersion: '116' // or '116.0.5845.96', 'stable', 'dev', 'canary', 'beta' | ||
browserVersion: '116.0.5845.96' // or 'stable', 'latest', 'dev', 'canary', 'beta' |
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 actually works for me:
[
'116: true',
'116.0.5845.96: true',
'stable: true',
'latest: true',
'dev: true',
'canary: true',
'beta: true'
]
website/docs/Capabilities.md
Outdated
|
||
:::caution | ||
|
||
If you set a driver binary, the browser won't be downloaded automatically. You'll need to have the corresponding browser already installed or specify a binary path as previously shown. |
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 mentioned before already when we document binary
for within the common driver options:
binary
Path to a custom driver binary. If set WebdriverIO won't attempt to download a driver but will use the one provided by this path. Make sure the driver is compatible with the browser you are using.
I think repeating this for all browser again isn't ideal.
website/docs/Configuration.md
Outdated
Type: `Number`<br /> | ||
Default: `4444` | ||
Default: `null` |
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.
Default: `null` |
website/docs/Configuration.md
Outdated
@@ -13,27 +13,35 @@ The following options are defined when using the [`webdriver`](https://www.npmjs | |||
|
|||
Protocol to use when communicating with the driver server. | |||
|
|||
If you specify a value other than the default, the webdriver won't be started automatically. |
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.
same as mentioned above
website/docs/DriverBinaries.md
Outdated
{ | ||
capabilities: [ | ||
{ | ||
browserName: 'chrome', // or 'firefox', 'msedge' |
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.
browserName: 'chrome', // or 'firefox', 'msedge' | |
browserName: 'chrome', // or 'firefox', 'msedge', 'safari' |
website/docs/DriverBinaries.md
Outdated
}, | ||
|
||
afterSession() { | ||
cp?.kill(); |
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.
cp
is not defined
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.
Oops, copy/paste from a toy I had and forgot to rename that. That being said, I will be removing this.
website/docs/DriverBinaries.md
Outdated
} | ||
``` | ||
|
||
The previous configuration will indicate WebdriverIO to automatically start/stop the specified `chromedriver` binary using an arbitrary unused port. If you need more control over the driver, simply specify a value for [port](configuration#port) and WebdriverIO will skip the automated start/stop. For example: |
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 am not sure if it is valuable to document this. You example works for a single session but it becomes a lot more complex when multiple sessions are involved. Furthermore you example does the same as when using WebdriverIOs built-in setup because Geckodriver is downloaded when you call start
so it will fail without network connections too.
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 am not sure if it is valuable to document this.
Agreed, it's very use-case specific, and the ## Manual setup
provides enough information on how to get/start the drivers.
Furthermore you example does the same as when using WebdriverIOs built-in setup because Geckodriver is downloaded when you call
start
so it will fail without network connections too.
Yeah, I missed to specify the customGeckoDriverPath
parameter, which unfortunately is broken. In other words, this won't work:
{
browserName: 'firefox',
'wdio:geckodriverOptions': {
binary: '/path/to/geckodriver'
}
}
That being said, I have created webdriverio-community/node-geckodriver#222 to fix it.
Thanks for the review @christian-bromann! I have replied to all your comments and pushed a new revision. Hope this addresses all your feedback. |
website/docs/DriverBinaries.md
Outdated
|
||
:::caution | ||
|
||
If you specify a browser `binary` but omit the `browserVersion` and its corresponding driver `binary`, WebdriverIO will auto-determine the driver version to download based on the auto-detected browser installation. In some environments, the auto-detected browser version may differ from the specified binary. Therefore, it's recommended to always specify the browser version when specifying a browser binary and omitting the driver binary. |
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.
In some environments, the auto-detected browser version may differ from the specified binary.
Can you elaborate?
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.
Example 1
Say you have a linux
machine with the following:
firefox
versionA
installed in/path/to/firefox
Then you use the following wdio
configuration:
{
browserName: 'firefox',
'moz:firefoxOptions': {
binary: '/path/to/firefox'
}
}
This will invoke setupGeckodriver("...", undefined)
in wdio
:
webdriverio/packages/wdio-utils/src/driver/manager.ts
Lines 103 to 106 in aa35c29
} else if (isFirefox(cap.browserName)) { | |
// "latest" works for setting up browser only but not geckodriver | |
const version = cap.browserVersion === 'latest' ? undefined : cap.browserVersion | |
return setupGeckodriver(cacheDir, version) |
import { download as downloadGeckodriver } from 'geckodriver' |
webdriverio/packages/wdio-utils/src/driver/utils.ts
Lines 241 to 243 in aa35c29
export function setupGeckodriver (cacheDir: string, driverVersion?: string) { | |
return downloadGeckodriver(driverVersion, cacheDir) | |
} |
Then in geckodriver
:
// get latest version of Geckodriver
if (!geckodriverVersion) {
// ...
}
The version you'll end up getting will be the latest which may not be compatible with firefox
version A
.
Example 2
Say you have a linux
machine with the following:
edge
versionA
installed in/usr/bin/microsoft-edge
edge
versionB
installed in/path/to/microsoft-edge
PATH
environment variable set to/usr/bin
Then you use the following wdio
configuration:
{
browserName: 'msedge',
'ms:edgeOptions': {
binary: '/path/to/microsoft-edge'
}
}
This will invoke setupEdgedriver("...", undefined)
in wdio
:
webdriverio/packages/wdio-utils/src/driver/manager.ts
Lines 101 to 102 in aa35c29
if (isEdge(cap.browserName)) { | |
return setupEdgedriver(cacheDir, cap.browserVersion) |
import { download as downloadEdgedriver } from 'edgedriver' |
webdriverio/packages/wdio-utils/src/driver/utils.ts
Lines 245 to 247 in aa35c29
export function setupEdgedriver (cacheDir: string, driverVersion?: string) { | |
return downloadEdgedriver(driverVersion, cacheDir) | |
} |
Then in edgedriver
(ref1, ref2):
// install.ts
import findEdgePath from './finder.js'
// ...
export async function download (
edgeVersion: string = process.env.EDGEDRIVER_VERSION,
cacheDir: string = process.env.EDGEDRIVER_CACHE_DIR || os.tmpdir()
) {
// ...
if (!edgeVersion) {
const edgePath = findEdgePath()
log.info(`Trying to detect Microsoft Edge version from binary found at ${edgePath}`)
edgeVersion = os.platform() === 'win32' ? await getEdgeVersionWin(edgePath) : await getEdgeVersionUnix(edgePath)
log.info(`Detected Microsoft Edge v${edgeVersion}`)
}
}
// finder.ts
// Look for edge by using the which command
function linux() {
// ...
return findByWhich(
EDGE_BINARY_NAMES,
[{ regex: EDGE_REGEX, weight: 51 }]
)
}
The version you'll up getting will be A
, yet you wanted the driver for B
.
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 see, to summarise this: if you define either a browser or a driver binary but not both, you will likely end up having no matching binaries and your test will fail. Do you think we can formulate it like this somehow? I had to read the sentence a couple of times without really understanding what it means 🙈
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, I've reworded the paragraph. Hopefully this does the trick.
@christian-bromann OK, I've replied to your comments and published a new revision. Third time's the charm 🤞! |
WHAT? Improve the automated webdriver setup documentation introduced in `8.14`. WHY? While this feature is awesome, I have a test setup environment with no Internet access. I was confused on how to disable this feature since the documentation did not cover this topic in depth. After looking into the source code to figure it out, I decided to pay-it-forward for other users by updating the documentation accordingly.
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.
Awesome, lgtm 🎉
Congrats on your first WebdriverIO contribution 🎉 This is awesome stuff! |
Thanks!Took a bit more tries than I anticipated, but I'm glad we were able to sort them out! |
WHAT? Fix an incorrect statement that says `browserVersion` is used to locate an existing installation of the browser, when in reality instead it always trigger a download. WHY? When I contributed #11128, I misunderstood the `browserVersion` logic. This update corrects this misunderstanding. HOW? Manually reviewed [packages/wdio-utils/src/driver/utils.ts][1] [1]: https://github.com/webdriverio/webdriverio/blob/v8.16.7/packages/wdio-utils/src/driver/utils.ts
Proposed changes
Improve the automated webdriver setup documentation introduced in
8.14
.While this feature is awesome, I have a test setup environment with no Internet access. I was confused on how to disable this feature since the documentation did not cover this topic in depth. After looking into the source code to figure it out, I decided to pay-it-forward for other users by updating the documentation accordingly.
Types of changes
Checklist
Further comments
N/A
Reviewers: @webdriverio/project-committers