我正在使用selenium webdriver,我通过id获取特定元素。 获取具有正确id的元素后,我尝试从列表中选择具有唯一属性值的1个元素。
我已经设法达到我需要的价值,但我对我找到的解决方案不满意。
情况:
var attributeName = "bla";
var id = "icon";
var iconElementsPromise = driver.findElements(By.id(id)); // returns a promise containing an array with WebElements
解决方案1:嵌套then
:这看起来很错误,但它确实有效。
iconElementsPromise
.then(function(iconElements) {
iconElements.forEach(function(element, index) {
element.getAttribute(attributeName)
.then(function(attribute) {
console.log("attribute: " + attribute);
});
});
});
解决方案2:只有1个嵌套then
:它看起来更好但现在我需要创建一个Promises数组,这没关系...但我想要没有嵌套
iconElementsPromise
.then(function(iconElements) {
var promises = [];
iconElements.forEach(function(element, index) {
promises.push(element.getAttribute("tag"));
});
return promises;
})
.then(function(promises) {
Promise.all(promises)
.then(function(attributes) {
console.log("attributes: " + attributes);
});
});
解决方案3:通过返回Promise.all(promises)
,我可以保持在同一个固定级别,并且不会嵌套then
。
iconElementsPromise
.then(function(iconElements) {
var promises = [];
iconElements.forEach(function(element, index) {
promises.push(element.getAttribute(attributeName));
});
return promises;
})
.then(function(promises) {
return Promise.all(promises);
})
.then(function(attributes) {
console.log("attributes: " + attributes);
});
解决方案1有2 then
s并获取每个属性
解决方案2和3各有3 then
s,并为我提供属性数组
获取每个属性或只是数组都可以。
我确实认为解决方案3或多或少是我想要的。但代码相当长。我觉得必须有一个更好,更可读和更短的方法来获取属性。
所以我的问题是:**使用promises获取属性的最佳方法是什么? **
赞赏的例子。
答案 0 :(得分:2)
3
使用map
缩短一个then
同时保持其可读性的较短版本{/ 1}}
iconElementsPromise
.then(function(iconElements) {
return Promise.all(iconElements.map(function(element){
return element.getAttribute(attributeName);
}));
})
.then(function(attributes) {
console.log("attributes: " + attributes);
});
答案 1 :(得分:1)
如果您的目标是选择具有唯一属性的1个元素,那么将此属性包含在定位器中会更容易:
// select with an XPath the first element having an attribute "bla" and a parent with the "icon" id
var element = driver.findElement(By.xpath("id('icon')/*[@bla]"));
// select with a CSS selector the first element having the attribute "bla" and a parent with the "icon" id
var element = driver.findElement(By.cssSelector("#icon > [bla]"));
但如果您真的想要所有属性,那么简短的解决方案就是使用webdriver.promise.map
:
var webdriver = require('selenium-webdriver');
var promise = webdriver.promise;
var By = webdriver.By;
var Key = webdriver.Key;
var EC = webdriver.until;
var driver = new webdriver.Builder()
.withCapabilities({'browserName': 'firefox'})
.build();
driver.get('http://stackoverflow.com/');
driver.findElements(By.xpath('//a')).then(function(elts) {
promise.map(elts, function(elt) {
return elt.getAttribute("href");
}).then(function(links) {
console.log(links);
})
});