mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 10:12:34 +00:00
Add shared Icon primitive and controlled glyph vocabulary (Carbon, filled)
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
||||
import { act } from 'react';
|
||||
import { createRoot, type Root } from 'react-dom/client';
|
||||
import { useNotificationStore, type NotificationKind } from '../stores/NotificationStore';
|
||||
import { Toaster } from './Toaster';
|
||||
|
||||
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
||||
|
||||
let container: HTMLDivElement;
|
||||
let root: Root;
|
||||
|
||||
beforeEach(() => {
|
||||
useNotificationStore.getState().clear();
|
||||
container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
root = createRoot(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
act(() => root.unmount());
|
||||
container.remove();
|
||||
useNotificationStore.getState().clear();
|
||||
});
|
||||
|
||||
const KINDS: NotificationKind[] = ['error', 'warning', 'success', 'info'];
|
||||
|
||||
describe('Toaster status glyphs', () => {
|
||||
// The point of the status icon is a non-colour severity channel (WCAG 1.4.1) — so
|
||||
// every kind must render a leading glyph, not lean on the border colour alone.
|
||||
test.each(KINDS)('a %s toast renders a leading status glyph', (kind) => {
|
||||
act(() => {
|
||||
useNotificationStore.getState().notify({ kind, title: `${kind} title`, message: 'body' });
|
||||
root.render(<Toaster />);
|
||||
});
|
||||
const toast = container.querySelector('[role="alert"], [role="status"]');
|
||||
expect(toast).not.toBeNull();
|
||||
// The status glyph is a direct-child <svg> of the toast (the close button's svg
|
||||
// is nested inside the button, so :scope > svg isolates the status icon).
|
||||
expect(toast!.querySelector(':scope > svg')).not.toBeNull();
|
||||
});
|
||||
|
||||
test('error and warning are assertive; success and info are polite', () => {
|
||||
act(() => {
|
||||
useNotificationStore.getState().notify({ kind: 'error', title: 'e', message: 'b' });
|
||||
useNotificationStore.getState().notify({ kind: 'success', title: 's', message: 'b' });
|
||||
root.render(<Toaster />);
|
||||
});
|
||||
expect(container.querySelector('[role="alert"]')).not.toBeNull();
|
||||
expect(container.querySelector('[role="status"]')).not.toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user