在 Nightwatch 命令队列中使用 REST 客户端

Using REST client in Nightwatch command queue

我正在使用基于 Nightwatch.jsNightwatch-Cucumber 进行测试。 Ans 我也使用 PageObject Pattern。这些测试不仅是基于 Selenium 的端到端测试,而且是 REST API 测试。对于 REST 测试,我使用 Atlassian JIRA REST client for Node。现在我想将 Nightwatch 的强大功能(包括 Selenium)与 REST 的强大功能结合起来。所以,我想同时使用这两种技术,我想在 Nightwatch 框架中集成 REST API 调用。

我尝试将 REST API 调用集成到 Nightwatch 的 perform() 函数中,以将 REST 调用添加到 Nightwatch command queue,但没有完全成功。我必须确保在执行下一个 Nightwatch 命令之前完全完成 REST 调用。目前,REST 调用之后的以下步骤将在 REST 调用完全完成之前执行。但是我该如何解决这个问题呢?

这是我的黄瓜特征文件:

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 的第二次调用在 Cucumber 步骤 When the user deletes a still existing project with key "ABC-123" via REST API 完全完成之前开始执行。

如果我在 Page Object 中取消注释 .waitForTime(4000) 行(这是一个自定义命令),那么我会得到正确的输出,但我不想以这种静态方式等待。很脏:

Starting selenium server... started - PID:  10554
.1
.2
3
.1
..

1 scenario (1 passed)
3 steps (3 passed)
0m07.783s

我如何解决我的问题以在下一步之后准确执行,或者我如何将 REST 调用集成到 Nightwatch 命令队列中。我也尝试过使我的功能 async 并使用 await 执行所有命令,但也没有成功。

如果您有需要同步 运行 的异步任务,则必须在 perform 函数中使用 done 回调。

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 的持续时间增加到适当的值。