Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testcafe xUnit reporter marks tests as both failure and error #7629

Closed
anthonyferroHU opened this issue Apr 13, 2023 · 2 comments
Closed

Testcafe xUnit reporter marks tests as both failure and error #7629

anthonyferroHU opened this issue Apr 13, 2023 · 2 comments
Labels
FREQUENCY: level 1 TYPE: bug The described behavior is considered as wrong (bug).

Comments

@anthonyferroHU
Copy link

anthonyferroHU commented Apr 13, 2023

What is your Scenario?

When using the testcafe xUnit reporter, if a test fails, the xml report logs 1 failure and 1 error count for the test. Similarly, if a test is stopped from an error (not a failing assertion), the xml report logs 1 failure and 1 error count for the test.

In this case, all 6 of these either failed or were stopped from an error, resulting in the following counts in the xml results:
<testsuite name="TestCafe Tests: Chrome 112.0.0.0 / macOS 10.15.7" tests="6" failures="6" skipped="0" errors="6"

We are moving to run these tests via AWS Codebuild, and these counts result in an error generating the report in Codebuild:

Error in UPLOAD_ARTIFACTS phase: [rspec_reports: [error processing report: [InvalidInputException: Test summary: status count cannot be negative]]]

This is happening because the reporter is marking each failing test as both an error and a failure; and combining this in the total count results in the number of failures + errors being larger than the number of tests. I didn't get much help from AWS support because they are expecting either a failure or an error per test. This feels like a valid request on the Testcafe side to ensure accurate xml results wherever we're running our tests.

What is the Current behavior?

Any test that does not pass is logged as both a failure and an error

What is the Expected behavior?

A test that does not pass should be logged as either a failure or an error, not both

What is your public website URL? (or attach your complete example)

n/a - Run a group of tests that fail using the testcafe xUnit reporter and specify an output file, check the total test, failure and error counts in the file after tests run

What is your TestCafe test code?

n/a - not an issue with test code, just the xUnit report summary

Your complete configuration file

No response

Your complete test report

<?xml version="1.0" encoding="UTF-8" ?>
<testsuite name="TestCafe Tests: Chrome 112.0.0.0 / macOS 10.15.7" tests="6" failures="6" skipped="0" errors="6" time="50.284" timestamp="Thu, 13 Apr 2023 13:25:49 GMT" >
  <testcase classname="Moderation - Forum Admin - List tests" name="Forum List Default State" time="47.688">
    <failure>
    <![CDATA[
      1) The specified selector does not match any element in the DOM tree.

          > | Selector('button.button.button--block.email-login-...)

         Browser: Chrome 112.0.0.0 / macOS 10.15.7

            42 |    await t.expect(this.emailButton.visible).ok();
            43 |  }
            44 |
            45 |  async clickEmail() {
            46 |    await this.emailButton();
          > 47 |    await t.click(this.emailButton);
            48 |  }
            49 |
            50 |  // social
            51 |  async isGoogleDisplayed() {
            52 |    await t.expect(this.googleButton.visible).ok();

            at <anonymous>
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:47:13)
            at asyncGeneratorStep
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
            at _next (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
    ]]>
    </failure>
  </testcase>
  <testcase classname="Moderation - Forum Admin - List tests" name="New Forum Displays in List" time="47.778">
    <failure>
    <![CDATA[
      1) The specified selector does not match any element in the DOM tree.

          > | Selector('button.button.button--block.email-login-...)

         Browser: Chrome 112.0.0.0 / macOS 10.15.7

            42 |    await t.expect(this.emailButton.visible).ok();
            43 |  }
            44 |
            45 |  async clickEmail() {
            46 |    await this.emailButton();
          > 47 |    await t.click(this.emailButton);
            48 |  }
            49 |
            50 |  // social
            51 |  async isGoogleDisplayed() {
            52 |    await t.expect(this.googleButton.visible).ok();

            at <anonymous>
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:47:13)
            at asyncGeneratorStep
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
            at _next (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
    ]]>
    </failure>
  </testcase>
  <testcase classname="Moderation - Forum Admin - List tests" name="Edit Forum Slug" time="47.684">
    <failure>
    <![CDATA[
      1) The specified selector does not match any element in the DOM tree.

          > | Selector('button.button.button--block.email-login-...)

         Browser: Chrome 112.0.0.0 / macOS 10.15.7

            42 |    await t.expect(this.emailButton.visible).ok();
            43 |  }
            44 |
            45 |  async clickEmail() {
            46 |    await this.emailButton();
          > 47 |    await t.click(this.emailButton);
            48 |  }
            49 |
            50 |  // social
            51 |  async isGoogleDisplayed() {
            52 |    await t.expect(this.googleButton.visible).ok();

            at <anonymous>
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:47:13)
            at asyncGeneratorStep
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
            at _next (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
    ]]>
    </failure>
  </testcase>
  <testcase classname="Moderation - Forum Admin - List tests" name="Edit Forum SEO" time="47.493">
    <failure>
    <![CDATA[
      1) The specified selector does not match any element in the DOM tree.

          > | Selector('button.button.button--block.email-login-...)

         Browser: Chrome 112.0.0.0 / macOS 10.15.7

            42 |    await t.expect(this.emailButton.visible).ok();
            43 |  }
            44 |
            45 |  async clickEmail() {
            46 |    await this.emailButton();
          > 47 |    await t.click(this.emailButton);
            48 |  }
            49 |
            50 |  // social
            51 |  async isGoogleDisplayed() {
            52 |    await t.expect(this.googleButton.visible).ok();

            at <anonymous>
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:47:13)
            at asyncGeneratorStep
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
            at _next (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
    ]]>
    </failure>
  </testcase>
  <testcase classname="Moderation - Forum Admin - Tags tests" name="Verify Forum Tags page" time="49.335">
    <failure>
    <![CDATA[
      1) The specified selector does not match any element in the DOM tree.

          > | Selector('button.button.button--block.email-login-...)

         Browser: Chrome 112.0.0.0 / macOS 10.15.7

            42 |    await t.expect(this.emailButton.visible).ok();
            43 |  }
            44 |
            45 |  async clickEmail() {
            46 |    await this.emailButton();
          > 47 |    await t.click(this.emailButton);
            48 |  }
            49 |
            50 |  // social
            51 |  async isGoogleDisplayed() {
            52 |    await t.expect(this.googleButton.visible).ok();

            at <anonymous>
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:47:13)
            at asyncGeneratorStep
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
            at _next (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
    ]]>
    </failure>
  </testcase>
  <testcase classname="Moderation - Forum Admin - Tags tests" name="Add three new tags, create a topic with three tags, browse with multiple tags, edit a tag, delete" time="49.318">
    <failure>
    <![CDATA[
      1) The specified selector does not match any element in the DOM tree.

          > | Selector('button.button.button--block.email-login-...)

         Browser: Chrome 112.0.0.0 / macOS 10.15.7

            42 |    await t.expect(this.emailButton.visible).ok();
            43 |  }
            44 |
            45 |  async clickEmail() {
            46 |    await this.emailButton();
          > 47 |    await t.click(this.emailButton);
            48 |  }
            49 |
            50 |  // social
            51 |  async isGoogleDisplayed() {
            52 |    await t.expect(this.googleButton.visible).ok();

            at <anonymous>
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:47:13)
            at asyncGeneratorStep
      (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
            at _next (/Users/anthony.ferro/Developer/nexus-e2e/components/loginDialog.js:2:37)
    ]]>
    </failure>
  </testcase>
</testsuite>

Screenshots

No response

Steps to Reproduce

Run a group of failing tests w/ this reporter configuration, check counts in spec_report.xml:
"reporter": [
{
"name": "xunit",
"output": "spec_report.xml"
}
],

TestCafe version

1.15.0

Node.js version

14, 18

Command-line arguments

-r xunit:spec_report.xml

Browser name(s) and version(s)

No response

Platform(s) and version(s)

No response

Other

Similar issues described here aquasecurity/trivy#880 and here https://stackoverflow.com/questions/64332952/why-does-my-aws-codebuild-test-report-result-in-an-incomplete-status

@anthonyferroHU anthonyferroHU added the TYPE: bug The described behavior is considered as wrong (bug). label Apr 13, 2023
@need-response-app need-response-app bot added the STATE: Need response An issue that requires a response or attention from the team. label Apr 13, 2023
@aleks-pro
Copy link
Collaborator

Hello @anthonyferroHU ,

You are right, testcafe treats failures and errors as identical attributes but according to the specification that I found, the meaning of these attributers differs. testcafe-reporter-xunit works in that way from the very beginning, so changing the current behavior may cause some breaking changes for a lot of users.

We need to discuss what we can do about this issue with the team. We will update this thread once we make a decision.

For the team: it looks like this issue has the same cause.

@need-response-app need-response-app bot removed the STATE: Need response An issue that requires a response or attention from the team. label Apr 21, 2023
@Artem-Babich
Copy link
Contributor

Artem-Babich commented Jun 20, 2023

Hello @anthonyferroHU,

After additional research we came to the conclusion that this behavior depends on the CI system you use, so as we mentioned above, we don't plan to change it. You can use the onBeforeWrite hook to remove the "testsuite" tag attribute:

// .testcaferc.js
const TEST_SUIT_REGEX = new RegExp(/<testsuite (name=".*") (tests=".*") (failures=".*") (skipped=".*") (errors=".*") (time=".*") (timestamp=".*") >/);

function xUnitOnBeforeWrite (writeInfo) {
    if (writeInfo.initiator !== 'reportTaskDone')
        return;

    if (!TEST_SUIT_REGEX.test(writeInfo.formattedText))
        return;

    writeInfo.formattedText = writeInfo.formattedText.replace(TEST_SUIT_REGEX, (...args) => {
        const [
                  _,
                  name,
                  tests,
                  failures,
                  skipped,
                  errors,
                  time,
                  timestamp,
              ] = args;

        return `<testsuite ${name} ${tests} ${failures} ${skipped} ${time} ${timestamp} >`;
    });
}

module.exports = {
    hooks: {
        reporter: {
            onBeforeWrite: {
                'xunit': xUnitOnBeforeWrite,
            },
        },
    },
};

Feel free to reopen this issue if this approach is not suitable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FREQUENCY: level 1 TYPE: bug The described behavior is considered as wrong (bug).
Projects
None yet
Development

No branches or pull requests

3 participants