browser.keys()无法在Firefox 53.0和webdriver.io上运行

Loo*_*Src 6 webdriver selenium-webdriver webdriver-io geckodriver

在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

Shi*_*ing 10

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

什么browser.keys()引擎盖下确实是调用 /session/:sessionId/keys的webdriver的JsonWire协议端点.但是,如果你看一下端点列表在W3C的webdriver的规范,这个端点不在列表中.我相信它以前是列表的一部分,但已被删除.相反,为了发送密钥,规范声明使用/session/:sessionId/element/:elementId/value端点,您可以使用webdriverio的browser.elementIdValue(ID, value)方法来调用.

现在,如果您阅读了Selenium关于JsonWireProtocol的文档/session/:sessionId/keys提到的规范,那么使用其他WebDriver功能复制实现非常容易.该端点简单地做到这一点:/session/:sessionId/keys

将序列键击发送到活动元素.

我们可以调用一个端点来获取当前活动元素,该元素/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");
}
Run Code Online (Sandbox Code Playgroud)

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

此命令类似于除隐式终止之外的每个方面中的send keys命令:修饰符不会在调用结束时释放.相反,修改键的状态保持在调用之间,因此可以在按下修改键的同时执行鼠标交互.

上述解决方案隐式释放修饰键,例如键序列末尾的 "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"]);
}
Run Code Online (Sandbox Code Playgroud)