我有一个电子商务网站,上面有与亚马逊类似的产品列表。我试图寻找一个元素,然后单击它。我已经尝试通过过滤器和地图,但两者都不适合我。请帮忙。
下面是每种产品的代码:
<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')); Expect(products.count())。toBe(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)不起作用;索引越界尝试访问索引为0的元素,但只有0个与定位符
匹配的元素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),我尝试单击循环中的所有元素,但它单击的是第一个元素,而不是单击第二个;它给出了Failed:stale element reference:元素未附加到页面文档。
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);
})
答案 0 :(得分:1)
您是否尝试过使用量角器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();
}
});
答案 1 :(得分:1)
您错误理解了量角器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);
}
});
答案 2 :(得分:0)
听起来像是您可以正常使用,可能会引起误解,但是如果您只是想单击列表中的特定产品,则可以使用
element(by.cssContainingText('.productNameHover', 'product4')).click();