【问题标题】:Not able to click on elements in loop in protractor无法单击量角器中循环中的元素
【发布时间】:2019-04-19 09:55:00
【问题描述】:

我有一个电子商务网站,其中包含与亚马逊类似的产品列表。我正在尝试寻找一个元素并单击它。我已经尝试过过滤器和地图,但都不适用于我。请帮忙。

以下是每个产品的代码:

<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) 不起作用;索引超出范围;尝试访问 index: 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);

Solution 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: element is not attach to the page document.

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

【问题讨论】:

    标签: loops dictionary filter protractor


    【解决方案1】:

    你对 Protractor 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);
        }
    });
    

    【讨论】:

    • 感谢解决方案E的清晰解释。现在,它可以更好地理解
    【解决方案2】:

    您是否尝试过使用量角器 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();
               }
        });
     })
    

    我建议你改用 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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多