实习生JS - 如何在链式命令方法中使用Promise.all()?

时间:2015-12-09 19:20:12

标签: javascript promise intern

我是使用Intern JS编写测试的新手,并且一直在关注他们的文档以使用Object interfacePage objects。根据文档,页面对象背后的想法是在标记更改的情况下封装特定页面的DOM。

在尝试遵循页面对象模式时,我的目标是在myPage上使用Promise.all()来查找多个DOM元素,然后将这些元素返回到实际的测试函数。

我大致基于documentation for leadfood/Command顶部附近的Promise.all()示例。当我调用test 1时,我怀疑我得到了错误的链接以返回我想要返回testOneStuff()函数...但是因为我没有看到包含链中Promise.all(),我发现自己不知所措。

当我尝试运行此测试时,似乎可以启动function (unitWrapper)(我在那里有一个console.log),然后在几秒钟之后失败了CancelError: Timeout reached...

这个想法甚至可能吗?我也意识到我可能会以一种不同寻常的方式接近这一点,因为除了他们文档中的一些基本示例之外,我对Intern JS中的典型模式并不熟悉。

以下是我正在做的相关部分:

在定义测试的文件中:

define([
  'intern!object',
  'intern/chai!assert',
  '../support/pages/MyPage'
], function (registerSuite, assert, MyPage) {
  registerSuite(function () {
    var myPage;

    return {
      name: 'my_test',

      setup: function () {
        myPage = new MyPage(this.remote);
      },

      'test 1': function () {
        return myPage
          .testOneStuff()
          .then(function (elements) {
            // here I would like 'elements' to be the object I'm
            // returning in function passed into Promise.all().then().
          });
      }
    };
  });
});

在定义MyPage的文件中:

define(function (require) {

  // Constructor to exec at runtime
  function MyPage(remote) {
    this.remote = remote;
  }

  MyPage.prototype = {
    constructor: MyPage,

    testOneStuff: function () {
      return this.remote
        .findByCssSelector('.unit-question')
        .then(function (unitWrapper) {

          // Note that 'this' is the command object.
          return Promise.all([
            // Note we've left the 'find' context with .unit-question as parent
            this.findByCssSelector('ul.question-numbers li.current').getVisibleText(),
            this.findAllByCssSelector('ul.answers li a.answer'),
            this.findByCssSelector('a.action-submit-answer'),
            this.findByCssSelector('a.action-advance-assessment')
          ]).then(function (results) {
            return {
              currentQuestionNumber: results[0],
              answerLinks: results[1],
              btnSubmit: results[2],
              btnNext: results[3]
            };
          });
        });
    }
  };

  return MyPage;
});

2 个答案:

答案 0 :(得分:1)

挂起可能是由于使用this启动then回调中的命令链。返回this或从this开始的命令链,从命令then回调将导致链死锁。相反,在回调中使用this.parent,例如:

return Promise.all([
    this.parent.findByCssSelector('...'),
    this.parent.findAllByCssSelector('...'),
    this.parent.findByCssSelector('...'),
    this.parent.findByCssSelector('...')
]).then(//...

答案 1 :(得分:0)

我刚才回到了一个非常类似的情况,不经意间。

由于我的测试进一步发展,我有很多不同的结构。所以这一次,我不想从页面对象的方法返回Promise.all().then()的结果,而只是想抓住两个命令链的结果并在断言中一起使用它们,然后继续链。

这是一个节选,显示似乎有效的模式。所有的控制台日志都按照它们被调用的顺序打印出来(这里链中可见),所以我假设所有链接的调用都在等待前面的调用完成,这是所希望的。这个链在一个定义我的测试之一的函数内(即我问题的示例代码中的test 1函数)。

// Store the instance of leadfoot/Command object in clearly named
// variable to avoid issues due to different contexts of `this`.
var command = this.remote;

... // other Command function calls
.end()
.then(function () {
  console.log('=== going to Promise.all');
  return Promise.all([
    command
      .findByCssSelector('li.question.current')
      .getAttribute('data-question-id'),
    command
      .findByCssSelector('h3.question')
      .getVisibleText()
  ]);
})
.then(function (results) {
  console.log('=== hopefully, then() for Promise.all?');
  var qid = results[0];
  var questionText = results[1];
  console.log(qid, questionText);
  console.log('=== then() is completed');

  // This allows continuing to chain Command methods
  return command;
})
.findByCssSelector('h3.question')
  .getVisibleText()
  .then(function (questionText) {
    console.log('=== I\'m the next then()!');
  })
.end()
... // chain continues as usual