【问题标题】:Looping over elements and testing them individually in protractor循环遍历元素并在量角器中单独测试它们
【发布时间】:2015-07-22 10:46:11
【问题描述】:

有没有办法实现循环,从而可以减少下面的代码?

    var navItems = element.all(by.repeater('item in mc.navItems'));
    expect(navItems.count()).toEqual(4);

    expect(navItems.get(0).getText()).toEqual('page1'.toUpperCase());
    navItems.get(0).click();
    expect(browser.getLocationAbsUrl()).toEqual('/page1');

    expect(navItems.get(1).getText()).toEqual('page2'.toUpperCase());
    navItems.get(1).click();
    expect(browser.getLocationAbsUrl()).toEqual('/page2');

    expect(navItems.get(2).getText()).toEqual('page3'.toUpperCase());
    navItems.get(2).click();
    expect(browser.getLocationAbsUrl()).toEqual('/page3');

    expect(navItems.get(3).getText()).toEqual('page4'.toUpperCase());
    navItems.get(3).click();
    expect(browser.getLocationAbsUrl()).toEqual('/page4');

我尝试了多种方法,但都失败了,因为我不确定如何让他们等到返回承诺的值。

这是一种失败的方法:

var navItems = element.all(by.repeater('item in mc.navItems'));
for(var i = 0; i < navItems.count(); i++) {
    expect(navItems.get(i).getText()).toEqual(expectedValue[i].toUpperCase());
    navItems.get(i).click();
    expect(browser.getLocationAbsUrl()).toEqual('/' + expectedValue[i]);
}

在哪里expectedValue = ['page1', 'page2', 'page3', 'page4'];

这样做的问题是,for 循环甚至在返回承诺值之前就评估条件,因此循环的内容永远不会执行。

我确定我可以使用 then 并将回调函数附加到 count() 但这只会让事情变得混乱,因为我必须将 navItems 设为全局变量,以便可以通过以下方式访问它回调函数,我还需要确保在执行回调函数之前填充navItems

我知道expect() 方法以一种非常干净的方式处理承诺,我想实现这样的东西。

【问题讨论】:

    标签: javascript angularjs jasmine protractor


    【解决方案1】:

    我在用黄瓜量角器,我做的是这样的

    element.all(by.repeater('item in mc.navItems')).then(function (elements) {
      navItems = elements
      var expectations = []
      for (var i = 0; i < navItems.count(); i++) {
        expect(navItems.get(i).getText()).toEqual(expectedValue[i].toUpperCase());
        navItems.get(i).click();
        expectations.push(expect(browser.getLocationAbsUrl()).toEqual('/' + expectedValue[i]));
      }
      Q.all(expectations).should.notify(callback)
    })
    

    所以测试会在通知回调之前等待所有期望执行

    【讨论】:

    • 但是 for 循环仍然不会执行,因为当循环开始执行时,navItems.count() 仍然不会等于 navItems 的长度。旁注:我知道我可以只使用expectedValue.length,但我想知道当长度未知时如何使用for 循环。
    • 我通过创建返回元素时的期望来编辑我的答案
    【解决方案2】:

    我不知道在问这个问题时each() 方法是否可用,但这些天我很确定each() 是最好的方法。

    在所述上下文中,答案类似于:

    var navItems = element.all(by.repeater('item in mc.navItems'));
    
    navItems.each((element, index) => {
      expect(element.getText()).toEqual(('page'+index).toUpperCase());
      element.click();
      expect(browser.getLocationAbsUrl()).toEqual('/page'+index);
    });
    

    比单独调用每个元素要好得多!

    【讨论】:

      【解决方案3】:

      我认为您遇到的问题不是延迟返回承诺,而是关闭。看这里-Using protractor with loops 您还可以使用带有if 的递归循环而不是使用for,因为它更简单-

      function loop(i){
           if(i>=navItems.count())
                    {
                      return null;
                    }
                    else
                    {
                      expect(navItems.get(i).getText()).toEqual(expectedValue[i].toUpperCase());
              navItems.get(i).click();
              expectations.push(expect(browser.getLocationAbsUrl()).toEqual('/' + expectedValue[i]));
                      })
                  return loop(i+1)
                }
              }return loop(navItems.count()); 
      

      【讨论】:

        【解决方案4】:

        第一步:首先获取元素列表

        let listOfElements = element.all(by.repeater('item in mc.navItems'));    
        

        第2步:使用下面的行迭代元素

        listOfElements.each(function (element, index) {
                            element.getText().then(function (text) {
                                console.log(index, text);
                            });
                        });
        

        【讨论】:

        • 这个答案需要解释
        猜你喜欢
        • 2017-01-15
        • 1970-01-01
        • 2020-04-09
        • 1970-01-01
        • 2015-10-23
        • 1970-01-01
        • 1970-01-01
        • 2021-10-09
        • 1970-01-01
        相关资源
        最近更新 更多