E2E使用浏览器信息对多个页面进行测试

时间:2017-02-07 04:22:06

标签: angularjs selenium protractor

我正在用量角器编写E2E测试。我不得不从浏览器中获取信息并多次执行一步。

我正在测试一个将在

时启动的屏幕
  • 用户点击“开始”
  • 登陆新页面
  • 调用下面的工作流程,将count作为参数传递
  • id html id不会改变。提交当前表单后再次查询时值会更改。
for(i = 0 ; i < count ; i++){
   console.log("counter is "+i);
   element(by('id')).evaluate('value').then(function(v) {
    // do some action on UI based on v
    element(by('id1')).sendKeys(v+v);
    // submit etc., 
    // some angular code runs in the frontend.
   }
   // need to wait since webdriver jumps to the next one without this completing
}

许多博客文章/文档建议您不能在循环中使用它,但不建议任何其他方法来执行此操作。

任何建议表示赞赏。

  

永远不要在循环内部使用protractor元素语句:简单的原因是webdriverJS(量角器)API是异步的。元素语句返回一个promise,当promise继续执行时,该promise将处于未解析状态。这导致不可预测的结果。因此,建议使用递归函数而不是循环。

来源:http://engineering.wingify.com/posts/angularapp-e2e-testing-with-protractor/

编辑:更新的问题,包含工作流程的详细信息。

3 个答案:

答案 0 :(得分:2)

当迭代具有异步调用时,通常不建议使用循环。

原因是当getCursuri()已经等于i时,在循环的最后一次迭代之后执行第一次异步调用。 因此,它很难打破循环并跟踪count的值。

解决问题的方法是使用递归函数:

i

但更好的方法是在一个大小与迭代次数相关的数组上使用var count = 3; var results = []; function iterate(i, n) { if(i < n) { console.log(`counter is ${i}`); browser.refresh(); return element(by.id('h-top-questions')).getText().then(function(text) { results.push(`${i}:${text}`); return iterate(i + 1, n); }); } } iterate(0, count).then(function(){ console.log("done!", results); }); 进行迭代:

promise.map

你也可以继续使用循环。首先,您必须使用var count = 3; protractor.promise.map(Array(count).fill(0), function(v, i) { console.log(`counter is ${i}`); browser.refresh(); return element(by.id('h-top-questions')).getText().then(function(text) { return `${i}:${text}`; }); }).then(function(results){ console.log("done!", results); }); 语句在异步函数(ES6)中获取let的值。 然后使用i调用所有同步代码来同步执行:

browser.call

答案 1 :(得分:1)

在量角器中循环工作就像这样

describe('Describe something', function() {
    var testParams = [1,2,3,4,5,6,7,8,9,10];
    beforeEach( function() {
        // ...
   });

for (var i = 0; i < testParams.length; i++) {
  (function (testSpec) {
    it('should do something', function() {
        // inside loop
    });

  })(testParams[i]);

};
});

编辑:我可能会误解你的问题,但在我看来你想在页面上完成所有(动态计数)操作,然后再转到下一个?

it('should clear old inspections', function() {  
                  inspectieModuleInspectieFixture.getRemoveInspectionButton().count().then(function (value) {
                        if(value == 0){
                            console.log('--- no inspections to remove ---');
                        }
                        for(var i = 0; i < value; i++){
                            //global.waitForClickable(inspectieModuleInspectieFixture.getRemoveInspectionButtonList(i+1));
                            inspectieModuleInspectieFixture.getRemoveInspectionButtonList(i+1).click();
                            console.log('iteration '+i + 'count '+value )
                        };
                    });
                    global.wait(5000);

            }); */

这会计算页面上的元素,然后它会为找到的元素执行操作

在上面的例子中,我使用容器来保存我的元素,所以我的代码仍然可读(即inspectieModuleInspectieFixture.getRemoveInspectionButton()持有$(“。elementSelectorExample”)

还有一个'global.waitForClickable'评论,这是对我创建的'时间模块'的影响,它扩展了'wait'的功能,在这种情况下,它会一直等到元素是可变/可点击的。< / p>

很容易反映出这样的事情:

    waitForElementNoDisplay: function(element){
    return browser.wait(function() {
        return element.isDisplayed().then(function(present) {
            return !present;
        })
    });
},

这将使量角器WAIT直到一个元素不再显示。(显示:无)

答案 2 :(得分:0)

如果你需要对每个元素执行一些操作,那么最好不要使用循环。使用.map()或.each()或.filter()代替

仍然不太清楚你该做什么,但这里是我做类似任务的例子,当你需要根据页面中的数据做出多少动作时:

class SomePage {

    typeValueForEachElement(elements) {
        elements.each((elem, index)=> {
            elem.getAttribute('value').then(value=> {
                elem.sendKeys(value + value)
                elem.submit()
            })
        })

    }
}

new SomePage().typeValueForEachElement($$('your locator here'))

这是可能有帮助的api参考

  

http://www.protractortest.org/#/api?view=ElementArrayFinder.prototype.map   http://www.protractortest.org/#/api?view=ElementArrayFinder.prototype.reduce   http://www.protractortest.org/#/api?view=ElementArrayFinder.prototype.each   http://www.protractortest.org/#/api?view=ElementArrayFinder.prototype.filter