gpt4 book ai didi

angularjs - 使用带有循环的 Protractor

转载 作者:行者123 更新时间:2023-12-02 22:04:22 24 4
gpt4 key购买 nike

当我在循环中使用 Protractor 时,循环索引 (i) 不是我所期望的。

症状:

Failed: Index out of bound. Trying to access element at index:'x', but there are only 'x' elements

Index is static and always equal to the last value

我的代码

for (var i = 0; i < MAX; ++i) {
getPromise().then(function() {
someArray[i] // 'i' always takes the value of 'MAX'
})
}

例如:

var expected = ['expect1', 'expect2', 'expect3'];
var els = element.all(by.css('selector'));
for (var i = 0; i < expected.length; ++i) {
els.get(i).getText().then(function(text) {
expect(text).toEqual(expected[i]); // Error: `i` is always 3.
})
}

var els = element.all(by.css('selector'));
for (var i = 0; i < 3; ++i) {
els.get(i).getText().then(function(text) {
if (text === 'should click') {
els.get(i).click(); // fails with "Failed: Index out of bound. Trying to access element at index:3, but there are only 3 elements"
}
})
}

var els = element.all(by.css('selector'));
els.then(function(rawelements) {
for (var i = 0; i < rawelements.length; ++i) {
rawelements[i].getText().then(function(text) {
if (text === 'should click') {
rawelements[i].click(); // fails with "Failed: Index out of bound. Trying to access element at index:'rawelements.length', but there are only 'rawelements.length' elements"
}
})
}
})

最佳答案

发生这种情况的原因是 Protractor 使用了 Promise。

Read https://github.com/angular/protractor/blob/master/docs/control-flow.md

Promise(即 element(by...)element.all(by...) )执行它们的 then当基础值准备好时起作用。这意味着所有的 promise 首先被安排,然后是 then结果准备就绪后,函数就会运行。

当你运行这样的东西时:

for (var i = 0; i < 3; ++i) {
console.log('1) i is: ', i);
getPromise().then(function() {
console.log('2) i is: ', i);
someArray[i] // 'i' always takes the value of 3
})
}
console.log('* finished looping. i is: ', i);

发生的情况是getPromise().then(function() {...})在 Promise 准备好之前立即返回,并且不执行 then 内的函数。所以首先循环运行3次,调度所有getPromise()来电。然后,随着 promise 的解决,相应的 then s 已运行。

控制台看起来像这样:

1) i is: 0 // schedules first `getPromise()`
1) i is: 1 // schedules second `getPromise()`
1) i is: 2 // schedules third `getPromise()`
* finished looping. i is: 3
2) i is: 3 // first `then` function runs, but i is already 3 now.
2) i is: 3 // second `then` function runs, but i is already 3 now.
2) i is: 3 // third `then` function runs, but i is already 3 now.

那么,如何在循环中运行 Protractor 呢?一般的解决方案是关闭。请参阅JavaScript closure inside loops – simple practical example

for (var i = 0; i < 3; ++i) {
console.log('1) i is: ', i);
var func = (function() {
var j = i;
return function() {
console.log('2) j is: ', j);
someArray[j] // 'j' takes the values of 0..2
}
})();
getPromise().then(func);
}
console.log('* finished looping. i is: ', i);

但这并不是那么好读。幸运的是,您还可以使用 Protractor 函数 filter(fn) , get(i) , first() , last() ,并且事实上 expect已修补以兑现 promise ,处理此问题。

回到前面提供的示例。第一个例子可以重写为:

var expected = ['expect1', 'expect2', 'expect3'];
var els = element.all(by.css('selector'));
for (var i = 0; i < expected.length; ++i) {
expect(els.get(i).getText()).toEqual(expected[i]); // note, the i is no longer in a `then` function and take the correct values.
}

第二个和第三个示例可以重写为:

var els = element.all(by.css('selector'));
els.filter(function(elem) {
return elem.getText().then(function(text) {
return text === 'should click';
});
}).click();
// note here we first used a 'filter' to select the appropriate elements, and used the fact that actions like `click` can act on an array to click all matching elements. The result is that we can stop using a for loop altogether.

换句话来说,Protractor 有很多方法来迭代或访问元素 i这样您就不需要使用 for 循环和 i 。但是如果你必须使用for循环和i ,可以使用闭包解决方案。

关于angularjs - 使用带有循环的 Protractor ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27910331/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com