循环元素并在量角器中单独测试它们

时间:2015-07-22 10:46:12

标签: javascript angularjs jasmine protractor

有没有办法实现循环,以便可以减少以下代码?

    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()方法以一种干净利落的方式处理承诺,我想实现类似的东西。

4 个答案:

答案 0 :(得分:4)

我使用量角器和黄瓜,我做的就像这样

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

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

答案 1 :(得分:1)

我不知道在问这个问题时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);
});

比单独调出每个元素好多了!

答案 2 :(得分:0)

我认为你所遇到的问题不在于延迟回报承诺,而是关闭。看看这里 - 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()); 

答案 3 :(得分:0)

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

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