#loops #dictionary #filter #protractor
#циклы #словарь #Фильтр #транспортир
Вопрос:
У меня есть веб-сайт электронной коммерции, на котором есть список товаров, похожих на Amazon. я пытаюсь найти элемент и щелкнуть по нему. я пробовал с помощью filter и map, и оба они не работают для меня. Пожалуйста, помогите.
Ниже приведен код для каждого продукта:
<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()).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) Я попытался щелкнуть по всем элементам в цикле, но он нажимает на первый элемент, а не на второй; он выдает сбой: устаревшая ссылка на элемент: элемент не прикреплен к документу страницы.
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);
})
Ответ №1:
Вы неправильно поняли API транспортира : each() / map() / filter()
. Рекомендуем вам изучить JavaScript Array forEach() / map() / filter(), чтобы лучше понять, прежде чем использовать Protractor API.
Решение А)
return products.getText()
должно бытьreturn elem.getText()
.filter()
возвращает массив элементов, поэтому вы не можете вызватьclick()
array.
Решение 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);
}
});
Комментарии:
1. Спасибо за четкое объяснение решения E. Теперь это дает лучшее понимание
Ответ №2:
Вы пробовали использовать функцию each () API транспортира?
var products = element.all(by.className('productNameHover'));
products.each(function(element) {
return element.getText().then(function (text) {
if(text === 'product4') {
return element.click();
}
});
})
Я бы посоветовал вам переключиться на новый async/await
синтаксис написания js-кода.
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();
}
});
Ответ №3:
Похоже, у вас все получилось, и я могу неправильно понять, но если вы просто пытаетесь щелкнуть по определенному продукту в списке, вы можете использовать
element(by.cssContainingText('.productNameHover', 'product4')).click();