Intern JS - 如何在链式命令方法中使用 Promise.all()?
Intern JS - how can I use Promise.all() within chained Command methods?
我不熟悉使用 Intern JS 编写测试,并且一直在关注他们的文档以使用 Object interface and Page objects,尤其是。根据文档,页面对象背后的想法是封装特定页面的 DOM,以防标记发生变化。
在尝试遵循页面对象模式时,我的目标是在 myPage
上有一个方法,它使用 Promise.all()
找到几个 DOM 元素,然后 return 这些到一个实际的测试函数。
我大致以 documentation for leadfood/Command 顶部附近的 Promise.all()
示例为基础。我怀疑我对 return 的链接错误 我想在调用 testOneStuff()
时返回到 test 1
函数......但是因为我没有看到将 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;
});
挂起可能是由于在 then
回调中使用 this
启动命令链。从命令 then
回调返回 this
或从 this
开始的命令链将使链死锁。相反,在回调中使用 this.parent
,例如:
return Promise.all([
this.parent.findByCssSelector('...'),
this.parent.findAllByCssSelector('...'),
this.parent.findByCssSelector('...'),
this.parent.findByCssSelector('...')
]).then(//...
我不小心回到了刚才非常相似的情况。
现在我的测试已经有了很大的发展,所以我有很多不同的结构。所以这一次,我不想从我的页面对象的方法中 return 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
我不熟悉使用 Intern JS 编写测试,并且一直在关注他们的文档以使用 Object interface and Page objects,尤其是。根据文档,页面对象背后的想法是封装特定页面的 DOM,以防标记发生变化。
在尝试遵循页面对象模式时,我的目标是在 myPage
上有一个方法,它使用 Promise.all()
找到几个 DOM 元素,然后 return 这些到一个实际的测试函数。
我大致以 documentation for leadfood/Command 顶部附近的 Promise.all()
示例为基础。我怀疑我对 return 的链接错误 我想在调用 testOneStuff()
时返回到 test 1
函数......但是因为我没有看到将 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;
});
挂起可能是由于在 then
回调中使用 this
启动命令链。从命令 then
回调返回 this
或从 this
开始的命令链将使链死锁。相反,在回调中使用 this.parent
,例如:
return Promise.all([
this.parent.findByCssSelector('...'),
this.parent.findAllByCssSelector('...'),
this.parent.findByCssSelector('...'),
this.parent.findByCssSelector('...')
]).then(//...
我不小心回到了刚才非常相似的情况。
现在我的测试已经有了很大的发展,所以我有很多不同的结构。所以这一次,我不想从我的页面对象的方法中 return 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