browser.keys() 不适用于 Firefox 53.0 & webdriver.io

browser.keys() is not working on Firefox 53.0 & webdriver.io

在 firefox 上,browser.keys 抛出错误。

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

请帮助我如何处理这个错误。

这是日志

[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

嗯,这个错误几乎可以解释 keys 命令的执行存在问题:WARNING: the "keys" command will be depcrecated soon. Please use a different command in order to avoid failures in your test after updating WebdriverIO.

它目前也只能在我的测试用例中与 chromedriver 一起使用,但我也无法使用它链接命令。 (模拟Ctrl+C,Ctrl+V).

请参阅我对 问题的回答。您必须找到另一种方法来解决这个问题,或者等待驱动程序(chromedrivergeckodriver 等)实施新的Selenium actions 方法。

我在那里给出的答案几乎涵盖了整个问题。或者,您可以尝试 codepoint 方法:browser.keys("\uE007")

希望对您有所帮助!

正如@iamdanchiv 在他的回答中提到的,browser.keys() 将被弃用,但有一个解决方法(我应该为此提交 PR)。

browser.keys() 在幕后所做的是调用 /session/:sessionId/keys WebDriver JsonWire 协议中的端点。但是,如果您查看 W3C Webdriver 规范中的 list of endpoints,就会发现此端点不在列表中。我相信它以前是列表的一部分,但已被删除。相反,为了发送密钥,规范规定使用 /session/:sessionId/element/:elementId/value 端点,您可以使用 webdriverio 的 browser.elementIdValue(ID, value) 方法来调用。

现在,如果您阅读了 Selenium's documentation on the JsonWireProtocol 中提到的 /session/:sessionId/keys 的规范,那么使用其他 WebDriver 功能复制实现是非常容易的。 /session/:sessionId/keys 端点只是这样做:

Sends a sequence key strokes to the active element.

有一个端点我们可以调用来抓取当前活动元素,它是/session/:sessionId/element/active,映射到webdriverio的 browser.elementActive() 方法。

在这种情况下,我们需要做的就是重新实现这个browser.keys()首先找出活动元素是什么,然后将键发送到该元素。

如果您想发送 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");
}

请注意,这并没有完全复制 /session/:sessionId/keys 的行为,根据 Selenium 的文档也是这样做的:

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.

上述解决方案确实在键序列的末尾隐式释放修饰键,例如"SHIFT"、"CTRL"。因此,如果你想按住一个键并进行鼠标交互,那么运气不好的伙计,也许我们必须等待浏览器实现 Webdriver Actions API。但是如果你只想发送 "CTRL" + "C",你可以像这样发送一个键数组:

var result = browser.elementActive();
var activeElement = result.value && result.value.ELEMENT;
if(activeElement){ 
     browser.elementIdValue(activeElement, ["CTRL", "c"]);
}

试试 webdriverio 版本 > v4.9.3,看起来他们修复了它: https://github.com/webdriverio/webdriverio/commit/1f1db4583f62c60c7907f14c080603376e7ec52b