我有一个电子商务网站,其中包含类似亚马逊的产品列表。我正在尝试寻找一个元素并单击它。我试过过滤器和地图,两者都不适合我。请帮忙。
以下是每种产品的代码:
<b class="productNameHover pcursor word-break">product1</b>
<b class="productNameHover pcursor word-break">product2</b>
<b class="productNameHover pcursor word-break">product3</b>
<b class="productNameHover pcursor word-break">product4</b>
说我的页面中有4个元素。所以,我试图得到计数,它为我工作。
var products = element.all(by.className('productNameHover'));期望(products.count())砥(4)。
当我尝试过滤,
解决方案A)不工作,没有错误消息但什么也没做
var products = element.all(by.className('productNameHover'));
products.filter(function(elem) {
return products.getText().then(function(text) {
return text === 'product4';
});
}).click();
browser.sleep(5000);
解决方案B)不工作;索引超出范围;尝试访问index:0处的元素,但只有0个元素与locator匹配
var products = element.all(by.className('productNameHover'));
products.filter(function(elem) {
return products.getText().then(function(text) {
return text === 'product4';
});
}).first().click();
browser.sleep(5000);
解决方案C)没有错误消息但什么也没做
var products = element.all(by.className('productNameHover'));
products.filter(function(elem) {
return products
.element(by.xpath(
"//div[@class='item text-center slide-image-content active']/img"
))
.getText()
.then(function(text) {
expect(text).toContain(product4);
})
.then(function(filteredElements) {
filteredElements.first().click();
});
});
browser.sleep(5000);
解决方案D)这是有效的,并给我所有的产品;但我需要点击单个产品或循环
var products = element.all(by.className('productNameHover'));
products.map(function(item) {
return item.getText();
}).then(function(txt) {
console.log(txt);
//expect(txt).toContain("product 4")
});
解决方案E)无法正常工作且没有错误消息
products.map(function(item) {
return item.getText();
}).then(function(txt) {
console.log(txt);
if( txt== 'product4') {
console.log(item);
item.click();
browser.sleep(5000);
}
});
解决方案F)我试图点击循环中的所有元素,但它点击第一个元素而不是点击第二个元素;它给出了失败:陈旧元素引用:元素未附加到页面文档。
products.map(function(item) {
browser.sleep(5000);
item.click();
browser.sleep(5000);
var backButton = element.all(by.className('btn btn-outline btn-big mt-3 ml-0 ml-sm-2')).first() ;
backButton.click();
browser.sleep(5000);
})
你错了理解Protractor API:each() / map() / filter()
。建议您在使用Protractor API之前学习JavaScript Array的forEach() / map() / filter()以便更好地理解。
解决方案A)
return products.getText()
应该是return elem.getText()
。filter()
返回一个元素数组,因此你不能在数组上调用click()
。解决方案B)
return products.getText()
应该是return elem.getText()
。解决方案E)map()
也返回数组。
products.map(function(item) {
return item.getText();
}).then(function(txt) {
// txt = [ 'product1', 'product2', 'product3', 'product4']
console.log(txt);
if( txt == 'product4') { // this condition never be true
console.log(item);
item.click();
browser.sleep(5000);
}
});
// correct code example
products.map(function(item) {
return item.getText();
}).then(function(txts) {
// txts = [ 'product1', 'product2', 'product3', 'product4']
console.log(txts);
let index = txts.indexOf('product4');
if( index > -1) {
products.get(index).click();
browser.sleep(5000);
}
});
您是否尝试过使用量角器API的each()函数?
var products = element.all(by.className('productNameHover'));
products.each(function(element) {
return element.getText().then(function (text) {
if(text === 'product4') {
return element.click();
}
});
})
我建议你切换到编写js代码的新async/await
语法。
const products = element.all(by.className('productNameHover'));
products.each(async function(element) {
let text = await element.getText();
if(text === 'product4') {
await element.click();
}
});
你也可以使用map()
功能 -
element.all(by.className('productNameHover')).map(function(element) {
return element.getText(function(text) {
return text === 'product4'
});
}).then(function(elements) {
for (var i = 0; i < elements.length; i++) {
elements.get(i).click();
}
});
听起来你工作得很好,我可能会误解,但如果你只是想点击列表中的特定产品,你可以使用
element(by.cssContainingText('.productNameHover', 'product4')).click();