Cleanup code and tests
CI Pipeline / test (20) (pull_request) Successful in 2m55s
CI Pipeline / test (18) (pull_request) Successful in 3m32s
CI Pipeline / e2e (webkit) (pull_request) Has been cancelled
CI Pipeline / visual-regression (pull_request) Has been cancelled
CI Pipeline / performance (pull_request) Has been cancelled
CI Pipeline / storybook (pull_request) Has been cancelled
CI Pipeline / lint (pull_request) Has been cancelled
CI Pipeline / build (pull_request) Has been cancelled
CI Pipeline / e2e (chromium) (pull_request) Has been cancelled
CI Pipeline / e2e (firefox) (pull_request) Has been cancelled

This commit is contained in:
adilallo
2025-10-14 17:34:05 -06:00
parent 9de194bfc0
commit c4a631a5d8
50 changed files with 436 additions and 370 deletions
+3 -3
View File
@@ -1,7 +1,7 @@
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
:root {
--font-inter: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
Roboto, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji",
"Segoe UI Emoji";
--font-inter:
"Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
"Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji";
}
+2 -1
View File
@@ -83,7 +83,8 @@ const Checkbox = memo(
};
// Generate unique ID for accessibility if not provided
const checkboxId = id || `checkbox-${useId()}`;
const generatedId = useId();
const checkboxId = id || `checkbox-${generatedId}`;
const accessibilityProps = {
role: "checkbox",
+1 -1
View File
@@ -28,7 +28,7 @@ const ContextMenu = forwardRef(
{children}
</div>
);
}
},
);
ContextMenu.displayName = "ContextMenu";
+4 -4
View File
@@ -14,7 +14,7 @@ const ContextMenuItem = forwardRef(
size = "medium",
...props
},
ref
ref,
) => {
const getTextSize = () => {
switch (size) {
@@ -57,7 +57,7 @@ const ContextMenuItem = forwardRef(
onClick(e);
}
},
[disabled, onClick]
[disabled, onClick],
);
const handleKeyDown = useCallback(
@@ -69,7 +69,7 @@ const ContextMenuItem = forwardRef(
}
}
},
[disabled, onClick]
[disabled, onClick],
);
return (
@@ -119,7 +119,7 @@ const ContextMenuItem = forwardRef(
)}
</div>
);
}
},
);
ContextMenuItem.displayName = "ContextMenuItem";
+1 -1
View File
@@ -22,7 +22,7 @@ const ContextMenuSection = forwardRef(
{children}
</div>
);
}
},
);
ContextMenuSection.displayName = "ContextMenuSection";
+5 -5
View File
@@ -22,7 +22,7 @@ const Input = forwardRef(
className = "",
...props
},
ref
ref,
) => {
// Generate unique ID for accessibility if not provided
const generatedId = useId();
@@ -127,7 +127,7 @@ const Input = forwardRef(
onChange(e);
}
},
[disabled, onChange]
[disabled, onChange],
);
const handleFocus = useCallback(
@@ -136,7 +136,7 @@ const Input = forwardRef(
onFocus(e);
}
},
[disabled, onFocus]
[disabled, onFocus],
);
const handleBlur = useCallback(
@@ -145,7 +145,7 @@ const Input = forwardRef(
onBlur(e);
}
},
[disabled, onBlur]
[disabled, onBlur],
);
return (
@@ -177,7 +177,7 @@ const Input = forwardRef(
</div>
</div>
);
}
},
);
Input.displayName = "Input";
+2 -1
View File
@@ -71,7 +71,8 @@ const RadioButton = ({
"focus:outline focus:outline-1 focus:outline-[var(--color-border-default-utility-info)] focus:shadow-[0_0_10px_1px_var(--color-surface-inverse-brand-primary)]";
// Generate unique ID for accessibility if not provided
const radioId = id || `radio-${useId()}`;
const generatedId = useId();
const radioId = id || `radio-${generatedId}`;
const handleToggle = useCallback(
(e) => {
+2 -1
View File
@@ -15,7 +15,8 @@ const RadioGroup = ({
...props
}) => {
// Generate unique ID for accessibility if not provided
const groupId = name || `radio-group-${useId()}`;
const generatedId = useId();
const groupId = name || `radio-group-${generatedId}`;
const handleChange = useCallback(
(optionValue) => {
+2 -1
View File
@@ -33,7 +33,8 @@ const Select = forwardRef(
},
ref
) => {
const selectId = id || `select-${useId()}`;
const generatedId = useId();
const selectId = id || `select-${generatedId}`;
const labelId = `${selectId}-label`;
const [isOpen, setIsOpen] = useState(false);
const [selectedValue, setSelectedValue] = useState(value || "");
+5 -5
View File
@@ -21,7 +21,7 @@ const Switch = memo(
onChange(e);
}
},
[onChange]
[onChange],
);
const handleKeyDown = useCallback(
@@ -33,7 +33,7 @@ const Switch = memo(
}
}
},
[onChange]
[onChange],
);
const handleFocus = useCallback(
@@ -42,7 +42,7 @@ const Switch = memo(
onFocus(e);
}
},
[onFocus]
[onFocus],
);
const handleBlur = useCallback(
@@ -51,7 +51,7 @@ const Switch = memo(
onBlur(e);
}
},
[onBlur]
[onBlur],
);
// Switch track styles based on checked state
@@ -155,7 +155,7 @@ const Switch = memo(
{label && <span className={labelClasses}>{label}</span>}
</div>
);
})
}),
);
Switch.displayName = "Switch";
+5 -5
View File
@@ -22,7 +22,7 @@ const TextArea = forwardRef(
rows,
...props
},
ref
ref,
) => {
// Generate unique ID for accessibility if not provided
const generatedId = useId();
@@ -130,7 +130,7 @@ const TextArea = forwardRef(
onChange(e);
}
},
[disabled, onChange]
[disabled, onChange],
);
const handleFocus = useCallback(
@@ -139,7 +139,7 @@ const TextArea = forwardRef(
onFocus(e);
}
},
[disabled, onFocus]
[disabled, onFocus],
);
const handleBlur = useCallback(
@@ -148,7 +148,7 @@ const TextArea = forwardRef(
onBlur(e);
}
},
[disabled, onBlur]
[disabled, onBlur],
);
return (
@@ -182,7 +182,7 @@ const TextArea = forwardRef(
</div>
</div>
);
}
},
);
TextArea.displayName = "TextArea";
+6 -6
View File
@@ -17,7 +17,7 @@ const Toggle = forwardRef(
className = "",
...props
},
ref
ref,
) => {
const toggleId = useId();
const labelId = useId();
@@ -120,7 +120,7 @@ const Toggle = forwardRef(
onChange(e);
}
},
[disabled, onChange]
[disabled, onChange],
);
const handleFocus = useCallback(
@@ -129,7 +129,7 @@ const Toggle = forwardRef(
onFocus(e);
}
},
[disabled, onFocus]
[disabled, onFocus],
);
const handleBlur = useCallback(
@@ -138,7 +138,7 @@ const Toggle = forwardRef(
onBlur(e);
}
},
[disabled, onBlur]
[disabled, onBlur],
);
const handleKeyDown = useCallback(
@@ -150,7 +150,7 @@ const Toggle = forwardRef(
}
}
},
[disabled, onChange]
[disabled, onChange],
);
return (
@@ -186,7 +186,7 @@ const Toggle = forwardRef(
</div>
</div>
);
}
},
);
Toggle.displayName = "Toggle";
+5 -5
View File
@@ -55,7 +55,7 @@ const ToggleGroup = memo(
onChange(e);
}
},
[onChange]
[onChange],
);
const handleFocus = useCallback(
@@ -64,7 +64,7 @@ const ToggleGroup = memo(
onFocus(e);
}
},
[onFocus]
[onFocus],
);
const handleBlur = useCallback(
@@ -73,7 +73,7 @@ const ToggleGroup = memo(
onBlur(e);
}
},
[onBlur]
[onBlur],
);
const handleKeyDown = useCallback(
@@ -85,7 +85,7 @@ const ToggleGroup = memo(
}
}
},
[onChange]
[onChange],
);
const toggleClasses = `
@@ -129,7 +129,7 @@ const ToggleGroup = memo(
{showText ? children : children || "☰"}
</button>
);
})
}),
);
ToggleGroup.displayName = "ToggleGroup";
+8 -5
View File
@@ -31,12 +31,15 @@
--color-*: initial;
/* Font families */
--font-sans: var(--font-inter), ui-sans-serif, system-ui, -apple-system,
--font-sans:
var(--font-inter), ui-sans-serif, system-ui, -apple-system, "Segoe UI",
Roboto, "Helvetica Neue", Arial, sans-serif;
--font-display:
var(--font-bricolage-grotesque), ui-sans-serif, system-ui, -apple-system,
"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-display: var(--font-bricolage-grotesque), ui-sans-serif, system-ui,
-apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-mono: var(--font-space-grotesk), ui-monospace, SFMono-Regular,
"SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
--font-mono:
var(--font-space-grotesk), ui-monospace, SFMono-Regular, "SF Mono",
Consolas, "Liberation Mono", Menlo, monospace;
/* Dimension */
--spacing-scale-000: 0px;
+19
View File
@@ -45,6 +45,7 @@
"@vitest/coverage-v8": "^3.2.4",
"eslint": "^9",
"eslint-config-next": "15.2.0",
"eslint-plugin-storybook": "^9.0.7",
"jest-axe": "^10.0.0",
"jsdom": "^26.1.0",
"msw": "^2.10.5",
@@ -12438,6 +12439,24 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/eslint-plugin-storybook": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-9.0.7.tgz",
"integrity": "sha512-da9oIFo2ww+/PWAsTrpeEPUmhel6Ej1++SwBvdf+SV0H6+rOPbzJGOh367hdOvkwKCbGdKRmw+JmXFCQfHCpqw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/csf": "^0.1.11",
"@typescript-eslint/utils": "^8.8.1",
"ts-dedent": "^2.2.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"eslint": ">=8"
}
},
"node_modules/eslint-scope": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+1
View File
@@ -80,6 +80,7 @@
"@vitest/coverage-v8": "^3.2.4",
"eslint": "^9",
"eslint-config-next": "15.2.0",
"eslint-plugin-storybook": "^9.0.7",
"jest-axe": "^10.0.0",
"jsdom": "^26.1.0",
"msw": "^2.10.5",
+26 -26
View File
@@ -17,7 +17,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenu>
<ContextMenuItem onClick={vi.fn()}>Item 1</ContextMenuItem>
<ContextMenuItem onClick={vi.fn()}>Item 2</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -28,7 +28,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenu>
<ContextMenuItem onClick={vi.fn()}>Item 1</ContextMenuItem>
<ContextMenuItem onClick={vi.fn()}>Item 2</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const menu = screen.getByRole("menu");
@@ -44,7 +44,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenu>
<ContextMenuItem onClick={vi.fn()}>Item 1</ContextMenuItem>
<ContextMenuItem onClick={vi.fn()}>Item 2</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const firstItem = screen.getByRole("menuitem", { name: "Item 1" });
@@ -58,7 +58,7 @@ describe("ContextMenu Components Accessibility", () => {
const { container } = render(
<ContextMenu>
<ContextMenuItem onClick={vi.fn()}>Test Item</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -68,7 +68,7 @@ describe("ContextMenu Components Accessibility", () => {
render(
<ContextMenu>
<ContextMenuItem onClick={vi.fn()}>Test Item</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByRole("menuitem");
@@ -81,7 +81,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenuItem onClick={vi.fn()} selected={true}>
Test Item
</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByRole("menuitem");
@@ -94,7 +94,7 @@ describe("ContextMenu Components Accessibility", () => {
render(
<ContextMenu>
<ContextMenuItem onClick={onClick}>Test Item</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByRole("menuitem");
@@ -110,7 +110,7 @@ describe("ContextMenu Components Accessibility", () => {
render(
<ContextMenu>
<ContextMenuItem onClick={onClick}>Test Item</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByRole("menuitem");
@@ -124,12 +124,12 @@ describe("ContextMenu Components Accessibility", () => {
render(
<ContextMenu>
<ContextMenuItem onClick={vi.fn()}>Test Item</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByRole("menuitem");
expect(item).toHaveClass(
"hover:!bg-[var(--color-surface-default-secondary)]"
"hover:!bg-[var(--color-surface-default-secondary)]",
);
});
@@ -139,7 +139,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenuItem onClick={vi.fn()} selected={true}>
Test Item
</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByRole("menuitem");
@@ -154,7 +154,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenuSection title="Test Section">
<ContextMenuItem onClick={vi.fn()}>Item 1</ContextMenuItem>
</ContextMenuSection>
</ContextMenu>
</ContextMenu>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -166,7 +166,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenuSection title="Test Section">
<ContextMenuItem onClick={vi.fn()}>Item 1</ContextMenuItem>
</ContextMenuSection>
</ContextMenu>
</ContextMenu>,
);
const title = screen.getByText("Test Section");
@@ -179,7 +179,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenuSection title="Test Section">
<ContextMenuItem onClick={vi.fn()}>Item 1</ContextMenuItem>
</ContextMenuSection>
</ContextMenu>
</ContextMenu>,
);
const title = screen.getByText("Test Section");
@@ -206,7 +206,7 @@ describe("ContextMenu Components Accessibility", () => {
const divider = screen.getByRole("separator");
expect(divider).toHaveClass(
"border-[var(--color-border-default-tertiary)]"
"border-[var(--color-border-default-tertiary)]",
);
});
});
@@ -268,7 +268,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenu>
<ContextMenuItem onClick={onClick}>Item 1</ContextMenuItem>
<ContextMenuItem onClick={vi.fn()}>Item 2</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const items = screen.getAllByRole("menuitem");
@@ -284,12 +284,12 @@ describe("ContextMenu Components Accessibility", () => {
render(
<ContextMenu>
<ContextMenuItem onClick={vi.fn()}>Test Item</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByRole("menuitem");
expect(item).toHaveClass(
"text-[var(--color-content-default-brand-primary)]"
"text-[var(--color-content-default-brand-primary)]",
);
});
@@ -297,7 +297,7 @@ describe("ContextMenu Components Accessibility", () => {
render(
<ContextMenu>
<ContextMenuSection title="Test Section" />
</ContextMenu>
</ContextMenu>,
);
const title = screen.getByText("Test Section");
@@ -308,12 +308,12 @@ describe("ContextMenu Components Accessibility", () => {
render(
<ContextMenu>
<ContextMenuDivider />
</ContextMenu>
</ContextMenu>,
);
const divider = screen.getByRole("separator");
expect(divider).toHaveClass(
"border-[var(--color-border-default-tertiary)]"
"border-[var(--color-border-default-tertiary)]",
);
});
});
@@ -328,7 +328,7 @@ describe("ContextMenu Components Accessibility", () => {
Item 2
</ContextMenuItem>
</ContextMenuSection>
</ContextMenu>
</ContextMenu>,
);
const menu = screen.getByRole("menu");
@@ -344,7 +344,7 @@ describe("ContextMenu Components Accessibility", () => {
const { rerender } = render(
<ContextMenuItem onClick={vi.fn()} selected={false}>
Test Item
</ContextMenuItem>
</ContextMenuItem>,
);
const item = screen.getByRole("menuitem");
@@ -353,7 +353,7 @@ describe("ContextMenu Components Accessibility", () => {
rerender(
<ContextMenuItem onClick={vi.fn()} selected={true}>
Test Item
</ContextMenuItem>
</ContextMenuItem>,
);
expect(item).toHaveAttribute("aria-current", "true");
@@ -372,7 +372,7 @@ describe("ContextMenu Components Accessibility", () => {
</ContextMenuSection>
<ContextMenuDivider />
<ContextMenuItem onClick={vi.fn()}>Item 3</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -390,7 +390,7 @@ describe("ContextMenu Components Accessibility", () => {
<ContextMenuItem onClick={vi.fn()} disabled={true}>
Disabled Item
</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
+7 -7
View File
@@ -27,7 +27,7 @@ describe("Input Component Accessibility", () => {
test("has no accessibility violations with horizontal label", async () => {
const { container } = render(
<Input label="Test input" labelVariant="horizontal" />
<Input label="Test input" labelVariant="horizontal" />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -98,7 +98,7 @@ describe("Input Component Accessibility", () => {
<div>
<Input label="First input" />
<Input label="Second input" />
</div>
</div>,
);
const firstInput = screen.getByLabelText("First input");
@@ -119,7 +119,7 @@ describe("Input Component Accessibility", () => {
<div>
<Input label="First input" />
<Input label="Second input" />
</div>
</div>,
);
const firstInput = screen.getByLabelText("First input");
@@ -184,7 +184,7 @@ describe("Input Component Accessibility", () => {
const handleBlur = vi.fn();
render(
<Input label="Test input" onFocus={handleFocus} onBlur={handleBlur} />
<Input label="Test input" onFocus={handleFocus} onBlur={handleBlur} />,
);
const input = screen.getByRole("textbox");
@@ -206,7 +206,7 @@ describe("Input Component Accessibility", () => {
render(
<form>
<Input name="test-field" label="Test input" />
</form>
</form>,
);
const input = screen.getByRole("textbox");
@@ -219,7 +219,7 @@ describe("Input Component Accessibility", () => {
label="Test input"
aria-describedby="help-text"
aria-required="true"
/>
/>,
);
const input = screen.getByRole("textbox");
@@ -239,7 +239,7 @@ describe("Input Component Accessibility", () => {
<Input label="First input" />
<Input label="Second input" />
<Input label="Third input" />
</div>
</div>,
);
const firstInput = screen.getByLabelText("First input");
+3 -1
View File
@@ -272,7 +272,9 @@ describe("Select Component Accessibility", () => {
render(<Select {...defaultProps} />);
const label = screen.getByText("Test Select");
expect(label).toHaveClass("text-[var(--color-content-default-primary)]");
expect(label).toHaveClass(
"text-[var(--color-content-default-secondary)]"
);
});
});
+4 -4
View File
@@ -56,7 +56,7 @@ describe("Toggle Accessibility", () => {
test("handles disabled state accessibility", () => {
const handleChange = vi.fn();
render(
<Toggle label="Test Toggle" disabled={true} onChange={handleChange} />
<Toggle label="Test Toggle" disabled={true} onChange={handleChange} />,
);
const toggle = screen.getByRole("switch");
@@ -88,7 +88,7 @@ describe("Toggle Accessibility", () => {
test("has no accessibility violations when disabled", async () => {
const { container } = render(
<Toggle label="Test Toggle" disabled={true} />
<Toggle label="Test Toggle" disabled={true} />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -96,7 +96,7 @@ describe("Toggle Accessibility", () => {
test("has no accessibility violations with icon", async () => {
const { container } = render(
<Toggle label="Test Toggle" showIcon={true} icon="I" />
<Toggle label="Test Toggle" showIcon={true} icon="I" />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -104,7 +104,7 @@ describe("Toggle Accessibility", () => {
test("has no accessibility violations with text", async () => {
const { container } = render(
<Toggle label="Test Toggle" showText={true} text="Toggle" />
<Toggle label="Test Toggle" showText={true} text="Toggle" />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -46,7 +46,7 @@ describe("ToggleGroup Accessibility", () => {
const toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass("bg-[var(--color-magenta-magenta100)]");
expect(toggleGroup).toHaveClass(
"shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]"
"shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]",
);
});
@@ -58,7 +58,7 @@ describe("ToggleGroup Accessibility", () => {
it("has no accessibility violations when focused", async () => {
const { container } = render(
<ToggleGroup state="focus">Focused Toggle</ToggleGroup>
<ToggleGroup state="focus">Focused Toggle</ToggleGroup>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -66,7 +66,7 @@ describe("ToggleGroup Accessibility", () => {
it("has no accessibility violations when selected", async () => {
const { container } = render(
<ToggleGroup state="selected">Selected Toggle</ToggleGroup>
<ToggleGroup state="selected">Selected Toggle</ToggleGroup>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -74,7 +74,7 @@ describe("ToggleGroup Accessibility", () => {
it("has no accessibility violations with text", async () => {
const { container } = render(
<ToggleGroup showText={true}>Text Toggle</ToggleGroup>
<ToggleGroup showText={true}>Text Toggle</ToggleGroup>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -84,7 +84,7 @@ describe("ToggleGroup Accessibility", () => {
const { container } = render(
<ToggleGroup showText={false} ariaLabel="Icon Toggle">
Icon Toggle
</ToggleGroup>
</ToggleGroup>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -15,7 +15,7 @@ describe("Checkbox Accessibility", () => {
test("should not have accessibility violations when checked", async () => {
const { container } = render(
<Checkbox label="Test checkbox" checked={true} />
<Checkbox label="Test checkbox" checked={true} />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -23,7 +23,7 @@ describe("Checkbox Accessibility", () => {
test("should not have accessibility violations when disabled", async () => {
const { container } = render(
<Checkbox label="Test checkbox" disabled={true} />
<Checkbox label="Test checkbox" disabled={true} />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -31,7 +31,7 @@ describe("Checkbox Accessibility", () => {
test("should not have accessibility violations in inverse mode", async () => {
const { container } = render(
<Checkbox label="Test checkbox" mode="inverse" />
<Checkbox label="Test checkbox" mode="inverse" />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -80,7 +80,7 @@ describe("Checkbox Accessibility", () => {
expect(checkbox).toHaveAttribute(
"aria-label",
"Custom accessibility label"
"Custom accessibility label",
);
});
@@ -92,9 +92,7 @@ describe("Checkbox Accessibility", () => {
expect(checkbox).toHaveAttribute("tabIndex", "0");
// Should not be focusable when disabled
rerender(
<Checkbox label="Test checkbox disabled" disabled={true} />
);
rerender(<Checkbox label="Test checkbox disabled" disabled={true} />);
const disabledCheckbox = screen.getByRole("checkbox");
expect(disabledCheckbox).toHaveAttribute("tabIndex", "-1");
});
@@ -131,7 +129,7 @@ describe("Checkbox Accessibility", () => {
// Check for color contrast violations
const contrastViolations = results.violations.filter(
(violation) => violation.id === "color-contrast"
(violation) => violation.id === "color-contrast",
);
expect(contrastViolations).toHaveLength(0);
});
@@ -142,7 +140,7 @@ describe("Checkbox Accessibility", () => {
// Check for focus indicator violations
const focusViolations = results.violations.filter(
(violation) => violation.id === "focus-order-semantics"
(violation) => violation.id === "focus-order-semantics",
);
expect(focusViolations).toHaveLength(0);
});
@@ -16,7 +16,7 @@ describe("RadioButton Accessibility", () => {
it("updates aria-checked when checked state changes", () => {
const { rerender } = render(
<RadioButton checked={false} label="Test Radio" />
<RadioButton checked={false} label="Test Radio" />,
);
let radioButton = screen.getByRole("radio");
@@ -117,7 +117,7 @@ describe("RadioButton Accessibility", () => {
<RadioButton label="First Radio" />
<RadioButton label="Second Radio" />
<RadioButton label="Third Radio" />
</div>
</div>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -132,7 +132,7 @@ describe("RadioButton Accessibility", () => {
<RadioButton label="Radio 1" />
<RadioButton label="Radio 2" />
<RadioButton label="Radio 3" />
</div>
</div>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -176,7 +176,7 @@ describe("RadioButton Accessibility", () => {
checked={false}
onChange={handleChange}
label="Focus Radio"
/>
/>,
);
const radioButton = screen.getByRole("radio");
@@ -185,7 +185,11 @@ describe("RadioButton Accessibility", () => {
// Change checked state
rerender(
<RadioButton checked={true} onChange={handleChange} label="Focus Radio" />
<RadioButton
checked={true}
onChange={handleChange}
label="Focus Radio"
/>,
);
// Should still be focusable
@@ -206,7 +210,7 @@ describe("RadioButton Accessibility", () => {
<RadioButton label="First Option" />
<RadioButton label="Second Option" />
<RadioButton label="Third Option" />
</div>
</div>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -220,7 +224,7 @@ describe("RadioButton Accessibility", () => {
it("has proper form association", () => {
render(
<RadioButton name="test-radio" value="test-value" label="Form Radio" />
<RadioButton name="test-radio" value="test-value" label="Form Radio" />,
);
const hiddenInput = screen.getByDisplayValue("test-value");
@@ -20,7 +20,7 @@ describe("RadioGroup Accessibility", () => {
it("has proper ARIA attributes on radiogroup", () => {
render(
<RadioGroup options={defaultOptions} aria-label="Test Radio Group" />
<RadioGroup options={defaultOptions} aria-label="Test Radio Group" />,
);
const radioGroup = screen.getByRole("radiogroup");
@@ -50,7 +50,7 @@ describe("RadioGroup Accessibility", () => {
it("updates selection state correctly", () => {
const { rerender } = render(
<RadioGroup options={defaultOptions} value="option1" />
<RadioGroup options={defaultOptions} value="option1" />,
);
let radioButtons = screen.getAllByRole("radio");
@@ -98,7 +98,7 @@ describe("RadioGroup Accessibility", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -125,7 +125,7 @@ describe("RadioGroup Accessibility", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -144,7 +144,7 @@ describe("RadioGroup Accessibility", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -163,7 +163,7 @@ describe("RadioGroup Accessibility", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -190,7 +190,7 @@ describe("RadioGroup Accessibility", () => {
<div>
<RadioGroup options={defaultOptions} />
<RadioGroup options={defaultOptions} />
</div>
</div>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -212,7 +212,7 @@ describe("RadioGroup Accessibility", () => {
it("has proper form association", () => {
render(
<RadioGroup options={defaultOptions} name="test-group" value="option2" />
<RadioGroup options={defaultOptions} name="test-group" value="option2" />,
);
const hiddenInputs = screen.getAllByDisplayValue("option1");
@@ -235,7 +235,7 @@ describe("RadioGroup Accessibility", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -248,7 +248,7 @@ describe("RadioGroup Accessibility", () => {
options={defaultOptions}
value="option2"
onChange={handleChange}
/>
/>,
);
// Should still be focusable
@@ -301,7 +301,7 @@ describe("RadioGroup Accessibility", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const radioButtons = screen.getAllByRole("radio");
+11 -11
View File
@@ -3,7 +3,7 @@ import { test, expect } from "@playwright/test";
test.describe("ContextMenu Components Storybook Tests", () => {
test.beforeEach(async ({ page }) => {
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--default"
"http://localhost:6006/?path=/story/forms-contextmenu--default",
);
});
@@ -38,7 +38,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("shows selected state correctly", async ({ page }) => {
// Navigate to MenuItem story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--menu-item"
"http://localhost:6006/?path=/story/forms-contextmenu--menu-item",
);
const menuItems = page.getByRole("option");
@@ -60,7 +60,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("shows submenu indicators", async ({ page }) => {
// Navigate to MenuItem story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--menu-item"
"http://localhost:6006/?path=/story/forms-contextmenu--menu-item",
);
const submenuArrows = page.getByTestId("submenu-arrow");
@@ -74,7 +74,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("shows checkmarks for selected items", async ({ page }) => {
// Navigate to MenuItem story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--menu-item"
"http://localhost:6006/?path=/story/forms-contextmenu--menu-item",
);
const checkmarks = page.getByTestId("checkmark");
@@ -88,7 +88,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("renders menu sections correctly", async ({ page }) => {
// Navigate to MenuSection story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--menu-section"
"http://localhost:6006/?path=/story/forms-contextmenu--menu-section",
);
const sectionTitles = page.getByText(/Section/);
@@ -104,7 +104,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("renders menu dividers correctly", async ({ page }) => {
// Navigate to MenuDivider story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--menu-divider"
"http://localhost:6006/?path=/story/forms-contextmenu--menu-divider",
);
const dividers = page.getByTestId("context-menu-divider");
@@ -120,7 +120,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("shows all variants correctly", async ({ page }) => {
// Navigate to All Variants story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--all-variants"
"http://localhost:6006/?path=/story/forms-contextmenu--all-variants",
);
const menu = page.getByRole("listbox");
@@ -195,7 +195,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("has correct styling for different sizes", async ({ page }) => {
// Navigate to All Variants story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--all-variants"
"http://localhost:6006/?path=/story/forms-contextmenu--all-variants",
);
const menuItems = page.getByRole("option");
@@ -232,7 +232,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("handles disabled items correctly", async ({ page }) => {
// Navigate to All Variants story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--all-variants"
"http://localhost:6006/?path=/story/forms-contextmenu--all-variants",
);
const menuItems = page.getByRole("option");
@@ -268,7 +268,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("renders with custom styling", async ({ page }) => {
// Navigate to With Custom Styling story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--with-custom-styling"
"http://localhost:6006/?path=/story/forms-contextmenu--with-custom-styling",
);
const menu = page.getByRole("listbox");
@@ -282,7 +282,7 @@ test.describe("ContextMenu Components Storybook Tests", () => {
test("handles interactive story correctly", async ({ page }) => {
// Navigate to Interactive story
await page.goto(
"http://localhost:6006/?path=/story/forms-contextmenu--interactive"
"http://localhost:6006/?path=/story/forms-contextmenu--interactive",
);
const menuItems = page.getByRole("option");
+6 -6
View File
@@ -71,7 +71,7 @@ test.describe("Select Component Storybook Tests", () => {
test("shows different sizes correctly", async ({ page }) => {
// Navigate to All Sizes story
await page.goto(
"http://localhost:6006/?path=/story/forms-select--all-sizes"
"http://localhost:6006/?path=/story/forms-select--all-sizes",
);
const selectButtons = page.getByRole("button");
@@ -89,7 +89,7 @@ test.describe("Select Component Storybook Tests", () => {
test("shows different states correctly", async ({ page }) => {
// Navigate to All States story
await page.goto(
"http://localhost:6006/?path=/story/forms-select--all-states"
"http://localhost:6006/?path=/story/forms-select--all-states",
);
const selectButtons = page.getByRole("button");
@@ -160,7 +160,7 @@ test.describe("Select Component Storybook Tests", () => {
test("disabled state prevents interaction", async ({ page }) => {
// Navigate to Disabled story
await page.goto(
"http://localhost:6006/?path=/story/forms-select--disabled"
"http://localhost:6006/?path=/story/forms-select--disabled",
);
const selectButton = page.getByRole("button");
@@ -177,7 +177,7 @@ test.describe("Select Component Storybook Tests", () => {
test("interactive story allows selection", async ({ page }) => {
// Navigate to Interactive story
await page.goto(
"http://localhost:6006/?path=/story/forms-select--interactive"
"http://localhost:6006/?path=/story/forms-select--interactive",
);
const selectButton = page.getByRole("button");
@@ -195,7 +195,7 @@ test.describe("Select Component Storybook Tests", () => {
test("horizontal label variant displays correctly", async ({ page }) => {
// Navigate to Horizontal Label story
await page.goto(
"http://localhost:6006/?path=/story/forms-select--horizontal-label"
"http://localhost:6006/?path=/story/forms-select--horizontal-label",
);
const selectButton = page.getByRole("button");
@@ -259,7 +259,7 @@ test.describe("Select Component Storybook Tests", () => {
test("focus behavior works correctly", async ({ page }) => {
// Navigate to Interactive story
await page.goto(
"http://localhost:6006/?path=/story/forms-select--interactive"
"http://localhost:6006/?path=/story/forms-select--interactive",
);
const selectButton = page.getByRole("button");
@@ -59,7 +59,7 @@ describe("ContextMenu Components Integration", () => {
const action1 = screen.getByRole("menuitem", { name: "Action 1" });
expect(action1).toHaveClass(
"bg-[var(--color-surface-default-secondary)]"
"bg-[var(--color-surface-default-secondary)]",
);
});
@@ -97,10 +97,10 @@ describe("ContextMenu Components Integration", () => {
const enabledItems = items.filter(
(item) =>
!item.hasAttribute("aria-disabled") ||
item.getAttribute("aria-disabled") !== "true"
item.getAttribute("aria-disabled") !== "true",
);
const disabledItems = items.filter(
(item) => item.getAttribute("aria-disabled") === "true"
(item) => item.getAttribute("aria-disabled") === "true",
);
enabledItems.forEach((item) => {
@@ -177,7 +177,7 @@ describe("ContextMenu Components Integration", () => {
]}
selectedValue=""
onItemClick={onItemClick}
/>
/>,
);
const item1 = screen.getByText("Item 1");
@@ -194,12 +194,12 @@ describe("ContextMenu Components Integration", () => {
]}
selectedValue="1"
onItemClick={onItemClick}
/>
/>,
);
expect(screen.getByText("Item 3")).toBeInTheDocument();
expect(screen.getByRole("menuitem", { name: "Item 1" })).toHaveClass(
"bg-[var(--color-surface-default-secondary)]"
"bg-[var(--color-surface-default-secondary)]",
);
});
@@ -213,7 +213,7 @@ describe("ContextMenu Components Integration", () => {
]}
selectedValue="2"
onItemClick={vi.fn()}
/>
/>,
);
expect(screen.getByText("Item 2")).toBeInTheDocument();
@@ -226,7 +226,7 @@ describe("ContextMenu Components Integration", () => {
]}
selectedValue=""
onItemClick={vi.fn()}
/>
/>,
);
expect(screen.queryByText("Item 2")).not.toBeInTheDocument();
@@ -278,7 +278,7 @@ describe("ContextMenu Components Integration", () => {
expect(screen.getByText("Option 1")).toBeInTheDocument();
expect(
screen.getByRole("button", { name: "Close Menu" })
screen.getByRole("button", { name: "Close Menu" }),
).toBeInTheDocument();
});
@@ -294,7 +294,7 @@ describe("ContextMenu Components Integration", () => {
expect(screen.queryByText("Option 1")).not.toBeInTheDocument();
expect(
screen.getByRole("button", { name: "Open Menu" })
screen.getByRole("button", { name: "Open Menu" }),
).toBeInTheDocument();
});
});
@@ -338,7 +338,7 @@ describe("ContextMenu Components Integration", () => {
<ContextMenuItem onClick={vi.fn()} selected={false}>
Item 2
</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
// Rapidly change selection state
@@ -351,7 +351,7 @@ describe("ContextMenu Components Integration", () => {
<ContextMenuItem onClick={vi.fn()} selected={i % 2 === 1}>
Item 2
</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
}
@@ -366,7 +366,7 @@ describe("ContextMenu Components Integration", () => {
render(
<ContextMenu>
<ContextMenuItem>Item without onClick</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByText("Item without onClick");
@@ -379,7 +379,7 @@ describe("ContextMenu Components Integration", () => {
<ContextMenuItem onClick={vi.fn()} selected={null}>
Item with invalid selected
</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const item = screen.getByText("Item with invalid selected");
+11 -11
View File
@@ -160,7 +160,7 @@ describe("Input Component Integration", () => {
fireEvent.change(input, { target: { value: "ab" } });
expect(screen.getByTestId("error-message")).toBeInTheDocument();
expect(input).toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
// Type longer value - should hide error
@@ -175,7 +175,7 @@ describe("Input Component Integration", () => {
<Input label="Email Input" type="email" />
<Input label="Password Input" type="password" />
<Input label="Number Input" type="number" />
</div>
</div>,
);
const textInput = screen.getByLabelText("Text Input");
@@ -210,7 +210,7 @@ describe("Input Component Integration", () => {
size="large"
labelVariant="horizontal"
/>
</div>
</div>,
);
// All inputs should be present
@@ -231,7 +231,7 @@ describe("Input Component Integration", () => {
onChange={handleChange}
onFocus={vi.fn()}
onBlur={vi.fn()}
/>
/>,
);
const input = screen.getByLabelText("Disabled Input");
@@ -252,7 +252,7 @@ describe("Input Component Integration", () => {
const input = screen.getByLabelText("Error Input");
expect(input).toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
expect(input).not.toBeDisabled();
});
@@ -287,7 +287,7 @@ describe("Input Component Integration", () => {
fireEvent.click(hoverButton);
expect(input).toHaveClass("border-[var(--color-border-default-tertiary)]");
expect(input).toHaveClass(
"shadow-[0_0_0_2px_var(--color-border-default-tertiary)]"
"shadow-[0_0_0_2px_var(--color-border-default-tertiary)]",
);
// Set active state
@@ -297,7 +297,7 @@ describe("Input Component Integration", () => {
// Focus state
fireEvent.focus(input);
expect(input).toHaveClass(
"border-[var(--color-border-default-utility-info)]"
"border-[var(--color-border-default-utility-info)]",
);
expect(input).toHaveClass("shadow-[0_0_5px_3px_#3281F8]");
});
@@ -308,7 +308,7 @@ describe("Input Component Integration", () => {
<Input label="First Input" />
<Input label="Second Input" />
<Input label="Third Input" />
</div>
</div>,
);
const firstInput = screen.getByLabelText("First Input");
@@ -345,7 +345,7 @@ describe("Input Component Integration", () => {
<form onSubmit={handleSubmit}>
<Input label="Test Input" name="testField" />
<button type="submit">Submit</button>
</form>
</form>,
);
const input = screen.getByLabelText("Test Input");
@@ -408,7 +408,7 @@ describe("Input Component Integration", () => {
// Initial state
expect(input).not.toBeDisabled();
expect(input).not.toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
// Toggle disabled
@@ -420,7 +420,7 @@ describe("Input Component Integration", () => {
fireEvent.click(toggleErrorButton); // Turn on error
// The error state applies the border color through the stateStyles.input class
expect(input).toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
});
});
@@ -131,13 +131,13 @@ describe("RadioButton Integration", () => {
// Initially standard mode
expect(radioButton).toHaveClass(
"outline-[var(--color-border-default-tertiary)]"
"outline-[var(--color-border-default-tertiary)]",
);
// Switch to inverse mode
await user.click(toggleButton);
expect(radioButton).toHaveClass(
"outline-[var(--color-border-inverse-primary)]"
"outline-[var(--color-border-inverse-primary)]",
);
});
@@ -231,13 +231,13 @@ describe("RadioButton Integration", () => {
await user.click(group1OptionB);
await user.click(group2OptionY);
const group1Inputs = screen.getAllByDisplayValue("option2").filter(
input => input.getAttribute("name") === "group1"
);
const group2Inputs = screen.getAllByDisplayValue("option2").filter(
input => input.getAttribute("name") === "group2"
);
const group1Inputs = screen
.getAllByDisplayValue("option2")
.filter((input) => input.getAttribute("name") === "group1");
const group2Inputs = screen
.getAllByDisplayValue("option2")
.filter((input) => input.getAttribute("name") === "group2");
expect(group1Inputs[0]).toBeChecked();
expect(group2Inputs[0]).toBeChecked();
});
@@ -309,13 +309,13 @@ describe("RadioButton Integration", () => {
await user.click(controlledOption2);
await user.click(uncontrolledOption2);
const controlledInputs = screen.getAllByDisplayValue("option2").filter(
input => input.getAttribute("name") === "controlled"
);
const uncontrolledInputs = screen.getAllByDisplayValue("option2").filter(
input => input.getAttribute("name") === "uncontrolled"
);
const controlledInputs = screen
.getAllByDisplayValue("option2")
.filter((input) => input.getAttribute("name") === "controlled");
const uncontrolledInputs = screen
.getAllByDisplayValue("option2")
.filter((input) => input.getAttribute("name") === "uncontrolled");
expect(controlledInputs[0]).toBeChecked();
expect(uncontrolledInputs[0]).toBeChecked();
});
@@ -14,10 +14,10 @@ describe("RadioGroup Integration", () => {
it("works in form context", async () => {
const user = userEvent.setup();
const handleSubmit = vi.fn();
function TestForm() {
const [value, setValue] = useState("option1");
return (
<form onSubmit={handleSubmit}>
<RadioGroup
@@ -53,10 +53,10 @@ describe("RadioGroup Integration", () => {
it("handles keyboard navigation", async () => {
const user = userEvent.setup();
const handleChange = vi.fn();
function KeyboardForm() {
const [value, setValue] = useState("option1");
return (
<RadioGroup
name="keyboard-radio-group"
@@ -70,15 +70,15 @@ describe("RadioGroup Integration", () => {
render(<KeyboardForm />);
const radioButtons = screen.getAllByRole("radio");
// Focus first radio button
radioButtons[0].focus();
expect(radioButtons[0]).toHaveFocus();
// Navigate to second radio button
await user.tab();
expect(radioButtons[1]).toHaveFocus();
// Activate with Space
await user.keyboard(" ");
expect(screen.getByDisplayValue("option2")).toBeChecked();
@@ -88,10 +88,14 @@ describe("RadioGroup Integration", () => {
function ModeSwitchForm() {
const [mode, setMode] = useState("standard");
const [value, setValue] = useState("option1");
return (
<div>
<button onClick={() => setMode(mode === "standard" ? "inverse" : "standard")}>
<button
onClick={() =>
setMode(mode === "standard" ? "inverse" : "standard")
}
>
Toggle Mode
</button>
<RadioGroup
@@ -110,16 +114,20 @@ describe("RadioGroup Integration", () => {
const toggleButton = screen.getByRole("button");
const radioButtons = screen.getAllByRole("radio");
// Initially standard mode
radioButtons.forEach(button => {
expect(button).toHaveClass("outline-[var(--color-border-default-tertiary)]");
radioButtons.forEach((button) => {
expect(button).toHaveClass(
"outline-[var(--color-border-default-tertiary)]",
);
});
// Switch to inverse mode
await user.click(toggleButton);
radioButtons.forEach(button => {
expect(button).toHaveClass("outline-[var(--color-border-inverse-primary)]");
radioButtons.forEach((button) => {
expect(button).toHaveClass(
"outline-[var(--color-border-inverse-primary)]",
);
});
});
@@ -127,7 +135,7 @@ describe("RadioGroup Integration", () => {
function StateForm() {
const [value, setValue] = useState("option1");
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>
@@ -148,10 +156,10 @@ describe("RadioGroup Integration", () => {
const radioButtons = screen.getAllByRole("radio");
const reRenderButton = screen.getByRole("button");
// Should be checked initially
expect(radioButtons[0]).toHaveAttribute("aria-checked", "true");
// Re-render should maintain state
user.click(reRenderButton);
expect(radioButtons[0]).toHaveAttribute("aria-checked", "true");
@@ -161,7 +169,7 @@ describe("RadioGroup Integration", () => {
function MultiGroupForm() {
const [group1Value, setGroup1Value] = useState("option1");
const [group2Value, setGroup2Value] = useState("option1");
return (
<div>
<div>
@@ -191,27 +199,27 @@ describe("RadioGroup Integration", () => {
// Both groups should work independently
// Find the Option 2 in group1 by filtering getAllByDisplayValue by name
const group1Option2Input = screen.getAllByDisplayValue("option2").find(
input => input.getAttribute("name") === "group1"
);
const group1Option2Input = screen
.getAllByDisplayValue("option2")
.find((input) => input.getAttribute("name") === "group1");
const group1Option2 = group1Option2Input.closest("label");
// Find the Option 3 in group2 by filtering getAllByDisplayValue by name
const group2Option3Input = screen.getAllByDisplayValue("option3").find(
input => input.getAttribute("name") === "group2"
);
const group2Option3Input = screen
.getAllByDisplayValue("option3")
.find((input) => input.getAttribute("name") === "group2");
const group2Option3 = group2Option3Input.closest("label");
await user.click(group1Option2);
await user.click(group2Option3);
const group1Inputs = screen.getAllByDisplayValue("option2").filter(
input => input.getAttribute("name") === "group1"
);
const group2Inputs = screen.getAllByDisplayValue("option3").filter(
input => input.getAttribute("name") === "group2"
);
const group1Inputs = screen
.getAllByDisplayValue("option2")
.filter((input) => input.getAttribute("name") === "group1");
const group2Inputs = screen
.getAllByDisplayValue("option3")
.filter((input) => input.getAttribute("name") === "group2");
expect(group1Inputs[0]).toBeChecked();
expect(group2Inputs[0]).toBeChecked();
});
@@ -220,7 +228,7 @@ describe("RadioGroup Integration", () => {
function ControlledForm() {
const [controlledValue, setControlledValue] = useState("option1");
const [uncontrolledValue, setUncontrolledValue] = useState("option1");
return (
<div>
<div>
@@ -250,27 +258,27 @@ describe("RadioGroup Integration", () => {
// Both should work the same way
// Find the Option 2 in controlled group by filtering getAllByDisplayValue by name
const controlledOption2Input = screen.getAllByDisplayValue("option2").find(
input => input.getAttribute("name") === "controlled"
);
const controlledOption2Input = screen
.getAllByDisplayValue("option2")
.find((input) => input.getAttribute("name") === "controlled");
const controlledOption2 = controlledOption2Input.closest("label");
// Find the Option 2 in uncontrolled group by filtering getAllByDisplayValue by name
const uncontrolledOption2Input = screen.getAllByDisplayValue("option2").find(
input => input.getAttribute("name") === "uncontrolled"
);
const uncontrolledOption2Input = screen
.getAllByDisplayValue("option2")
.find((input) => input.getAttribute("name") === "uncontrolled");
const uncontrolledOption2 = uncontrolledOption2Input.closest("label");
await user.click(controlledOption2);
await user.click(uncontrolledOption2);
const controlledInputs = screen.getAllByDisplayValue("option2").filter(
input => input.getAttribute("name") === "controlled"
);
const uncontrolledInputs = screen.getAllByDisplayValue("option2").filter(
input => input.getAttribute("name") === "uncontrolled"
);
const controlledInputs = screen
.getAllByDisplayValue("option2")
.filter((input) => input.getAttribute("name") === "controlled");
const uncontrolledInputs = screen
.getAllByDisplayValue("option2")
.filter((input) => input.getAttribute("name") === "uncontrolled");
expect(controlledInputs[0]).toBeChecked();
expect(uncontrolledInputs[0]).toBeChecked();
});
@@ -278,13 +286,13 @@ describe("RadioGroup Integration", () => {
it("handles accessibility in complex forms", () => {
function AccessibleForm() {
const [value, setValue] = useState("option1");
const accessibleOptions = [
{ value: "option1", label: "Option 1", ariaLabel: "First option" },
{ value: "option2", label: "Option 2", ariaLabel: "Second option" },
{ value: "option3", label: "Option 3", ariaLabel: "Third option" },
];
return (
<form>
<fieldset>
@@ -305,16 +313,16 @@ describe("RadioGroup Integration", () => {
const radioGroup = screen.getByRole("radiogroup");
const radioButtons = screen.getAllByRole("radio");
// Should have proper accessibility attributes
expect(radioGroup).toHaveAttribute("aria-label", "Accessible radio group");
radioButtons.forEach(button => {
radioButtons.forEach((button) => {
expect(button).toHaveAttribute("role", "radio");
expect(button).toHaveAttribute("aria-checked");
expect(button).toHaveAttribute("tabIndex", "0");
});
// Should have aria-labels
expect(radioButtons[0]).toHaveAttribute("aria-label", "First option");
expect(radioButtons[1]).toHaveAttribute("aria-label", "Second option");
@@ -325,10 +333,14 @@ describe("RadioGroup Integration", () => {
function DynamicForm() {
const [value, setValue] = useState("option1");
const [options, setOptions] = useState(defaultOptions);
return (
<div>
<button onClick={() => setOptions([...options, { value: "option4", label: "Option 4" }])}>
<button
onClick={() =>
setOptions([...options, { value: "option4", label: "Option 4" }])
}
>
Add Option
</button>
<RadioGroup
@@ -345,10 +357,10 @@ describe("RadioGroup Integration", () => {
render(<DynamicForm />);
const addButton = screen.getByRole("button");
// Initially 3 options
expect(screen.getAllByRole("radio")).toHaveLength(3);
// Add option
await user.click(addButton);
expect(screen.getAllByRole("radio")).toHaveLength(4);
@@ -358,7 +370,7 @@ describe("RadioGroup Integration", () => {
it("handles empty options gracefully", () => {
function EmptyForm() {
const [value, setValue] = useState("");
return (
<RadioGroup
name="empty-radio-group"
@@ -379,10 +391,10 @@ describe("RadioGroup Integration", () => {
it("maintains single selection behavior", async () => {
const user = userEvent.setup();
const handleChange = vi.fn();
function SingleSelectionForm() {
const [value, setValue] = useState("option1");
return (
<RadioGroup
name="single-selection-radio-group"
@@ -399,21 +411,21 @@ describe("RadioGroup Integration", () => {
render(<SingleSelectionForm />);
const radioButtons = screen.getAllByRole("radio");
// Initially option1 should be selected
expect(radioButtons[0]).toHaveAttribute("aria-checked", "true");
expect(radioButtons[1]).toHaveAttribute("aria-checked", "false");
expect(radioButtons[2]).toHaveAttribute("aria-checked", "false");
// Click option2
const option2 = screen.getByText("Option 2").closest("label");
await user.click(option2);
// Only option2 should be selected
expect(radioButtons[0]).toHaveAttribute("aria-checked", "false");
expect(radioButtons[1]).toHaveAttribute("aria-checked", "true");
expect(radioButtons[2]).toHaveAttribute("aria-checked", "false");
expect(handleChange).toHaveBeenCalledWith("option2");
});
});
@@ -71,7 +71,7 @@ describe("Select Component Integration", () => {
await user.click(submitButton);
expect(screen.getByTestId("error")).toHaveTextContent(
"Please select an option"
"Please select an option",
);
});
@@ -298,17 +298,17 @@ describe("Select Component Integration", () => {
name: /Dynamic Select/,
});
expect(selectButton).not.toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
rerender(<DynamicSelect error={true} />);
expect(selectButton).toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
rerender(<DynamicSelect error={false} />);
expect(selectButton).not.toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
});
@@ -339,7 +339,7 @@ describe("Select Component Integration", () => {
expect(selectButton).toHaveFocus();
// Should have focus state styling, not active state
expect(selectButton).toHaveClass(
"focus-visible:border-[var(--color-border-default-utility-info)]"
"focus-visible:border-[var(--color-border-default-utility-info)]",
);
});
@@ -354,7 +354,7 @@ describe("Select Component Integration", () => {
// Click should not trigger focus-visible styles (class is always present but only active on keyboard focus)
// The focus-visible class is always in the component but only applies on keyboard focus
expect(selectButton).toHaveClass(
"focus-visible:border-[var(--color-border-default-utility-info)]"
"focus-visible:border-[var(--color-border-default-utility-info)]",
);
});
});
@@ -392,7 +392,7 @@ describe("Select Component Integration", () => {
label="Large Select"
placeholder="Select an option"
options={largeOptions}
/>
/>,
);
const selectButton = screen.getByRole("button", { name: /Large Select/ });
@@ -74,7 +74,7 @@ describe("Switch Integration", () => {
<Switch label="First Switch" />
<Switch label="Second Switch" />
<Switch label="Third Switch" />
</div>
</div>,
);
const switches = screen.getAllByRole("switch");
@@ -238,7 +238,7 @@ describe("Switch Integration", () => {
await waitFor(() => {
expect(switchButton).toHaveAttribute(
"aria-checked",
i % 2 === 0 ? "true" : "false"
i % 2 === 0 ? "true" : "false",
);
});
}
@@ -251,7 +251,7 @@ describe("Switch Integration", () => {
<Switch label="Another Text Switch" />
<Switch />
<Switch label="Final Switch" />
</div>
</div>,
);
const switches = screen.getAllByRole("switch");
+13 -13
View File
@@ -110,20 +110,20 @@ describe("TextArea Integration Tests", () => {
const { rerender } = render(<DynamicTextArea state="default" />);
let textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"border-[var(--color-border-default-tertiary)]"
"border-[var(--color-border-default-tertiary)]",
);
rerender(<DynamicTextArea state="hover" />);
textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"shadow-[0_0_0_2px_var(--color-border-default-tertiary)]"
"shadow-[0_0_0_2px_var(--color-border-default-tertiary)]",
);
rerender(<DynamicTextArea state="focus" />);
textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"border-[var(--color-border-default-utility-info)]",
"shadow-[0_0_5px_3px_#3281F8]"
"shadow-[0_0_5px_3px_#3281F8]",
);
});
@@ -141,13 +141,13 @@ describe("TextArea Integration Tests", () => {
const { rerender } = render(<DynamicTextArea error={false} />);
let textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"border-[var(--color-border-default-tertiary)]"
"border-[var(--color-border-default-tertiary)]",
);
rerender(<DynamicTextArea error={true} />);
textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
});
@@ -181,7 +181,7 @@ describe("TextArea Integration Tests", () => {
label="Test TextArea"
onFocus={handleFocus}
onBlur={handleBlur}
/>
/>,
);
const textarea = screen.getByRole("textbox");
@@ -212,17 +212,17 @@ describe("TextArea Integration Tests", () => {
label="Large TextArea"
placeholder="Large placeholder"
/>
</div>
</div>,
);
expect(
screen.getByPlaceholderText("Small placeholder")
screen.getByPlaceholderText("Small placeholder"),
).toBeInTheDocument();
expect(
screen.getByPlaceholderText("Medium placeholder")
screen.getByPlaceholderText("Medium placeholder"),
).toBeInTheDocument();
expect(
screen.getByPlaceholderText("Large placeholder")
screen.getByPlaceholderText("Large placeholder"),
).toBeInTheDocument();
});
@@ -236,7 +236,7 @@ describe("TextArea Integration Tests", () => {
placeholder="Disabled input"
disabled
/>
</div>
</div>,
);
const validTextarea = screen.getByPlaceholderText("Valid input");
@@ -244,10 +244,10 @@ describe("TextArea Integration Tests", () => {
const disabledTextarea = screen.getByPlaceholderText("Disabled input");
expect(validTextarea).toHaveClass(
"border-[var(--color-border-default-tertiary)]"
"border-[var(--color-border-default-tertiary)]",
);
expect(invalidTextarea).toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
expect(disabledTextarea).toBeDisabled();
});
@@ -12,7 +12,7 @@ describe("Toggle Integration", () => {
<form onSubmit={handleSubmit}>
<Toggle label="Test Toggle" name="toggle" />
<button type="submit">Submit</button>
</form>
</form>,
);
const toggle = screen.getByRole("switch", { name: "Test Toggle" });
@@ -32,7 +32,7 @@ describe("Toggle Integration", () => {
<Toggle label="First Toggle" />
<Toggle label="Second Toggle" />
<Toggle label="Third Toggle" />
</div>
</div>,
);
const firstToggle = screen.getByRole("switch", { name: "First Toggle" });
@@ -72,7 +72,7 @@ describe("Toggle Integration", () => {
<div>
<Toggle label="First Toggle" onChange={handleChange1} />
<Toggle label="Second Toggle" onChange={handleChange2} />
</div>
</div>,
);
const firstToggle = screen.getByRole("switch", { name: "First Toggle" });
@@ -120,7 +120,7 @@ describe("Toggle Integration", () => {
showText={true}
icon="I"
text="Toggle"
/>
/>,
);
toggle = screen.getByRole("switch");
expect(toggle).toHaveTextContent("I");
@@ -167,7 +167,7 @@ describe("Toggle Integration", () => {
text="Toggle"
/>
<Toggle label="Empty Toggle" />
</div>
</div>,
);
const iconToggle = screen.getByRole("switch", { name: "Icon Toggle" });
@@ -62,7 +62,7 @@ describe("ToggleGroup Integration", () => {
</ToggleGroup>
</div>
<button type="submit">Submit</button>
</form>
</form>,
);
const submitButton = screen.getByRole("button", { name: "Submit" });
@@ -85,18 +85,22 @@ describe("ToggleGroup Integration", () => {
it("handles dynamic prop changes", () => {
const { rerender } = render(
<DynamicToggleGroup position="left" state="default" showText={true} />
<DynamicToggleGroup position="left" state="default" showText={true} />,
);
let toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"rounded-l-[var(--measures-radius-medium)]",
"rounded-r-none"
"rounded-r-none",
);
expect(toggleGroup).toHaveTextContent("Dynamic Content");
rerender(
<DynamicToggleGroup position="middle" state="selected" showText={false} />
<DynamicToggleGroup
position="middle"
state="selected"
showText={false}
/>,
);
toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass("rounded-none");
@@ -126,14 +130,14 @@ describe("ToggleGroup Integration", () => {
fireEvent.click(toggleGroups[1]);
await waitFor(() => {
expect(toggleGroups[1]).toHaveClass(
"bg-[var(--color-magenta-magenta100)]"
"bg-[var(--color-magenta-magenta100)]",
);
});
});
it("handles content changes", () => {
const { rerender } = render(
<ToggleGroup showText={true}>Initial Content</ToggleGroup>
<ToggleGroup showText={true}>Initial Content</ToggleGroup>,
);
let toggleGroup = screen.getByRole("button");
@@ -186,7 +190,7 @@ describe("ToggleGroup Integration", () => {
fireEvent.click(toggleGroups[i % 3]);
await waitFor(() => {
expect(toggleGroups[i % 3]).toHaveClass(
"bg-[var(--color-magenta-magenta100)]"
"bg-[var(--color-magenta-magenta100)]",
);
});
}
@@ -204,7 +208,7 @@ describe("ToggleGroup Integration", () => {
<ToggleGroup position="right" showText={true}>
Text Only
</ToggleGroup>
</div>
</div>,
);
const toggleGroups = screen.getAllByRole("button");
+1 -1
View File
@@ -81,7 +81,7 @@ test.describe("Checkbox Storybook Tests", () => {
await expect(page.locator('[data-testid="control-mode"]')).toBeVisible();
await expect(page.locator('[data-testid="control-state"]')).toBeVisible();
await expect(
page.locator('[data-testid="control-disabled"]')
page.locator('[data-testid="control-disabled"]'),
).toBeVisible();
await expect(page.locator('[data-testid="control-label"]')).toBeVisible();
});
@@ -3,7 +3,7 @@ import { test, expect } from "@playwright/test";
test.describe("RadioButton Storybook Tests", () => {
test.beforeEach(async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiobutton--default"
"http://localhost:6006/iframe.html?id=forms-radiobutton--default",
);
});
@@ -15,7 +15,7 @@ test.describe("RadioButton Storybook Tests", () => {
test("renders checked story", async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiobutton--checked"
"http://localhost:6006/iframe.html?id=forms-radiobutton--checked",
);
const radioButton = page.locator('[role="radio"]');
@@ -25,7 +25,7 @@ test.describe("RadioButton Storybook Tests", () => {
test("renders standard story", async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiobutton--standard"
"http://localhost:6006/iframe.html?id=forms-radiobutton--standard",
);
const radioButtons = page.locator('[role="radio"]');
@@ -39,7 +39,7 @@ test.describe("RadioButton Storybook Tests", () => {
test("renders inverse story", async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiobutton--inverse"
"http://localhost:6006/iframe.html?id=forms-radiobutton--inverse",
);
const radioButtons = page.locator('[role="radio"]');
@@ -66,12 +66,12 @@ test.describe("RadioButton Storybook Tests", () => {
await page.selectOption('[data-testid="mode-control"]', "inverse");
const radioButton = page.locator('[role="radio"]');
await expect(radioButton).toHaveClass(
/outline-\[var\(--color-border-inverse-primary\)\]/
/outline-\[var\(--color-border-inverse-primary\)\]/,
);
await page.selectOption('[data-testid="mode-control"]', "standard");
await expect(radioButton).toHaveClass(
/outline-\[var\(--color-border-default-tertiary\)\]/
/outline-\[var\(--color-border-default-tertiary\)\]/,
);
});
@@ -156,13 +156,13 @@ test.describe("RadioButton Storybook Tests", () => {
await page.selectOption('[data-testid="mode-control"]', "standard");
const radioButton = page.locator('[role="radio"]');
await expect(radioButton).toHaveClass(
/outline-\[var\(--color-border-default-tertiary\)\]/
/outline-\[var\(--color-border-default-tertiary\)\]/,
);
// Test inverse mode
await page.selectOption('[data-testid="mode-control"]', "inverse");
await expect(radioButton).toHaveClass(
/outline-\[var\(--color-border-inverse-primary\)\]/
/outline-\[var\(--color-border-inverse-primary\)\]/,
);
});
@@ -173,7 +173,7 @@ export const FormIntegration = {
// All should have the same name
const names = await Promise.all(
hiddenInputs.map((input) => input.getAttribute("name"))
hiddenInputs.map((input) => input.getAttribute("name")),
);
expect(names.every((name) => name === names[0])).toBe(true);
+10 -10
View File
@@ -3,7 +3,7 @@ import { test, expect } from "@playwright/test";
test.describe("RadioGroup Storybook Tests", () => {
test.beforeEach(async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiogroup--default"
"http://localhost:6006/iframe.html?id=forms-radiogroup--default",
);
});
@@ -17,7 +17,7 @@ test.describe("RadioGroup Storybook Tests", () => {
test("renders standard story", async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiogroup--standard"
"http://localhost:6006/iframe.html?id=forms-radiogroup--standard",
);
const radioGroup = page.locator('[role="radiogroup"]');
@@ -32,7 +32,7 @@ test.describe("RadioGroup Storybook Tests", () => {
test("renders inverse story", async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiogroup--inverse"
"http://localhost:6006/iframe.html?id=forms-radiogroup--inverse",
);
const radioGroup = page.locator('[role="radiogroup"]');
@@ -47,7 +47,7 @@ test.describe("RadioGroup Storybook Tests", () => {
test("renders interactive story", async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiogroup--interactive"
"http://localhost:6006/iframe.html?id=forms-radiogroup--interactive",
);
const radioGroup = page.locator('[role="radiogroup"]');
@@ -69,14 +69,14 @@ test.describe("RadioGroup Storybook Tests", () => {
// All radio buttons should have inverse styling
for (let i = 0; i < (await radioButtons.count()); i++) {
await expect(radioButtons.nth(i)).toHaveClass(
/outline-\[var\(--color-border-inverse-primary\)\]/
/outline-\[var\(--color-border-inverse-primary\)\]/,
);
}
await page.selectOption('[data-testid="mode-control"]', "standard");
for (let i = 0; i < (await radioButtons.count()); i++) {
await expect(radioButtons.nth(i)).toHaveClass(
/outline-\[var\(--color-border-default-tertiary\)\]/
/outline-\[var\(--color-border-default-tertiary\)\]/,
);
}
});
@@ -180,7 +180,7 @@ test.describe("RadioGroup Storybook Tests", () => {
// All should have the same name
const names = await hiddenInputs.evaluateAll((inputs) =>
inputs.map((input) => input.getAttribute("name"))
inputs.map((input) => input.getAttribute("name")),
);
expect(names.every((name) => name === names[0])).toBe(true);
});
@@ -193,7 +193,7 @@ test.describe("RadioGroup Storybook Tests", () => {
await expect(firstDot).toHaveClass(
/w-\[16px\]/,
/h-\[16px\]/,
/rounded-full/
/rounded-full/,
);
// Click second option
@@ -204,13 +204,13 @@ test.describe("RadioGroup Storybook Tests", () => {
await expect(secondDot).toHaveClass(
/w-\[16px\]/,
/h-\[16px\]/,
/rounded-full/
/rounded-full/,
);
});
test("handles interactive story state changes", async ({ page }) => {
await page.goto(
"http://localhost:6006/iframe.html?id=forms-radiogroup--interactive"
"http://localhost:6006/iframe.html?id=forms-radiogroup--interactive",
);
// Should show initial state
+8 -8
View File
@@ -38,7 +38,7 @@ describe("ContextMenu Component", () => {
"border",
"rounded-[var(--measures-radius-medium)]",
"shadow-lg",
"p-[4px]"
"p-[4px]",
);
});
@@ -55,7 +55,7 @@ describe("ContextMenu Component", () => {
const { container } = render(
<ContextMenu {...defaultProps}>
<ContextMenuItem onClick={vi.fn()}>Menu Item</ContextMenuItem>
</ContextMenu>
</ContextMenu>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -93,7 +93,7 @@ describe("ContextMenuItem Component", () => {
const item = screen.getByRole("menuitem");
expect(item).toHaveClass(
"bg-[var(--color-surface-default-secondary)]",
"rounded-[var(--measures-radius-small)]"
"rounded-[var(--measures-radius-small)]",
);
});
@@ -163,7 +163,7 @@ describe("ContextMenuItem Component", () => {
const item = screen.getByRole("menuitem");
expect(item).toHaveClass(
"hover:!bg-[var(--color-surface-default-secondary)]"
"hover:!bg-[var(--color-surface-default-secondary)]",
);
});
});
@@ -173,7 +173,7 @@ describe("ContextMenuItem Component", () => {
const { container } = render(
<ContextMenu>
<ContextMenuItem {...defaultProps} />
</ContextMenu>
</ContextMenu>,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
@@ -193,7 +193,7 @@ describe("ContextMenuItem Component", () => {
const item = screen.getByRole("menuitem");
expect(item).toHaveClass(
"text-[var(--color-content-default-brand-primary)]"
"text-[var(--color-content-default-brand-primary)]",
);
});
@@ -240,7 +240,7 @@ describe("ContextMenuSection Component", () => {
const title = screen.getByText("Section Title");
expect(title).toHaveClass(
"text-[var(--color-content-default-primary)]",
"font-medium"
"font-medium",
);
});
});
@@ -270,7 +270,7 @@ describe("ContextMenuDivider Component", () => {
expect(divider).toHaveClass(
"border-t",
"border-[var(--color-border-default-tertiary)]",
"my-1"
"my-1",
);
});
});
+1 -1
View File
@@ -229,7 +229,7 @@ describe("Input Component", () => {
expect(label).toHaveClass("text-[12px]");
expect(label).toHaveClass("leading-[14px]");
expect(label).toHaveClass("font-medium");
expect(label).toHaveStyle("color: var(--color-content-default-secondary)");
expect(label).toHaveClass("text-[var(--color-content-default-secondary)]");
});
test("applies correct input text styling for different sizes", () => {
+23 -11
View File
@@ -31,7 +31,11 @@ describe("RadioButton", () => {
const handleChange = vi.fn();
render(
<RadioButton checked={false} onChange={handleChange} label="Test Radio" />
<RadioButton
checked={false}
onChange={handleChange}
label="Test Radio"
/>,
);
const radioButton = screen.getByRole("radio");
@@ -53,7 +57,7 @@ describe("RadioButton", () => {
value="test-value"
onChange={handleChange}
label="Test Radio"
/>
/>,
);
const radioButton = screen.getByRole("radio");
@@ -70,7 +74,7 @@ describe("RadioButton", () => {
const handleChange = vi.fn();
render(
<RadioButton checked={true} onChange={handleChange} label="Test Radio" />
<RadioButton checked={true} onChange={handleChange} label="Test Radio" />,
);
const radioButton = screen.getByRole("radio");
@@ -85,7 +89,11 @@ describe("RadioButton", () => {
const handleChange = vi.fn();
render(
<RadioButton checked={false} onChange={handleChange} label="Test Radio" />
<RadioButton
checked={false}
onChange={handleChange}
label="Test Radio"
/>,
);
const radioButton = screen.getByRole("radio");
@@ -103,7 +111,11 @@ describe("RadioButton", () => {
const handleChange = vi.fn();
render(
<RadioButton checked={false} onChange={handleChange} label="Test Radio" />
<RadioButton
checked={false}
onChange={handleChange}
label="Test Radio"
/>,
);
const radioButton = screen.getByRole("radio");
@@ -121,7 +133,7 @@ describe("RadioButton", () => {
const radioButton = screen.getByRole("radio");
expect(radioButton).toHaveClass(
"outline-[var(--color-border-default-tertiary)]"
"outline-[var(--color-border-default-tertiary)]",
);
});
@@ -130,7 +142,7 @@ describe("RadioButton", () => {
const radioButton = screen.getByRole("radio");
expect(radioButton).toHaveClass(
"outline-[var(--color-border-inverse-primary)]"
"outline-[var(--color-border-inverse-primary)]",
);
});
@@ -155,7 +167,7 @@ describe("RadioButton", () => {
value="test-value"
checked={true}
label="Test Radio"
/>
/>,
);
const hiddenInput = screen.getByDisplayValue("test-value");
@@ -209,7 +221,7 @@ describe("RadioButton", () => {
it("shows dot indicator when checked", () => {
render(
<RadioButton checked={true} mode="standard" label="Checked Radio" />
<RadioButton checked={true} mode="standard" label="Checked Radio" />,
);
const dot = screen.getByRole("radio").querySelector("div");
@@ -218,7 +230,7 @@ describe("RadioButton", () => {
it("hides dot indicator when unchecked", () => {
render(
<RadioButton checked={false} mode="standard" label="Unchecked Radio" />
<RadioButton checked={false} mode="standard" label="Unchecked Radio" />,
);
const dot = screen.getByRole("radio").querySelector("div");
@@ -230,7 +242,7 @@ describe("RadioButton", () => {
expect(
backgroundColor === "transparent" ||
backgroundColor === "rgba(0, 0, 0, 0)" ||
backgroundColor === ""
backgroundColor === "",
).toBe(true);
});
});
+9 -9
View File
@@ -47,7 +47,7 @@ describe("RadioGroup", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const option2 = screen.getByText("Option 2").closest("label");
@@ -65,7 +65,7 @@ describe("RadioGroup", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
// Click option 3
@@ -84,7 +84,7 @@ describe("RadioGroup", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -103,7 +103,7 @@ describe("RadioGroup", () => {
options={defaultOptions}
value="option1"
onChange={handleChange}
/>
/>,
);
const radioButtons = screen.getAllByRole("radio");
@@ -119,7 +119,7 @@ describe("RadioGroup", () => {
const radioButtons = screen.getAllByRole("radio");
radioButtons.forEach((button) => {
expect(button).toHaveClass(
"outline-[var(--color-border-default-tertiary)]"
"outline-[var(--color-border-default-tertiary)]",
);
});
});
@@ -130,7 +130,7 @@ describe("RadioGroup", () => {
const radioButtons = screen.getAllByRole("radio");
radioButtons.forEach((button) => {
expect(button).toHaveClass(
"outline-[var(--color-border-inverse-primary)]"
"outline-[var(--color-border-inverse-primary)]",
);
});
});
@@ -174,7 +174,7 @@ describe("RadioGroup", () => {
it("passes aria-label to radiogroup", () => {
render(
<RadioGroup options={defaultOptions} aria-label="Test Radio Group" />
<RadioGroup options={defaultOptions} aria-label="Test Radio Group" />,
);
const radioGroup = screen.getByRole("radiogroup");
@@ -206,7 +206,7 @@ describe("RadioGroup", () => {
it("maintains selection state correctly", () => {
const { rerender } = render(
<RadioGroup options={defaultOptions} value="option1" />
<RadioGroup options={defaultOptions} value="option1" />,
);
let radioButtons = screen.getAllByRole("radio");
@@ -228,7 +228,7 @@ describe("RadioGroup", () => {
options={defaultOptions}
value="option2"
onChange={handleChange}
/>
/>,
);
const option2 = screen.getByText("Option 2").closest("label");
+11 -8
View File
@@ -28,7 +28,10 @@ describe("Select Component", () => {
it("renders without label when not provided", () => {
render(
<Select placeholder="Select an option" options={defaultProps.options} />
<Select
placeholder="Select an option"
options={defaultProps.options}
/>,
);
expect(screen.queryByText("Test Select")).not.toBeInTheDocument();
@@ -74,7 +77,7 @@ describe("Select Component", () => {
it("applies correct height for small horizontal label", () => {
render(
<Select {...defaultProps} size="small" labelVariant="horizontal" />
<Select {...defaultProps} size="small" labelVariant="horizontal" />,
);
const selectButton = screen.getByRole("button");
@@ -95,7 +98,7 @@ describe("Select Component", () => {
const selectButton = screen.getByRole("button");
expect(selectButton).toHaveClass(
"border-[var(--color-border-default-tertiary)]"
"border-[var(--color-border-default-tertiary)]",
);
});
@@ -104,7 +107,7 @@ describe("Select Component", () => {
const selectButton = screen.getByRole("button");
expect(selectButton).toHaveClass(
"shadow-[0_0_0_2px_var(--color-border-default-tertiary)]"
"shadow-[0_0_0_2px_var(--color-border-default-tertiary)]",
);
});
@@ -113,7 +116,7 @@ describe("Select Component", () => {
const selectButton = screen.getByRole("button");
expect(selectButton).toHaveClass(
"border-[var(--color-border-default-utility-info)]"
"border-[var(--color-border-default-utility-info)]",
);
expect(selectButton).toHaveClass("shadow-[0_0_5px_3px_#3281F8]");
});
@@ -123,7 +126,7 @@ describe("Select Component", () => {
const selectButton = screen.getByRole("button");
expect(selectButton).toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
});
@@ -285,7 +288,7 @@ describe("Select Component", () => {
<div>
<Select {...defaultProps} />
<div data-testid="outside">Outside element</div>
</div>
</div>,
);
const selectButton = screen.getByRole("button");
@@ -381,7 +384,7 @@ describe("Select Component", () => {
expect(selectButton).toHaveFocus();
expect(selectButton).toHaveClass(
"focus-visible:border-[var(--color-border-default-utility-info)]"
"focus-visible:border-[var(--color-border-default-utility-info)]",
);
});
+3 -3
View File
@@ -19,7 +19,7 @@ describe("Switch Component", () => {
onChange={handleChange}
label="Test Switch"
state="focus"
/>
/>,
);
const switchButton = screen.getByRole("switch");
@@ -140,7 +140,7 @@ describe("Switch Component", () => {
"transition-all",
"duration-200",
"focus:outline-none",
"focus-visible:shadow-[0_0_5px_3px_#3281F8]"
"focus-visible:shadow-[0_0_5px_3px_#3281F8]",
);
});
@@ -178,7 +178,7 @@ describe("Switch Component", () => {
"font-normal",
"text-[14px]",
"leading-[20px]",
"text-[var(--color-content-default-primary)]"
"text-[var(--color-content-default-primary)]",
);
});
});
+6 -6
View File
@@ -63,7 +63,7 @@ describe("TextArea", () => {
render(<TextArea error />);
const textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"border-[var(--color-border-default-utility-negative)]"
"border-[var(--color-border-default-utility-negative)]",
);
});
@@ -71,20 +71,20 @@ describe("TextArea", () => {
const { rerender } = render(<TextArea state="active" />);
let textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"border-[var(--color-border-default-tertiary)]"
"border-[var(--color-border-default-tertiary)]",
);
rerender(<TextArea state="hover" />);
textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"shadow-[0_0_0_2px_var(--color-border-default-tertiary)]"
"shadow-[0_0_0_2px_var(--color-border-default-tertiary)]",
);
rerender(<TextArea state="focus" />);
textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass(
"border-[var(--color-border-default-utility-info)]",
"shadow-[0_0_5px_3px_#3281F8]"
"shadow-[0_0_5px_3px_#3281F8]",
);
});
@@ -151,7 +151,7 @@ describe("TextArea", () => {
size="small"
labelVariant="horizontal"
label="Small Horizontal"
/>
/>,
);
const textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass("h-[60px]");
@@ -163,7 +163,7 @@ describe("TextArea", () => {
size="medium"
labelVariant="horizontal"
label="Medium Horizontal"
/>
/>,
);
const textarea = screen.getByRole("textbox");
expect(textarea).toHaveClass("h-[110px]");
+5 -5
View File
@@ -21,7 +21,7 @@ describe("Toggle Component", () => {
checked={true}
disabled={true}
className="custom-class"
/>
/>,
);
const toggle = screen.getByRole("switch");
@@ -82,7 +82,7 @@ describe("Toggle Component", () => {
showText={true}
icon="I"
text="Toggle"
/>
/>,
);
const toggle = screen.getByRole("switch");
@@ -103,7 +103,7 @@ describe("Toggle Component", () => {
test("does not call onChange when disabled", () => {
const handleChange = vi.fn();
render(
<Toggle label="Test Toggle" disabled={true} onChange={handleChange} />
<Toggle label="Test Toggle" disabled={true} onChange={handleChange} />,
);
const toggle = screen.getByRole("switch");
@@ -132,7 +132,7 @@ describe("Toggle Component", () => {
const toggle = screen.getByRole("switch");
expect(toggle).toHaveClass(
"hover:!bg-[var(--color-surface-default-secondary)]"
"hover:!bg-[var(--color-surface-default-secondary)]",
);
});
@@ -141,7 +141,7 @@ describe("Toggle Component", () => {
const toggle = screen.getByRole("switch");
expect(toggle).not.toHaveClass(
"hover:!bg-[var(--color-surface-default-secondary)]"
"hover:!bg-[var(--color-surface-default-secondary)]",
);
});
+16 -16
View File
@@ -15,7 +15,7 @@ describe("ToggleGroup Component", () => {
render(
<ToggleGroup position="middle" state="selected" showText={true}>
Custom Content
</ToggleGroup>
</ToggleGroup>,
);
const toggleGroup = screen.getByRole("button");
expect(toggleGroup).toBeInTheDocument();
@@ -24,12 +24,12 @@ describe("ToggleGroup Component", () => {
it("handles position prop correctly", () => {
const { rerender } = render(
<ToggleGroup position="left">Left</ToggleGroup>
<ToggleGroup position="left">Left</ToggleGroup>,
);
let toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"rounded-l-[var(--measures-radius-medium)]",
"rounded-r-none"
"rounded-r-none",
);
rerender(<ToggleGroup position="middle">Middle</ToggleGroup>);
@@ -40,17 +40,17 @@ describe("ToggleGroup Component", () => {
toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"rounded-r-[var(--measures-radius-medium)]",
"rounded-l-none"
"rounded-l-none",
);
});
it("handles state prop correctly", () => {
const { rerender } = render(
<ToggleGroup state="default">Default</ToggleGroup>
<ToggleGroup state="default">Default</ToggleGroup>,
);
let toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"bg-[var(--color-surface-default-primary)]"
"bg-[var(--color-surface-default-primary)]",
);
rerender(<ToggleGroup state="hover">Hover</ToggleGroup>);
@@ -61,20 +61,20 @@ describe("ToggleGroup Component", () => {
toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"bg-[var(--color-surface-default-primary)]",
"shadow-[0_0_5px_1px_#3281F8]"
"shadow-[0_0_5px_1px_#3281F8]",
);
rerender(<ToggleGroup state="selected">Selected</ToggleGroup>);
toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"bg-[var(--color-magenta-magenta100)]",
"shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]"
"shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]",
);
});
it("handles showText prop correctly", () => {
const { rerender } = render(
<ToggleGroup showText={true}>Visible Text</ToggleGroup>
<ToggleGroup showText={true}>Visible Text</ToggleGroup>,
);
let toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveTextContent("Visible Text");
@@ -131,11 +131,11 @@ describe("ToggleGroup Component", () => {
it("applies correct classes for different states", () => {
const { rerender } = render(
<ToggleGroup state="default">Default</ToggleGroup>
<ToggleGroup state="default">Default</ToggleGroup>,
);
let toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"bg-[var(--color-surface-default-primary)]"
"bg-[var(--color-surface-default-primary)]",
);
rerender(<ToggleGroup state="hover">Hover</ToggleGroup>);
@@ -150,18 +150,18 @@ describe("ToggleGroup Component", () => {
toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"bg-[var(--color-magenta-magenta100)]",
"shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]"
"shadow-[inset_0_0_0_1px_var(--color-border-default-secondary)]",
);
});
it("applies correct position classes", () => {
const { rerender } = render(
<ToggleGroup position="left">Left</ToggleGroup>
<ToggleGroup position="left">Left</ToggleGroup>,
);
let toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"rounded-l-[var(--measures-radius-medium)]",
"rounded-r-none"
"rounded-r-none",
);
rerender(<ToggleGroup position="middle">Middle</ToggleGroup>);
@@ -172,7 +172,7 @@ describe("ToggleGroup Component", () => {
toggleGroup = screen.getByRole("button");
expect(toggleGroup).toHaveClass(
"rounded-r-[var(--measures-radius-medium)]",
"rounded-l-none"
"rounded-l-none",
);
});
@@ -195,7 +195,7 @@ describe("ToggleGroup Component", () => {
"hover:bg-[var(--color-magenta-magenta100)]",
"flex",
"items-center",
"justify-center"
"justify-center",
);
});
+5 -5
View File
@@ -4,7 +4,7 @@ test.describe("Checkbox Visual Regression Tests", () => {
test("Standard mode - unchecked", async ({ page }) => {
await page.goto("/forms");
await expect(
page.locator('[data-testid="standard-unchecked"]')
page.locator('[data-testid="standard-unchecked"]'),
).toBeVisible();
await expect(page).toHaveScreenshot("checkbox-standard-unchecked.png");
});
@@ -12,7 +12,7 @@ test.describe("Checkbox Visual Regression Tests", () => {
test("Standard mode - checked", async ({ page }) => {
await page.goto("/forms");
await expect(
page.locator('[data-testid="standard-checked"]')
page.locator('[data-testid="standard-checked"]'),
).toBeVisible();
await expect(page).toHaveScreenshot("checkbox-standard-checked.png");
});
@@ -20,7 +20,7 @@ test.describe("Checkbox Visual Regression Tests", () => {
test("Inverse mode - unchecked", async ({ page }) => {
await page.goto("/forms");
await expect(
page.locator('[data-testid="inverse-unchecked"]')
page.locator('[data-testid="inverse-unchecked"]'),
).toBeVisible();
await expect(page).toHaveScreenshot("checkbox-inverse-unchecked.png");
});
@@ -62,7 +62,7 @@ test.describe("Checkbox Visual Regression Tests", () => {
test("Disabled state - standard", async ({ page }) => {
await page.goto("/forms");
await expect(
page.locator('[data-testid="standard-disabled"]')
page.locator('[data-testid="standard-disabled"]'),
).toBeVisible();
await expect(page).toHaveScreenshot("checkbox-standard-disabled.png");
});
@@ -70,7 +70,7 @@ test.describe("Checkbox Visual Regression Tests", () => {
test("Disabled state - inverse", async ({ page }) => {
await page.goto("/forms");
await expect(
page.locator('[data-testid="inverse-disabled"]')
page.locator('[data-testid="inverse-disabled"]'),
).toBeVisible();
await expect(page).toHaveScreenshot("checkbox-inverse-disabled.png");
});
+5 -1
View File
@@ -16,7 +16,11 @@ export default defineConfig({
"tests/unit/**/*.test.{js,jsx,ts,tsx}",
"tests/integration/**/*.test.{js,jsx,ts,tsx}",
"tests/accessibility/**/*.test.{js,jsx,ts,tsx}",
"tests/e2e/**/*.test.{js,jsx,ts,tsx}",
"tests/e2e/**/*.e2e.test.{js,jsx,ts,tsx}",
],
exclude: [
"tests/e2e/**/*.storybook.test.{js,jsx,ts,tsx}",
"tests/e2e/**/*.spec.{js,jsx,ts,tsx}",
],
css: true,
coverage: {