在Protractor中传播承诺

时间:2015-08-07 22:58:38

标签: javascript angularjs selenium-webdriver promise protractor

q library有这个简洁的功能来解决并将多个promise传播到不同的参数中:

  

如果您对数组有承诺,可以使用spread作为   替换当时。扩散函数“扩展”值   履行处理程序的参数。

return getUsername()
    .then(function (username) {
        return [username, getUser(username)];
    })
    .spread(function (username, user) {

    });

在量角器中,我们尝试使用来自WebDriverJS的内置protractor.promise

问题:

是否可以将{spread}功能与protractor.promise一起使用?

示例用例:

我们已经为check if an element is focused实施了自定义茉莉花匹配器。在这里,我们需要在进行相等比较之前解决两个promise。目前,我们正在使用protractor.promise.all()then()

protractor.promise.all([
    elm.getId(),
    browser.driver.switchTo().activeElement().getId()
]).then(function (values) {
    jasmine.matchersUtil.equals(values[0], values[1]);
});

理想情况下,我们希望处于更具可读性的状态:

protractor.promise.all([
    elm.getId(),
    browser.driver.switchTo().activeElement().getId()
]).spread(function (currentElementID, activeElementID) {
    return jasmine.matchersUtil.equals(currentElementID, activeElementID);
})

2 个答案:

答案 0 :(得分:7)

使用它可能有点难看,但你可以定义一个独立的辅助函数,它可以作为参数传递给then()并有一个回调,通常传递给then()到被传递给它。然后,此函数将数组值转换为函数参数:

protractor.promise.all([
    elm.getId(),
    browser.driver.switchTo().activeElement().getId()
]).then(spread(function (currentElementID, activeElementID) {
    // ---^^^----- use helper function to spread args
    jasmine.matchersUtil.equals(currentElementID, activeElementID);
}));


// helper function gets a callback
function spread(callback) {
    // and returns a new function which will be used by `then()`
    return function (array) {
        // with a result of calling callback via apply to spread array values
        return callback.apply(null, array);
    };
}

您仍然可以将其与另一个then()链接,并提供拒绝回调;它使Protractor的所有行为保持相同,但只是将值数组转换为参数。

缺点是它没有像你的例子那样完美的外观(不是.all().spread()而是.all().then(spread()))你可能不得不为这个助手创建一个模块或者全局定义它能够在多个测试文件中轻松使用它。

<强>更新

使用ES2015,可以使用destructuring assignmentthen()

protractor.promise.all([
    elm.getId(),
    browser.driver.switchTo().activeElement().getId()
]).then(function (values) {
    // Destructure values to separate variables
    const [currentElementID, activeElementID] = values; 
    jasmine.matchersUtil.equals(currentElementID, activeElementID);
}));

答案 1 :(得分:4)

TL; DR 显然,用protractor.promise替换q并不完全安全。例如,一旦我决定延长ElementArrayFinder,我就进行了悬挂式测试:

旧回答:

以下是我为解决这个问题所做的工作。

我已经protractor.promise 替换了q(不确定它是否真的可以安全):

onPrepare: {
    protractor.promise = require("q");
},

但是,到目前为止没有任何结果,现在我能够使用spread()q通过protractor.promise提供的其他语法糖:

toBeActive: function() {
    return {
        compare: function(elm) {
            return {
                pass: protractor.promise.all([
                    elm.getId(),
                    browser.driver.switchTo().activeElement().getId()
                ]).spread(function (currentElementID, activeElementID) {
                    return jasmine.matchersUtil.equals(currentElementID, activeElementID);
                })
            };
        }
    };
}

相关的github主题:protractor.promise to use q