@sa11y/jest 7.1.0-alpha.2 → 7.1.1
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 +6 -1
- package/dist/automatic.d.ts +2 -34
- package/dist/automatic.d.ts.map +1 -1
- package/dist/automatic.js +16 -175
- package/dist/groupViolationResultsProcessor.d.ts +0 -16
- package/dist/groupViolationResultsProcessor.d.ts.map +1 -1
- package/dist/groupViolationResultsProcessor.js +4 -130
- package/dist/matcher.d.ts +3 -16
- package/dist/matcher.d.ts.map +1 -1
- package/dist/matcher.js +19 -49
- package/dist/setup.d.ts +1 -16
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +15 -91
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Accessibility matcher for [Jest](https://jestjs.io)
|
|
|
19
19
|
- [JSON result transformation](#json-result-transformation)
|
|
20
20
|
- [Limitations](#limitations)
|
|
21
21
|
- [Disabled Checks](#disabled-checks)
|
|
22
|
+
- [Related Packages](#related-packages)
|
|
22
23
|
|
|
23
24
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
24
25
|
|
|
@@ -108,7 +109,7 @@ it('should be accessible', async () => {
|
|
|
108
109
|
// Setup DOM to be tested for accessibility
|
|
109
110
|
//...
|
|
110
111
|
|
|
111
|
-
// assert that
|
|
112
|
+
// assert that DOM is accessible (using base preset-rule)
|
|
112
113
|
await expect(document).toBeAccessible();
|
|
113
114
|
|
|
114
115
|
// Can be used to test accessibility of a specific HTML element
|
|
@@ -278,3 +279,7 @@ Automatic checks currently has the following limitations.
|
|
|
278
279
|
### Disabled Checks
|
|
279
280
|
|
|
280
281
|
- @sa11y/jest automatic checks also disabled rules which were disabled in `toBeAccessible` Jest API ([disabled-checks](https://github.com/salesforce/sa11y/tree/master/packages/jest#disabled-checks))
|
|
282
|
+
|
|
283
|
+
## Related Packages
|
|
284
|
+
|
|
285
|
+
- [`@sa11y/matcher`](../matcher/README.md): Provides the core accessibility checking APIs used by this package. Use it directly for custom test runners or advanced integrations.
|
package/dist/automatic.d.ts
CHANGED
|
@@ -1,35 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
export type AutoCheckOpts = {
|
|
5
|
-
runAfterEach?: boolean;
|
|
6
|
-
cleanupAfterEach?: boolean;
|
|
7
|
-
consolidateResults?: boolean;
|
|
8
|
-
filesFilter?: string[];
|
|
9
|
-
runDOMMutationObserver?: boolean;
|
|
10
|
-
enableIncompleteResults?: boolean;
|
|
11
|
-
};
|
|
12
|
-
export type RenderedDOMSaveOpts = {
|
|
13
|
-
renderedDOMDumpDirPath?: string;
|
|
14
|
-
generateRenderedDOMFileSaveLocation?: (testFilePath: string, testName: string) => {
|
|
15
|
-
fileName: string;
|
|
16
|
-
fileUrl: string;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
export declare const setOriginalDocumentBodyHtml: (bodyHtml: string | null) => void;
|
|
20
|
-
export declare const getOriginalDocumentBodyHtml: () => string | null;
|
|
21
|
-
/**
|
|
22
|
-
* Check if current test file needs to be skipped based on any provided filter
|
|
23
|
-
*/
|
|
24
|
-
export declare function skipTest(testPath: string | undefined, filesFilter?: string[]): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Run accessibility check on each element node in the body using {@link toBeAccessible}
|
|
27
|
-
* @param opts - Options for automatic checks {@link AutoCheckOpts}
|
|
28
|
-
*/
|
|
29
|
-
export declare function automaticCheck(opts?: AutoCheckOpts, renderedDOMSaveOpts?: RenderedDOMSaveOpts): Promise<void>;
|
|
30
|
-
/**
|
|
31
|
-
* Register accessibility checks to be run automatically after each test
|
|
32
|
-
* @param opts - Options for automatic checks {@link AutoCheckOpts}
|
|
33
|
-
*/
|
|
34
|
-
export declare function registerSa11yAutomaticChecks(opts?: AutoCheckOpts, renderedDOMSaveOpts?: RenderedDOMSaveOpts): void;
|
|
1
|
+
import type { AutoCheckOpts } from '@sa11y/matcher';
|
|
2
|
+
export declare function registerSa11yAutomaticChecks(opts?: AutoCheckOpts): void;
|
|
35
3
|
//# sourceMappingURL=automatic.d.ts.map
|
package/dist/automatic.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automatic.d.ts","sourceRoot":"","sources":["../src/automatic.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"automatic.d.ts","sourceRoot":"","sources":["../src/automatic.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,wBAAgB,4BAA4B,CAAC,IAAI,GAAE,aAAoC,GAAG,IAAI,CAc7F"}
|
package/dist/automatic.js
CHANGED
|
@@ -1,188 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSa11yAutomaticChecks = void 0;
|
|
2
4
|
/*
|
|
3
|
-
* Copyright (c)
|
|
5
|
+
* Copyright (c) 2025, salesforce.com, inc.
|
|
4
6
|
* All rights reserved.
|
|
5
7
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
6
8
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
9
|
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.registerSa11yAutomaticChecks = exports.automaticCheck = exports.skipTest = exports.getOriginalDocumentBodyHtml = exports.setOriginalDocumentBodyHtml = void 0;
|
|
10
|
-
const common_1 = require("@sa11y/common");
|
|
11
|
-
const assert_1 = require("@sa11y/assert");
|
|
12
|
-
const format_1 = require("@sa11y/format");
|
|
13
|
-
const matcher_1 = require("./matcher");
|
|
14
10
|
const globals_1 = require("@jest/globals");
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const defaultAutoCheckOpts = {
|
|
20
|
-
runAfterEach: true,
|
|
21
|
-
cleanupAfterEach: true,
|
|
22
|
-
consolidateResults: true,
|
|
23
|
-
filesFilter: [],
|
|
24
|
-
runDOMMutationObserver: false,
|
|
25
|
-
enableIncompleteResults: false,
|
|
26
|
-
};
|
|
27
|
-
const defaultRenderedDOMSaveOpts = {
|
|
28
|
-
renderedDOMDumpDirPath: '',
|
|
29
|
-
};
|
|
30
|
-
let originalDocumentBodyHtml = null;
|
|
31
|
-
let mutatedNodes = [];
|
|
32
|
-
const setOriginalDocumentBodyHtml = (bodyHtml) => {
|
|
33
|
-
originalDocumentBodyHtml = bodyHtml ?? null;
|
|
34
|
-
};
|
|
35
|
-
exports.setOriginalDocumentBodyHtml = setOriginalDocumentBodyHtml;
|
|
36
|
-
const getOriginalDocumentBodyHtml = () => {
|
|
37
|
-
return originalDocumentBodyHtml;
|
|
38
|
-
};
|
|
39
|
-
exports.getOriginalDocumentBodyHtml = getOriginalDocumentBodyHtml;
|
|
40
|
-
/**
|
|
41
|
-
* Check if current test file needs to be skipped based on any provided filter
|
|
42
|
-
*/
|
|
43
|
-
function skipTest(testPath, filesFilter) {
|
|
44
|
-
if (!testPath || !filesFilter || !(filesFilter?.length > 0))
|
|
45
|
-
return false;
|
|
46
|
-
const skipTest = filesFilter.some((fileName) => testPath.toLowerCase().includes(fileName.toLowerCase()));
|
|
47
|
-
if (skipTest) {
|
|
48
|
-
(0, common_1.log)(`Skipping automatic accessibility check on ${testPath} as it matches given files filter: ${filesFilter.toString()}`);
|
|
49
|
-
}
|
|
50
|
-
return skipTest;
|
|
51
|
-
}
|
|
52
|
-
exports.skipTest = skipTest;
|
|
53
|
-
/**
|
|
54
|
-
* Run accessibility check on each element node in the body using {@link toBeAccessible}
|
|
55
|
-
* @param opts - Options for automatic checks {@link AutoCheckOpts}
|
|
56
|
-
*/
|
|
57
|
-
async function automaticCheck(opts = defaultAutoCheckOpts, renderedDOMSaveOpts = defaultRenderedDOMSaveOpts) {
|
|
58
|
-
if (skipTest(globals_1.expect.getState().testPath, opts.filesFilter))
|
|
59
|
-
return;
|
|
60
|
-
// Skip automatic check if test is using fake timer as it would result in timeout
|
|
61
|
-
if ((0, matcher_1.isTestUsingFakeTimer)()) {
|
|
62
|
-
(0, common_1.log)('Skipping automatic accessibility check as Jest fake timer is in use.');
|
|
11
|
+
const matcher_1 = require("@sa11y/matcher");
|
|
12
|
+
const matcher_2 = require("./matcher");
|
|
13
|
+
function registerSa11yAutomaticChecks(opts = matcher_1.defaultAutoCheckOpts) {
|
|
14
|
+
if (!opts.runAfterEach)
|
|
63
15
|
return;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
let config = customRules.length === 0
|
|
67
|
-
? (0, preset_rules_1.adaptA11yConfig)(preset_rules_1.defaultRuleset)
|
|
68
|
-
: (0, preset_rules_1.adaptA11yConfigCustomRules)(preset_rules_1.defaultRuleset, customRules);
|
|
69
|
-
if (opts.enableIncompleteResults)
|
|
70
|
-
config = (0, preset_rules_1.adaptA11yConfigIncompleteResults)(config);
|
|
71
|
-
let a11yResults = [];
|
|
72
|
-
const currentDocumentHtml = document.body.innerHTML;
|
|
73
|
-
if (originalDocumentBodyHtml) {
|
|
74
|
-
document.body.innerHTML = originalDocumentBodyHtml;
|
|
75
|
-
}
|
|
76
|
-
// Create a DOM walker filtering only elements (skipping text, comment nodes etc)
|
|
77
|
-
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT);
|
|
78
|
-
let currNode = walker.firstChild();
|
|
79
|
-
let renderedDOMSavedFileName = '';
|
|
80
|
-
try {
|
|
81
|
-
if (!opts.runDOMMutationObserver) {
|
|
82
|
-
while (currNode !== null) {
|
|
83
|
-
// TODO (spike): Use a logger lib with log levels selectable at runtime
|
|
84
|
-
// console.log(
|
|
85
|
-
// `♿ [DEBUG] Automatically checking a11y of ${currNode.nodeName}
|
|
86
|
-
// for test "${expect.getState().currentTestName}"
|
|
87
|
-
// : ${testPath}`
|
|
88
|
-
// );
|
|
89
|
-
// W-10004832 - Exclude descendancy based rules from automatic checks
|
|
90
|
-
a11yResults.push(...(await (0, assert_1.getA11yResultsJSDOM)(currNode, config, opts.enableIncompleteResults)));
|
|
91
|
-
currNode = walker.nextSibling();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
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);
|
|
118
|
-
document.body.innerHTML = '';
|
|
119
|
-
// loop mutated nodes
|
|
120
|
-
for await (const mutatedNode of mutatedNodes) {
|
|
121
|
-
if (mutatedNode) {
|
|
122
|
-
document.body.innerHTML = mutatedNode;
|
|
123
|
-
a11yResults.push(...(await (0, assert_1.getA11yResultsJSDOM)(document.body, config, opts.enableIncompleteResults)));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
finally {
|
|
16
|
+
const observer = new MutationObserver(matcher_1.mutationObserverCallback);
|
|
17
|
+
beforeEach(() => {
|
|
129
18
|
if (opts.runDOMMutationObserver) {
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
(0, exports.setOriginalDocumentBodyHtml)(null);
|
|
133
|
-
document.body.innerHTML = currentDocumentHtml;
|
|
134
|
-
if (opts.cleanupAfterEach)
|
|
135
|
-
document.body.innerHTML = ''; // remove non-element nodes
|
|
136
|
-
// TODO (spike): Disable stack trace for automatic checks.
|
|
137
|
-
// Will this affect all errors globally?
|
|
138
|
-
// Error.stackTraceLimit = 0;
|
|
139
|
-
if (process.env.SELECTOR_FILTER_KEYWORDS) {
|
|
140
|
-
a11yResults = (0, format_1.exceptionListFilterSelectorKeywords)(a11yResults, process.env.SELECTOR_FILTER_KEYWORDS.split(','));
|
|
19
|
+
observer.observe(document.body, matcher_1.observerOptions);
|
|
141
20
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
mutation.addedNodes.forEach((node) => {
|
|
149
|
-
if (node?.parentElement?.innerHTML) {
|
|
150
|
-
mutatedNodes.push(node.parentElement.innerHTML);
|
|
151
|
-
}
|
|
152
|
-
else if (node?.outerHTML) {
|
|
153
|
-
mutatedNodes.push(node?.outerHTML);
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit
|
|
159
|
-
const observerOptions = {
|
|
160
|
-
subtree: true,
|
|
161
|
-
childList: true,
|
|
162
|
-
attributes: true,
|
|
163
|
-
characterData: true, // monitor changes to the character data contained within nodes
|
|
164
|
-
};
|
|
165
|
-
/**
|
|
166
|
-
* Register accessibility checks to be run automatically after each test
|
|
167
|
-
* @param opts - Options for automatic checks {@link AutoCheckOpts}
|
|
168
|
-
*/
|
|
169
|
-
function registerSa11yAutomaticChecks(opts = defaultAutoCheckOpts, renderedDOMSaveOpts = defaultRenderedDOMSaveOpts) {
|
|
170
|
-
if (opts.runAfterEach) {
|
|
171
|
-
const observer = new MutationObserver(observerCallback);
|
|
172
|
-
// TODO (fix): Make registration idempotent
|
|
173
|
-
(0, common_1.log)('Registering sa11y checks to be run automatically after each test');
|
|
174
|
-
beforeEach(() => {
|
|
175
|
-
if (opts.runDOMMutationObserver) {
|
|
176
|
-
observer.observe(document.body, observerOptions);
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
afterEach(async () => {
|
|
180
|
-
if (opts.runDOMMutationObserver) {
|
|
181
|
-
observer.disconnect(); // stop mutation observer
|
|
182
|
-
}
|
|
183
|
-
await automaticCheck(opts, renderedDOMSaveOpts);
|
|
184
|
-
});
|
|
185
|
-
}
|
|
21
|
+
});
|
|
22
|
+
afterEach(async () => {
|
|
23
|
+
if (opts.runDOMMutationObserver)
|
|
24
|
+
observer.disconnect();
|
|
25
|
+
await (0, matcher_1.runAutomaticCheck)(opts, globals_1.expect.getState().testPath, matcher_2.isTestUsingFakeTimer);
|
|
26
|
+
});
|
|
186
27
|
}
|
|
187
28
|
exports.registerSa11yAutomaticChecks = registerSa11yAutomaticChecks;
|
|
188
29
|
//# sourceMappingURL=automatic.js.map
|
|
@@ -1,20 +1,4 @@
|
|
|
1
1
|
import { AggregatedResult } from '@jest/test-result';
|
|
2
|
-
export type ErrorElement = {
|
|
3
|
-
html: string;
|
|
4
|
-
selectors: string;
|
|
5
|
-
hierarchy: string;
|
|
6
|
-
any: string;
|
|
7
|
-
all: string;
|
|
8
|
-
none: string;
|
|
9
|
-
relatedNodeAny: string;
|
|
10
|
-
relatedNodeAll: string;
|
|
11
|
-
relatedNodeNone: string;
|
|
12
|
-
message?: string;
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Create a test failure html elements array grouped by rule violation
|
|
16
|
-
*/
|
|
17
|
-
export declare function createA11yErrorElements(errorElements: ErrorElement[]): string;
|
|
18
2
|
/**
|
|
19
3
|
* Custom results processor for a11y results grouping the violations. Only affects JSON results file output.
|
|
20
4
|
* To be used with jest cli options --json --outputFile
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"groupViolationResultsProcessor.d.ts","sourceRoot":"","sources":["../src/groupViolationResultsProcessor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAA+B,MAAM,mBAAmB,CAAC;AA0DlF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAa5E;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAaxF"}
|
|
@@ -1,134 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resultsProcessorManualChecks = exports.resultsProcessor =
|
|
3
|
+
exports.resultsProcessorManualChecks = exports.resultsProcessor = void 0;
|
|
4
4
|
const common_1 = require("@sa11y/common");
|
|
5
5
|
const format_1 = require("@sa11y/format");
|
|
6
|
-
const
|
|
7
|
-
const formatForAxeMessage = `\n${formatSpacing}\t`;
|
|
8
|
-
const axeMessages = {
|
|
9
|
-
toSolveAny: `${formatForAxeMessage}- More Info: To solve the problem, you need to fix at least (1) of the following:\n`,
|
|
10
|
-
toSolveFirst: `${formatForAxeMessage}- More Info: To solve the problem, you need to fix one of the following:\n`,
|
|
11
|
-
toSolveSecond: `${formatForAxeMessage}- And fix the following:\n`,
|
|
12
|
-
relatedNodes: `${formatForAxeMessage}- Related Nodes: \n`,
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Create a test failure html elements array grouped by rule violation
|
|
16
|
-
*/
|
|
17
|
-
function createA11yErrorElements(errorElements) {
|
|
18
|
-
const a11yErrorElements = [];
|
|
19
|
-
let onlyOneSummary = false;
|
|
20
|
-
const appendRelatedNodes = (errorMessage, relatedNodes) => {
|
|
21
|
-
return relatedNodes ? `${errorMessage}${axeMessages.relatedNodes}${relatedNodes}` : errorMessage;
|
|
22
|
-
};
|
|
23
|
-
errorElements.forEach((errorElement, index) => {
|
|
24
|
-
let errorMessage = `${formatSpacing}(${index + 1}) - HTML element : ${errorElement.html
|
|
25
|
-
.replace(/</g, '<')
|
|
26
|
-
.replace(/>/, '>')}`;
|
|
27
|
-
errorMessage += `${formatForAxeMessage}- CSS selector(s) : ${errorElement.selectors.replace(/>/, '>')}`;
|
|
28
|
-
errorMessage += `${formatForAxeMessage}- HTML Tag Hierarchy : ${errorElement.hierarchy}`;
|
|
29
|
-
if (errorElement.message)
|
|
30
|
-
errorMessage += `${formatForAxeMessage}- Error Message (Needs Review) : ${errorElement.message}`;
|
|
31
|
-
const isAny = errorElement.any?.length > 0;
|
|
32
|
-
const isAll = errorElement.all?.length > 0;
|
|
33
|
-
const isNone = errorElement.none?.length > 0;
|
|
34
|
-
if (!onlyOneSummary) {
|
|
35
|
-
if (isAny) {
|
|
36
|
-
errorMessage += `${axeMessages.toSolveAny}${errorElement.any}`;
|
|
37
|
-
errorMessage = appendRelatedNodes(errorMessage, errorElement.relatedNodeAny);
|
|
38
|
-
if (isAll) {
|
|
39
|
-
errorMessage += `${axeMessages.toSolveSecond}${errorElement.all}`;
|
|
40
|
-
errorMessage = appendRelatedNodes(errorMessage, errorElement.relatedNodeAll);
|
|
41
|
-
}
|
|
42
|
-
if (isNone) {
|
|
43
|
-
errorMessage += `${axeMessages.toSolveSecond}${errorElement.none}`;
|
|
44
|
-
errorMessage = appendRelatedNodes(errorMessage, errorElement.relatedNodeNone);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
else if (isAll) {
|
|
48
|
-
errorMessage += `${axeMessages.toSolveFirst}${errorElement.all}`;
|
|
49
|
-
errorMessage = appendRelatedNodes(errorMessage, errorElement.relatedNodeAll);
|
|
50
|
-
if (isNone) {
|
|
51
|
-
errorMessage += `${axeMessages.toSolveSecond}${errorElement.none}`;
|
|
52
|
-
errorMessage = appendRelatedNodes(errorMessage, errorElement.relatedNodeNone);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
if (isNone) {
|
|
57
|
-
errorMessage += `${axeMessages.toSolveFirst}${errorElement.none}`;
|
|
58
|
-
errorMessage = appendRelatedNodes(errorMessage, errorElement.relatedNodeNone);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
errorMessage = appendRelatedNodes(errorMessage, errorElement.relatedNodeAny);
|
|
64
|
-
}
|
|
65
|
-
onlyOneSummary = isAny && !isAll && !isNone;
|
|
66
|
-
a11yErrorElements.push(errorMessage);
|
|
67
|
-
});
|
|
68
|
-
return a11yErrorElements.join('\n');
|
|
69
|
-
}
|
|
70
|
-
exports.createA11yErrorElements = createA11yErrorElements;
|
|
71
|
-
/**
|
|
72
|
-
* Create a test failure violation error message grouped by rule violation
|
|
73
|
-
*/
|
|
74
|
-
function createA11yRuleViolation(a11yRule, ruleIndex) {
|
|
75
|
-
return `(${ruleIndex}) [${a11yRule.id}] ${a11yRule.description}
|
|
76
|
-
* Error element(s) : ${a11yRule.errorElements.length}\n${createA11yErrorElements(a11yRule.errorElements)}
|
|
77
|
-
* Help:
|
|
78
|
-
• Help URL: ${a11yRule.helpUrl}
|
|
79
|
-
• WCAG Criteria: ${a11yRule.wcagCriteria}`;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Create a test processA11yDetailsAndMessages violation error message grouped by rule violation
|
|
83
|
-
*/
|
|
84
|
-
function processA11yDetailsAndMessages(error, a11yFailureMessages) {
|
|
85
|
-
const a11yRuleViolations = {};
|
|
86
|
-
let a11yRuleViolationsCount = 0;
|
|
87
|
-
let a11yErrorElementsCount = 0;
|
|
88
|
-
error.a11yResults.forEach((a11yResult) => {
|
|
89
|
-
a11yErrorElementsCount++;
|
|
90
|
-
if (!a11yRuleViolations[a11yResult.wcag]) {
|
|
91
|
-
a11yRuleViolationsCount++;
|
|
92
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
93
|
-
a11yRuleViolations[a11yResult.wcag] = {
|
|
94
|
-
id: a11yResult.id,
|
|
95
|
-
description: a11yResult.description,
|
|
96
|
-
helpUrl: a11yResult.helpUrl,
|
|
97
|
-
wcagCriteria: a11yResult.wcag,
|
|
98
|
-
summary: a11yResult.summary,
|
|
99
|
-
errorElements: [],
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
a11yRuleViolations[a11yResult.wcag].errorElements.push({
|
|
103
|
-
html: a11yResult.html,
|
|
104
|
-
selectors: a11yResult.selectors,
|
|
105
|
-
hierarchy: a11yResult.ancestry,
|
|
106
|
-
any: a11yResult.any,
|
|
107
|
-
all: a11yResult.all,
|
|
108
|
-
none: a11yResult.none,
|
|
109
|
-
relatedNodeAny: a11yResult.relatedNodeAny,
|
|
110
|
-
relatedNodeAll: a11yResult.relatedNodeAll,
|
|
111
|
-
relatedNodeNone: a11yResult.relatedNodeNone,
|
|
112
|
-
message: a11yResult?.message,
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
const a11yFailureMessage = `
|
|
116
|
-
${error.renderedDOMSavedFileName ? `HTML Source: ${error.renderedDOMSavedFileName}\n` : ''}
|
|
117
|
-
The test has failed the accessibility check. Accessibility Stacktrace/Issues:
|
|
118
|
-
${a11yErrorElementsCount} HTML elements have accessibility issue(s). ${a11yRuleViolationsCount} rules failed.
|
|
119
|
-
|
|
120
|
-
${Object.values(a11yRuleViolations)
|
|
121
|
-
.map((a11yRuleViolation, index) => createA11yRuleViolation(a11yRuleViolation, index + 1))
|
|
122
|
-
.join('\n')}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
For more info about automated accessibility testing: https://sfdc.co/a11y-test
|
|
126
|
-
For tips on fixing accessibility bugs: https://sfdc.co/a11y
|
|
127
|
-
For technical questions regarding Salesforce accessibility tools, contact our Sa11y team: http://sfdc.co/sa11y-users
|
|
128
|
-
For guidance on accessibility related specifics, contact our A11y team: http://sfdc.co/tmp-a11y
|
|
129
|
-
`;
|
|
130
|
-
a11yFailureMessages.push(a11yFailureMessage);
|
|
131
|
-
}
|
|
6
|
+
const matcher_1 = require("@sa11y/matcher");
|
|
132
7
|
/**
|
|
133
8
|
* Convert any a11y errors from test failures into their own test suite, results
|
|
134
9
|
*/
|
|
@@ -146,7 +21,7 @@ function processA11yErrors(results, testSuite, testResult) {
|
|
|
146
21
|
if (error.name === format_1.A11yError.name) {
|
|
147
22
|
a11yErrorsExist = true;
|
|
148
23
|
a11yFailureDetails.push({ ...failure });
|
|
149
|
-
processA11yDetailsAndMessages(error, a11yFailureMessages);
|
|
24
|
+
(0, matcher_1.processA11yDetailsAndMessages)(error, a11yFailureMessages);
|
|
150
25
|
}
|
|
151
26
|
});
|
|
152
27
|
if (!a11yErrorsExist) {
|
|
@@ -164,7 +39,7 @@ function processA11yMatcherErrors(results, testSuite, testResult) {
|
|
|
164
39
|
testResult.failureDetails.forEach((failure) => {
|
|
165
40
|
const error = failure?.error?.matcherResult?.a11yError;
|
|
166
41
|
if (error !== undefined) {
|
|
167
|
-
processA11yDetailsAndMessages(error, a11yFailureMessages);
|
|
42
|
+
(0, matcher_1.processA11yDetailsAndMessages)(error, a11yFailureMessages);
|
|
168
43
|
testResult.failureMessages = [...a11yFailureMessages];
|
|
169
44
|
}
|
|
170
45
|
});
|
|
@@ -209,7 +84,6 @@ exports.resultsProcessorManualChecks = resultsProcessorManualChecks;
|
|
|
209
84
|
const exportedFunctions = {
|
|
210
85
|
resultsProcessor,
|
|
211
86
|
resultsProcessorManualChecks,
|
|
212
|
-
createA11yErrorElements,
|
|
213
87
|
};
|
|
214
88
|
module.exports = exportedFunctions;
|
|
215
89
|
//# sourceMappingURL=groupViolationResultsProcessor.js.map
|
package/dist/matcher.d.ts
CHANGED
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
/// <reference types="jest" />
|
|
2
2
|
import { A11yCheckableContext } from '@sa11y/assert';
|
|
3
|
-
import { A11yError } from '@sa11y/format';
|
|
4
3
|
import { A11yConfig } from '@sa11y/common';
|
|
5
|
-
declare global {
|
|
6
|
-
namespace jest {
|
|
7
|
-
interface Matchers<R> extends jest.CustomMatcher {
|
|
8
|
-
toBeAccessible(config?: A11yConfig): Promise<CustomMatcherResult>;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Jest expect matcher to check DOM for accessibility issues
|
|
14
|
-
* @param received - DOM or HTML Element to be tested for accessibility. Defaults to current DOM.
|
|
15
|
-
* @param config - A11yConfig to be used to test for accessibility. Defaults to `base` ruleset.
|
|
16
|
-
*/
|
|
17
|
-
export declare function toBeAccessible(received?: A11yCheckableContext, config?: A11yConfig): Promise<jest.CustomMatcherResult & {
|
|
18
|
-
a11yError: A11yError;
|
|
19
|
-
}>;
|
|
20
4
|
/**
|
|
21
5
|
* Detect if fake timer is being used in a jest test.
|
|
22
6
|
* Fake timers result in axe timeout https://github.com/dequelabs/axe-core/issues/3055
|
|
@@ -24,4 +8,7 @@ export declare function toBeAccessible(received?: A11yCheckableContext, config?:
|
|
|
24
8
|
* Ref: https://github.com/facebook/jest/issues/10555
|
|
25
9
|
*/
|
|
26
10
|
export declare function isTestUsingFakeTimer(): boolean;
|
|
11
|
+
export declare function toBeAccessible(received?: A11yCheckableContext, config?: A11yConfig): Promise<jest.CustomMatcherResult & {
|
|
12
|
+
a11yError: Error;
|
|
13
|
+
}>;
|
|
27
14
|
//# sourceMappingURL=matcher.d.ts.map
|
package/dist/matcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../src/matcher.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../src/matcher.ts"],"names":[],"mappings":";AAOA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C;AAED,wBAAsB,cAAc,CAChC,QAAQ,GAAE,oBAA+B,EACzC,MAAM,GAAE,UAA2B,GACpC,OAAO,CAAC,IAAI,CAAC,mBAAmB,GAAG;IAAE,SAAS,EAAE,KAAK,CAAA;CAAE,CAAC,CAc1D"}
|
package/dist/matcher.js
CHANGED
|
@@ -1,60 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toBeAccessible = exports.isTestUsingFakeTimer = void 0;
|
|
2
4
|
/*
|
|
3
|
-
* Copyright (c)
|
|
5
|
+
* Copyright (c) 2025, salesforce.com, inc.
|
|
4
6
|
* All rights reserved.
|
|
5
7
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
6
8
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
9
|
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.isTestUsingFakeTimer = exports.toBeAccessible = void 0;
|
|
10
10
|
const jest_matcher_utils_1 = require("jest-matcher-utils");
|
|
11
|
-
const assert_1 = require("@sa11y/assert");
|
|
12
|
-
const format_1 = require("@sa11y/format");
|
|
13
11
|
const preset_rules_1 = require("@sa11y/preset-rules");
|
|
14
|
-
const
|
|
15
|
-
'Switch to real timer before invoking accessibility check. ' +
|
|
16
|
-
'Ref: https://jestjs.io/docs/timer-mocks';
|
|
17
|
-
const matcherHintMsg = `expected document to have no accessibility violations but found`;
|
|
18
|
-
const expectedMsg = `0 issues`;
|
|
19
|
-
const formatOptions = {
|
|
20
|
-
a11yViolationIndicator: '⭕',
|
|
21
|
-
helpUrlIndicator: '🔗',
|
|
22
|
-
highlighter: jest_matcher_utils_1.printReceived,
|
|
23
|
-
deduplicate: false,
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Jest expect matcher to check DOM for accessibility issues
|
|
27
|
-
* @param received - DOM or HTML Element to be tested for accessibility. Defaults to current DOM.
|
|
28
|
-
* @param config - A11yConfig to be used to test for accessibility. Defaults to `base` ruleset.
|
|
29
|
-
*/
|
|
30
|
-
async function toBeAccessible(received = document, config = preset_rules_1.defaultRuleset) {
|
|
31
|
-
let isAccessible = true;
|
|
32
|
-
// a11yError can be 'undefined' when used with `not` matcher and there is no error
|
|
33
|
-
let a11yError = new format_1.A11yError([], []);
|
|
34
|
-
let receivedMsg = expectedMsg;
|
|
35
|
-
if (isTestUsingFakeTimer())
|
|
36
|
-
throw new Error(fakeTimerErrMsg);
|
|
37
|
-
// TODO (Improvement): Can we detect if this is invoked async and error if not ?
|
|
38
|
-
try {
|
|
39
|
-
await (0, assert_1.assertAccessible)(received, (0, preset_rules_1.adaptA11yConfig)(config));
|
|
40
|
-
}
|
|
41
|
-
catch (e) {
|
|
42
|
-
if (e instanceof format_1.A11yError) {
|
|
43
|
-
a11yError = e;
|
|
44
|
-
isAccessible = false;
|
|
45
|
-
receivedMsg = `${a11yError.length} issues`;
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
throw e;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
pass: isAccessible,
|
|
53
|
-
message: () => (0, jest_matcher_utils_1.matcherHint)(`${toBeAccessible.name}: ${matcherHintMsg} ${receivedMsg}: \n\n ${a11yError.format(formatOptions)}`, `${a11yError.length} issues`, expectedMsg),
|
|
54
|
-
a11yError: a11yError,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
exports.toBeAccessible = toBeAccessible;
|
|
12
|
+
const matcher_1 = require("@sa11y/matcher");
|
|
58
13
|
/**
|
|
59
14
|
* Detect if fake timer is being used in a jest test.
|
|
60
15
|
* Fake timers result in axe timeout https://github.com/dequelabs/axe-core/issues/3055
|
|
@@ -68,4 +23,19 @@ function isTestUsingFakeTimer() {
|
|
|
68
23
|
(setTimeout.hasOwnProperty('_isMockFunction') || setTimeout.hasOwnProperty('clock')));
|
|
69
24
|
}
|
|
70
25
|
exports.isTestUsingFakeTimer = isTestUsingFakeTimer;
|
|
26
|
+
async function toBeAccessible(received = document, config = preset_rules_1.defaultRuleset) {
|
|
27
|
+
if (isTestUsingFakeTimer())
|
|
28
|
+
throw new Error(matcher_1.fakeTimerErrMsg);
|
|
29
|
+
const { isAccessible, a11yError, receivedMsg } = await (0, matcher_1.runA11yCheck)(received, config);
|
|
30
|
+
return {
|
|
31
|
+
pass: isAccessible,
|
|
32
|
+
message: () => (0, jest_matcher_utils_1.matcherHint)(`toBeAccessible`) +
|
|
33
|
+
`\n\nExpected: no accessibility violations\nReceived: ${receivedMsg}\n\n${a11yError.format({
|
|
34
|
+
...matcher_1.formatOptions,
|
|
35
|
+
highlighter: jest_matcher_utils_1.printReceived,
|
|
36
|
+
})}`,
|
|
37
|
+
a11yError,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
exports.toBeAccessible = toBeAccessible;
|
|
71
41
|
//# sourceMappingURL=matcher.js.map
|
package/dist/setup.d.ts
CHANGED
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Options to be passed on to {@link setup}
|
|
4
|
-
*/
|
|
5
|
-
export type Sa11yOpts = {
|
|
6
|
-
autoCheckOpts: AutoCheckOpts;
|
|
7
|
-
renderedDOMSaveOpts: RenderedDOMSaveOpts;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Register Sa11y Jest API and automatic checks depending on {@link Sa11yOpts}
|
|
11
|
-
* @param opts - {@link Sa11yOpts} to opt-in to automatic checks
|
|
12
|
-
*/
|
|
13
|
-
export declare function setup(opts?: Sa11yOpts): void;
|
|
14
|
-
/**
|
|
15
|
-
* Register accessibility helpers toBeAccessible as jest matchers
|
|
16
|
-
*/
|
|
1
|
+
export declare function setup(opts?: import("@sa11y/matcher/dist/setup").Sa11yOpts): void;
|
|
17
2
|
export declare function registerSa11yMatcher(): void;
|
|
18
3
|
//# sourceMappingURL=setup.d.ts.map
|
package/dist/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAiBA,wBAAgB,KAAK,CAAC,IAAI,gDAAmB,GAAG,IAAI,CAanD;AACD,wBAAgB,oBAAoB,IAAI,IAAI,CAU3C"}
|
package/dist/setup.js
CHANGED
|
@@ -1,108 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSa11yMatcher = exports.setup = void 0;
|
|
2
4
|
/*
|
|
3
|
-
* Copyright (c)
|
|
5
|
+
* Copyright (c) 2025, salesforce.com, inc.
|
|
4
6
|
* All rights reserved.
|
|
5
7
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
6
8
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
9
|
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.registerSa11yMatcher = exports.setup = void 0;
|
|
10
|
-
const matcher_1 = require("./matcher");
|
|
11
|
-
const common_1 = require("@sa11y/common");
|
|
12
|
-
const automatic_1 = require("./automatic");
|
|
13
10
|
const globals_1 = require("@jest/globals");
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
consolidateResults: false,
|
|
23
|
-
runDOMMutationObserver: false,
|
|
24
|
-
enableIncompleteResults: false,
|
|
25
|
-
},
|
|
26
|
-
renderedDOMSaveOpts: {
|
|
27
|
-
renderedDOMDumpDirPath: '',
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
function registerRemoveChild() {
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
32
|
-
const originalRemoveChild = Element.prototype.removeChild;
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
34
|
-
Element.prototype.removeChild = function (oldChild) {
|
|
35
|
-
if (oldChild.parentNode === this) {
|
|
36
|
-
// Your custom implementation here
|
|
37
|
-
if (!(0, automatic_1.getOriginalDocumentBodyHtml)()) {
|
|
38
|
-
(0, automatic_1.setOriginalDocumentBodyHtml)(document?.body?.innerHTML ?? '');
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return originalRemoveChild.call(this, oldChild);
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
const improvedChecksFilter = [
|
|
45
|
-
'ui-email-stream-components/modules/emailStream/adminHealthInsights/__tests__/adminHealthInsights.test.js',
|
|
46
|
-
];
|
|
47
|
-
/**
|
|
48
|
-
* Register Sa11y Jest API and automatic checks depending on {@link Sa11yOpts}
|
|
49
|
-
* @param opts - {@link Sa11yOpts} to opt-in to automatic checks
|
|
50
|
-
*/
|
|
51
|
-
function setup(opts = defaultSa11yOpts) {
|
|
52
|
-
if (process.env.SA11Y_AUTO) {
|
|
53
|
-
const testPath = globals_1.expect.getState().testPath ?? '';
|
|
54
|
-
const ignoreImprovedChecks = improvedChecksFilter.some((fileName) => testPath.toLowerCase().includes(fileName.toLowerCase()));
|
|
55
|
-
if (!ignoreImprovedChecks) {
|
|
56
|
-
registerRemoveChild();
|
|
57
|
-
}
|
|
11
|
+
const matcher_1 = require("@sa11y/matcher");
|
|
12
|
+
const automatic_1 = require("./automatic");
|
|
13
|
+
const matcher_2 = require("./matcher");
|
|
14
|
+
function setup(opts = matcher_1.defaultSa11yOpts) {
|
|
15
|
+
const testPath = globals_1.expect.getState().testPath ?? '';
|
|
16
|
+
const ignoreImprovedChecks = matcher_1.improvedChecksFilter.some((fileName) => testPath.toLowerCase().includes(fileName.toLowerCase()));
|
|
17
|
+
if (process.env.SA11Y_AUTO && !ignoreImprovedChecks) {
|
|
18
|
+
(0, matcher_1.registerRemoveChild)();
|
|
58
19
|
}
|
|
59
20
|
registerSa11yMatcher();
|
|
60
|
-
(0,
|
|
61
|
-
// Set defaults from env vars
|
|
21
|
+
(0, matcher_1.registerCustomSa11yRules)();
|
|
62
22
|
const autoCheckOpts = opts.autoCheckOpts;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
autoCheckOpts.consolidateResults || (autoCheckOpts.consolidateResults = autoCheckOpts.runAfterEach);
|
|
66
|
-
autoCheckOpts.cleanupAfterEach || (autoCheckOpts.cleanupAfterEach = !!process.env.SA11Y_CLEANUP);
|
|
67
|
-
if (process.env.SA11Y_AUTO_FILTER?.trim().length)
|
|
68
|
-
autoCheckOpts.filesFilter || (autoCheckOpts.filesFilter = process.env.SA11Y_AUTO_FILTER.split(','));
|
|
69
|
-
const exemptedFiles = (0, common_1.useFilesToBeExempted)();
|
|
70
|
-
if (exemptedFiles.length !== 0) {
|
|
71
|
-
autoCheckOpts.filesFilter = (autoCheckOpts.filesFilter ?? []).concat(exemptedFiles);
|
|
72
|
-
}
|
|
73
|
-
// TODO remove @W-14447754 - add files filter
|
|
74
|
-
autoCheckOpts.filesFilter = (autoCheckOpts.filesFilter ?? []).concat([
|
|
75
|
-
'ui-help-components/modules/forceHelp/linkToReleaseNotes/__tests__/linkToReleaseNotes.spec.js',
|
|
76
|
-
'ui-help-components/modules/forceHelp/linkToNonSalesforceResource/__tests__/linkToNonSalesforceResource.spec.js',
|
|
77
|
-
'ui-help-components/modules/forceHelp/linkToAppexchange/__tests__/linkToAppexchange.spec.js',
|
|
78
|
-
'ui-help-components/modules/forceHelp/linkToTrailblazer/__tests__/linkToTrailblazer.spec.js',
|
|
79
|
-
'ui-help-components/modules/forceHelp/linkToVidyard/__tests__/linkToVidyard.spec.js',
|
|
80
|
-
'ui-help-components/modules/forceHelp/linkToSalesforceDevelopers/__tests__/linkToSalesforceDevelopers.spec.js',
|
|
81
|
-
'ui-help-components/modules/forceHelp/linkToWebinar/__tests__/linkToWebinar.spec.js',
|
|
82
|
-
'ui-help-components/modules/forceHelp/linkToTrust/__tests__/linkToTrust.spec.js',
|
|
83
|
-
'ui-help-components/modules/forceHelp/linkToPartnerCommunity/__tests__/linkToPartnerCommunity.spec.js',
|
|
84
|
-
'ui-help-components/modules/forceHelp/linkToDocResource/__tests__/linkToDocResource.spec.js',
|
|
85
|
-
'ui-help-components/modules/forceHelp/searchResultItem/__tests__/searchResultItem.spec.js',
|
|
86
|
-
'ui-help-components/modules/forceHelp/linkToTrailhead/__tests__/linkToTrailhead.spec.js',
|
|
87
|
-
'ui-help-components/modules/forceHelp/linkToSalesforceSuccess/__tests__/linkToSalesforceSuccess.spec.js',
|
|
88
|
-
'ui-help-components/modules/forceHelp/linkToSalesforceHelp/__tests__/linkToSalesforceHelp.spec.js',
|
|
89
|
-
'ui-help-components/modules/forceHelp/link/__tests__/link.spec.js',
|
|
90
|
-
'ui-help-components/modules/forceHelp/searchResults/__tests__/searchResults.spec.js',
|
|
91
|
-
'ui-help-components/modules/forceHelp/linkToKnownIssue/__tests__/linkToKnownIssue.spec.js',
|
|
92
|
-
]);
|
|
93
|
-
// set the flag to true to run sa11y in DOM Mutation Observer mode
|
|
94
|
-
autoCheckOpts.runDOMMutationObserver || (autoCheckOpts.runDOMMutationObserver = !!process.env.SA11Y_ENABLE_DOM_MUTATION_OBSERVER);
|
|
95
|
-
autoCheckOpts.enableIncompleteResults || (autoCheckOpts.enableIncompleteResults = !!process.env.SA11Y_ENABLE_INCOMPLETE_RESULTS);
|
|
96
|
-
const renderedDOMSaveOpts = opts.renderedDOMSaveOpts;
|
|
97
|
-
(0, automatic_1.registerSa11yAutomaticChecks)(autoCheckOpts, renderedDOMSaveOpts);
|
|
23
|
+
(0, matcher_1.updateAutoCheckOpts)(autoCheckOpts);
|
|
24
|
+
(0, automatic_1.registerSa11yAutomaticChecks)(autoCheckOpts);
|
|
98
25
|
}
|
|
99
26
|
exports.setup = setup;
|
|
100
|
-
/**
|
|
101
|
-
* Register accessibility helpers toBeAccessible as jest matchers
|
|
102
|
-
*/
|
|
103
27
|
function registerSa11yMatcher() {
|
|
104
28
|
if (globals_1.expect !== undefined) {
|
|
105
|
-
globals_1.expect.extend({ toBeAccessible:
|
|
29
|
+
globals_1.expect.extend({ toBeAccessible: matcher_2.toBeAccessible });
|
|
106
30
|
}
|
|
107
31
|
else {
|
|
108
32
|
throw new Error("Unable to find Jest's expect function." +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sa11y/jest",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.1",
|
|
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,10 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@jest/test-result": "^27",
|
|
27
|
-
"@sa11y/assert": "7.1.
|
|
28
|
-
"@sa11y/format": "7.1.
|
|
29
|
-
"@sa11y/
|
|
27
|
+
"@sa11y/assert": "7.1.1",
|
|
28
|
+
"@sa11y/format": "7.1.1",
|
|
29
|
+
"@sa11y/matcher": "7.1.1",
|
|
30
|
+
"@sa11y/preset-rules": "7.1.1",
|
|
30
31
|
"jest-matcher-utils": "^27"
|
|
31
32
|
},
|
|
32
33
|
"peerDependencies": {
|
|
@@ -34,8 +35,8 @@
|
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@jest/globals": "28.1.3",
|
|
37
|
-
"@sa11y/common": "7.1.
|
|
38
|
-
"@sa11y/test-utils": "7.1.
|
|
38
|
+
"@sa11y/common": "7.1.1",
|
|
39
|
+
"@sa11y/test-utils": "7.1.1"
|
|
39
40
|
},
|
|
40
41
|
"publishConfig": {
|
|
41
42
|
"access": "public"
|
|
@@ -43,5 +44,5 @@
|
|
|
43
44
|
"engines": {
|
|
44
45
|
"node": "^18 || ^20"
|
|
45
46
|
},
|
|
46
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "30752b4258f1eca16f1c6e984d6bb088820b6e33"
|
|
47
48
|
}
|