为什么 WebdriverIO 对从未使用过的 webelement 发出 POST 'element' 请求?

Why WebdriverIO makes POST 'element' request for webelement that is never used?

我在玩 webdriverIO,它看起来很不错!我已经喜欢这个框架的很多特性。

我正在调查 WebdriverIO 如何处理不存在的元素和惰性元素加载这个测试:

it('no element, and not used', () => {
    browser.pause(5000)
    let non_exist = browser.$('.nonexist')
});

转轮输出:

```
[17:23:25]  COMMAND    POST     "/wd/hub/session/6b79fd07-5f5d-42ce-b1e5-f99734aae128/element"
[17:23:25]  DATA                {"using":"css selector","value":".nonexist"}
```

webdriver 服务器日志:

```
*** Element info: {Using=css selector, value=.nonexist}
17:23:25.840 INFO - Executing: [delete session: 6b79fd07-5f5d-42ce-b1e5-f99734aae128])
```

所以我看到 WebdriverIO 仍然向 selenium 服务器发送 POST 请求,并尝试在声明中找到元素。

现在让我们看第二个测试。我在这里声明元素,该元素在页面上不存在,但稍后尝试使用它:

it('no element, used later in the code', () => {
    browser.pause(5000)
    let myElem = browser.$('.nonexist')
    console.log('AND NOW FAIL!')
    console.log(myElem.getText())
});

测试运行程序输出:

```
[17:30:35]  COMMAND     POST     "/wd/hub/session/05e4115c-ed66-4e47-8a01-c37208d379ab/element"
[17:30:35]  DATA                {"using":"css selector","value":".nonexist"}
AND NOW FAIL!
[17:30:36]  COMMAND     POST     "/wd/hub/session/05e4115c-ed66-4e47-8a01-c37208d379ab/elements"
[17:30:36]  DATA                {"using":"css selector","value":".nonexist"}
[17:30:36]  RESULT              []
```

Selenium 服务器日志:

```
*** Element info: {Using=css selector, value=.nonexist}
17:30:36.133 INFO - Executing: [find elements: By.cssSelector: .nonexist])
17:30:36.155 INFO - Done: [find elements: By.cssSelector: .nonexist]
```

Webdriver IO 发送 2 个请求 - 首先是声明,然后是 'elements' 尝试对此元素应用某些操作的请求。

所以问题是,为什么 WebdriverIO 在我的示例中尝试两次查找元素?没有抛出异常,一切都很好,但我只是想知道这是一个错误还是设计使然?

这是设计使然。即使 Webdriver Spec 声明如果未找到元素,驱动程序应该抛出异常 WebdriverIO 不会。这背后的原因是,在 WebdriverIO 中,您可以对不存在的元素调用操作。这是出于语法原因。它允许在变量中定义元素,然后在以后像这样使用它:

var myElem = $('#notExisting')
myElem.waitForExist() // waits for element to exist
console.log(myElem.getText()) // returns text if elem shows up

但是 WebdriverIO 足够聪明,如果您想在元素上调用一个操作,如果它不存在,就像您上面提到的那样:

var myElem = $('#notExisting')
console.log(myElem.getText()) // THROWS EXCEPTION

这种设计的一个缺点是查询不存在的元素比查询存在的元素花费更多的时间,但从长远来看可以忽略不计。显然优点是更好更容易阅读测试代码,从而节省更多时间。