无法在量角器中单击循环中的元素

时间:2019-04-19 09:55:01

标签: loops dictionary filter protractor

我有一个电子商务网站,上面有与亚马逊类似的产品列表。我试图寻找一个元素,然后单击它。我已经尝试通过过滤器和地图,但两者都不适合我。请帮忙。

下面是每种产品的代码:

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

3 个答案:

答案 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)

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

答案 2 :(得分:0)

听起来像是您可以正常使用,可能会引起误解,但是如果您只是想单击列表中的特定产品,则可以使用

element(by.cssContainingText('.productNameHover', 'product4')).click();