If you are using Protractor to test your web application against the Google Chrome browser, you might have come accross the following error message:
E/runner - Unable to start a WebDriver session.
E/launcher - Error: SessionNotCreatedError: session not created:
This version of ChromeDriver only supports Chrome version 114
Current browser version is <SOME_VERSION> with binary path <SOME_PATH>
So, why is this error happening and how to avoid it, while still being able to test against a recent version of Chrome?
If you just want to know how to solve the issue, go straight to How to get rid of the error?.
Overview of key components
To understand why this is happening, let's first get an overview of the key components involved in running end-to-end tests with Protractor.
On one end is the browser that the tests are going to run on. On the other end is Protractor, which needs to read the test files, translate them to browser operations, send them to the browser and get back the test results. In order for Protractor to be able to communicate with a browser, an intermediary "driver" is needed. There are drivers for each of the supported browsers, all following the W3C WebDriver Standard. For Chrome specifically, there is ChromeDriver.
Now, there are a couple of different routes that Protractor can take to communicate with the browser, but all involve the use of an appropriate WebDriver:
- Communicate with the browser directly. This is what happens when you use directConnect: true in your Protractor configuration.
(NOTE: This only works for Chrome and Firefox.) - Communicate with the browser through a local Selenium Server instance. This is what happens when you use the seleniumServerJar option in your Protractor configuration or use the seleniumAddress option to bind to a locally running instance.
- Communicate with the browser through a remote Selenium Server instance. This is what happens when you use the seleniumAddress option in your Protractor configuration to bind to a remotely running instance or use a cloud-based testing platform, such as BrowserStack or SauceLabs.
Also, keep in mind that each browser version is only compatible with specific versions of the corresponding WebDriver.
To deal with the complexity of getting the necessary WebDrivers at appropriate versions and optionally getting and running a Selenium Server, Protractor uses another library, webdriver-manager.
Why is the error happening?
At some point, the process and APIs involved in identifying and downloading a ChromeDriver binary version for a version of Chrome changed. This change affects Chrome/ChromeDriver versions 115 and newer. You can find more details about the changes here.
As a result, webdriver-manager
is no longer able to locate and download any ChromeDriver version newer than v114. Consequently, when Protractor relies on webdriver-manager
, it can only communicate with Chrome versions around v114. This is problematic since, as of the time of writing, the stable Chrome version is 126.
There are also some discussions about the issue on the webdriver-manager repository on GitHub, for example here and here.
How to get rid of the error?
If you are affected by this issue, the easiest way to solve it is by taking charge of providing the ChromeDriver binary to Protractor/Selenium, instead of relying on webdriver-manager
for that. Fortunately, there is another npm package that can greatly help with that: chromedriver
- Add chromedriver to your
devDependencies
inpackage.json
. The version of thechromedriver
package directly matches the version of ChromeDriver that it will download by default, which correlates to the version of Chrome you can "drive". In most cases, you should install the latest available version.
- Optionally, you can configure
chromedriver
to auto-detect the installed version of Chrome and download an appropriate version of ChromeDriver. This is useful when the tests are going to run on different environments, with different versions of Chrome.
One way to do this, is to adddetect_chromedriver_version=true
to your.npmrc
file. See the chromedriver package documentation for more information on available configuration options.
- Run
npm install
to install the newly addedchromedriver
package. As part of the installation process,chromedriver
will also download a version of the ChromeDriver binary.
By following the above steps, you will end up with an appropriate version of ChromeDriver. Now, you need to instruct Protractor/Selenium to use it. This involves different steps depending on how Protractor is communicating with the browser.
Case 1: directConnect
or seleniumServerJar
If you are using directConnect: true or the seleniumServerJar option in your Protractor configuration, you need to let Protractor know where to find the ChromeDriver binary by using the chromeDriver configuration option:
// protractor.conf.js
exports.config = {
chromeDriver: require('chromedriver').path,
// ...
};
Case 2: seleniumAddress
and webdriver-manager
If you are using the seleniumAddress option in your Protractor configuration to bind to an already running Selenium Server instance (typically started with webdriver-manager start
), then you need to make the following changes:
- Configure
webdriver-manager
to not download a ChromeDriver binary (which it does by default), so that the Selenium Server will instead find and use our version. For example, if you run the commandnpx webdriver-manager update
, change it tonpx webdriver-manager update --no-chrome
.
- Ensure that the
node_modules/.bin/
directory is on thePATH
environment variable when starting the Selenium Server. This will allow the server to find and use the ChromeDriver binary downloaded by thechromedriver
package.
A straightforward way to achieve this is to run the start command from an npm script, which, by default, augments the PATH with package executables. For example, add a script in yourpackage.json
to start the Selenium Server:
// package.json
{
"scripts": {
"start-selenium": "webdriver-manager start",
// ...
},
// ...
} - On Windows, the Selenium Server gets confused by the
node_modules/.bin/chromedriver
executable, which is intended for UNIX-based systems, and fails to use the correct executable:node_modules/.bin/chromedriver.cmd
If your tests are going to be run on Windows as well, one way to fix this is to add apostinstall
npm script to yourpackage.json
to remove the unneeded executable on Windows machines. For example:// package.json
Don't forget to run
{
"scripts": {
"postinstall": "node --eval \"os.platform().startsWith('win') && fs.unlinkSync('node_modules/.bin/chromedriver')\"",
// ...
},
// ...
}npm install
once again after you define the script, so that it runs on the already installed executables.
Conclusion
By making these changes, you can circumvent webdriver-manager
's inability to download newer versions of ChromeDriver and will again be able to run your end-to-end tests with Protractor against the most recent versions of the Google Chrome browser.