18

We have Cucumber Ruby automation framework where we run few tests on Chrome headless browser in a Docker on Jenkins. A few days ago we started receiving an error "This version of ChromeDriver only supports Chrome version 75" this time we were using ChromeDriver 2.46 and with google-chrome-unstable browser using the following command:

#Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update -y
RUN apt-get install -y google-chrome-unstable
RUN apt-get install unzip

# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_VERSION 2.46
ENV CHROMEDRIVER_VERSION 75.0.3770.8
ENV CHROMEDRIVER_DIR /chromedriver
RUN mkdir $CHROMEDRIVER_DIR
# Download and install Chromedriver
RUN wget -q --continue -P $CHROMEDRIVER_DIR "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip"
RUN unzip $CHROMEDRIVER_DIR/chromedriver* -d $CHROMEDRIVER_DIR
ENV PATH $CHROMEDRIVER_DIR:$PATH

I have now updated chromedriver version to 75.0.3770.8 and browser to google-chrome-beta=75.0.3770.27-1

#Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update -y
RUN apt-get install -y google-chrome-beta=75.0.3770.27-1
RUN apt-get install unzip

# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_VERSION 75.0.3770.8
ENV CHROMEDRIVER_DIR /chromedriver
RUN mkdir $CHROMEDRIVER_DIR
RUN echo $CHROMEDRIVER_DIR
# Download and install Chromedriver
RUN wget -q --continue -P $CHROMEDRIVER_DIR "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip"
RUN unzip $CHROMEDRIVER_DIR/chromedriver* -d $CHROMEDRIVER_DIR
ENV PATH $CHROMEDRIVER_DIR:$PATH

And now I can see the error as:

unknown command: Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError)

Is it possible to disable W3C mode or download an older version of Chrome browser and driver that doesn't use it? I think the possibility to disable W3C check would be great.

DebanjanB
  • 118,661
  • 30
  • 168
  • 217
sugu
  • 173
  • 1
  • 1
  • 5
  • Do you know which command is called? Are you sure you want to run on betas? Why don't you run on `apt-get install -y google-chrome` and `CHROMEDRIVER_VERSION 74.0.3729.6` ? – lojza May 13 '19 at 12:01
  • Hi @lojza , thanks for responding! I think you mean to use `apt-get install -y google-chrome-stable` right? I have tried this combination and error that I get is **This version of ChromeDriver only supports Chrome version 75 (Selenium::WebDriver::Error::SessionNotCreatedError)**. Commands that are failing with new versions are: `wait_for expect(test).to have_test1 steps %Q{ } block` etc. Is there any way to download chrome version 73 with `apt-get install`? or is it possible to disable W3C check in latest chrome version? – sugu May 13 '19 at 14:21
  • Yes, sorry. Check your version of chrome with `google-chrome -version` and then download proper version of chrome driver as described here http://chromedriver.chromium.org/downloads/version-selection If you pass `"w3c": true` to chromeOptions it should work, check https://bugs.chromium.org/p/chromedriver/issues/detail?id=1942 – lojza May 13 '19 at 14:37
  • Thanks again lojza for quick response, I have tried multiple combinations with correct chrome driver version. But the issue is since last chrome update if I download `apt-get install -y google-chrome-stable` `google-chrome --version` is `74.0.3729.131` and if I download corresponding chromedriver version `74.0.3729.6` and run our tests I get `This version of ChromeDriver only supports Chrome version 75` so basically there is an issue that chromedriver `74.0.3729.6` is pointing to google-chrome 75 instead of 74. – sugu May 13 '19 at 16:58
  • Can you please tell me if there is any way to download `google-chrome 73` using `apt-get install` now as it is no longer a stable version? or for `google-chomre 75` can we disable w3c check? – sugu May 13 '19 at 16:58
  • Are you sure, you are running ChromeDriver 74? As I mention above try `ChromeOptions options = new ChromeOptions(); options.setCapability("w3c",true); driver = new ChromeDriver(options);` – lojza May 14 '19 at 07:05
  • yup, I'm sure. I was printing the version after installing it. The issue is ChromeDriver 74.0.3729.6 is expecting browser 75 version instead of 74. I have raised this bug with chromium https://bugs.chromium.org/p/chromedriver/issues/detail?id=2906. The workaround, for now, it to disable w3c on the new version by setting ChromeOption "w3c" to false. Thanks for your quick responses lojza. – sugu May 15 '19 at 14:32
  • Which version of selenium are You using? – SkorpEN Jul 10 '19 at 14:05

7 Answers7

23

All you have to do is just to disable the W3C when initializing the webdriver

options = webdriver.ChromeOptions()
options.add_experimental_option('w3c', False)
create_webdriver('Chrome', options=options)

Environment:

  • Chrome 75
  • ChromeDriver 75
  • 1
    Interesting that the more popular options recommend 'True', whereas this option with 'False' was the only one that worked for me. – Deskjokey Jun 08 '19 at 08:45
  • 1
    Thank you, this worked a treat for me! My Capybara Chrome setup was as follows (if this helps anyone). `Capybara.register_driver :headless_chrome do |app| capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( chromeOptions: { args: %w[headless disable-gpu], w3c: false } ) Capybara::Selenium::Driver.new( app, browser: :chrome, desired_capabilities: capabilities ) end` Apologies for the bad formatting of the code. – Joe Jun 09 '19 at 16:05
  • @Joe You should post that as a separate answer considering this is a Ruby-specific thread. I wouldn't have known how to implement Nhật Linh Nguyễn's solution without your translation! – Arepo Jun 18 '19 at 19:53
  • Please don't answer ruby questions with python, it confuses readers. – JeffC Jun 19 '19 at 21:52
  • @Arepo, thanks... although it looks like mahi-man already has. – Joe Jul 08 '19 at 18:53
18

This error message...

unknown command: Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError)

...implies that the ChromeDriver was unable to call non W3C standard command while in W3C mode while initiating/spawning a new WebBrowser i.e. Chrome Browser session.

Here the main issue is, when ChromeDriver's client requests a W3C-compliant session but the response from ChromeDriver does not conform to the W3C spec, and causes errors in language APIs.


Analysis

As per the discussion in ChromeDriver response in W3C mode is not standard compliant John Chen (Owner - WebDriver for Google Chrome) mentioned that, Simon Stewart (Creator - WebDriver) had updated that:

  • The new session response for a w3c session should look like:

    {
      "value": {
        "sessionId": "some-uuid",
        "capabilities": {
          "browserName": "chrome",
          ...
        }
      }
    }
    
  • But when starting a new session with the w3c option set to true in the chromeOptions as follows:

    • Selenium/Python:

      from selenium import webdriver
      opt = webdriver.ChromeOptions()
      opt.add_experimental_option('w3c', True)
      driver = webdriver.Chrome(chrome_options=opt)
      
    • Selenium/Java:

      {
        "sessionId": "af4656c27fb94485b7872e1fc616923a",
        "status": "ok",
        "value": {
          "browserName": "chrome",
          ...
        }
      }
      
  • The returned response looks like:

    {
      "sessionId": "af4656c27fb94485b7872e1fc616923a",
      "status": "ok",
      "value": {
        "browserName": "chrome",
        ...
      }
    }
    

Which is neither a correctly formed response for the JSON Wire Protocol (where "status" would be an integer), nor a correctly formed W3C response and without a correctly formed response, the w3c compatible cannot be used.

This revision and this commit addressed this issue.


This usecase

As you are using ChromeDriver v75.x and Chrome v75.x and you are still seeing the same error, you need to pass the ExperimentalOption w3c as true exclusively as follows:

capabilities = { "chromeOptions" => {'w3c' => true} }

Update

Till ChromeDriver v74.x, Chrome and ChromDriver combo was running in w3c mode by default but there was bug with in the chromedriver/server/http_handler.cc. As per the details in goog:chromeOptions.w3c=false doesn't work for POST request with empty body:

Method HttpHandler::HandleCommand checks the value of the kW3CDefault constant instead of session goog:chromeOptions.w3c value. As a result, JSON Wire protocol support was broken, where POST requests with an empty body are allowed. JSON Wire protocol will be in demand until displayed endpoint is resumed in the w3c mode. It should be noted that W3C WebDriver specification doesn't forbid the use of 'displayed' endpoint and this feature is actively used in some APIs.

As Is Element Displayed command is not part of W3C spec, but is still used by some APIs, and its functionality can be difficult to replicate in those APIs. This Change List [revision and commit] re-enables this command in W3C mode to ease transition to W3C mode.

@John have already confirmed us to expect an update to ChromeDriver v75.0 tomorrow with the fix.


Here's the solution

As promised by John Chen [Owner - WebDriver for Google Chrome], ChromeDriver versions 75.0.3770.90 and 76.0.3809.25 have been released, and are now available at the ChromeDriver Downloads site. These versions include the following bug fixes over the previous releases of ChromeDriver 75 and 76:

  • Fixed a bug that incorrectly rejected POST requests with empty body in OSS mode
  • Added new endpoints for retrieving Chrome log

In addition, version 76.0.3809.25 also includes the following change:

  • Added endpoint for Is Displayed command in W3C mode

Snapshot

75_76

DebanjanB
  • 118,661
  • 30
  • 168
  • 217
  • 1
    The question is on Ruby, not python/Java. This answer is WAY too verbose... just answer the question. He's not trying to build the watch... he just wants to know what time it is. – JeffC Jun 19 '19 at 21:51
  • 3
    v75.0.3770.90 doesn't fix this problem because it doesn't contain the 'Is Displayed' endpoint. The v76 update does solve the problem... but it's still in beta :/ – PinnyM Jun 20 '19 at 14:09
  • 12
    This was a very useful analysis and it helped me understand the underlying problem. Sometimes people *are* interested in knowing why the fix they're making works or doesn't work and this was great at tying up various threads for me. – Gareth Jun 25 '19 at 15:34
10

If you are getting this error using rails + rspec + capybara + selenium, the way to pass the option to disable W3C is as follows:

Capybara.register_driver :chrome do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {'w3c' => false}
  )
  Capybara::Selenium::Driver.new(app, :browser => :chrome, desired_capabilities: capabilities)
end
mahi-man
  • 2,961
  • 1
  • 22
  • 31
1

Not sure what framework you're using but i have the same error after updating my browser & chromedriver to latest one v75.0.3770.90. My suggestion is that looking for the session init section in your scripts and add the option to disable w3c. E.g mine before upgrading:

chrome_options = Selenium::WebDriver::Chrome::Options.new
options[:options] = chrome_options
Capybara::Selenium::Driver.new(app, options)

after upgrading

chrome_options = Selenium::WebDriver::Chrome::Options.new
chrome_options.add_option('w3c',false)
options[:options] = chrome_options
Capybara::Selenium::Driver.new(app, options)
Dinh Luong
  • 139
  • 13
1

Just add w3c: false in the end like in this example:

  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: { args: ["window-size=#{DEFAULT_X_RES},#{DEFAULT_Y_RES}"], w3c: false })
Daniel
  • 11
  • 1
1

For my PHP friends who search the depths of the internet...
The newest version of PHPUnit_Extensions_Selenium2TestCase

Which is at the moment a composer constraint of

"phpunit/phpunit-selenium": ">=7",
"phpunit/phpunit": ">=6" 

Can use the following options. Note my struggle::

'w3c' => false

This must be a boolean and not a string.

class NavigationTest extends PHPUnit_Extensions_Selenium2TestCase
{

    public function setUp()
    {
        static $count;
        $count or $count = 1 and print PHP_EOL . 'java -jar ' . dirname(__DIR__) . '/selenium-server-standalone-3.141.59.jar' . PHP_EOL;
        self::shareSession(true);
        $this->setDesiredCapabilities([
            "chromeOptions" => [
                'w3c' => false
            ]
        ]);
        $this->setHost('localhost');
        $this->setPort(4444);
        $this->setBrowser('chrome');
        $this->setBrowserUrl('http://localhost:9919/');
        $this->prepareSession()->currentWindow()->maximize();

    }
}
Tyler Miles
  • 346
  • 2
  • 13
0

In my case it was different version of selenium that not supported w3c. Decrease chromedriver to version 74.0.3729.6 make all work work. It could also be fixed by updateing selenium version to latest that support W3C.

SkorpEN
  • 1,367
  • 15
  • 23