在Protractor中传播承诺

ale*_*cxe 10 javascript promise angularjs selenium-webdriver protractor

q有这个简洁的功能来解析和传播多个promises到单独的参数:

如果你有一个数组的承诺,你可以使用spread作为替代.扩展函数将值"扩展"到履行处理程序的参数上.

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

    });
Run Code Online (Sandbox Code Playgroud)

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

问题:

是否可以使用"传播"功能protractor.promise

用例示例:

我们已经实现了一个自定义的jasmine matcher来检查元素是否被聚焦.在这里,我们需要在进行相等比较之前解决两个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]);
});
Run Code Online (Sandbox Code Playgroud)

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

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

Mic*_*nov 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);
    };
}
Run Code Online (Sandbox Code Playgroud)

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

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

更新:

使用ES2015,可以使用解构赋值以及then():

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);
}));
Run Code Online (Sandbox Code Playgroud)

  • 我简单地看了一下源代码,就像开发人员在你的Github问题中说的那样,它有一个叫做控制流的东西,用在promise方法中([desc](https://github.com/SeleniumHQ/selenium/blob/master) /javascript/webdriver/promise.js#L1193)).我想它负责规范的顺序和/或在多个浏览器实例中并行运行测试的能力,但我不确定.这些流程在高级别初始化,[当绑定驱动程序时](https://github.com/SeleniumHQ/selenium/blob/01399fffecd5a20af6f31aed6cb0043c9c5cde65/javascript/node/selenium-webdriver/builder.js#L454) (2认同)