6

On firefox, browser.keys throwing error.

Os: MacOs
Firefox version: 53.0.3
Geckodriver: 0.16.1
Webdriver.io: 4.8

Please help me how to deal with this error.

Here are the logs

[17:11:35]  COMMAND POST     "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/url"
[17:11:41]  COMMAND POST     "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/refresh"
[17:11:45]  COMMAND GET      "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/window/current/size"
[17:11:46]  COMMAND POST     "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/elements"
[17:11:46]  COMMAND GET      "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/element/0/displayed"
[17:11:46]  COMMAND GET      "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/element/1/displayed"
[17:11:46]  COMMAND POST     "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/elements"
[17:11:46]  COMMAND GET      "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/element/0/displayed"
[17:11:46]  COMMAND GET      "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/element/1/displayed"
[17:11:46]  COMMAND POST     "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/elements"
[17:11:47]  COMMAND POST     "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/element/0/value"
WARNING: the "keys" command will be depcrecated soon. Please use a different command in order to avoid failures in your test after updating WebdriverIO.
[17:11:47]  COMMAND POST     "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/keys"
[17:11:47]  COMMAND GET      "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/screenshot"
[17:11:48]      Saved screenshot: ERROR_firefox_2017-06-03T00-11-47.734Z.png
[17:11:48]  COMMAND DELETE   "/wd/hub/session/97804a03-d52a-4232-9e3c-41e1fac6a9c5/cookie"
Error: sendKeysToActiveElement
Build info: version: '3.4.0', revision: 'unknown', time: 'unknown'
System info: host: 'xxx.local', ip: '10.142.4.252', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.5', java.version: '1.8.0_131'
Driver info: driver.version: RemoteWebDriver
Error: The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.
    at Object.wait (/Users/xxxx/c3web/xxxx/node_modules/fibers/future.js:449:15)
    at Object.keys (/Users/xxxxx/node_modules/wdio-sync/build/index.js:264:31)
    at Object.exports.customCommands.selector (/Users/xxx/c3web/xxxx/testlib/browser/customCommands.js:158:17)
    at /Users/xxxx/node_modules/wdio-sync/build/index.js:191:29
    - - - - -
    at keys("Enter") - index.js:244:37
    at elementIdValue("0", "xxxyyyzzz") - index.js:293:3
LookAtSrc
  • 133
  • 2
  • 8

3 Answers3

11

As @iamdanchiv mentioned in his answer, the browser.keys() will be deprecated, but there is a workaround (and I should submit a PR for this).

What browser.keys() does under the hood is to call the /session/:sessionId/keys endpoint in the WebDriver JsonWire protocol. However, if you look at the list of endpoints in the W3C Webdriver's specification, this endpoint is not in the list. I believe it was previously part of the list, but has been dropped. Instead, to send keys, the specification states to use the /session/:sessionId/element/:elementId/value endpoint instead, which you can use webdriverio's browser.elementIdValue(ID, value) method to call.

Now, if you read up on the specifications of /session/:sessionId/keys mentioned in Selenium's documentation on the JsonWireProtocol it is pretty easy to do replicate the implementation using other WebDriver functionalities. The /session/:sessionId/keys endpoint simply does this:

Sends a sequence key strokes to the active element.

There is an endpoint we can call to grab the current active element, which is /session/:sessionId/element/active, which is mapped to webdriverio's browser.elementActive() method.

At such, all we need to do is to reimplement this browser.keys() is to find out first what's the active element, then send the keys to that element.

So this is the workaround solution, if you wanted to send browser.keys("hello world"):

var result = browser.elementActive();
var activeElement = result.value && (result.value.ELEMENT || result.value["element-6066-11e4-a52e-4f735466cecf"]);
// Newer versions of the webdriver like Gecko/IEDriver return the element as "element-6066-11e4-a52e-4f735466cecf" (which is documented in the W3C specs) instead of "ELEMENT".
if(activeElement){ 
     browser.elementIdValue(activeElement, "hello world");
}

Note this is does not replicate of the behaviour of /session/:sessionId/keys exactly, which also does this according to Selenium's documentation:

This command is similar to the send keys command in every aspect except the implicit termination: The modifiers are not released at the end of the call. Rather, the state of the modifier keys is kept between calls, so mouse interactions can be performed while modifier keys are depressed.

The above solution does implicitly release modifier keys such as "SHIFT", "CTRL" at the end of the key sequence. So if you want to hold a key and do mouse interactions, then tough luck buddy, perhaps we have to wait for the browsers to implement the Webdriver Actions API. But if all you wanted to do is to send "CTRL" + "C", you just can send an array of keys like this:

var result = browser.elementActive();
var activeElement = result.value && result.value.ELEMENT;
if(activeElement){ 
     browser.elementIdValue(activeElement, ["CTRL", "c"]);
}
Shi Ling
  • 146
  • 8
  • 1
    For me, there was no ELEMENT property but there was an object on the value property with a key of element + some random string with a value of some random string. So this worked for me: `let result = browser.elementActive(); let activeElement = (result.value as any)[Object.keys(result.value)[0]]; if (activeElement) { browser.elementIdValue(activeElement, key); }` Thanks for your answer!! – AliF50 Jun 27 '18 at 20:38
  • 1
    Yea, WC3 has change the specs for returning the `ELEMENT`, now the key used is `element-6066-11e4-a52e-4f735466cecf`, which newer versions of the GeckoDriver for FF and as far as I know the IEDriver now uses. Workaround for line 2 is `var activeElement = result.value && (result.value.ELEMENT || result.value["element-6066-11e4-a52e-4f735466cecf"])` – Shi Ling Jul 19 '18 at 08:55
  • so what is the solution? `browser.elementIdValue(activeElement, ["CTRL", "c"]);` ? – Gobliins Mar 13 '20 at 12:29
  • Well, unfortunately `elementIdValue` is not anymore in WDIO5 – Gobliins Mar 13 '20 at 12:39
1

Well, that error pretty much explains that there is an issue with the implementation of the keys command: WARNING: the "keys" command will be depcrecated soon. Please use a different command in order to avoid failures in your test after updating WebdriverIO..

It is currently only working with chromedriver in my test cases too, but I'm also not able to chain commands with it. (simulate Ctrl+C, Ctrl+V).

See my answer on this question. You'll have to find another way to go around this, or wait for the drivers (chromedriver, geckodriver, etc.) to implement the new Selenium actions methods.

The answer I gave there pretty much covers the entire issue. Alternatively, you could try the codepoint approach: browser.keys("\uE007").

Hope this helps you!

iamdanchiv
  • 3,828
  • 4
  • 32
  • 40
1

Try it with webdriverio version > v4.9.3, looks like they fixed it: https://github.com/webdriverio/webdriverio/commit/1f1db4583f62c60c7907f14c080603376e7ec52b

Oliver Wolf
  • 124
  • 5