UNPKG

@octopusdeploy/design-system-components

Version:
547 lines (546 loc) • 23.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const testing_library_1 = require("@octopusdeploy/testing-library"); const react_1 = require("@testing-library/react"); const react_2 = __importDefault(require("react")); const vitest_1 = require("vitest"); const vitest_axe_1 = require("vitest-axe"); const TestDesignSystemProvider_1 = require("../../../TestDesignSystemProvider"); const Checkbox_1 = require("../Checkbox"); const CheckboxGroup_1 = require("../CheckboxGroup"); (0, vitest_1.describe)("Checkbox", () => { (0, vitest_1.describe)("basic functionality", () => { (0, vitest_1.it)("renders the checkbox", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", }); checkbox.assertIsInTheDocument(); }); (0, vitest_1.it)("renders the label", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", }); checkbox.assertHasLabel("Test Label"); }); (0, vitest_1.it)("renders the description", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", description: "This is a test description", }); checkbox.assertHasText("This is a test description"); }); (0, vitest_1.it)("has correct input attributes", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", }); checkbox.assertHasName("test"); checkbox.assertHasValue("test-value"); }); (0, vitest_1.it)("calls onChange when clicked", async () => { const checkbox = renderCheckboxWithContext({ value: "test-value", label: "Test Label", name: "test", }, { value: ["other-value"], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); await checkbox.click(); checkbox.assertOnChangeCalledWithValue(["other-value", "test-value"]); }); (0, vitest_1.it)("calls onChange when unchecked", async () => { const checkbox = renderCheckboxWithContext({ value: "test-value", label: "Test Label", name: "test", }, { value: ["test-value", "other-value"], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); await checkbox.click(); checkbox.assertOnChangeCalledWithValue(["other-value"]); }); }); (0, vitest_1.describe)("checked state", () => { (0, vitest_1.it)("is selected when context value includes the checkbox value", () => { const checkbox = renderCheckboxWithContext({ value: "test-value", label: "Test Label", name: "test", }, { value: ["test-value"], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); checkbox.assertIsSelected(); }); (0, vitest_1.it)("is not selected when context value does not include the checkbox value", () => { const checkbox = renderCheckboxWithContext({ value: "test-value", label: "Test Label", name: "test", }, { value: ["other-value"], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); checkbox.assertIsNotSelected(); }); }); (0, vitest_1.describe)("disabled state", () => { (0, vitest_1.it)("is disabled when disabled prop is true", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", disabled: true, }); checkbox.assertIsDisabled(); }); (0, vitest_1.it)("is disabled when context disabled is true", () => { const checkbox = renderCheckboxWithContext({ value: "test-value", label: "Test Label", name: "test", }, { value: ["other-value"], onChange: vitest_1.vi.fn(), disabled: true, groupId: "test-group", }); checkbox.assertIsDisabled(); }); (0, vitest_1.it)("is disabled when both prop and context disabled are true", () => { const checkbox = renderCheckboxWithContext({ value: "test-value", label: "Test Label", name: "test", disabled: true, }, { value: ["other-value"], onChange: vitest_1.vi.fn(), disabled: true, groupId: "test-group", }); checkbox.assertIsDisabled(); }); }); (0, vitest_1.describe)("default marker", () => { (0, vitest_1.it)("shows default marker when hasDefaultMarker is true", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", hasDefaultMarker: true, }); checkbox.assertHasText("(Default)"); }); (0, vitest_1.it)("does not show default marker when hasDefaultMarker is false", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", hasDefaultMarker: false, }); checkbox.assertDoesNotHaveText("(Default)"); }); }); (0, vitest_1.describe)("indeterminate state", () => { (0, vitest_1.it)("shows indeterminate state when isIndeterminate is true", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", isIndeterminate: true, }); checkbox.assertIsIndeterminate(); }); (0, vitest_1.it)("does not show indeterminate state when isIndeterminate is false", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", isIndeterminate: false, }); checkbox.assertIsNotIndeterminate(); }); }); (0, vitest_1.describe)("boolean values", () => { (0, vitest_1.it)("works with boolean values", () => { const checkbox = renderCheckboxWithContext({ value: true, label: "Yes", name: "boolean-test", }, { value: [true], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); checkbox.assertIsSelected(); checkbox.assertHasValue("true"); }); (0, vitest_1.it)("calls onChange with boolean value", async () => { const checkbox = renderCheckboxWithContext({ value: false, label: "No", name: "boolean-test", }, { value: [true], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); await checkbox.click(); checkbox.assertOnChangeCalledWithValue([true, false]); }); }); (0, vitest_1.describe)("string values", () => { (0, vitest_1.it)("works with string values", () => { const checkbox = renderCheckboxWithContext({ value: "option1", label: "Option 1", name: "string-test", }, { value: ["option1"], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); checkbox.assertIsSelected(); checkbox.assertHasValue("option1"); }); (0, vitest_1.it)("calls onChange with string value", async () => { const checkbox = renderCheckboxWithContext({ value: "option2", label: "Option 2", name: "string-test", }, { value: ["option1"], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); await checkbox.click(); checkbox.assertOnChangeCalledWithValue(["option1", "option2"]); }); (0, vitest_1.it)("works with singular checkbox and string value", async () => { const onChange = vitest_1.vi.fn(); const uncheckedCheckbox = renderCheckbox({ value: "", label: "Enable Feature (Unchecked)", name: "feature-toggle-unchecked", onChange, }); uncheckedCheckbox.assertIsNotSelected(); await uncheckedCheckbox.click(); (0, vitest_1.expect)(onChange).toHaveBeenCalledWith("enabled"); onChange.mockClear(); const checkedCheckbox = renderCheckbox({ value: "enabled", label: "Enable Feature (Checked)", name: "feature-toggle-checked", onChange, }); checkedCheckbox.assertIsSelected(); await checkedCheckbox.click(); (0, vitest_1.expect)(onChange).toHaveBeenCalledWith(""); }); }); (0, vitest_1.describe)("within CheckboxGroupNew context", () => { (0, vitest_1.it)("works properly within CheckboxGroupNew", async () => { const onChange = vitest_1.vi.fn(); let currentValue = ["option1"]; const TestComponent = () => { const [value, setValue] = react_2.default.useState(["option1"]); const handleChange = (newValue) => { const arrayValue = Array.isArray(newValue) ? newValue : [newValue]; currentValue = arrayValue; setValue(arrayValue); onChange(arrayValue); }; return ((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(CheckboxGroup_1.CheckboxGroup, { label: "Test Group", value: value, onChange: handleChange, children: [(0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { value: "option1", label: "Option 1", name: "test-group" }), (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { value: "option2", label: "Option 2", name: "test-group" })] }) })); }; (0, react_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {})); const option1 = testing_library_1.domQueries.getCheckbox("Option 1"); const option2 = testing_library_1.domQueries.getCheckbox("Option 2"); (0, vitest_1.expect)(option1.isChecked).toBe(true); (0, vitest_1.expect)(option2.isChecked).toBe(false); await option2.click(); (0, vitest_1.expect)(onChange).toHaveBeenCalledWith(["option1", "option2"]); await option1.click(); (0, vitest_1.expect)(onChange).toHaveBeenCalledWith(["option2"]); }); }); (0, vitest_1.describe)("checkbox without label", () => { (0, vitest_1.it)("renders the checkbox with aria-label only", () => { const checkbox = renderCheckbox({ value: "test-value", ariaLabel: "Select row", name: "test", }); checkbox.assertIsInTheDocument(); checkbox.assertHasAriaLabel("Select row"); checkbox.assertHasNoVisibleLabel(); }); (0, vitest_1.it)("has correct input attributes", () => { const checkbox = renderCheckbox({ value: "test-value", ariaLabel: "Select row", name: "test-no-label", }); checkbox.assertHasName("test-no-label"); checkbox.assertHasValue("test-value"); }); (0, vitest_1.it)("calls onChange when clicked (standalone)", async () => { const onChange = vitest_1.vi.fn(); const checkbox = renderCheckbox({ value: false, ariaLabel: "Toggle option", name: "standalone-no-label", onChange, }); await checkbox.click(); (0, vitest_1.expect)(onChange).toHaveBeenCalledWith(true); }); (0, vitest_1.it)("works with context (checked state and onChange)", async () => { const checkbox = renderCheckboxWithContext({ value: "test-value", ariaLabel: "Select row", name: "test", }, { value: ["test-value"], onChange: vitest_1.vi.fn(), disabled: false, groupId: "test-group", }); checkbox.assertIsSelected(); await checkbox.click(); checkbox.assertOnChangeCalledWithValue([]); }); (0, vitest_1.it)("is disabled when disabled prop is true", () => { const checkbox = renderCheckbox({ value: "test-value", ariaLabel: "Select row", name: "test", disabled: true, }); checkbox.assertIsDisabled(); }); (0, vitest_1.it)("shows indeterminate state when isIndeterminate is true", () => { const checkbox = renderCheckbox({ value: "test-value", ariaLabel: "Select row", name: "test", isIndeterminate: true, }); checkbox.assertIsIndeterminate(); }); (0, vitest_1.it)("is accessible", async () => { const { container } = renderCheckbox({ value: "test-value", ariaLabel: "Select row", name: "test", }); const results = await (0, vitest_axe_1.axe)(container.container); (0, vitest_1.expect)(results).toHaveNoViolations(); }); (0, vitest_1.it)("has proper aria-checked attribute", () => { const checkbox = renderCheckbox({ value: "test-value", ariaLabel: "Select row", name: "test", }); checkbox.assertHasProperAriaChecked(); }); (0, vitest_1.it)("is findable by accessible name (getByLabelText)", () => { const checkbox = renderCheckbox({ value: "test-value", ariaLabel: "Select row", name: "test", }); checkbox.assertHasLabel("Select row"); }); }); (0, vitest_1.describe)("accessibility", () => { (0, vitest_1.it)("is accessible", async () => { const { container } = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", }); const results = await (0, vitest_axe_1.axe)(container.container); (0, vitest_1.expect)(results).toHaveNoViolations(); }); (0, vitest_1.it)("is accessible when disabled", async () => { const { container } = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", disabled: true, }); const results = await (0, vitest_axe_1.axe)(container.container); (0, vitest_1.expect)(results).toHaveNoViolations(); }); (0, vitest_1.it)("is accessible when indeterminate", async () => { const { container } = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", isIndeterminate: true, }); const results = await (0, vitest_axe_1.axe)(container.container); (0, vitest_1.expect)(results).toHaveNoViolations(); }); (0, vitest_1.it)("has proper label association", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", }); checkbox.assertHasLabel("Test Label"); checkbox.assertHasProperLabelAssociation(); }); (0, vitest_1.it)("has proper aria-checked attribute", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", }); checkbox.assertHasProperAriaChecked(); }); (0, vitest_1.it)("has proper aria-checked attribute when indeterminate", () => { const checkbox = renderCheckbox({ value: "test-value", label: "Test Label", name: "test", isIndeterminate: true, }); checkbox.assertHasProperAriaChecked("mixed"); }); }); }); function getAccessibleName(options) { if ("label" in options && options.label !== undefined) return options.label; if ("ariaLabel" in options) return options.ariaLabel; return ""; } function getVisibleLabel(options) { if ("label" in options && options.label !== undefined) return options.label; return undefined; } function renderCheckbox(options) { const result = (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { ...options }) })); return getCheckboxInteractions(result, options, undefined); } function renderCheckboxWithContext(options, contextValue) { const onChange = contextValue.onChange || vitest_1.vi.fn(); const fullContextValue = { ...contextValue, onChange }; const result = (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsx)(CheckboxGroup_1.CheckboxGroupContext.Provider, { value: fullContextValue, children: (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { ...options }) }) })); return getCheckboxInteractions(result, options, onChange); } function getCheckboxInteractions(result, options, onChange) { const accessibleName = getAccessibleName(options); const visibleLabel = getVisibleLabel(options); const checkbox = testing_library_1.domQueries.getCheckbox(accessibleName); const interactions = { click: async () => { await checkbox.click(); }, assertIsInTheDocument: () => { checkbox.assertIsInTheDocument(); }, assertHasLabel: (expectedLabel) => { (0, vitest_1.expect)(react_1.screen.getByLabelText(expectedLabel)).toBeInTheDocument(); }, assertHasName: (expectedName) => { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const input = react_1.screen.getByRole("checkbox"); (0, vitest_1.expect)(input).toHaveAttribute("name", expectedName); }, assertHasValue: (expectedValue) => { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const input = react_1.screen.getByRole("checkbox"); (0, vitest_1.expect)(input.value).toBe(expectedValue); }, assertIsSelected: () => { (0, vitest_1.expect)(checkbox.isChecked).toBe(true); }, assertIsNotSelected: () => { (0, vitest_1.expect)(checkbox.isChecked).toBe(false); }, assertIsDisabled: () => { checkbox.assertIsDisabled(); }, assertIsEnabled: () => { checkbox.assertIsEnabled(); }, assertIsIndeterminate: () => { const input = react_1.screen.getByRole("checkbox"); // eslint-disable-next-line jest-dom/prefer-checked (0, vitest_1.expect)(input).toHaveAttribute("aria-checked", "mixed"); }, assertIsNotIndeterminate: () => { const input = react_1.screen.getByRole("checkbox"); // eslint-disable-next-line jest-dom/prefer-checked (0, vitest_1.expect)(input).not.toHaveAttribute("aria-checked", "mixed"); }, assertOnChangeCalledWithValue: (expectedValue) => { (0, vitest_1.expect)(onChange).toHaveBeenCalledWith(expectedValue); }, assertHasText: (text) => { (0, vitest_1.expect)(react_1.screen.getByText(text)).toBeInTheDocument(); }, assertDoesNotHaveText: (text) => { (0, vitest_1.expect)(react_1.screen.queryByText(text)).not.toBeInTheDocument(); }, assertHasAriaLabel: (expectedAriaLabel) => { const checkbox = testing_library_1.domQueries.getCheckbox(expectedAriaLabel); (0, vitest_1.expect)(checkbox.innerElement).toHaveAttribute("aria-label", expectedAriaLabel); }, assertHasNoVisibleLabel: () => { // When using ariaLabel only, the accessible name is not rendered as visible text (0, vitest_1.expect)(react_1.screen.queryByText(accessibleName)).not.toBeInTheDocument(); }, assertHasProperLabelAssociation: () => { if (visibleLabel === undefined) return; const input = react_1.screen.getByRole("checkbox"); const labelText = react_1.screen.getByText(visibleLabel); (0, vitest_1.expect)(labelText).toHaveAttribute("for", input.id); (0, vitest_1.expect)(input.id).toMatch(/^checkbox-.*$/); }, assertHasProperAriaChecked: (expectedValue) => { const input = react_1.screen.getByRole("checkbox"); if (expectedValue) { (0, vitest_1.expect)(input).toHaveAttribute("aria-checked", expectedValue); } else { (0, vitest_1.expect)(input).toHaveAttribute("aria-checked"); } }, container: result, }; return interactions; }