From 264dd533c06b553267e30b4e8785834a209f48a7 Mon Sep 17 00:00:00 2001 From: Brent Swisher Date: Wed, 1 Jul 2026 14:42:14 -0400 Subject: [PATCH] test(alert): migrate tests from @open-wc/testing to vitest --- packages/pharos/package.json | 2 + .../src/components/alert/pharos-alert.test.ts | 61 ++-- packages/pharos/src/test/fixture.ts | 62 ++++ packages/pharos/src/test/matchers.ts | 122 ++++++++ packages/pharos/vitest.setup.ts | 3 + yarn.lock | 284 +++++++++++++++++- 6 files changed, 501 insertions(+), 33 deletions(-) create mode 100644 packages/pharos/src/test/fixture.ts create mode 100644 packages/pharos/src/test/matchers.ts diff --git a/packages/pharos/package.json b/packages/pharos/package.json index 4b0f0cc8e..e117e200a 100644 --- a/packages/pharos/package.json +++ b/packages/pharos/package.json @@ -68,6 +68,7 @@ }, "devDependencies": { "@custom-elements-manifest/analyzer": "^0.11.0", + "@open-wc/semantic-dom-diff": "^0.20.1", "@open-wc/testing": "patch:@open-wc/testing@npm%3A4.0.0#~/.yarn/patches/@open-wc-testing-npm-4.0.0-96dbe4d202.patch", "@types/react": "^18.3.28", "@types/react-dom": "^18.3.7", @@ -75,6 +76,7 @@ "@vitest/coverage-istanbul": "^4.1.9", "@webcomponents/scoped-custom-element-registry": "^0.0.10", "autoprefixer": "^10.5.2", + "axe-core": "^4.11.1", "chokidar": "^5.0.0", "globby": "^16.2.0", "minify-html-literals": "^1.3.5", diff --git a/packages/pharos/src/components/alert/pharos-alert.test.ts b/packages/pharos/src/components/alert/pharos-alert.test.ts index 354b2a7ad..20dc7b559 100644 --- a/packages/pharos/src/components/alert/pharos-alert.test.ts +++ b/packages/pharos/src/components/alert/pharos-alert.test.ts @@ -1,6 +1,7 @@ -import { fixture, expect } from '@open-wc/testing'; +import { beforeEach, describe, expect, it } from 'vitest'; import { html } from 'lit/static-html.js'; +import { fixture, errorFixture } from '../../test/fixture'; import type { PharosAlert } from './pharos-alert'; import type { PharosButton } from '../button/pharos-button'; import type { PharosLink } from '../link/pharos-link'; @@ -10,26 +11,26 @@ describe('pharos-alert', () => { beforeEach(async () => { component = await fixture(html` - It worked! + It worked! `); }); it('is accessible', async () => { - await expect(component).to.be.accessible(); + await expect(component).toBeAccessible(); }); - it('throws an error for missing status attribute', async () => { - component = await fixture(html` It worked! `).catch( - (e) => e - ); - expect('status is a required attribute.').to.be.thrown; + it('throws an error for a missing status attribute', async () => { + const error = await errorFixture(html` It worked! `); + + expect(error.message).toContain('status is a required attribute.'); }); it('renders the alert when a status is provided', async () => { - component = await fixture(html` - It worked! + const alert = await fixture(html` + It worked! `); - expect(component).shadowDom.to.equal(` + + expect(alert).toEqualShadowDom(` `); + expect(alert).toHaveTextContent('It worked!'); }); - it('throws an error for an invalid status value', async () => { - component = await fixture(html` - It worked! - `).catch((e) => e); - expect('fake is not a valid status. Valid statuses are: info, success, warning, error').to.be - .thrown; - }); + const error = await errorFixture(html` + It worked! + `); + expect(error.message).toContain( + 'fake is not a valid status. Valid statuses are: info, success, warning, error' + ); + }); it('adds a class to slotted links', async () => { const link = document.createElement('test-pharos-link') as PharosLink; @@ -64,40 +66,37 @@ describe('pharos-alert', () => { await component.updateComplete; const anchor = link.renderRoot.querySelector('#link-element'); - expect(anchor).to.have.class('link--alert'); + expect(anchor?.classList.contains('link--alert')).toBe(true); }); it('is closable', async () => { - component = await fixture(html` + const alert = await fixture(html` It worked! `); - await component.updateComplete; - - const closeButton = component.renderRoot.querySelector('.alert__button') as PharosButton; + const closeButton = alert.renderRoot.querySelector('.alert__button') as HTMLElement; closeButton.click(); - expect(document.getElementById('closable-alert')).to.be.null; + expect(document.getElementById('closable-alert')).toBeNull(); }); it('fires a custom event pharos-alert-closed when closed by user interaction', async () => { - component = await fixture(html` + const alert = await fixture(html` It worked! `); + let wasFired = false; - const handleClose = (): void => { + alert.addEventListener('pharos-alert-closed', () => { wasFired = true; - }; - component.addEventListener('pharos-alert-closed', handleClose); - await component.updateComplete; + }); - const closeButton = component.renderRoot.querySelector('.alert__button') as PharosButton; + const closeButton = alert.renderRoot.querySelector('.alert__button') as PharosButton; closeButton.click(); - expect(wasFired).to.be.true; + expect(wasFired).toBe(true); }); }); diff --git a/packages/pharos/src/test/fixture.ts b/packages/pharos/src/test/fixture.ts new file mode 100644 index 000000000..382011a11 --- /dev/null +++ b/packages/pharos/src/test/fixture.ts @@ -0,0 +1,62 @@ +import { render } from 'lit'; +import type { TemplateResult } from 'lit'; + +interface FixtureOptions { + /** + * Render the template into this element instead of a fresh wrapper, and + * attach the element itself to the document. + */ + parentNode?: HTMLElement; +} + +const hasUpdateComplete = (value: unknown): value is { updateComplete: Promise } => { + const update = (value as { updateComplete?: { then?: unknown } } | null)?.updateComplete; + return typeof update?.then === 'function'; +}; + +const mount = (template: TemplateResult, parentNode?: HTMLElement): Element => { + // Clear the document body to ensure there are no elements left from earlier tests in the same file. + document.body.replaceChildren(); + + const container = parentNode ?? document.createElement('div'); + document.body.appendChild(container); + + render(template, container); + + return container.firstElementChild as Element; +}; + +/** + * Render a Lit template into a container attached to the document and + * resolve once the first element has finished its initial update. + */ +export async function fixture( + template: TemplateResult, + options: FixtureOptions = {} +): Promise { + const element = mount(template, options.parentNode) as T; + // This ensures the shadow DOM is ready for testing before returning the element. + if (hasUpdateComplete(element)) await element.updateComplete; + return element; +} + +/** + * Mounts a Lit template but expects the element's first + * update to *reject* — returns the thrown error instead of letting it surface + * as an unhandled rejection. + */ +export async function errorFixture( + template: TemplateResult, + options: FixtureOptions = {} +): Promise { + const element = mount(template, options.parentNode); + if (!hasUpdateComplete(element)) { + throw new Error('fixtureError: element has no updateComplete to reject'); + } + try { + await element.updateComplete; + } catch (error) { + return error as Error; + } + throw new Error('fixtureError: expected the element update to reject, but it resolved'); +} diff --git a/packages/pharos/src/test/matchers.ts b/packages/pharos/src/test/matchers.ts new file mode 100644 index 000000000..681f7b161 --- /dev/null +++ b/packages/pharos/src/test/matchers.ts @@ -0,0 +1,122 @@ +import { expect } from 'vitest'; +import axe from 'axe-core'; +import { getDiffableHTML, type DiffOptions } from '@open-wc/semantic-dom-diff/get-diffable-html.js'; + +interface AccessibleOptions { + ignoredRules?: string[]; +} + +const formatViolations = (violations: axe.Result[]): string => { + const lines: string[] = ['Accessibility Violations', '---']; + violations.forEach((violation) => { + lines.push(`Rule: ${violation.id}`); + lines.push(`Impact: ${violation.impact}`); + lines.push(`${violation.help} (${violation.helpUrl})`); + violation.nodes.forEach((node) => { + lines.push(''); + if (node.target) { + lines.push(`Issue target: ${node.target}`); + } + lines.push(`Context: ${node.html}`); + if (node.failureSummary) { + lines.push(node.failureSummary); + } + }); + lines.push('---'); + }); + return lines.join('\n'); +}; + +expect.extend({ + // check for accessibility violations using axe-core. + async toBeAccessible(received: Element, options: AccessibleOptions = {}) { + const runOptions: axe.RunOptions = { resultTypes: ['violations'] }; + if (options.ignoredRules?.length) { + runOptions.rules = Object.fromEntries( + options.ignoredRules.map((rule) => [rule, { enabled: false }]) + ); + } + const { violations } = await axe.run(received, runOptions); + const pass = violations.length === 0; + return { + pass, + message: () => + pass + ? 'expected element to have accessibility violations, but none were found' + : formatViolations(violations), + }; + }, + + // check that the element's light DOM matches the expected HTML. + toEqualDom(received: Element, expected: string, options?: DiffOptions) { + const actual = getDiffableHTML(received.outerHTML, options); + const expectedHTML = getDiffableHTML(expected, options); + return { + pass: actual === expectedHTML, + message: () => 'expected DOM to equal the given HTML', + actual, + expected: expectedHTML, + }; + }, + // check that the element's shadow DOM matches the expected HTML. + toEqualShadowDom(received: Element, expected: string, options?: DiffOptions) { + const shadowRoot = received.shadowRoot; + if (!shadowRoot) { + return { + pass: false, + message: () => 'expected element to have a shadow root, but it did not', + }; + } + const actual = getDiffableHTML(shadowRoot.innerHTML, options); + const expectedHTML = getDiffableHTML(expected, options); + return { + pass: actual === expectedHTML, + message: () => 'expected shadow DOM to equal the given HTML', + actual, + expected: expectedHTML, + }; + }, +}); + +interface PharosMatchers { + /** + * Asserts the element has no axe-core accessibility violations. + * + * @param options.ignoredRules - axe rule IDs to disable for this run + * + * @example + * await expect(component).toBeAccessible(); + * await expect(component).toBeAccessible({ ignoredRules: ['region'] }); + */ + toBeAccessible(options?: AccessibleOptions): Promise; + /** + * Asserts the element's light DOM matches the expected HTML, ignoring + * whitespace and Lit's marker comments. + * + * @param expected - the expected HTML string. + * @param options - `getDiffableHTML` options, e.g. `{ ignoreAttributes: [...] }`. + * + * @example + * expect(component).toEqualDom('
text
'); + */ + toEqualDom(expected: string, options?: DiffOptions): R; + /** + * Asserts the element's shadow DOM matches the expected HTML, ignoring + * whitespace and Lit's marker comments. + * + * @param expected - the expected shadow DOM HTML string. + * @param options - `getDiffableHTML` options, e.g. `{ ignoreAttributes: [...] }`. + * + * @example + * expect(component).toEqualShadowDom(` + * + * `); + */ + toEqualShadowDom(expected: string, options?: DiffOptions): R; +} + +declare module 'vitest' { + interface Matchers extends PharosMatchers {} + interface Assertion extends PharosMatchers {} + interface AsymmetricMatchersContaining extends PharosMatchers {} +} diff --git a/packages/pharos/vitest.setup.ts b/packages/pharos/vitest.setup.ts index 91beb88f4..2f499a78b 100644 --- a/packages/pharos/vitest.setup.ts +++ b/packages/pharos/vitest.setup.ts @@ -3,3 +3,6 @@ import '@webcomponents/scoped-custom-element-registry'; // Register every Pharos component under the `test-` prefix import './src/test/initComponents'; + +// Register custom matchers globally +import './src/test/matchers'; diff --git a/yarn.lock b/yarn.lock index b47004c22..a232eea80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4070,6 +4070,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/aix-ppc64@npm:0.28.0" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/aix-ppc64@npm:0.28.1" @@ -4077,6 +4084,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-arm64@npm:0.28.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/android-arm64@npm:0.28.1" @@ -4084,6 +4098,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-arm@npm:0.28.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/android-arm@npm:0.28.1" @@ -4091,6 +4112,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-x64@npm:0.28.0" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/android-x64@npm:0.28.1" @@ -4098,6 +4126,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/darwin-arm64@npm:0.28.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/darwin-arm64@npm:0.28.1" @@ -4105,6 +4140,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/darwin-x64@npm:0.28.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/darwin-x64@npm:0.28.1" @@ -4112,6 +4154,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/freebsd-arm64@npm:0.28.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/freebsd-arm64@npm:0.28.1" @@ -4119,6 +4168,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/freebsd-x64@npm:0.28.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/freebsd-x64@npm:0.28.1" @@ -4126,6 +4182,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-arm64@npm:0.28.0" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-arm64@npm:0.28.1" @@ -4133,6 +4196,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-arm@npm:0.28.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-arm@npm:0.28.1" @@ -4140,6 +4210,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-ia32@npm:0.28.0" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-ia32@npm:0.28.1" @@ -4147,6 +4224,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-loong64@npm:0.28.0" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-loong64@npm:0.28.1" @@ -4154,6 +4238,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-mips64el@npm:0.28.0" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-mips64el@npm:0.28.1" @@ -4161,6 +4252,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-ppc64@npm:0.28.0" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-ppc64@npm:0.28.1" @@ -4168,6 +4266,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-riscv64@npm:0.28.0" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-riscv64@npm:0.28.1" @@ -4175,6 +4280,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-s390x@npm:0.28.0" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-s390x@npm:0.28.1" @@ -4182,6 +4294,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-x64@npm:0.28.0" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/linux-x64@npm:0.28.1" @@ -4189,6 +4308,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/netbsd-arm64@npm:0.28.0" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-arm64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/netbsd-arm64@npm:0.28.1" @@ -4196,6 +4322,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/netbsd-x64@npm:0.28.0" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/netbsd-x64@npm:0.28.1" @@ -4203,6 +4336,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openbsd-arm64@npm:0.28.0" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/openbsd-arm64@npm:0.28.1" @@ -4210,6 +4350,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openbsd-x64@npm:0.28.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/openbsd-x64@npm:0.28.1" @@ -4217,6 +4364,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openharmony-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openharmony-arm64@npm:0.28.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openharmony-arm64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/openharmony-arm64@npm:0.28.1" @@ -4224,6 +4378,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/sunos-x64@npm:0.28.0" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/sunos-x64@npm:0.28.1" @@ -4231,6 +4392,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-arm64@npm:0.28.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/win32-arm64@npm:0.28.1" @@ -4238,6 +4406,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-ia32@npm:0.28.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/win32-ia32@npm:0.28.1" @@ -4245,6 +4420,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-x64@npm:0.28.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.28.1": version: 0.28.1 resolution: "@esbuild/win32-x64@npm:0.28.1" @@ -4934,6 +5116,7 @@ __metadata: "@floating-ui/dom": "npm:^1.7.6" "@lit-labs/scoped-registry-mixin": "npm:^1.0.4" "@open-wc/dedupe-mixin": "npm:^2.0.1" + "@open-wc/semantic-dom-diff": "npm:^0.20.1" "@open-wc/testing": "patch:@open-wc/testing@npm%3A4.0.0#~/.yarn/patches/@open-wc-testing-npm-4.0.0-96dbe4d202.patch" "@types/react": "npm:^18.3.28" "@types/react-dom": "npm:^18.3.7" @@ -4941,6 +5124,7 @@ __metadata: "@vitest/coverage-istanbul": "npm:^4.1.9" "@webcomponents/scoped-custom-element-registry": "npm:^0.0.10" autoprefixer: "npm:^10.5.2" + axe-core: "npm:^4.11.1" chokidar: "npm:^5.0.0" focus-trap: "npm:^8.2.2" globby: "npm:^16.2.0" @@ -6171,7 +6355,7 @@ __metadata: languageName: node linkType: hard -"@open-wc/semantic-dom-diff@npm:^0.20.0": +"@open-wc/semantic-dom-diff@npm:^0.20.0, @open-wc/semantic-dom-diff@npm:^0.20.1": version: 0.20.1 resolution: "@open-wc/semantic-dom-diff@npm:0.20.1" dependencies: @@ -10723,6 +10907,13 @@ __metadata: languageName: node linkType: hard +"axe-core@npm:^4.11.1": + version: 4.12.1 + resolution: "axe-core@npm:4.12.1" + checksum: 10c0/03438bd98cef38ad57554feea0d8de21705001db2655c27e0c33ff55e16dd7d6f49c28fb420dc93f7532e68ff363c0953056a5836e6f47068f193eb1765c7db7 + languageName: node + linkType: hard + "axios@npm:^1.6.1, axios@npm:^1.6.4": version: 1.16.0 resolution: "axios@npm:1.16.0" @@ -14504,7 +14695,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0 || ^0.28.0, esbuild@npm:^0.28.0": +"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0 || ^0.28.0": version: 0.28.1 resolution: "esbuild@npm:0.28.1" dependencies: @@ -14593,6 +14784,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.28.0": + version: 0.28.0 + resolution: "esbuild@npm:0.28.0" + dependencies: + "@esbuild/aix-ppc64": "npm:0.28.0" + "@esbuild/android-arm": "npm:0.28.0" + "@esbuild/android-arm64": "npm:0.28.0" + "@esbuild/android-x64": "npm:0.28.0" + "@esbuild/darwin-arm64": "npm:0.28.0" + "@esbuild/darwin-x64": "npm:0.28.0" + "@esbuild/freebsd-arm64": "npm:0.28.0" + "@esbuild/freebsd-x64": "npm:0.28.0" + "@esbuild/linux-arm": "npm:0.28.0" + "@esbuild/linux-arm64": "npm:0.28.0" + "@esbuild/linux-ia32": "npm:0.28.0" + "@esbuild/linux-loong64": "npm:0.28.0" + "@esbuild/linux-mips64el": "npm:0.28.0" + "@esbuild/linux-ppc64": "npm:0.28.0" + "@esbuild/linux-riscv64": "npm:0.28.0" + "@esbuild/linux-s390x": "npm:0.28.0" + "@esbuild/linux-x64": "npm:0.28.0" + "@esbuild/netbsd-arm64": "npm:0.28.0" + "@esbuild/netbsd-x64": "npm:0.28.0" + "@esbuild/openbsd-arm64": "npm:0.28.0" + "@esbuild/openbsd-x64": "npm:0.28.0" + "@esbuild/openharmony-arm64": "npm:0.28.0" + "@esbuild/sunos-x64": "npm:0.28.0" + "@esbuild/win32-arm64": "npm:0.28.0" + "@esbuild/win32-ia32": "npm:0.28.0" + "@esbuild/win32-x64": "npm:0.28.0" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/8acd95c238ec6c4a9d16163277faf228a8994b642d187b3fe667ffbb469008e6748cde144fdc3c175bf8e78ee49e15a0ed9b9f183fdb5fcea1772f87fb1372a4 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0"