@octopusdeploy/design-system-components
Version:
The design systems component library.
349 lines (348 loc) • 19.7 kB
JavaScript
"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 RadioButtonNew_1 = require("../RadioButtonNew");
const RadioGroupNew_1 = require("../RadioGroupNew");
(0, vitest_1.describe)("RadioGroupNew", () => {
(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 ${(0, descriptionWithLinks_1.descriptionLink)("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)(RadioGroupNew_1.RadioGroupNew, { label: "Boolean Test", value: true, onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { value: true, label: "Yes", name: "boolean-test" }), (0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { 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)(RadioGroupNew_1.RadioGroupNew, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { value: "option1", label: "Option 1", name: "test", hasDefaultMarker: true }), (0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { 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)(RadioGroupNew_1.RadioGroupNew, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { value: "option1", label: "Option 1", name: "test", hasDefaultMarker: false }), (0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { 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)(RadioGroupNew_1.RadioGroupNew, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { value: "option1", label: "Option 1", name: "test" }), (0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { 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)(RadioGroupNew_1.RadioGroupNew, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { value: "option1", label: "Option 1", name: "test", description: "First option description" }), (0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { 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)(RadioGroupNew_1.RadioGroupNew, { label: "Test Label", value: "option1", onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { value: "option1", label: "Option 1", name: "test" }), (0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { 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)(RadioGroupNew_1.RadioGroupNew, { ...options, onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { value: "option1", label: "Option 1", name: "test" }), (0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { 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)(RadioGroupNew_1.RadioGroupNew, { ...options, onChange: onChange, children: [(0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { value: true, label: "Yes", name: "boolean-test" }), (0, jsx_runtime_1.jsx)(RadioButtonNew_1.RadioButtonNew, { 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;
}