(
options: A11yAuditOptions = {},
)
| 191 | * Run an accessibility audit using axe-core |
| 192 | */ |
| 193 | export async function runAudit( |
| 194 | options: A11yAuditOptions = {}, |
| 195 | ): Promise<A11yAuditResult> { |
| 196 | const { |
| 197 | threshold = 'serious', |
| 198 | context = document, |
| 199 | ruleSet = 'wcag21aa', |
| 200 | enabledRules, |
| 201 | disabledRules, |
| 202 | exclude = [], |
| 203 | customRules = {}, |
| 204 | } = options |
| 205 | |
| 206 | // Merge user exclusions with default devtools exclusions |
| 207 | const allExclusions = [...DEFAULT_EXCLUDE_SELECTORS, ...exclude] |
| 208 | |
| 209 | const startTime = performance.now() |
| 210 | const contextDescription = getContextDescription(context) |
| 211 | |
| 212 | try { |
| 213 | // Build axe-core options |
| 214 | const axeOptions: RunOptions = { |
| 215 | resultTypes: ['violations', 'passes', 'incomplete'], |
| 216 | ...RULE_SET_CONFIGS[ruleSet], |
| 217 | } |
| 218 | |
| 219 | // Handle specific rule configurations |
| 220 | if (enabledRules && enabledRules.length > 0) { |
| 221 | axeOptions.runOnly = { |
| 222 | type: 'rule', |
| 223 | values: enabledRules, |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | // Build rules configuration for disabled rules |
| 228 | if (disabledRules && disabledRules.length > 0) { |
| 229 | const rules: RuleObject = {} |
| 230 | for (const ruleId of disabledRules) { |
| 231 | rules[ruleId] = { enabled: false } |
| 232 | } |
| 233 | axeOptions.rules = rules |
| 234 | } |
| 235 | |
| 236 | // Determine the context to audit |
| 237 | let auditContext: axe.ElementContext = context as axe.ElementContext |
| 238 | |
| 239 | // Add exclusions if specified (always include devtools exclusions) |
| 240 | if (allExclusions.length > 0) { |
| 241 | auditContext = { |
| 242 | include: [auditContext as Element], |
| 243 | exclude: allExclusions.map((sel) => [sel]), |
| 244 | } as axe.ElementContext |
| 245 | } |
| 246 | |
| 247 | // Run the axe-core audit |
| 248 | const results = await axe.run(auditContext, axeOptions) |
| 249 | |
| 250 | // Convert axe-core results to our format |
no test coverage detected