UNPKG

@octopusdeploy/design-system-components

Version:
349 lines (348 loc) • 19.5 kB
"use strict"; 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 vitest_1 = require("vitest"); const vitest_axe_1 = require("vitest-axe"); const TestDesignSystemProvider_1 = require("../../../TestDesignSystemProvider"); const descriptionWithLinks_1 = require("../../utils/descriptionWithLinks"); const RadioButton_1 = require("../RadioButton"); const RadioGroup_1 = require("../RadioGroup"); (0, vitest_1.describe)("RadioGroup", () => { (0, vitest_1.describe)("basic functionality", () => { (0, vitest_1.it)("renders the group", () => { const radioGroup = renderRadioGroup({ label: "Test Label", value: "option1", }); radioGroup.assertIsInTheDocument(); }); (0, vitest_1.it)("renders the label", () => { const radioGroup = renderRadioGroup({ label: "Test Label", value: "option1", }); radioGroup.assertHasText("Test Label"); }); (0, vitest_1.it)("renders with string description", () => { const radioGroup = renderRadioGroup({ label: "Test Label", description: "This is a test description", value: "option1", }); radioGroup.assertHasText("This is a test description"); }); (0, vitest_1.it)("renders with rich description content", () => { const richDescription = (0, descriptionWithLinks_1.descriptionText) `This is a ${descriptionWithLinks_1.descriptionText.link("link", "/test")} description.`; const radioGroup = renderRadioGroup({ label: "Test Label", description: richDescription, value: "option1", }); // Check that the description container exists and contains the expected content const descriptionElement = react_1.screen.getByText((content, element) => { return element?.textContent === "This is a link description."; }); (0, vitest_1.expect)(descriptionElement).toBeInTheDocument(); // Verify the link is present radioGroup.assertHasLink("link"); }); (0, vitest_1.it)("renders radio button options", () => { const radioGroup = renderRadioGroup({ label: "Test Label", value: "option1", }); radioGroup.assertHasRadioButtons(["Option 1", "Option 2"]); }); }); (0, vitest_1.describe)("selection and interaction", () => { (0, vitest_1.it)("shows the correct selected value", () => { const radioGroup = renderRadioGroup({ label: "Test Label", value: "option2", }); radioGroup.assertRadioButtonSelected("Option 2"); radioGroup.assertRadioButtonNotSelected("Option 1"); }); (0, vitest_1.it)("calls onChange when radio button is clicked", async () => { const radioGroup = renderRadioGroup({ label: "Test Label", value: "option1", }); await radioGroup.clickRadioButton("Option 2"); radioGroup.assertOnChangeCalledWithValue("option2"); }); (0, vitest_1.it)("works with boolean values", async () => { const radioGroup = renderRadioGroupWithBooleans({ label: "Boolean Test", value: true, name: "boolean-test", }); await radioGroup.clickRadioButton("No"); radioGroup.assertOnChangeCalledWithValue(false); }); (0, vitest_1.it)("shows correct selected boolean value", () => { const radioGroup = renderRadioGroupWithBooleans({ label: "Boolean Test", value: false, name: "boolean-test", }); radioGroup.assertRadioButtonSelected("No"); radioGroup.assertRadioButtonNotSelected("Yes"); }); (0, vitest_1.it)("displays boolean values correctly", () => { const onChange = vitest_1.vi.fn(); (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(RadioGroup_1.RadioGroup, { label: "Boolean Test", value: true, onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: true, label: "Yes", name: "boolean-test" }), (0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: false, label: "No", name: "boolean-test" })] }) })); const yesInput = react_1.screen.getByLabelText("Yes"); const noInput = react_1.screen.getByLabelText("No"); // Radio buttons should only be checked/unchecked, not have string values (0, vitest_1.expect)(yesInput).toBeChecked(); (0, vitest_1.expect)(noInput).not.toBeChecked(); }); }); (0, vitest_1.describe)("required and optional markers", () => { (0, vitest_1.it)("shows optional marker when hasOptionalMarker is true", () => { renderRadioGroup({ label: "Test Label", hasOptionalMarker: true, value: "option1", }); // The optional marker is part of the legend text content const legendWithOptional = react_1.screen.getByText((content, element) => { return element?.textContent === "Test Label (optional)"; }); (0, vitest_1.expect)(legendWithOptional).toBeInTheDocument(); }); (0, vitest_1.it)("shows required marker when hasRequiredMarker is true", () => { renderRadioGroup({ label: "Test Label", hasRequiredMarker: true, value: "option1", }); // The required marker is part of the legend text content const legendWithRequired = react_1.screen.getByText((content, element) => { return element?.textContent === "Test Label (required)"; }); (0, vitest_1.expect)(legendWithRequired).toBeInTheDocument(); }); (0, vitest_1.it)("shows no markers when both markers are true", () => { renderRadioGroup({ label: "Test Label", hasOptionalMarker: true, hasRequiredMarker: true, value: "option1", }); // When both markers are true, neither should be shown - just the label const legendWithoutMarkers = react_1.screen.getByText((content, element) => { return element?.textContent === "Test Label"; }); (0, vitest_1.expect)(legendWithoutMarkers).toBeInTheDocument(); // Verify no marker text exists (0, vitest_1.expect)(react_1.screen.queryByText(/\(required\)/)).not.toBeInTheDocument(); (0, vitest_1.expect)(react_1.screen.queryByText(/\(optional\)/)).not.toBeInTheDocument(); }); }); (0, vitest_1.describe)("error handling", () => { (0, vitest_1.it)("displays error message", () => { const radioGroup = renderRadioGroup({ label: "Test Label", validationMessage: "This field is required", value: "option1", }); radioGroup.assertHasError("This field is required"); }); (0, vitest_1.it)("hides error message after user interaction", async () => { const radioGroup = renderRadioGroup({ label: "Test Label", validationMessage: "This field is required", value: "option1", }); radioGroup.assertHasError("This field is required"); await radioGroup.clickRadioButton("Option 2"); radioGroup.assertHasNoError(); }); }); (0, vitest_1.describe)("disabled state", () => { (0, vitest_1.it)("disables the entire group when disabled is true", () => { const radioGroup = renderRadioGroup({ label: "Test Label", disabled: true, value: "option1", }); radioGroup.assertIsDisabled(); }); (0, vitest_1.it)("prevents onChange when disabled", async () => { const radioGroup = renderRadioGroup({ label: "Test Label", disabled: true, value: "option1", }); await radioGroup.clickRadioButton("Option 2"); radioGroup.assertOnChangeNotCalled(); }); }); (0, vitest_1.describe)("hidden content", () => { (0, vitest_1.it)("hides label when hideLabel is true", () => { const radioGroup = renderRadioGroup({ label: "Test Label", hideLabel: true, value: "option1", }); radioGroup.assertLabelIsHidden("Test Label"); }); (0, vitest_1.it)("hides description when hideDescription is true", () => { const radioGroup = renderRadioGroup({ label: "Test Label", description: "Test description", hideDescription: true, value: "option1", }); radioGroup.assertDescriptionIsHidden("Test description"); }); }); (0, vitest_1.describe)("default markers", () => { (0, vitest_1.it)("shows default marker on radio button when hasDefaultMarker is true", () => { const onChange = vitest_1.vi.fn(); (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(RadioGroup_1.RadioGroup, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option1", label: "Option 1", name: "test", hasDefaultMarker: true }), (0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option2", label: "Option 2", name: "test" })] }) })); (0, vitest_1.expect)(react_1.screen.getByText("(Default)")).toBeInTheDocument(); }); (0, vitest_1.it)("does not show default marker when hasDefaultMarker is false", () => { const onChange = vitest_1.vi.fn(); (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(RadioGroup_1.RadioGroup, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option1", label: "Option 1", name: "test", hasDefaultMarker: false }), (0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option2", label: "Option 2", name: "test" })] }) })); (0, vitest_1.expect)(react_1.screen.queryByText("(Default)")).not.toBeInTheDocument(); }); }); (0, vitest_1.describe)("autoFocus", () => { (0, vitest_1.it)("focuses the radio button with autoFocus", () => { const onChange = vitest_1.vi.fn(); (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(RadioGroup_1.RadioGroup, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option1", label: "Option 1", name: "test" }), (0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option2", label: "Option 2", name: "test", autoFocus: true })] }) })); const option2 = testing_library_1.domQueries.getRadioButton("Option 2"); option2.assertHasFocus(); }); }); (0, vitest_1.describe)("accessibility", () => { (0, vitest_1.it)("is accessible", async () => { const { container } = renderRadioGroup({ label: "Test Label", value: "option1", }); const results = await (0, vitest_axe_1.axe)(container.container); (0, vitest_1.expect)(results).toHaveNoViolations(); }); (0, vitest_1.it)("is accessible with error", async () => { const { container } = renderRadioGroup({ label: "Test Label", validationMessage: "This field is required", value: "option1", }); 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 } = renderRadioGroup({ label: "Test Label", disabled: true, value: "option1", }); const results = await (0, vitest_axe_1.axe)(container.container); (0, vitest_1.expect)(results).toHaveNoViolations(); }); (0, vitest_1.it)("is accessible with descriptions on radio buttons", async () => { const onChange = vitest_1.vi.fn(); const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(RadioGroup_1.RadioGroup, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option1", label: "Option 1", name: "test", description: "First option description" }), (0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option2", label: "Option 2", name: "test", description: "Second option description" })] }) })); const results = await (0, vitest_axe_1.axe)(container); (0, vitest_1.expect)(results).toHaveNoViolations(); }); (0, vitest_1.it)("has proper radiogroup role", () => { const radioGroup = renderRadioGroup({ label: "Test Label", value: "option1", }); radioGroup.assertHasRadioGroupRole(); }); (0, vitest_1.it)("has proper label associations for individual radio buttons", () => { const onChange = vitest_1.vi.fn(); (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(RadioGroup_1.RadioGroup, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option1", label: "Option 1", name: "test" }), (0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option2", label: "Option 2", name: "test" })] }) })); const option1Input = react_1.screen.getByLabelText("Option 1"); const option2Input = react_1.screen.getByLabelText("Option 2"); (0, vitest_1.expect)(option1Input).toBeInTheDocument(); (0, vitest_1.expect)(option2Input).toBeInTheDocument(); }); }); }); function renderRadioGroup(options) { const onChange = vitest_1.vi.fn(); const result = (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(RadioGroup_1.RadioGroup, { ...options, onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option1", label: "Option 1", name: "test" }), (0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: "option2", label: "Option 2", name: "test" })] }) })); return getRadioGroupInteractions(result, options.label, onChange); } function renderRadioGroupWithBooleans(options) { const onChange = vitest_1.vi.fn(); const result = (0, react_1.render)((0, jsx_runtime_1.jsx)(TestDesignSystemProvider_1.TestDesignSystemProvider, { children: (0, jsx_runtime_1.jsxs)(RadioGroup_1.RadioGroup, { ...options, onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: true, label: "Yes", name: "boolean-test" }), (0, jsx_runtime_1.jsx)(RadioButton_1.RadioButton, { value: false, label: "No", name: "boolean-test" })] }) })); return getRadioGroupInteractions(result, options.label, onChange); } function getRadioGroupInteractions(result, label, onChange) { const radioGroup = testing_library_1.domQueries.getRadioButtonGroup(label); const interactions = { clickRadioButton: async (radioButtonLabel) => { const radioButton = testing_library_1.domQueries.getRadioButton(radioButtonLabel); await radioButton.click(); }, assertIsInTheDocument: () => { radioGroup.assertIsInTheDocument(); }, 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(); }, assertHasLink: (linkText) => { (0, vitest_1.expect)(react_1.screen.getByRole("link", { name: linkText })).toBeInTheDocument(); }, assertHasRadioButtons: (radioButtonLabels) => { radioButtonLabels.forEach((labelText) => { (0, vitest_1.expect)(react_1.screen.getByLabelText(labelText)).toBeInTheDocument(); }); }, assertRadioButtonSelected: (radioButtonLabel) => { const radioButton = testing_library_1.domQueries.getRadioButton(radioButtonLabel); radioButton.assertIsSelected(); }, assertRadioButtonNotSelected: (radioButtonLabel) => { const radioButton = testing_library_1.domQueries.getRadioButton(radioButtonLabel); radioButton.assertIsNotSelected(); }, assertOnChangeCalledWithValue: (value) => { (0, vitest_1.expect)(onChange).toHaveBeenCalledWith(value); }, assertOnChangeNotCalled: () => { (0, vitest_1.expect)(onChange).not.toHaveBeenCalled(); }, assertHasError: (errorText) => { (0, vitest_1.expect)(react_1.screen.getByText(errorText)).toBeInTheDocument(); }, assertHasNoError: () => { (0, vitest_1.expect)(react_1.screen.queryByLabelText("Error")).not.toBeInTheDocument(); }, assertIsDisabled: () => { const fieldset = react_1.screen.getByRole("radiogroup"); (0, vitest_1.expect)(fieldset).toBeDisabled(); }, assertLabelIsHidden: (labelText) => { const legend = react_1.screen.getByText(labelText); // Check that the clip property is set to hide the element (0, vitest_1.expect)(legend).toHaveStyle({ clip: vitest_1.expect.stringMatching(/rect\(0.*0.*0.*0\)/) }); }, assertDescriptionIsHidden: (descriptionText) => { const description = react_1.screen.getByText(descriptionText); // Check that the clip property is set to hide the element (0, vitest_1.expect)(description).toHaveStyle({ clip: vitest_1.expect.stringMatching(/rect\(0.*0.*0.*0\)/) }); }, assertHasRadioGroupRole: () => { (0, vitest_1.expect)(react_1.screen.getByRole("radiogroup")).toBeInTheDocument(); }, container: result, }; return interactions; }