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

feat(jest): add custom results processor for a11y failures #62

Merged
merged 78 commits into from
Jun 22, 2021

Conversation

mohanraj-r
Copy link
Contributor

@mohanraj-r mohanraj-r commented May 21, 2021

Features ✨

Jest automatic checks 🤖

  • jest: add a custom test results processor
    • create a new test suite to hold a11y errors
    • add WCAG metadata to results output
    • transform a11y error details into suite, test names

Results

Before - with default results processor (a11y error is embedded within the test failure)

JSON result:

"assertionResults": [
  {
    "ancestorTitles": [
      "integration test @sa11y/jest"
    ],
    "failureMessages": [
      "A11yError: 1 Accessibility issues found\n * (link-name) Links must have discernible text: a\n\t- Help URL: https://dequeuniversity.com/rules/axe/4.1/link-name\n    at Function.checkAndThrow (packages/format/src/format.ts:67:19)\n    at automaticCheck (packages/jest/src/automatic.ts:54:19)\n    at Object.<anonymous> (packages/jest/src/automatic.ts:69:13)"
    ],
    "fullName": "integration test @sa11y/jest should throw error for inaccessible dom",
    "location": null,
    "status": "failed",
    "title": "should throw error for inaccessible dom"
  }
]

Screen Shot 2021-06-17 at 1 24 29 PM

After - with new sa11y results processor added in this PR (and automatic checks)

Original JSON test result (failure with embedded a11y error) is now disabled

"assertionResults": [
        {
          "ancestorTitles": [
            "integration test @sa11y/jest"
          ],
          "failureMessages": [
            "A11yError: 1 Accessibility issues found\n * (link-name) Links must have discernible text: a\n\t- Help URL: https://dequeuniversity.com/rules/axe/4.1/link-name\n    at Function.checkAndThrow (packages/format/src/format.ts:67:19)\n    at automaticCheck (packages/jest/src/automatic.ts:54:19)\n    at Object.<anonymous> (packages/jest/src/automatic.ts:69:13)"
          ],
          "fullName": "integration test @sa11y/jest should throw error for inaccessible dom",
          "location": null,
          "status": "disabled",
          "title": "should throw error for inaccessible dom"
        },
]

New JSON test result created to represent the a11y failure bringing a11y metadata to forefront

"assertionResults": [
  {
    "ancestorTitles": [
      "integration test @sa11y/jest",
      "integration test @sa11y/jest should throw error for inaccessible dom"
    ],
    "failureMessages": [
      "Accessibility issues found: Links must have discernible text\nCSS Selectors: a\nHTML element: <a href=\"#\"></a>\nHelp: https://dequeuniversity.com/rules/axe/4.1/link-name\nTests: \"integration test @sa11y/jest should throw error for inaccessible dom\"\nSummary: Fix all of the following:\n  Element is in tab order and does not have accessible text\n\nFix any of the following:\n  Element does not have text that is visible to screen readers\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute"
    ],
    "fullName": "Links must have discernible text: a",
    "location": null,
    "status": "failed",
    "title": "should throw error for inaccessible dom"
  }
],

Screen Shot 2021-06-17 at 1 10 15 PM

TODO

@mohanraj-r mohanraj-r self-assigned this May 21, 2021
@mohanraj-r mohanraj-r changed the title refactor: use map to consolidate results; add a util to convert axe result feat(jest): Output consolidated a11y failures after test run May 21, 2021
@codecov
Copy link

codecov bot commented May 26, 2021

Codecov Report

Merging #62 (d24cea3) into master (64c35af) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##            master       #62   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           18        19    +1     
  Lines          208       234   +26     
  Branches        27        31    +4     
=========================================
+ Hits           208       234   +26     
Impacted Files Coverage Δ
packages/common/src/format.ts 100.00% <100.00%> (ø)
packages/common/src/helpers.ts 100.00% <100.00%> (ø)
packages/common/src/index.ts 100.00% <100.00%> (ø)
packages/format/src/format.ts 100.00% <100.00%> (ø)
packages/format/src/result.ts 100.00% <100.00%> (ø)
packages/format/src/wcag.ts 100.00% <100.00%> (ø)
packages/jest/src/automatic.ts 100.00% <100.00%> (ø)
packages/jest/src/matcher.ts 100.00% <100.00%> (ø)
packages/jest/src/resultsProcessor.ts 100.00% <100.00%> (ø)
packages/test-utils/src/test-data.ts 100.00% <100.00%> (ø)
... and 10 more

@mohanraj-r mohanraj-r changed the title feat(jest): Output consolidated a11y failures after test run feat(jest): output consolidated a11y failures after test run May 26, 2021
@mohanraj-r mohanraj-r marked this pull request as ready for review June 17, 2021 03:14
@mohanraj-r mohanraj-r requested review from cordeliadillon and a team as code owners June 17, 2021 03:14
Copy link

@trevor-bliss trevor-bliss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. Couple questions.

packages/jest/src/resultsProcessor.ts Outdated Show resolved Hide resolved
packages/jest/src/resultsProcessor.ts Show resolved Hide resolved
* Modify existing test suites, test results containing a11y errors after a11y errors
* are extracted out into their own test suites and results.
*/
function modifyTestSuiteResults(results: AggregatedResult, testSuite: TestResult, testResult: AssertionResult) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what the purpose of this function is. Can you explain more?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the custom reporter is transforming the a11y errors into their own test failures contained within a new suite based on the a11y rule (const suiteKey = [Sa11y ${a11yResult.wcag} ${a11yResult.id} ${suiteName}]), the original test in which the a11y error occurred is being disabled and test failure counts adjusted accordingly. Guess if the main logic is refactored to use map/filter without using any intermediates, it might be possible to just filter these out instead of disabling (the test counts will still need to be adjusted I think).

I have updated the PR desc to include docs/screenshots to illustrate this. Please check them out and let me know if it makes sense and if we can include them as part of jest README.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I just want to make sure we don't mess up the overall test and failure counts. E.g., If we have a functional failure and then that is fixed but replaced by an a11y failure, then the total tests and failure counts should remain the same.

It sounds like you're accounting for that. Just wanted to make sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good point. The failure count and the total test count could increase with the sa11y results processor - because each a11y failure from a test would be extracted to be its own test failure. When there is only 1 a11y failure in a test, the count would stay the same. But when there are multiple unique a11y failures in a test, the count could increase. But the results processor doesn't affect default console reporter or other reporters - it affects just the JSON output. Added a limitations section to the doc to reflect this and other points - can you please review.

Also created #66 as it is important and deserves its own issue.

Copy link
Contributor Author

@mohanraj-r mohanraj-r left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review @trevor-bliss 👍
I have addressed/responded to your comments. Please take a look.

packages/jest/src/resultsProcessor.ts Outdated Show resolved Hide resolved
packages/jest/src/resultsProcessor.ts Show resolved Hide resolved
* Modify existing test suites, test results containing a11y errors after a11y errors
* are extracted out into their own test suites and results.
*/
function modifyTestSuiteResults(results: AggregatedResult, testSuite: TestResult, testResult: AssertionResult) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the custom reporter is transforming the a11y errors into their own test failures contained within a new suite based on the a11y rule (const suiteKey = [Sa11y ${a11yResult.wcag} ${a11yResult.id} ${suiteName}]), the original test in which the a11y error occurred is being disabled and test failure counts adjusted accordingly. Guess if the main logic is refactored to use map/filter without using any intermediates, it might be possible to just filter these out instead of disabling (the test counts will still need to be adjusted I think).

I have updated the PR desc to include docs/screenshots to illustrate this. Please check them out and let me know if it makes sense and if we can include them as part of jest README.

trevor-bliss
trevor-bliss previously approved these changes Jun 21, 2021
- Automatic check is triggered regardless of the test status which would result in the original test failure if any getting overwritten by a11y failures if any from automatic checks ([#66](https://github.com/salesforce/sa11y/issues/66))
- Tests using the sa11y jest api would get tested twice with automatic checks - once as part of the sa11y API in the test and again as part of the automatic check
- a11y issues from automatic checks would overwrite the a11y issues found by the API
- If the sa11y API has been added to the test to check specific intermediate states of the DOM, enabling automatic checks could result in missed a11y issues

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this point is also covered by the next one below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is related, but there is also a fine difference - Enabling automatic checks without using the API vs while also using the API. Please check if the rewording now makes sense.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess to me since you say the automatic check is only at the end of the test it was clear to me that checking intermediate states of the DOM, whether you called the API or not, would not be caught. I'm fine to keep it worded like this though if you think it's more clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Trevor. I will try to revisit and reword/remove it in a subsequent PR.

- Workaround: Remove the DOM cleanup code from the test and opt-in to using sa11y to clean-up the DOM using the options as described above (`cleanupAfterEach: true` or `SA11Y_CLEANUP=1`)
- With the sa11y results processor
- Though the originating test from which the a11y failures are extracted is disabled, and test counts adjusted accordingly - the original test suite failure message still contains the a11y failures.
- The test suite failure message is typically not displayed or used in testing workflows. But if your testing workflow uses the test suite failure message, this might cause confusion.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The double indentation here feels a little confusing to me. Can we combine these 3 bullets into a single bullet and a couple sentences maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, modified - please take a look.

Copy link
Contributor Author

@mohanraj-r mohanraj-r left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trevor-bliss modified the docs (and also did some last bits of cleanup/refactoring). Can you please take a look.

- Automatic check is triggered regardless of the test status which would result in the original test failure if any getting overwritten by a11y failures if any from automatic checks ([#66](https://github.com/salesforce/sa11y/issues/66))
- Tests using the sa11y jest api would get tested twice with automatic checks - once as part of the sa11y API in the test and again as part of the automatic check
- a11y issues from automatic checks would overwrite the a11y issues found by the API
- If the sa11y API has been added to the test to check specific intermediate states of the DOM, enabling automatic checks could result in missed a11y issues
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is related, but there is also a fine difference - Enabling automatic checks without using the API vs while also using the API. Please check if the rewording now makes sense.

- Workaround: Remove the DOM cleanup code from the test and opt-in to using sa11y to clean-up the DOM using the options as described above (`cleanupAfterEach: true` or `SA11Y_CLEANUP=1`)
- With the sa11y results processor
- Though the originating test from which the a11y failures are extracted is disabled, and test counts adjusted accordingly - the original test suite failure message still contains the a11y failures.
- The test suite failure message is typically not displayed or used in testing workflows. But if your testing workflow uses the test suite failure message, this might cause confusion.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, modified - please take a look.

@mohanraj-r mohanraj-r merged commit 120fe16 into salesforce:master Jun 22, 2021
@mohanraj-r mohanraj-r deleted the feat_output_failures_json branch June 22, 2021 23:13
@mohanraj-r mohanraj-r restored the feat_output_failures_json branch June 22, 2021 23:13
@mohanraj-r mohanraj-r deleted the feat_output_failures_json branch June 23, 2021 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants