我可以 return 来自 promise 的数据吗

Can I return data from a promise

我正在寻找与 SO 问题相关的更多帮助

这是关于使用 Selenium Webdriver 的 javascript 实现来自动化网站组件。

从引用问题中给出的示例中,我无法弄清楚如何将 allHtml 数组传回调用方法以及测试逻辑所在的小黄瓜步骤定义。

我已经尝试了多种方法(太多无法记录),并进行了许多小时的谷歌搜索。我只是不知道如何从承诺中传回任何东西(一旦它被解决并且我们定义了 allHtml)。是的,我可以输出到控制台,但这在我需要根据实际与预期的比较来断言通过或失败的真实世界测试场景中没有帮助。

承诺是痛苦的。它们对我来说是新的,在我把头缠在它们身上之前会很痛。

作为最后的手段(也可能是唯一的解决方案),我将考虑使用 webdriver-sync 以避免 javascript 版本的 webdriver 固有的承诺。

任何帮助或指导将不胜感激,以了解如何在承诺完全解决后将事情从承诺中传回(如果可能的话)。在我看来,Promises 是关于在事物准备就绪时使用它们,而不是之前或之后。

谢谢,艾尔

AddApplicationPage.prototype.getFilteredAppLibraryTemplates = function (context) {
    var eleArray = this.getAppLibraryTemplateIcons(context);
    return eleArray;
}

AddApplicationPage.prototype.getAppLibraryTemplateIcons = function (context) {

    var pendingElements = context.driver.findElements(By.className('appLibrary-templateIcon'))

    pendingElements.then(function (elements) {
        var pendingHtml = elements.map(function (elem) {
            return elem.getInnerHtml();
        });
        promise.all(pendingHtml).then(function (allHtml) {
            // how do i pass allHtml back up the food chain 
            // so i can do some comparison to the expected list
        });
    });
}

你不能。

异步函数仍然是异步函数。 You can't return the result from itfindElements 执行完毕,结果不存在。

Promise 只是一个方便的对象,您可以随时 return 传递它并为其分配回调函数。


您说您使用的是 Gerkin,所以我假设您使用的是 Cucumber.js。看看它的documentation:

  this.Given(/^I am on the Cucumber.js GitHub repository$/, function (callback) {
    // Express the regexp above with the code you wish you had.
    // `this` is set to a World instance.
    // i.e. you may use this.browser to execute the step:

    this.visit('https://github.com/cucumber/cucumber-js', callback);

    // The callback is passed to visit() so that when the job's finished, the next step can
    // be executed by Cucumber.
  });

传递给您传递给步骤定义的函数的第一个参数是您在获得结果时调用的回调。

不用担心将结果传回。只需传递回调函数 forward 并在完成后调用它即可。

解决了,很好。我的愿望是在小黄瓜步骤定义中验证元素(与预期相比)。 我发现,如果我将 promise 到数组的转换移到步骤定义中,它也能正常工作,并且不会隐藏验证过程。 更坏的情况我会使用这个解决方案。

AddApplicationPage.prototype.getAppLibraryTemplateIcons = function (context) {
    return context.driver.findElements(appLibraryTemplateIcon);
}

this.Then(/^I should see matching filtered results$/, function () {

  var pedingElements = addApplicationPage.getAppLibraryTemplateIcons(this);

  pedingElements.then(function (elements) {

      var pendingHtml = elements.map(function (elem) {
          return elem.getInnerHtml();
      });

      promise.all(pendingHtml).then(function (allHtml) {
          var expectedHtml = ["Google Apps"];        
          expect(expectedHtml).to.deep.equal(allHtml);    
      })

  });                                                                   
});