5

(我看过这个 SO 讨论,但不知道如何将它应用到我的案例中,所以我问了一个新问题。希望它不是重复的)

我正在使用 Protractor 和 Cucumber.js 测试用 Angular 编写的表单。

所以我想做的是告诉量角器去点击一个字段的标题(这是一个链接)然后,当那个字段出现时,在里面输入一些文本,然后转到下一个字段的标题,等等。

这是我在 Cucumber 中的步骤:

When I fill the form with the following data
    | field            | content           |
    | First Name       | John              |
    | Last Name        | Doe               |
    | Address          | Some test address |
# and so forth

这是对步骤定义的半心半意的尝试:

this.When(/^I fill the form with the following data$/, function (table, callback) {
    data = table.hashes();
    # that gives me an array of objects such as this one:
    # [ { field: 'First Name', content: 'John' },...]

    for (var i = 0; i < data.length; i++){
        var el = element(by.cssContainingText('#my-form a', data[i].field));
          el.click().then(function(){
                var fieldEl = el.element(by.xpath("../.."))
                    .element(by.css('textarea'));
                fieldEl.sendKeys(data[i].content);
            });
        }
    };
    callback();
});

但当然,这是行不通的,因为在 Protractor 有时间单击字段名称并将必要的数据输入字段之前,回调函数就被调用,Cucumber 进入下一步。

所以我的问题是,如何使用 Protractor 和 Cucumber.js 编写将 Cucumber 表中定义的数据插入表单字段的步骤?使用 for 循环是否可行?

4

1 回答 1

4

您的循环正在排队承诺,因此循环在任何“点击”或发送键发生之前完成。您需要callback在所有承诺都解决后调用。

我看到了两种解决方案(我认为)。您可以跟踪数组中的承诺,然后使用protractor.promise.all(参见http://spin.atomicobject.com/2014/12/17/asynchronous-testing-protractor-angular/)等待承诺数组完成. 首先将 Promise 保存在一个var promises = []数组中:

var p = el.click().then(function(){ ... });
promises.push(p)

然后在循环之外:

protractor.promise.all(promises).then(callback);

或者,您可以依靠 ControlFlow 保持您的 Promise 在循环中有序,并在循环的最后一次迭代中调用回调:

var p = fieldEl.sendKeys(data[i].content);
if (i === data.length - 1) { // beware: you want to check "i" inside the loop and not in a promise created in the loop.
     p.then(callback);
}

尽管有相反的文字,我不能保证其中任何一个都有效。希望他们至少为您指明正确的方向。

于 2015-04-26T07:07:27.150 回答