我正在使用基于Nightwatch-Cucumber
的Nightwatch.js
进行测试。我也使用PageObject Pattern
。这些测试不仅是基于Selenium
的end2end测试,还有REST API
测试。对于REST测试,我使用的是Atlassian JIRA REST client for Node。现在我想将Nightwatch的功能(包括Selenium)与REST的强大功能结合起来。所以,我希望将这两种技术结合使用,并希望在Nightwatch框架中集成REST API调用。
我试图在Nightwatch的perform()
函数中集成REST API调用,以将REST调用添加到Nightwatch command queue,但没有取得圆满成功。我必须确保在执行下一个Nightwatch命令之前完成REST调用。目前,在REST调用完成之前,将执行REST调用之后的以下步骤。但是我该如何解决这个问题呢?
这是我的Cucumber功能文件:
Feature: JIRA projects tests
Scenario: my first test
When the user logs out
When the user deletes a still existing project with key "ABC-123" via REST API
When the user logs out
这些是我的Step Definitions
:
const { client } = require("nightwatch-cucumber");
const { defineSupportCode } = require("cucumber");
const myPage = client.page.myPageView();
defineSupportCode(({ Given, When, Then }) => {
When(/^the user logs out$/, () => {
return myPage.logoutUser(client);
});
When(
/^the user deletes a still existing project with key "([^"]*)" via REST API$/,
projectKey => {
return myPage.deleteProjectViaRestApi(client, projectKey);
}
);
});
这些是我的Page Object
功能:
const restClientConnector = require("../../rest/restClientConnector");
const environmentVariables = require("../../helpers/getEnvironmentVariables");
module.exports = {
elements: {},
commands: [
{
logoutUser(client) {
console.log("1");
return client
.deleteCookies()
.url(
environmentVariables.launchUrl(client) +
"/crowd/console/logoff.action"
);
},
deleteProjectViaRestApi(client, projectKey) {
return client
.perform(function() {
//delete the given project
restClientConnector
.jiraConnector(
environmentVariables.jiraHostUrl,
environmentVariables.jiraAdminUsername,
environmentVariables.jiraAdminPassword
)
.project.deleteProject(
{
projectIdOrKey: projectKey
},
function(error, result) {
console.log("2");
}
);
})
.perform(function() {
restClientConnector
.jiraConnector(
environmentVariables.jiraHostUrl,
environmentVariables.jiraAdminUsername,
environmentVariables.jiraAdminPassword
)
.project.getProject(
{
projectIdOrKey: projectKey
},
function(error, result) {
console.log("3");
}
);
});
//.waitForTime(4000);
}
}
]
};
所以,我希望3个Cucumber步骤同步运行,一个接一个。我添加了一些console.log()
输出来检查这一点。我的测试运行期间我期望控制台输出的顺序:
1
2
3
1
相反,我得到以下输出:
Starting selenium server... started - PID: 10436
.1
..1
..
1 scenario (1 passed)
3 steps (3 passed)
0m03.782s
3
2
因此,Cucumber步When the user logs out
的第二次调用开始执行黄瓜步骤When the user deletes a still existing project with key "ABC-123" via REST API
完全完成。
如果我在.waitForTime(4000)
中取消注释行Page Object
(它是一个自定义命令),那么我得到正确的输出,但我不想以这样的静态方式等待。这很脏:
Starting selenium server... started - PID: 10554
.1
.2
3
.1
..
1 scenario (1 passed)
3 steps (3 passed)
0m07.783s
如何解决我的问题,在下一步之后执行一步,或者如何在Nightwatch命令队列中集成REST调用。我也尝试用async
制作我的功能并用await
执行所有命令,但也没有成功。
如果您需要同步运行异步任务,则必须在done
函数中使用perform
回调。
browser.perform(function(done) {
//do some async stuff...
done();
});
您希望在异步任务完成后调用done
。在你的情况下,它应该类似于这样:
deleteProjectViaRestApi(client, projectKey) {
return client
.perform(function(done) {
//delete the given project
restClientConnector
.jiraConnector(
environmentVariables.jiraHostUrl,
environmentVariables.jiraAdminUsername,
environmentVariables.jiraAdminPassword
)
.project.deleteProject(
{
projectIdOrKey: projectKey
},
function(error, result) {
console.log("2");
done();
}
);
})
.perform(function(done) {
restClientConnector
.jiraConnector(
environmentVariables.jiraHostUrl,
environmentVariables.jiraAdminUsername,
environmentVariables.jiraAdminPassword
)
.project.getProject(
{
projectIdOrKey: projectKey
},
function(error, result) {
console.log("3");
done();
}
);
});
}
如果遇到done
回调超时的问题,你应该将外部全局文件中的asyncHookTimeout
的持续时间增加到适当的值。