Невозможно нажать на элементы в цикле в транспортире - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть сайт электронной коммерции, на котором есть список продуктов, похожих на Amazon.я пытаюсь найти элемент и щелкнуть по нему.Я пробовал по фильтрам и карте, и оба не работают для меня.Пожалуйста, помогите.

Ниже приведен код для каждого продукта:

<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);

Soluction 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: ссылка на устаревший элемент: элемент не прикреплен к документу страницы.

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);
})

Ответы [ 3 ]

1 голос
/ 19 апреля 2019

Вы неправильно поняли API-интерфейс транспортира: each() / map() / filter(). Рекомендуем вам изучить JavaScript массива forEach () / map () / filter () , чтобы лучше понять, прежде чем использовать Protractor API.

Раствор А)

  1. return products.getText() должно быть return elem.getText().
  2. filter() возвращает массив элементов, поэтому вы не можете вызвать click() для массива.

Раствор B)

  1. 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 голос
/ 19 апреля 2019

Вы пытались использовать функцию 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();
             }
     });
0 голосов
/ 19 апреля 2019

Звучит так, будто вы все заработали, и я могу ошибаться, но если вы просто пытаетесь нажать на конкретный продукт в списке, вы можете использовать

element(by.cssContainingText('.productNameHover', 'product4')).click();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...