Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError) with Selenium ChromeDriver in Cucumber Ruby
Solution 1:
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
Solution 2:
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 totrue
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.
- Relevant part of the spec: https://w3c.github.io/webdriver/webdriver-spec.html#new-session
- Relevant tests from spec: https://github.com/w3c/web-platform-tests/pull/5187
- ChromeDriver version: 2.31.488774 (7e15618d1bf16df8bf0ecf2914ed1964a387ba0b)
- Chrome version: 60.0.3112.90 (Official Build) (64-bit)
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 thekW3CDefault
constant instead of sessiongoog: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 untildisplayed
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
Solution 3:
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
Solution 4:
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)
Solution 5:
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 })