@sa11y/jest 7.1.0-alpha.1 → 7.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -108,7 +108,7 @@ it('should be accessible', async () => {
108
108
  // Setup DOM to be tested for accessibility
109
109
  //...
110
110
 
111
- // assert that DOM is accessible (using base preset-rule)
111
+ // assert that whole DOM is accessible (using base preset-rule)
112
112
  await expect(document).toBeAccessible();
113
113
 
114
114
  // Can be used to test accessibility of a specific HTML element
@@ -9,6 +9,13 @@ export type AutoCheckOpts = {
9
9
  runDOMMutationObserver?: boolean;
10
10
  enableIncompleteResults?: boolean;
11
11
  };
12
+ export type RenderedDOMSaveOpts = {
13
+ renderedDOMDumpDirPath?: string;
14
+ generateRenderedDOMFileSaveLocation?: (testFilePath: string, testName: string) => {
15
+ fileName: string;
16
+ fileUrl: string;
17
+ };
18
+ };
12
19
  export declare const setOriginalDocumentBodyHtml: (bodyHtml: string | null) => void;
13
20
  export declare const getOriginalDocumentBodyHtml: () => string | null;
14
21
  /**
@@ -19,10 +26,10 @@ export declare function skipTest(testPath: string | undefined, filesFilter?: str
19
26
  * Run accessibility check on each element node in the body using {@link toBeAccessible}
20
27
  * @param opts - Options for automatic checks {@link AutoCheckOpts}
21
28
  */
22
- export declare function automaticCheck(opts?: AutoCheckOpts): Promise<void>;
29
+ export declare function automaticCheck(opts?: AutoCheckOpts, renderedDOMSaveOpts?: RenderedDOMSaveOpts): Promise<void>;
23
30
  /**
24
31
  * Register accessibility checks to be run automatically after each test
25
32
  * @param opts - Options for automatic checks {@link AutoCheckOpts}
26
33
  */
27
- export declare function registerSa11yAutomaticChecks(opts?: AutoCheckOpts): void;
34
+ export declare function registerSa11yAutomaticChecks(opts?: AutoCheckOpts, renderedDOMSaveOpts?: RenderedDOMSaveOpts): void;
28
35
  //# sourceMappingURL=automatic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"automatic.d.ts","sourceRoot":"","sources":["../src/automatic.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAI7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACrC,CAAC;AAkBF,eAAO,MAAM,2BAA2B,aAAc,MAAM,GAAG,IAAI,SAElE,CAAC;AAEF,eAAO,MAAM,2BAA2B,qBAEvC,CAAC;AAEF;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAUtF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,GAAE,aAAoC,GAAG,OAAO,CAAC,IAAI,CAAC,CAqE9F;AAsBD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,GAAE,aAAoC,GAAG,IAAI,CAmB7F"}
1
+ {"version":3,"file":"automatic.d.ts","sourceRoot":"","sources":["../src/automatic.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAI7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,mCAAmC,CAAC,EAAE,CAClC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,KACf;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C,CAAC;AAsBF,eAAO,MAAM,2BAA2B,aAAc,MAAM,GAAG,IAAI,SAElE,CAAC;AAEF,eAAO,MAAM,2BAA2B,qBAEvC,CAAC;AAEF;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAUtF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAChC,IAAI,GAAE,aAAoC,EAC1C,mBAAmB,GAAE,mBAAgD,GACtE,OAAO,CAAC,IAAI,CAAC,CAmGf;AAsBD;;;GAGG;AACH,wBAAgB,4BAA4B,CACxC,IAAI,GAAE,aAAoC,EAC1C,mBAAmB,GAAE,mBAAgD,GACtE,IAAI,CAmBN"}
package/dist/automatic.js CHANGED
@@ -24,6 +24,9 @@ const defaultAutoCheckOpts = {
24
24
  runDOMMutationObserver: false,
25
25
  enableIncompleteResults: false,
26
26
  };
27
+ const defaultRenderedDOMSaveOpts = {
28
+ renderedDOMDumpDirPath: '',
29
+ };
27
30
  let originalDocumentBodyHtml = null;
28
31
  let mutatedNodes = [];
29
32
  const setOriginalDocumentBodyHtml = (bodyHtml) => {
@@ -51,7 +54,7 @@ exports.skipTest = skipTest;
51
54
  * Run accessibility check on each element node in the body using {@link toBeAccessible}
52
55
  * @param opts - Options for automatic checks {@link AutoCheckOpts}
53
56
  */
54
- async function automaticCheck(opts = defaultAutoCheckOpts) {
57
+ async function automaticCheck(opts = defaultAutoCheckOpts, renderedDOMSaveOpts = defaultRenderedDOMSaveOpts) {
55
58
  if (skipTest(globals_1.expect.getState().testPath, opts.filesFilter))
56
59
  return;
57
60
  // Skip automatic check if test is using fake timer as it would result in timeout
@@ -73,6 +76,7 @@ async function automaticCheck(opts = defaultAutoCheckOpts) {
73
76
  // Create a DOM walker filtering only elements (skipping text, comment nodes etc)
74
77
  const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT);
75
78
  let currNode = walker.firstChild();
79
+ let renderedDOMSavedFileName = '';
76
80
  try {
77
81
  if (!opts.runDOMMutationObserver) {
78
82
  while (currNode !== null) {
@@ -88,7 +92,29 @@ async function automaticCheck(opts = defaultAutoCheckOpts) {
88
92
  }
89
93
  }
90
94
  else {
91
- a11yResults.push(...(await (0, assert_1.getA11yResultsJSDOM)(document.body, config, opts.enableIncompleteResults)));
95
+ const a11yResultsJSDOM = await (0, assert_1.getA11yResultsJSDOM)(document.body, config, opts.enableIncompleteResults);
96
+ if (a11yResultsJSDOM?.length > 0) {
97
+ if (!!renderedDOMSaveOpts.renderedDOMDumpDirPath &&
98
+ !!renderedDOMSaveOpts.generateRenderedDOMFileSaveLocation) {
99
+ try {
100
+ // save the document body HTML
101
+ const testFilePath = globals_1.expect.getState().testPath ?? '';
102
+ const testName = globals_1.expect.getState().currentTestName ?? '';
103
+ if (!testFilePath || !testName) {
104
+ console.log(`Skipping saving rendered DOM HTML as one or both of test file path and test name are empty`);
105
+ }
106
+ else {
107
+ const { fileName, fileUrl } = renderedDOMSaveOpts.generateRenderedDOMFileSaveLocation(testFilePath, testName);
108
+ renderedDOMSavedFileName = fileUrl;
109
+ (0, common_1.writeHtmlFileInPath)(renderedDOMSaveOpts.renderedDOMDumpDirPath, fileName, document.body.innerHTML);
110
+ }
111
+ }
112
+ catch (e) {
113
+ console.log(`ran into an error while saving rendered DOM - ${e.message}`);
114
+ }
115
+ }
116
+ }
117
+ a11yResults.push(...a11yResultsJSDOM);
92
118
  document.body.innerHTML = '';
93
119
  // loop mutated nodes
94
120
  for await (const mutatedNode of mutatedNodes) {
@@ -99,9 +125,6 @@ async function automaticCheck(opts = defaultAutoCheckOpts) {
99
125
  }
100
126
  }
101
127
  }
102
- catch (e) {
103
- format_1.AxeError.throwAxeError(e);
104
- }
105
128
  finally {
106
129
  if (opts.runDOMMutationObserver) {
107
130
  mutatedNodes = [];
@@ -116,7 +139,7 @@ async function automaticCheck(opts = defaultAutoCheckOpts) {
116
139
  if (process.env.SELECTOR_FILTER_KEYWORDS) {
117
140
  a11yResults = (0, format_1.exceptionListFilterSelectorKeywords)(a11yResults, process.env.SELECTOR_FILTER_KEYWORDS.split(','));
118
141
  }
119
- format_1.A11yError.checkAndThrow(a11yResults, { deduplicate: opts.consolidateResults });
142
+ format_1.A11yError.checkAndThrow(a11yResults, { deduplicate: opts.consolidateResults, renderedDOMSavedFileName });
120
143
  }
121
144
  }
122
145
  exports.automaticCheck = automaticCheck;
@@ -143,7 +166,7 @@ const observerOptions = {
143
166
  * Register accessibility checks to be run automatically after each test
144
167
  * @param opts - Options for automatic checks {@link AutoCheckOpts}
145
168
  */
146
- function registerSa11yAutomaticChecks(opts = defaultAutoCheckOpts) {
169
+ function registerSa11yAutomaticChecks(opts = defaultAutoCheckOpts, renderedDOMSaveOpts = defaultRenderedDOMSaveOpts) {
147
170
  if (opts.runAfterEach) {
148
171
  const observer = new MutationObserver(observerCallback);
149
172
  // TODO (fix): Make registration idempotent
@@ -157,7 +180,7 @@ function registerSa11yAutomaticChecks(opts = defaultAutoCheckOpts) {
157
180
  if (opts.runDOMMutationObserver) {
158
181
  observer.disconnect(); // stop mutation observer
159
182
  }
160
- await automaticCheck(opts);
183
+ await automaticCheck(opts, renderedDOMSaveOpts);
161
184
  });
162
185
  }
163
186
  }
@@ -1 +1 @@
1
- {"version":3,"file":"groupViolationResultsProcessor.d.ts","sourceRoot":"","sources":["../src/groupViolationResultsProcessor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAA+B,MAAM,mBAAmB,CAAC;AAoBlF,MAAM,MAAM,YAAY,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAoBF;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,YAAY,EAAE,UAqDpE;AAsHD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAa5E;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAaxF"}
1
+ {"version":3,"file":"groupViolationResultsProcessor.d.ts","sourceRoot":"","sources":["../src/groupViolationResultsProcessor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAA+B,MAAM,mBAAmB,CAAC;AAelF,MAAM,MAAM,YAAY,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAoBF;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,YAAY,EAAE,UAqDpE;AA4GD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAa5E;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAaxF"}
@@ -113,6 +113,7 @@ function processA11yDetailsAndMessages(error, a11yFailureMessages) {
113
113
  });
114
114
  });
115
115
  const a11yFailureMessage = `
116
+ ${error.renderedDOMSavedFileName ? `HTML Source: ${error.renderedDOMSavedFileName}\n` : ''}
116
117
  The test has failed the accessibility check. Accessibility Stacktrace/Issues:
117
118
  ${a11yErrorElementsCount} HTML elements have accessibility issue(s). ${a11yRuleViolationsCount} rules failed.
118
119
 
@@ -133,10 +134,8 @@ For guidance on accessibility related specifics, contact our A11y team: http://s
133
134
  */
134
135
  function processA11yErrors(results, testSuite, testResult) {
135
136
  const a11yFailureDetails = [];
136
- const axeFailureDetails = [];
137
137
  const a11yFailureMessages = [];
138
- const axeFailureMessages = [];
139
- let a11yAxeErrorsExist = false;
138
+ let a11yErrorsExist = false;
140
139
  testResult.failureDetails.forEach((failure) => {
141
140
  let error = failure.error;
142
141
  // If using circus test runner https://github.com/facebook/jest/issues/11405#issuecomment-843549606
@@ -145,28 +144,20 @@ function processA11yErrors(results, testSuite, testResult) {
145
144
  if (error === undefined)
146
145
  error = failure;
147
146
  if (error.name === format_1.A11yError.name) {
148
- a11yAxeErrorsExist = true;
147
+ a11yErrorsExist = true;
149
148
  a11yFailureDetails.push({ ...failure });
150
149
  processA11yDetailsAndMessages(error, a11yFailureMessages);
151
150
  }
152
- if (error.name === format_1.AxeError.name) {
153
- a11yAxeErrorsExist = true;
154
- axeFailureDetails.push({ ...failure });
155
- axeFailureMessages.push(`
156
- The test has failed to execute the accessibility check.
157
- Please contact our Sa11y team: http://sfdc.co/sa11y-users
158
- `);
159
- }
160
151
  });
161
- if (!a11yAxeErrorsExist) {
152
+ if (!a11yErrorsExist) {
162
153
  testSuite.numFailingTests -= 1;
163
154
  results.numFailedTests -= 1;
164
155
  if (testSuite.numFailingTests === 0)
165
156
  results.numFailedTestSuites -= 1;
166
157
  }
167
- testResult.failureDetails = [...a11yFailureDetails, ...axeFailureDetails];
168
- testResult.failureMessages = [...a11yFailureMessages, ...axeFailureMessages];
169
- testResult.status = testResult.failureDetails.length === 0 ? 'passed' : testResult.status;
158
+ testResult.failureDetails = [...a11yFailureDetails];
159
+ testResult.failureMessages = [...a11yFailureMessages];
160
+ testResult.status = a11yFailureDetails.length === 0 ? 'passed' : testResult.status;
170
161
  }
171
162
  function processA11yMatcherErrors(results, testSuite, testResult) {
172
163
  const a11yFailureMessages = [];
package/dist/setup.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { AutoCheckOpts } from './automatic';
1
+ import { AutoCheckOpts, RenderedDOMSaveOpts } from './automatic';
2
2
  /**
3
3
  * Options to be passed on to {@link setup}
4
4
  */
5
5
  export type Sa11yOpts = {
6
6
  autoCheckOpts: AutoCheckOpts;
7
+ renderedDOMSaveOpts: RenderedDOMSaveOpts;
7
8
  };
8
9
  /**
9
10
  * Register Sa11y Jest API and automatic checks depending on {@link Sa11yOpts}
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AASA,OAAO,EACH,aAAa,EAIhB,MAAM,aAAa,CAAC;AAIrB;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACpB,aAAa,EAAE,aAAa,CAAC;CAKhC,CAAC;AAoCF;;;GAGG;AACH,wBAAgB,KAAK,CAAC,IAAI,GAAE,SAA4B,GAAG,IAAI,CAiD9D;AACD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAU3C"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AASA,OAAO,EACH,aAAa,EAIb,mBAAmB,EACtB,MAAM,aAAa,CAAC;AAIrB;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACpB,aAAa,EAAE,aAAa,CAAC;IAC7B,mBAAmB,EAAE,mBAAmB,CAAC;CAK5C,CAAC;AAuCF;;;GAGG;AACH,wBAAgB,KAAK,CAAC,IAAI,GAAE,SAA4B,GAAG,IAAI,CAmD9D;AACD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAU3C"}
package/dist/setup.js CHANGED
@@ -23,6 +23,9 @@ const defaultSa11yOpts = {
23
23
  runDOMMutationObserver: false,
24
24
  enableIncompleteResults: false,
25
25
  },
26
+ renderedDOMSaveOpts: {
27
+ renderedDOMDumpDirPath: '',
28
+ },
26
29
  };
27
30
  function registerRemoveChild() {
28
31
  // eslint-disable-next-line @typescript-eslint/unbound-method
@@ -90,7 +93,8 @@ function setup(opts = defaultSa11yOpts) {
90
93
  // set the flag to true to run sa11y in DOM Mutation Observer mode
91
94
  autoCheckOpts.runDOMMutationObserver || (autoCheckOpts.runDOMMutationObserver = !!process.env.SA11Y_ENABLE_DOM_MUTATION_OBSERVER);
92
95
  autoCheckOpts.enableIncompleteResults || (autoCheckOpts.enableIncompleteResults = !!process.env.SA11Y_ENABLE_INCOMPLETE_RESULTS);
93
- (0, automatic_1.registerSa11yAutomaticChecks)(autoCheckOpts);
96
+ const renderedDOMSaveOpts = opts.renderedDOMSaveOpts;
97
+ (0, automatic_1.registerSa11yAutomaticChecks)(autoCheckOpts, renderedDOMSaveOpts);
94
98
  }
95
99
  exports.setup = setup;
96
100
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sa11y/jest",
3
- "version": "7.1.0-alpha.1",
3
+ "version": "7.1.0-alpha.2",
4
4
  "description": "Accessibility testing matcher for Jest",
5
5
  "license": "BSD-3-Clause",
6
6
  "homepage": "https://github.com/salesforce/sa11y/tree/master/packages/jest#readme",
@@ -24,9 +24,9 @@
24
24
  ],
25
25
  "dependencies": {
26
26
  "@jest/test-result": "^27",
27
- "@sa11y/assert": "7.1.0-alpha.1",
28
- "@sa11y/format": "7.1.0-alpha.1",
29
- "@sa11y/preset-rules": "7.1.0-alpha.1",
27
+ "@sa11y/assert": "7.1.0-alpha.2",
28
+ "@sa11y/format": "7.1.0-alpha.2",
29
+ "@sa11y/preset-rules": "7.1.0-alpha.2",
30
30
  "jest-matcher-utils": "^27"
31
31
  },
32
32
  "peerDependencies": {
@@ -34,8 +34,8 @@
34
34
  },
35
35
  "devDependencies": {
36
36
  "@jest/globals": "28.1.3",
37
- "@sa11y/common": "7.1.0-alpha.1",
38
- "@sa11y/test-utils": "7.1.0-alpha.1"
37
+ "@sa11y/common": "7.1.0-alpha.2",
38
+ "@sa11y/test-utils": "7.1.0-alpha.2"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"
@@ -43,5 +43,5 @@
43
43
  "engines": {
44
44
  "node": "^18 || ^20"
45
45
  },
46
- "gitHead": "d8b64c285f066b8dcc955882c5bf399ef6b1c279"
46
+ "gitHead": "108d459f5c12828a7071769bef8812be898df56b"
47
47
  }