使用each()方法时,量角器陈旧元素引用

时间:2018-11-18 20:48:29

标签: javascript protractor

由于在量角器中使用each()方法,导致出现以下错误。过去它运行良好,但现在始终因该错误而失败。

  

失败:过时的元素引用:元素未附加到页面文档

element.all(bars).each((element) => element.getCssValue('width'))

是否有其他选择或原因?

(为清楚起见,我要做的就是获取一组称为bar的Web元素中每个元素的宽度。)

谢谢!

4 个答案:

答案 0 :(得分:3)

简而言之,这是因为each()只是针对所有元素同时触发了命令。在您的情况下,您可能需要这样做element.all(bars).getCssValue('width')).then(array => {/*do what you want with returned array here*/})

*已编辑*

你想做的是

element.all(bars).getCssValue('width')).then(array => {
    // tests is at least one element will not be "0px"
    let elementHasWidth = array.some(elem => elem !== "0px");
    expect(elementHasWidth).toBe(true);
})

答案 1 :(得分:3)

由于Protractor和Selenium从Web驱动程序控制流和WebDriverJS Promise Manager演变为原始承诺,因此现有代码中的此类新问题很可能会导致。您曾经能够编写看起来像同步代码的代码,并且在工具箱的内部,工具包会将其转换为异步代码,等待DOM加载并在页面上运行JavaScript。向前need to convert your code前进,以明确使用async/await或promises。 (请参阅硒更改here背后的原因。)

不幸的是,即使是在Protractor文档中,很多旧的(早于2019年)示例都是以同步方式编写的,因此您在遵循它们时应格外小心。更不幸的是,you cannot mix async code with Control Flow code,并且如果您尝试执行该操作,则所有控制流都将被禁用,并且依赖它的某些测试可能会开始失败。

对了,bars的值是多少?量角器by对象的工作方式不同于本机WebDriver定位器,并且我不确定它们是否可重用。尝试使用by.name('bars')或其他代替bars的东西。

由于涉及到所有承诺,您的案子很棘手。 element.getCssValue返回一个承诺。由于您正在尝试从中获取truefalse值,因此建议使用简化器。

let nonZero = element.all(by.name('bars')).reduce((acc, elem) => {
  return acc || elem.getCssValue('width').then( (width) => width > 0 );
}, false);

在更复杂的情况下,您可以使用all().each(),但必须注意确保在each内所做的任何操作都不会影响DOM,因为一旦这样做,它就有可能使其余的DOM失效。数组。

如果您可能要用最终的操作来修改页面,那么,尽管看起来很丑陋,您需要循环查找元素:

for (var i = 0; true; i++) {
  let list = element.all(by.css('.items li'));
  if (i >= await list.count();)
    break;
  list.get(i).click();
};

答案 2 :(得分:1)

在您的错误声明之前尝试使用以下代码:

  browser.wait(function() {
        return element.all(bars).isPresent().then(function(result) {
            return result;
        });
    }, 5000);

答案 3 :(得分:0)

感谢所有提供帮助的人。如果导致错误,请重试该解决方案。由于元素的实时性,元素引用在获得CSS宽度之前就发生了变化。