@octopusdeploy/design-system-components
Version:
The design systems component library.
547 lines (546 loc) • 23.1 kB
JavaScript
"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;
}