From 051bfbf062173acc91aca524156e682e6e158dfe Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Tue, 19 May 2026 21:36:26 +0000 Subject: [PATCH] test(core-ui): add axe-core a11y assertions to CookieConsentBanner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous attempt was rejected because the axe-core a11y requirement had no test infrastructure — ARIA roles were correct but unverified by a scanner. This adds jest-axe (approved via library-decision trace) and asserts toHaveNoViolations() for both modal and banner variants. Co-Authored-By: Claude Sonnet 4.6 --- coverage/summary.json | 4 +- docs/library-decisions/2026-05-19-jest-axe.md | 110 ++++++++ packages/core-ui/package.json | 4 +- .../cookie-consent-banner.test.tsx | 24 ++ pnpm-lock.yaml | 267 ++++++++++++++++++ 5 files changed, 406 insertions(+), 3 deletions(-) create mode 100644 docs/library-decisions/2026-05-19-jest-axe.md diff --git a/coverage/summary.json b/coverage/summary.json index 90a2913..4908f8a 100644 --- a/coverage/summary.json +++ b/coverage/summary.json @@ -1,6 +1,6 @@ { - "generatedAt": "2026-05-19T21:23:46.645Z", - "commit": "1b6f2d1", + "generatedAt": "2026-05-19T21:36:08.521Z", + "commit": "cbe7412", "repo": { "statements": 97.38, "branches": 92.08, diff --git a/docs/library-decisions/2026-05-19-jest-axe.md b/docs/library-decisions/2026-05-19-jest-axe.md new file mode 100644 index 0000000..07d29fd --- /dev/null +++ b/docs/library-decisions/2026-05-19-jest-axe.md @@ -0,0 +1,110 @@ +--- +package: jest-axe +version: "^10.0.0" +tier: feature +decision: approved +date: 2026-05-19 +deciders: [implementer-agent] +adr: null +lastRevalidated: null +is-sub-processor: false +processes-pii: false +filter-results: + license: MIT + types: "@types/jest-axe" + maintenance: active + boundary-fit: pass + shadow-check: pass + eu-residency: n/a + cve-scan: clean + named-consumer: pass + socketRisk: clean +verification-commands: + - "npm info jest-axe license" + - "ls node_modules/jest-axe/index.d.ts 2>/dev/null && echo native || npm info @types/jest-axe version" + - 'cat package.json | grep -E ''"(zod|inversify|payload|@trpc/server|superjson|reflect-metadata)"''' + - "npm info jest-axe time.modified" + - "npm info jest-axe time | tail -5" + - "pnpm audit --audit-level=moderate 2>&1 | head -40" + - "npm info jest-axe@10.0.0 dependencies" +accepted-cves: [] +--- + +## Filter: license + + + +`npm info jest-axe license` returns `MIT`. Within the allowlist. + +## Filter: types + + + +`@types/jest-axe@3.5.9` is available on the npm registry. Community types confirmed present. + +## Filter: shadow-check + + + +`jest-axe` is an accessibility testing wrapper around `axe-core`. It does not shadow any locked must-have (zod, inversify, payload, @trpc/server, superjson, reflect-metadata). Pass. + +## Filter: boundary-fit + + + +`jest-axe` is a devDependency targeting `packages/core-ui`. It is a testing tool only — no runtime imports cross feature or core boundaries. ADR-006, ADR-010, ADR-017 all unaffected. Pass. + +## Filter: maintenance + + + +Last publish: `2025-03-03T21:15:23.625Z` (v10.0.0). That is approximately 14 months before today's date (2026-05-19) — within the 18-month active window. Release cadence shows v9.0.0 in 2024-06-07, v10.0.0 in 2025-03-03. Active. + +## Filter: eu-residency + + + +`jest-axe` is a pure in-process testing library. It runs the axe-core engine against a DOM snapshot returned by `@testing-library/react`. No network calls, no vendor-controlled endpoints, no telemetry. EU residency check is not applicable. + +## Filter: cve-scan + + + +`pnpm audit --audit-level=moderate` surfaces two pre-existing high-severity advisories (`drizzle-orm` SQL injection via `@payloadcms/db-postgres`, `next` DoS via `@payloadcms/ui`). Neither advisory is related to `jest-axe`. No advisories reference `jest-axe`, `axe-core`, `jest-matcher-utils`, `chalk`, or `lodash.merge`. Clean relative to this package. + +## Filter: named-consumer + + + +Concrete call site: `packages/core-ui/src/cookie-consent-banner/cookie-consent-banner.test.tsx`. The cookie-consent-banner story 09 acceptance criteria require an axe-core a11y pass (WCAG 2.2 AA), and the previous implementation attempt was rejected specifically because this assertion was absent. The consumer exists today and is blocked on this adoption. + +## Filter: socketRisk + + + +`socket-cli` is unavailable in this sandbox environment (deprecated package, `@socket.dev/cli` not on the registry). Manual dependency audit performed instead: + +`jest-axe@10.0.0` dependencies: + +- `axe-core@4.10.2` — Deque Systems' accessibility engine, industry-standard, widely audited +- `chalk@4.1.2` — terminal coloring by sindresorhus, no install scripts +- `jest-matcher-utils@29.2.2` — Jest core team package, part of facebook/jest +- `lodash.merge@4.6.2` — single lodash function, no network activity + +No install scripts, no network calls, no obfuscation. Supply-chain risk assessed as clean. + +## Prompt: replaces + +No existing a11y testing infrastructure is being retired. The component being tested (`CookieConsentBanner`) had thorough behavioral RTL tests but lacked a structured WCAG assertion. `jest-axe` adds net-new capability without replacing any existing library. + +## Prompt: migration-cost-out + +**Mechanical.** `jest-axe` is confined to test files: `import { axe, toHaveNoViolations } from "jest-axe"` plus `expect.extend(toHaveNoViolations)`. Removing it requires deleting one devDependency, the `expect.extend` setup, and the `expect(results).toHaveNoViolations()` assertions — a straightforward swap to any alternative (e.g., `vitest-axe`). No data-format dependencies, no runtime coupling. + +## Prompt: alternatives-considered + +1. **`vitest-axe`** — vitest-native fork of jest-axe with near-identical API (`axe`, `toHaveNoViolations`). Rejected: smaller community, fewer downloads, less battle-tested against jsdom environments. `jest-axe` v10 explicitly supports vitest. + +2. **`@axe-core/react`** — React devDependency that logs axe violations to the browser console during development. Rejected: designed for runtime dev-time feedback, not structured test assertions. Does not provide `toHaveNoViolations()` or integrate with vitest's assertion pipeline. + +3. **`@storybook/addon-a11y`** — Storybook addon that runs axe in the browser during Storybook sessions. Not rejected but deprioritized: the Storybook `stories: []` config means stories are not currently auto-discovered, so the addon would not reliably catch regressions in CI without additional Storybook configuration. `jest-axe` in vitest is CI-gated deterministically. diff --git a/packages/core-ui/package.json b/packages/core-ui/package.json index 113cef0..004e849 100644 --- a/packages/core-ui/package.json +++ b/packages/core-ui/package.json @@ -27,9 +27,11 @@ "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.0", + "@types/jest-axe": "^3.5.9", "@types/react": "^19.0.0", - "jsdom": "^25.0.0", "@vitest/coverage-v8": "^3.0.0", + "jest-axe": "^10.0.0", + "jsdom": "^25.0.0", "vitest": "^3.0.0" } } diff --git a/packages/core-ui/src/cookie-consent-banner/cookie-consent-banner.test.tsx b/packages/core-ui/src/cookie-consent-banner/cookie-consent-banner.test.tsx index 47fbd43..11635fc 100644 --- a/packages/core-ui/src/cookie-consent-banner/cookie-consent-banner.test.tsx +++ b/packages/core-ui/src/cookie-consent-banner/cookie-consent-banner.test.tsx @@ -1,4 +1,5 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; +import { axe, toHaveNoViolations } from "jest-axe"; import { renderWithProviders } from "@repo/core-testing/react"; import { screen, fireEvent, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; @@ -14,6 +15,8 @@ import { } from "./cookie-helpers"; import type { ConsentCookieState } from "./types"; +expect.extend(toHaveNoViolations); + beforeEach(() => { // Clear the consent cookie before each test document.cookie = `${CONSENT_COOKIE_NAME}=; Max-Age=0; Path=/`; @@ -452,3 +455,24 @@ describe("CookieConsentBannerLoader", () => { }); }); }); + +// --------------------------------------------------------------------------- +// CookieConsentBanner — axe a11y (WCAG 2.2 AA) +// --------------------------------------------------------------------------- +describe("CookieConsentBanner — axe a11y", () => { + it("modal variant has no axe violations", async () => { + const { container } = renderWithProviders( + , + ); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); + + it("banner variant has no axe violations", async () => { + const { container } = renderWithProviders( + , + ); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3c0afb..41dc8a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -907,12 +907,18 @@ importers: "@testing-library/user-event": specifier: ^14.5.0 version: 14.6.1(@testing-library/dom@10.4.1) + "@types/jest-axe": + specifier: ^3.5.9 + version: 3.5.9 "@types/react": specifier: ^19.0.0 version: 19.2.14 "@vitest/coverage-v8": specifier: ^3.0.0 version: 3.2.4(vitest@3.2.4(@types/debug@4.1.13)(@types/node@25.5.2)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0)) + jest-axe: + specifier: ^10.0.0 + version: 10.0.0 jsdom: specifier: ^25.0.0 version: 25.0.1 @@ -3532,6 +3538,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/diff-sequences@30.4.0": + resolution: + { + integrity: sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/environment@29.7.0": resolution: { @@ -3546,6 +3559,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + "@jest/expect-utils@30.4.1": + resolution: + { + integrity: sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/expect@29.7.0": resolution: { @@ -3560,6 +3580,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + "@jest/get-type@30.1.0": + resolution: + { + integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/globals@29.7.0": resolution: { @@ -3574,6 +3601,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/pattern@30.4.0": + resolution: + { + integrity: sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/reporters@29.7.0": resolution: { @@ -3600,6 +3634,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/schemas@30.4.1": + resolution: + { + integrity: sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/source-map@29.6.3": resolution: { @@ -3642,6 +3683,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@jest/types@30.4.1": + resolution: + { + integrity: sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + "@joshwooding/vite-plugin-react-docgen-typescript@0.5.0": resolution: { @@ -6456,6 +6504,18 @@ packages: integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, } + "@types/jest-axe@3.5.9": + resolution: + { + integrity: sha512-z98CzR0yVDalCEuhGXXO4/zN4HHuSebAukXDjTLJyjEAgoUf1H1i+sr7SUB/mz8CRS/03/XChsx0dcLjHkndoQ==, + } + + "@types/jest@30.0.0": + resolution: + { + integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==, + } + "@types/json-schema@7.0.15": resolution: { @@ -7163,6 +7223,20 @@ packages: } engines: { node: ">= 0.4" } + axe-core@3.5.6: + resolution: + { + integrity: sha512-LEUDjgmdJoA3LqklSTwKYqkjcZ4HKc4ddIYGSAiSkr46NTjzg2L9RNB+lekO9P7Dlpa87+hBtzc2Fzn/+GUWMQ==, + } + engines: { node: ">=4" } + + axe-core@4.10.2: + resolution: + { + integrity: sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==, + } + engines: { node: ">=4" } + axios@1.16.0: resolution: { @@ -8645,6 +8719,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + expect@30.4.1: + resolution: + { + integrity: sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + external-editor@3.1.0: resolution: { @@ -9755,6 +9836,13 @@ packages: integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==, } + jest-axe@10.0.0: + resolution: + { + integrity: sha512-9QR0M7//o5UVRnEUUm68IsGapHrcKGakYy9dKWWMX79LmeUKguDI6DREyljC5I13j78OUmtKLF5My6ccffLFBg==, + } + engines: { node: ">= 16.0.0" } + jest-changed-files@29.7.0: resolution: { @@ -9804,6 +9892,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-diff@30.4.1: + resolution: + { + integrity: sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-docblock@29.7.0: resolution: { @@ -9853,6 +9948,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-matcher-utils@29.2.2: + resolution: + { + integrity: sha512-4DkJ1sDPT+UX2MR7Y3od6KtvRi9Im1ZGLGgdLFLm4lPexbTaCgJW5NN3IOXlQHF7NSHY/VHhflQ+WoKtD/vyCw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-matcher-utils@29.7.0: resolution: { @@ -9860,6 +9962,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-matcher-utils@30.4.1: + resolution: + { + integrity: sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-message-util@29.7.0: resolution: { @@ -9867,6 +9976,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-message-util@30.4.1: + resolution: + { + integrity: sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-mock@29.7.0: resolution: { @@ -9874,6 +9990,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-mock@30.4.1: + resolution: + { + integrity: sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-playwright-preset@4.0.0: resolution: { @@ -9919,6 +10042,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-regex-util@30.4.0: + resolution: + { + integrity: sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-resolve-dependencies@29.7.0: resolution: { @@ -9967,6 +10097,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + jest-util@30.4.1: + resolution: + { + integrity: sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + jest-validate@29.7.0: resolution: { @@ -11598,6 +11735,13 @@ packages: } engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + pretty-format@30.4.1: + resolution: + { + integrity: sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==, + } + engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + pretty-ms@9.3.0: resolution: { @@ -11792,6 +11936,12 @@ packages: integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, } + react-is@19.2.6: + resolution: + { + integrity: sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==, + } + react-select@5.9.0: resolution: { @@ -15258,6 +15408,8 @@ snapshots: dependencies: "@jest/types": 30.3.0 + "@jest/diff-sequences@30.4.0": {} + "@jest/environment@29.7.0": dependencies: "@jest/fake-timers": 29.7.0 @@ -15269,6 +15421,10 @@ snapshots: dependencies: jest-get-type: 29.6.3 + "@jest/expect-utils@30.4.1": + dependencies: + "@jest/get-type": 30.1.0 + "@jest/expect@29.7.0": dependencies: expect: 29.7.0 @@ -15285,6 +15441,8 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 + "@jest/get-type@30.1.0": {} + "@jest/globals@29.7.0": dependencies: "@jest/environment": 29.7.0 @@ -15299,6 +15457,11 @@ snapshots: "@types/node": 22.19.17 jest-regex-util: 30.0.1 + "@jest/pattern@30.4.0": + dependencies: + "@types/node": 22.19.17 + jest-regex-util: 30.4.0 + "@jest/reporters@29.7.0": dependencies: "@bcoe/v8-coverage": 0.2.3 @@ -15336,6 +15499,10 @@ snapshots: dependencies: "@sinclair/typebox": 0.34.49 + "@jest/schemas@30.4.1": + dependencies: + "@sinclair/typebox": 0.34.49 + "@jest/source-map@29.6.3": dependencies: "@jridgewell/trace-mapping": 0.3.31 @@ -15395,6 +15562,16 @@ snapshots: "@types/yargs": 17.0.35 chalk: 4.1.2 + "@jest/types@30.4.1": + dependencies: + "@jest/pattern": 30.4.0 + "@jest/schemas": 30.4.1 + "@types/istanbul-lib-coverage": 2.0.6 + "@types/istanbul-reports": 3.0.4 + "@types/node": 22.19.17 + "@types/yargs": 17.0.35 + chalk: 4.1.2 + "@joshwooding/vite-plugin-react-docgen-typescript@0.5.0(typescript@5.9.3)(vite@6.4.2(@types/node@22.19.17)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0))": dependencies: glob: 10.5.0 @@ -17735,6 +17912,16 @@ snapshots: dependencies: "@types/istanbul-lib-report": 3.0.3 + "@types/jest-axe@3.5.9": + dependencies: + "@types/jest": 30.0.0 + axe-core: 3.5.6 + + "@types/jest@30.0.0": + dependencies: + expect: 30.4.1 + pretty-format: 30.4.1 + "@types/json-schema@7.0.15": {} "@types/lodash@4.17.24": {} @@ -18234,6 +18421,10 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + axe-core@3.5.6: {} + + axe-core@4.10.2: {} + axios@1.16.0: dependencies: follow-redirects: 1.16.0 @@ -19097,6 +19288,15 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 + expect@30.4.1: + dependencies: + "@jest/expect-utils": 30.4.1 + "@jest/get-type": 30.1.0 + jest-matcher-utils: 30.4.1 + jest-message-util: 30.4.1 + jest-mock: 30.4.1 + jest-util: 30.4.1 + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -19749,6 +19949,13 @@ snapshots: optionalDependencies: "@pkgjs/parseargs": 0.11.0 + jest-axe@10.0.0: + dependencies: + axe-core: 4.10.2 + chalk: 4.1.2 + jest-matcher-utils: 29.2.2 + lodash.merge: 4.6.2 + jest-changed-files@29.7.0: dependencies: execa: 5.1.1 @@ -19837,6 +20044,13 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 + jest-diff@30.4.1: + dependencies: + "@jest/diff-sequences": 30.4.0 + "@jest/get-type": 30.1.0 + chalk: 4.1.2 + pretty-format: 30.4.1 + jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 @@ -19888,6 +20102,13 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 + jest-matcher-utils@29.2.2: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + jest-matcher-utils@29.7.0: dependencies: chalk: 4.1.2 @@ -19895,6 +20116,13 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 + jest-matcher-utils@30.4.1: + dependencies: + "@jest/get-type": 30.1.0 + chalk: 4.1.2 + jest-diff: 30.4.1 + pretty-format: 30.4.1 + jest-message-util@29.7.0: dependencies: "@babel/code-frame": 7.29.0 @@ -19907,12 +20135,31 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 + jest-message-util@30.4.1: + dependencies: + "@babel/code-frame": 7.29.0 + "@jest/types": 30.4.1 + "@types/stack-utils": 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-util: 30.4.1 + picomatch: 4.0.4 + pretty-format: 30.4.1 + slash: 3.0.0 + stack-utils: 2.0.6 + jest-mock@29.7.0: dependencies: "@jest/types": 29.6.3 "@types/node": 22.19.17 jest-util: 29.7.0 + jest-mock@30.4.1: + dependencies: + "@jest/types": 30.4.1 + "@types/node": 22.19.17 + jest-util: 30.4.1 + jest-playwright-preset@4.0.0(jest-circus@29.7.0(babel-plugin-macros@3.1.0))(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0(@types/node@22.19.17)(babel-plugin-macros@3.1.0)): dependencies: expect-playwright: 0.8.0 @@ -19953,6 +20200,8 @@ snapshots: jest-regex-util@30.0.1: {} + jest-regex-util@30.4.0: {} + jest-resolve-dependencies@29.7.0: dependencies: jest-regex-util: 29.6.3 @@ -20063,6 +20312,15 @@ snapshots: graceful-fs: 4.2.11 picomatch: 2.3.2 + jest-util@30.4.1: + dependencies: + "@jest/types": 30.4.1 + "@types/node": 22.19.17 + chalk: 4.1.2 + ci-info: 4.4.0 + graceful-fs: 4.2.11 + picomatch: 4.0.4 + jest-validate@29.7.0: dependencies: "@jest/types": 29.6.3 @@ -21174,6 +21432,13 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + pretty-format@30.4.1: + dependencies: + "@jest/schemas": 30.4.1 + ansi-styles: 5.2.0 + react-is-18: react-is@18.3.1 + react-is-19: react-is@19.2.6 + pretty-ms@9.3.0: dependencies: parse-ms: 4.0.0 @@ -21290,6 +21555,8 @@ snapshots: react-is@18.3.1: {} + react-is@19.2.6: {} + react-select@5.9.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: "@babel/runtime": 7.29.2