实习生:在 Promise 上循环。<Array.<leadfoot/Element>>
Intern: loop on Promise.<Array.<leadfoot/Element>>
为了简单起见,假设我有以下 DOM 结构:
<div class='myparent'>
<div class='child'>
<div class="label">A</div>
<div class="ico"/>
</div>
<div class='child'>
<div class="label">B</div>
<div class="ico"/>
</div>
<div class='child'>
<div class="label">C</div>
<div class="ico"/>
</div>
</div>
我想在函数 findAllByCssSelector('.child') 返回的所有 child
元素中循环。特别是,仅当 div 的 label
是 B.
时,我才会单击 ico
div 子元素
我会记得,findAllByCssSelector()
returns Promise.<Array.<leadfoot/Element>>
.
通常我应该这样做:
var my_label = null;
this.remote
.findAllByCssSelector('.my-selector').then(function (elementArray) {
for(.....) {
elementArray[i]
.getVisibileText()
.then(function (text) {
if(text == my_label)
elementArray[i].findByCssSelector('.ico').click().end()
}
}
})
我试过这段代码但没有成功,因为 getVisibleText().then()
函数中的 elementArray[i]
不存在 - 就像我失去了它的引用一样。此外,我还需要如果在循环结束时找不到标签,则应抛出异常。
我怎样才能做到这一点?请问有人能帮忙吗?
最简单的方法是直接对项目使用 Xpath 表达式 select,例如:
.findByXpath('//div[@class="child" and div[@class="label" and text()="B"]]/div[@class="ico"]')
上面的表达式将找到第一个 div 和 class "ico" 那是 div 和 class "child" 有 child div 和 class "label" 和文本内容 "B".
更新
使用 Xpath 表达式几乎总是比使用 Leadfoot 命令遍历元素更可取,因为它的效率要高得多,但如果出于某种原因需要循环,您可以执行以下操作:
var my_label = null;
this.remote
.findAllByCssSelector('.my-selector')
.then(function (elementArray) {
return Promise.all(elementArray.map(function (element) {
return element.getVisibleText()
.then(function (text) {
if (text === my_label) {
return element.findByCssSelector('.ico')
.then(function (ico) {
return ico.click();
});
}
});
});
});
需要注意的几个要点:
- 当您在
then
回调 中执行异步操作时,您需要 return Promises/Commands 来自 then
回调
- 元素方法(如
element.findByCssSelector
)return 承诺,而非命令,因此您不能对结果调用 click
。
为了简单起见,假设我有以下 DOM 结构:
<div class='myparent'>
<div class='child'>
<div class="label">A</div>
<div class="ico"/>
</div>
<div class='child'>
<div class="label">B</div>
<div class="ico"/>
</div>
<div class='child'>
<div class="label">C</div>
<div class="ico"/>
</div>
</div>
我想在函数 findAllByCssSelector('.child') 返回的所有 child
元素中循环。特别是,仅当 div 的 label
是 B.
ico
div 子元素
我会记得,findAllByCssSelector()
returns Promise.<Array.<leadfoot/Element>>
.
通常我应该这样做:
var my_label = null;
this.remote
.findAllByCssSelector('.my-selector').then(function (elementArray) {
for(.....) {
elementArray[i]
.getVisibileText()
.then(function (text) {
if(text == my_label)
elementArray[i].findByCssSelector('.ico').click().end()
}
}
})
我试过这段代码但没有成功,因为 getVisibleText().then()
函数中的 elementArray[i]
不存在 - 就像我失去了它的引用一样。此外,我还需要如果在循环结束时找不到标签,则应抛出异常。
我怎样才能做到这一点?请问有人能帮忙吗?
最简单的方法是直接对项目使用 Xpath 表达式 select,例如:
.findByXpath('//div[@class="child" and div[@class="label" and text()="B"]]/div[@class="ico"]')
上面的表达式将找到第一个 div 和 class "ico" 那是 div 和 class "child" 有 child div 和 class "label" 和文本内容 "B".
更新
使用 Xpath 表达式几乎总是比使用 Leadfoot 命令遍历元素更可取,因为它的效率要高得多,但如果出于某种原因需要循环,您可以执行以下操作:
var my_label = null;
this.remote
.findAllByCssSelector('.my-selector')
.then(function (elementArray) {
return Promise.all(elementArray.map(function (element) {
return element.getVisibleText()
.then(function (text) {
if (text === my_label) {
return element.findByCssSelector('.ico')
.then(function (ico) {
return ico.click();
});
}
});
});
});
需要注意的几个要点:
- 当您在
then
回调 中执行异步操作时,您需要 return Promises/Commands 来自 - 元素方法(如
element.findByCssSelector
)return 承诺,而非命令,因此您不能对结果调用click
。
then
回调