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"