Skip to content

feat(sdk/testing): add toBeAccessible matcher for vitest assertions#4219

Merged
Blackbaud-SteveBrush merged 17 commits intomainfrom
vitest-matchers
Apr 17, 2026
Merged

feat(sdk/testing): add toBeAccessible matcher for vitest assertions#4219
Blackbaud-SteveBrush merged 17 commits intomainfrom
vitest-matchers

Conversation

@Blackbaud-SteveBrush
Copy link
Copy Markdown
Member

@Blackbaud-SteveBrush Blackbaud-SteveBrush commented Feb 19, 2026

AB#3703606

Summary by CodeRabbit

  • New Features

    • Added a Vitest accessibility matcher (toBeAccessible) and a Vitest setup for automatic accessibility checks.
  • Documentation

    • Added a Vitest setup guide with configuration and usage instructions.
  • Refactor

    • Reorganized accessibility analyzer and types into a private testing layer and adjusted public exports.
  • Tests

    • Added integration tests covering the new accessibility matcher and failure messages.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 19, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e8975c57-36e5-4624-814a-958fb0ea9665

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Vitest integration and a custom accessibility matcher, relocates the a11y analyzer into a private testing library, introduces testing/build/config files for Vitest/Karma/ESLint/ng-packagr, updates exports and path aliases, and adds integration tests and type definitions.

Changes

Cohort / File(s) Summary
Vitest integration & matchers
libs/sdk/testing/vitest/{vitest.config.ts,ng-package.json}, libs/sdk/testing/vitest/src/{index.ts,a11y.matcher.ts,setup-matchers.integration.spec.ts,types/expectation-result.ts}
Adds Vitest config and setupFiles export, implements toBeAccessible matcher with type augmentation and ExpectationResult, and adds integration tests validating accessible/inaccessible cases and error messaging.
Private testing library & analyzer move
libs/sdk/testing/private/{src/{a11y-analyzer.ts,a11y-analyzer-config.ts,index.ts},project.json,ng-package.json,tsconfig.spec.json}
Moves SkyA11yAnalyzer and its config to a private lib, adds internal JSDoc, refactors filtering/message assembly, and exposes analyzer from the private package with project/ng-packagr/tsconfig entries.
Main testing package & exports/aliases
libs/sdk/testing/{src/index.ts,project.json,package.json,README.md}, tsconfig.base.json
Removes a11y exports from public index, adds vitest export subpath and peer dependency, documents Vitest setup in README, adds test-integration target for Vitest, and adds TS path aliases for private and setup-matchers.
Infrastructure & lint/test configs
libs/sdk/testing/private/{eslint.config.js,karma.conf.js}, libs/sdk/testing/vitest/ng-package.json
Introduces consolidated ESLint config, Karma config extending base with coverageDir override, and ng-packagr config for vitest/private packages.
Imports & matcher usage updates
libs/sdk/testing/src/lib/matchers/{matchers.ts,matchers.spec.ts}
Repoints imports to @skyux-sdk/testing/private, adds type-only imports and module-boundary suppression comment; runtime behavior unchanged.

Sequence Diagram

sequenceDiagram
    participant Test as Test Suite
    participant Matcher as toBeAccessible Matcher
    participant Analyzer as SkyA11yAnalyzer
    participant DOM as DOM/Element

    Test->>Matcher: call toBeAccessible(element, config?)
    Matcher->>Matcher: normalize & validate target
    Matcher->>Analyzer: run(target, config)
    Analyzer->>DOM: analyze via axe-core
    Analyzer-->>Matcher: returns (success) or throws (violations)
    alt No Violations
        Matcher-->>Test: pass: true, message "No violations found"
    else Violations Found
        Matcher-->>Test: pass: false, message Error details
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Suggested labels

risk level (author): 1

Poem

🐰 I nibble through tests and hop with cheer,

Vitest matchers found, accessibility near.
Private burrow holds the analyzer tight,
I thump my feet for a clearer sight.
Hooray — no barriers in the night's soft light!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(sdk/testing): add toBeAccessible matcher for vitest assertions' directly and clearly summarizes the main change: adding a new Vitest assertion matcher named toBeAccessible for accessibility testing.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch vitest-matchers

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link
Copy Markdown

nx-cloud bot commented Feb 19, 2026

View your CI Pipeline Execution ↗ for commit 4746ad7

Command Status Duration Result
nx build playground --baseHref=https://blackbau... ✅ Succeeded 4m 49s View ↗
nx build code-examples-playground --baseHref=ht... ✅ Succeeded 4m 50s View ↗
nx build integration --baseHref=https://blackba... ✅ Succeeded 2m 43s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-16 18:32:08 UTC

@Blackbaud-SteveBrush Blackbaud-SteveBrush added the risk level (author): 2 This change has a slight chance of introducing a bug label Feb 19, 2026
@Blackbaud-SteveBrush Blackbaud-SteveBrush changed the title feat(sdk/testing): add toBeAccessible matcher for vitest assertions feat(sdk/testing)!: add toBeAccessible matcher for vitest assertions Feb 19, 2026
Comment thread libs/sdk/testing/vitest/vitest.config.ts
Comment thread libs/sdk/testing/private/src/a11y-analyzer-config.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces Vitest support for SKY UX's accessibility testing capabilities by adding a toBeAccessible matcher for Vitest assertions, alongside a breaking change that moves internal types to a private secondary entry point.

Changes:

  • Creates two new secondary entry points: @skyux-sdk/testing/private (for internal implementation) and @skyux-sdk/testing/vitest/setup-matchers.js (for Vitest matcher registration)
  • Implements toBeAccessible custom matcher for Vitest that leverages the existing axe-core accessibility analyzer
  • Refactors and improves test quality in the a11y analyzer by modernizing from callback-based patterns to async/await
  • Fixes regex pattern bug in tag filtering (changed best* to best for proper matching)

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tsconfig.base.json Adds TypeScript path mappings for the new private and vitest secondary entry points
libs/sdk/testing/vitest/vitest.config.ts Configures Vitest integration tests to use jsdom environment and load the built matcher setup file
libs/sdk/testing/vitest/src/types/expectation-result.ts Defines the return type interface for custom Vitest matchers
libs/sdk/testing/vitest/src/setup-matchers.integration.spec.ts Integration tests verifying the matcher works correctly with accessible and inaccessible content
libs/sdk/testing/vitest/src/index.ts Type declarations for the toBeAccessible matcher and module augmentation
libs/sdk/testing/vitest/src/a11y.matcher.ts Implementation of the toBeAccessible matcher using SkyA11yAnalyzer
libs/sdk/testing/vitest/ng-package.json Build configuration for the vitest secondary entry point
libs/sdk/testing/src/lib/matchers/matchers.ts Updates import to use @skyux-sdk/testing/private for analyzer types
libs/sdk/testing/src/lib/matchers/matchers.spec.ts Updates import to use @skyux-sdk/testing/private for analyzer config type
libs/sdk/testing/src/index.ts Removes public exports of SkyA11yAnalyzer and SkyA11yAnalyzerConfig (breaking change)
libs/sdk/testing/project.json Adds test-integration target for Vitest tests and testing-private:test dependency
libs/sdk/testing/private/tsconfig.spec.json Test configuration for the private secondary entry point
libs/sdk/testing/private/src/index.ts Exports SkyA11yAnalyzer and SkyA11yAnalyzerConfig from private entry point
libs/sdk/testing/private/src/a11y-analyzer.ts Refactored analyzer with improved code formatting, regex fix, and @internal JSDoc
libs/sdk/testing/private/src/a11y-analyzer.spec.ts Modernized tests using async/await instead of callbacks, added new test cases
libs/sdk/testing/private/src/a11y-analyzer-config.ts Config interface with @internal JSDoc
libs/sdk/testing/private/project.json Project configuration for the private secondary entry point
libs/sdk/testing/private/ng-package.json Build configuration for the private secondary entry point
libs/sdk/testing/private/karma.conf.js Karma test runner configuration
libs/sdk/testing/private/eslint.config.js ESLint configuration
libs/sdk/testing/package.json Adds vitest peer dependency (optional), exports configuration for setup-matchers subpath
libs/sdk/testing/README.md Adds documentation for Vitest setup instructions

Comment thread libs/sdk/testing/project.json
Comment thread libs/sdk/testing/private/ng-package.json
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@libs/sdk/testing/package.json`:
- Around line 18-23: Add a root export entry to the package's "exports" so
imports from "@skyux-sdk/testing" resolve; update the exports object to include
a "." key that points to the package's main bundles and types (e.g., point "."
-> "./fesm2022/skyux-sdk-testing.mjs" and types to
"./types/skyux-sdk-testing.d.ts" or the equivalent files used by this package)
so existing imports like "import { expect } from '@skyux-sdk/testing'" and
"import { SkyAppTestUtility } from '@skyux-sdk/testing'" continue to work;
ensure the new "." export mirrors the top-level entrypoints used by consumers
and coexists with the existing "./vitest/setup-matchers.js" subpath.

In `@libs/sdk/testing/private/karma.conf.js`:
- Around line 1-2: Remove the two header comment lines at the top of the Karma
configuration file (the lines starting with "// Karma configuration file..." and
"// https://karma-runner.github.io/...") to comply with the no-comments rule;
simply delete those comment lines so the file contains only executable
configuration code.

In `@libs/sdk/testing/private/src/a11y-analyzer-config.ts`:
- Around line 1-3: Remove the JSDoc comment block at the top of
a11y-analyzer-config.ts (the /** `@internal` */ block) so the file contains no
comments; simply delete those three comment lines and ensure no other comments
remain in the file to comply with the no-comments lint rule.

In `@libs/sdk/testing/private/src/a11y-analyzer.spec.ts`:
- Around line 129-134: The catch blocks in the tests call toMatch on the caught
error (err) which is typed as unknown; change the assertions to access the
Error.message property instead (e.g., expect((err as
Error).message).toMatch(...)) so the matcher receives a string and TypeScript is
satisfied; update each occurrence around SkyA11yAnalyzer.run in this file
(including the blocks at the shown diff and the other locations referencing
lines ~166-171 and ~219-221) to assert against err.message (or cast to Error)
and keep the existing regex checks.

In `@libs/sdk/testing/private/src/a11y-analyzer.ts`:
- Around line 87-89: Remove the newly added JSDoc block containing "@internal"
in libs/sdk/testing/private/src/a11y-analyzer.ts; delete the /** `@internal` */
comment so the file has no inline comments and rely on the package's private
entry point to indicate internal visibility instead.

In `@libs/sdk/testing/src/lib/matchers/matchers.spec.ts`:
- Around line 7-8: The inline eslint-disable comment on the import of
SkyA11yAnalyzerConfig in matchers.spec.ts should be removed and the
module-boundary policy updated to allow the private package instead; update your
`@nx/enforce-module-boundaries` configuration (or workspace/module boundary
settings) to permit the dependency on '@skyux-sdk/testing/private' for this
library (e.g., add it to allowedDependencies/allowedExternalDependencies or
adjust the relevant depConstraints for this package), then delete the "//
eslint-disable-next-line `@nx/enforce-module-boundaries`" line before the import
of SkyA11yAnalyzerConfig so the file contains a plain import without inline
comments.

In `@libs/sdk/testing/src/lib/matchers/matchers.ts`:
- Around line 2-6: Remove the inline eslint-disable comment on the import in
matchers.ts by updating the NX module-boundary rules: add
'@skyux-sdk/testing/private' to the allowedDependencies (or adjust the project's
module-boundary config) so the import of SkyA11yAnalyzer and
SkyA11yAnalyzerConfig no longer requires an inline disable; update the
workspace/project ESLint or nx.json moduleBoundary settings accordingly and then
delete the "// eslint-disable-next-line `@nx/enforce-module-boundaries`" line from
the import statement.

In `@libs/sdk/testing/vitest/src/a11y.matcher.ts`:
- Around line 1-5: Remove the inline eslint-disable comment before the import of
SkyA11yAnalyzer/SkyA11yAnalyzerConfig and instead handle this at config level:
either update ESLint config (overrides for this file pattern or a rule exception
for module-boundaries) to allow imports from '@skyux-sdk/testing/private' or
refactor exports so the public package can be used; locate the problematic
import statement referencing SkyA11yAnalyzer and SkyA11yAnalyzerConfig and
delete the inline suppression, then add the appropriate rule override in your
ESLint configuration (or adjust module boundaries) so the file no longer
requires an inline comment.

In `@libs/sdk/testing/vitest/src/index.ts`:
- Around line 1-18: Remove all inline comments and JSDoc from
libs/sdk/testing/vitest/src/index.ts: delete the eslint-disable line above the
SkyA11yAnalyzerConfig import and remove the JSDoc block above the
CustomMatchers.toBeAccessible signature, leaving only the TypeScript
declarations (interface CustomMatchers, toBeAccessible, and the declare module
'vitest' / Matchers extension). Move the removed documentation into the package
README or changelog and enforce the ESLint rule via a project-level override
(not inline) so no in-file disables remain.

Comment thread libs/sdk/testing/package.json
Comment thread libs/sdk/testing/private/karma.conf.js
Comment thread libs/sdk/testing/private/src/a11y-analyzer-config.ts
Comment thread libs/sdk/testing/private/src/a11y-analyzer.spec.ts
Comment thread libs/sdk/testing/private/src/a11y-analyzer.ts
Comment thread libs/sdk/testing/src/lib/matchers/matchers.spec.ts
Comment thread libs/sdk/testing/src/lib/matchers/matchers.ts
Comment thread libs/sdk/testing/vitest/src/matchers/to-be-accessible.ts
Comment thread libs/sdk/testing/vitest/src/index.ts Outdated
@Blackbaud-SteveBrush Blackbaud-SteveBrush changed the title feat(sdk/testing)!: add toBeAccessible matcher for vitest assertions feat(sdk/testing): add toBeAccessible matcher for vitest assertions Apr 16, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (2)

libs/sdk/testing/private/src/a11y-analyzer.spec.ts:134

  • This assertion matches the thrown Error object against a regex. Since SkyA11yAnalyzer.run rejects with an Error, it’s safer/clearer to match against (err as Error).message (as done elsewhere in this file) to avoid relying on object stringification.
    libs/sdk/testing/private/src/a11y-analyzer.spec.ts:171
  • This assertion matches the thrown Error object against a regex. Prefer matching against (err as Error).message for consistency and to avoid depending on how the Error is stringified.

Comment thread libs/sdk/testing/tsconfig.lib.json Outdated
Comment thread libs/sdk/testing/tsconfig.spec.json Outdated
Comment thread libs/sdk/testing/vitest/ng-package.json
Comment thread libs/sdk/testing/vitest/src/matchers/to-be-accessible.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.

Comment thread libs/sdk/testing/private/project.json
@Blackbaud-SteveBrush Blackbaud-SteveBrush marked this pull request as ready for review April 16, 2026 18:18
Comment thread libs/sdk/testing/vitest/tsconfig.spec.json
@Blackbaud-SteveBrush Blackbaud-SteveBrush enabled auto-merge (squash) April 17, 2026 15:04
@Blackbaud-SteveBrush Blackbaud-SteveBrush merged commit 56dedfe into main Apr 17, 2026
194 of 195 checks passed
@Blackbaud-SteveBrush Blackbaud-SteveBrush deleted the vitest-matchers branch April 17, 2026 15:27
Blackbaud-SteveBrush pushed a commit that referenced this pull request Apr 17, 2026
## [14.1.0](14.0.1...14.1.0)
(2026-04-17)


### Features

* **sdk/testing:** add `toBeAccessible` matcher for vitest assertions
([#4219](#4219))
([56dedfe](56dedfe))
* **sdk/testing:** implement `ng add` schematic for `@skyux-sdk/testing`
package ([#4376](#4376))
([4db0f98](4db0f98))


### Bug Fixes

* **components/ag-grid:** header checkbox uses correct indeterminate
styling when using native multiselect
([#4375](#4375))
([04d11f7](04d11f7))
* **components/lists:** use correct padding on active toolbar filter
button ([#4373](#4373))
([07974aa](07974aa))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk level (author): 2 This change has a slight chance of introducing a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants