【问题标题】:How to wrap `AxeBuilder.analyse()` in a promise in Jasmine / Protractor?如何在 Jasmine / Protractor 的承诺中包装“AxeBuilder.analysis()”?
【发布时间】:2016-08-18 19:29:28
【问题描述】:

我一直在开发 Jasmine 自定义匹配器以检查页面是否可访问。

重要的部分如下所示:

var _result = {};
AxeBuilder(browser.driver).analyze(function(results) {
    if (util.equals(results.violations.length, expected)) {
        _result.pass = true;
        _result.message = 'Selection was accessible.';
    } else {
        _result.pass = false;
        _result.message = results.violations;
    }
});
return result;

我的问题是_result(不是results)总是一个空对象。

我怀疑问题在于 AxeBuilder(...).analyze(...) 是异步的但不返回承诺。

我的测试不是从 Karma 运行的,它是通过我的 Protractor 配置启动的。

如果我的怀疑是真的,我将如何将其包装在一个承诺中?

【问题讨论】:

    标签: asynchronous jasmine promise protractor


    【解决方案1】:

    如果可能,您应该使用量角器中提供的 WebDriverJS 承诺

    function builder() {
          return AxeBuilder(browser.driver).analyze(function(results) {
             var deferred = protractor.promise.defer();
             if (util.equals(results.violations.length, expected)) {
               _result.pass = true;
               _result.message = 'Selection was accessible.';
               deferred.fulfill(_result);
             } else {
               _result.pass = false;
               _result.message = results.violations;
               deferred.reject(_result);
             }
             return deferred;
         });
    }
    

    这是你如何使用它,

     builder().then(function(_result) {
            console.log(_result.pass);
        }, function(err) {
           console.error(err);
     });
    

    【讨论】:

    • 这很有趣,看起来很有希望(没有双关语),但仍然不适合我。
    • 我认为AxeBuilder(browser.driver).analyze 失败了。回调是否被调用?也许在里面添加一个控制台日志,看看它是否到达那里?
    【解决方案2】:

    您可以实现回调概念,以防止在结果对象准备好之前执行语句'return result'。你可以试试下面的代码。

     var _result = {firstvalue:"test"};
     AxeBuilder(browser.driver).analyze(function(results,callback) {
          if (util.equals(results.violations.length, expected)) {
               _result.pass = true;
               _result.message = 'Selection was accessible.';
           } else {
             _result.pass = false;
             _result.message = results.violations;
          }
         callback(result);
      });
    
    var callback=function(result){
       return result;
      }
    

    【讨论】:

    • 我没有成功。
    • 对不起,情况不变result.pass未定义。
    • @atwright147,创建一个任意值的对象,而不是创建一个空的对象 var _result = {first:"Test"};
    【解决方案3】:

    我不熟悉 AxeBuilder。正如你提到的 AxeBuilder.analyze() 是一个异步方法,你需要在分析方法中返回 _result 变量。试试下面的代码,

    return AxeBuilder(browser.driver).analyze(function(results) {
      if (util.equals(results.violations.length, expected)) {
        _result.pass = true;
        _result.message = 'Selection was accessible.';
      } else {
        _result.pass = false;
        _result.message = results.violations;
      }
       return _result;
    });
    

    在您的代码中,您在执行分析方法之前返回 _resultvariable。

    【讨论】:

    • 感谢您的快速回复。这似乎不起作用,因为它没有返回承诺,并且我的其余代码在完成工作之前执行。我想我需要把它包装在一个承诺中(不知何故)。
    猜你喜欢
    • 2020-03-27
    • 2014-08-02
    • 2015-10-26
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    相关资源
    最近更新 更多