@octopusdeploy/design-system-components
Version:
The design systems component library.
523 lines (522 loc) • 30.4 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 react_2 = require("react");
const vitest_1 = require("vitest");
const Button_1 = require("../../../Button");
const TextField_1 = require("../TextField");
(0, vitest_1.describe)("<TextField />", () => {
(0, vitest_1.test)("renders with correct label", () => {
const input = renderTextInput({ label: "Test Label" });
input.shouldHaveLabel("Test Label");
input.shouldBeInDocument();
});
(0, vitest_1.test)("renders with placeholder text", () => {
const placeholder = "Enter your text here";
const input = renderTextInput({ label: "Test Label", placeholder });
input.shouldHavePlaceholder(placeholder);
});
(0, vitest_1.test)("renders with initial value", () => {
const value = "Initial value";
const input = renderTextInput({ label: "Test Label", value });
input.shouldHaveValue(value);
});
(0, vitest_1.test)("renders with description", () => {
const description = "This is a helpful description";
const input = renderTextInput({ label: "Test Label", description });
input.shouldHaveDescription(description);
});
(0, vitest_1.describe)("validationState", () => {
(0, vitest_1.test)("defaults to error state when validationMessage is provided without validationState", () => {
const validationMessage = "This field is required";
const input = renderTextInput({ label: "Test Label", validationMessage });
input.shouldHaveValidationMessage(validationMessage);
input.shouldShowErrorValidationState();
});
(0, vitest_1.test)("renders error state when validationState=error and a validationMessage is provided", () => {
const validationMessage = "This field is required";
const input = renderTextInput({ label: "Test Label", validationMessage, validationState: "error" });
input.shouldHaveValidationMessage(validationMessage);
input.shouldShowErrorValidationState();
});
(0, vitest_1.test)("renders success state when validationState=success and a validationMessage is provided", () => {
const validationMessage = "Looks good";
const input = renderTextInput({ label: "Test Label", validationMessage, validationState: "success" });
input.shouldHaveValidationMessage(validationMessage);
input.shouldShowSuccessValidationState();
});
(0, vitest_1.test)("does not render any validation state when validationState=error but no validationMessage is provided", () => {
const input = renderTextInput({ label: "Test Label", validationState: "error" });
input.shouldNotShowAnyValidationState();
});
(0, vitest_1.test)("does not render any validation state when validationState=success but no validationMessage is provided", () => {
const input = renderTextInput({ label: "Test Label", validationState: "success" });
input.shouldNotShowAnyValidationState();
});
});
(0, vitest_1.test)("uses provided name attribute", () => {
const name = "custom-name";
const input = renderTextInput({ label: "Test Label", name });
input.shouldHaveName(name);
});
(0, vitest_1.test)("has autofocus when autoFocus is true", () => {
const input = renderTextInput({ label: "Test Label", autoFocus: true });
input.shouldHaveFocus();
});
(0, vitest_1.test)("handles empty onChange gracefully", () => {
(0, react_1.render)((0, jsx_runtime_1.jsx)(TextField_1.TextField, { label: "Test Label", onChange: vitest_1.vi.fn() }));
testing_library_1.domQueries.getTextInput("Test Label").assertIsInTheDocument();
});
(0, vitest_1.test)("calls onChange when user types", async () => {
const input = renderTextInput({ label: "Test Label" });
await input.type("hello");
input.shouldHaveCalledOnChangeWith("hello");
});
(0, vitest_1.test)("supports different input types", () => {
const emailInput = renderTextInput({ label: "Email", type: "email" });
const passwordInput = renderTextInput({ label: "Password", type: "password" });
const numberInput = renderTextInput({ label: "Number", type: "number" });
emailInput.shouldHaveType("email");
passwordInput.shouldHaveType("password");
numberInput.shouldHaveType("number");
});
(0, vitest_1.describe)("disabled and readonly properties", () => {
(0, vitest_1.test)("renders as disabled when disabled prop is true", () => {
const input = renderTextInput({ label: "Test Label", disabled: true });
input.shouldBeDisabled();
});
(0, vitest_1.test)("disabled input cannot be typed in", async () => {
const input = renderTextInput({ label: "Test Label", disabled: true });
await input.attemptToType("should not work");
input.shouldNotHaveCalledOnChange();
});
(0, vitest_1.test)("renders as readonly when readOnly prop is true", () => {
const input = renderTextInput({ label: "Test Label", readOnly: true });
input.shouldBeReadOnly();
});
(0, vitest_1.test)("readonly input cannot be typed in", async () => {
const input = renderTextInput({ label: "Test Label", readOnly: true });
await input.attemptToType("should not work");
input.shouldNotHaveCalledOnChange();
});
});
(0, vitest_1.describe)("default, required and optional marker properties", () => {
(0, vitest_1.test)("renders with required marker when hasRequiredMarker is true", () => {
const input = renderTextInput({ label: "Test Label", hasRequiredMarker: true });
input.shouldHaveRequiredMarker();
});
(0, vitest_1.test)("renders with optional marker when hasOptionalMarker is true", () => {
const input = renderTextInput({ label: "Test Label", hasOptionalMarker: true });
input.shouldHaveOptionalMarker();
});
(0, vitest_1.test)("renders with default marker when hasDefaultMarker is true", () => {
const input = renderTextInput({ label: "Test Label", hasDefaultMarker: true });
input.shouldHaveDefaultMarker();
});
});
(0, vitest_1.describe)("accessibility attributes", () => {
(0, vitest_1.test)("has correct accessibility attributes when error is present", () => {
const validationMessage = "Invalid input";
const input = renderTextInput({ label: "Test Label", validationMessage });
input.shouldHaveAriaInvalid(true);
input.shouldHaveAriaDescribedByError();
});
(0, vitest_1.test)("has correct accessibility attributes when description is present", () => {
const description = "Help text";
const input = renderTextInput({ label: "Test Label", description });
input.shouldHaveAriaDescribedByDescription();
});
(0, vitest_1.test)("has correct accessibility attributes when both description and error are present", () => {
const description = "Help text";
const validationMessage = "Error message";
const input = renderTextInput({ label: "Test Label", description, validationMessage });
input.shouldHaveAriaDescribedByBoth();
input.shouldHaveAriaInvalid(true);
});
});
(0, vitest_1.describe)("local validation", () => {
(0, vitest_1.test)("shows a required error once the field is cleared", async () => {
const input = renderTextInput({ label: "Test Label", required: true, value: "hello" });
await input.clear();
input.shouldHaveError("This field is required.");
});
(0, vitest_1.test)("does not show a required error while the field has a value", async () => {
const input = renderTextInput({ label: "Test Label", required: true });
await input.type("hello");
input.shouldNotHaveError("This field is required.");
});
(0, vitest_1.test)("clears the required error once a value is entered", async () => {
const input = renderTextInput({ label: "Test Label", required: true, value: "hello" });
await input.clear();
input.shouldHaveError("This field is required.");
await input.type("hello again");
input.shouldNotHaveError("This field is required.");
});
(0, vitest_1.test)("does not show a required error for a required number field with value 0", async () => {
const input = renderTextInput({ label: "Test Label", type: "number", required: true, value: "5" });
await input.type("0");
input.shouldNotHaveError("This field is required.");
});
(0, vitest_1.test)("shows a minimum value error when the number entered is below min", async () => {
const input = renderTextInput({ label: "Test Label", type: "number", min: 10 });
await input.type("5");
input.shouldHaveError("This field's minimum allowed value is 10.");
});
(0, vitest_1.test)("shows a maximum value error when the number entered is above max", async () => {
const input = renderTextInput({ label: "Test Label", type: "number", max: 10 });
await input.type("15");
input.shouldHaveError("This field's maximum allowed value is 10.");
});
(0, vitest_1.test)("does not show a min/max error when the number entered is within range", async () => {
const input = renderTextInput({ label: "Test Label", type: "number", min: 1, max: 10 });
await input.type("5");
input.shouldNotHaveError("This field's minimum allowed value is 1.");
input.shouldNotHaveError("This field's maximum allowed value is 10.");
});
(0, vitest_1.test)("min/max validation does not apply when type is not number", async () => {
const input = renderTextInput({ label: "Test Label", min: 10, max: 20 });
await input.type("999");
input.shouldNotHaveError("minimum allowed value");
input.shouldNotHaveError("maximum allowed value");
});
(0, vitest_1.test)("shows a minimum length error when the text entered is shorter than minLength", async () => {
const input = renderTextInput({ label: "Test Label", minLength: 5 });
await input.type("ab");
input.shouldHaveError("This field's value must be 5 characters or more.");
});
(0, vitest_1.test)("shows a maximum length error when the text entered exceeds maxLength", async () => {
const input = renderTextInput({ label: "Test Label", maxLength: 5 });
await input.type("abcdef");
input.shouldHaveError("This field's value must be 5 characters or less.");
});
(0, vitest_1.test)("does not show a length error when the text entered is within range", async () => {
const input = renderTextInput({ label: "Test Label", minLength: 2, maxLength: 5 });
await input.type("abc");
input.shouldNotHaveError("characters or more");
input.shouldNotHaveError("characters or less");
});
(0, vitest_1.test)("does not show a minLength error for an empty, non-required field", async () => {
const input = renderTextInput({ label: "Test Label", minLength: 5, value: "hello" });
await input.clear();
input.shouldNotHaveError("characters or more");
});
});
(0, vitest_1.describe)("validation on external value change", () => {
(0, vitest_1.test)("shows a required error when the value is cleared externally", () => {
const input = renderTextInputWithExternalValue({ label: "Test Label", required: true, value: "hello" });
input.shouldNotHaveError("This field is required.");
input.setValue("");
input.shouldHaveError("This field is required.");
});
(0, vitest_1.test)("clears the required error when a value is set externally", () => {
const input = renderTextInputWithExternalValue({ label: "Test Label", required: true, value: "hello" });
input.setValue("");
input.shouldHaveError("This field is required.");
input.setValue("world");
input.shouldNotHaveError("This field is required.");
});
});
(0, vitest_1.describe)("external validation message dismissal", () => {
(0, vitest_1.test)("keeps showing the external validation message when the field has not been edited", () => {
const input = renderTextInput({ label: "Test Label", value: "hello", validationMessage: "Server error" });
input.shouldHaveError("Server error");
});
(0, vitest_1.test)("dismisses the external validation message once the field is edited", async () => {
const input = renderTextInput({ label: "Test Label", value: "hello", validationMessage: "Server error" });
await input.type("hello there");
input.shouldNotHaveError("Server error");
});
(0, vitest_1.test)("shows a new external validation message even without a further edit", async () => {
const input = renderTextInput({ label: "Test Label", value: "hello", validationMessage: "Server error" });
await input.type("hello there");
input.shouldNotHaveError("Server error");
input.setExternalValidationMessage("A different server error");
input.shouldHaveError("A different server error");
});
// Mirrors a real resubmit: useMutation clears its error to undefined at the start of every submit,
// before the new (possibly identical) result comes back - that transition through undefined is what
// lets an unchanged message reappear correctly instead of being mistaken for the stale, dismissed one.
(0, vitest_1.test)("shows the same external validation message again if it is cleared and re-set, as on a resubmit", async () => {
const input = renderTextInput({ label: "Test Label", value: "hello", validationMessage: "Server error" });
await input.type("hello there");
input.shouldNotHaveError("Server error");
input.setExternalValidationMessage(undefined);
input.setExternalValidationMessage("Server error");
input.shouldHaveError("Server error");
});
// Documents the remaining, narrower tradeoff: if a caller replaces the message directly with an
// identical one - without clearing it to undefined first - that's indistinguishable from the old,
// already-dismissed one and stays hidden until the next edit.
(0, vitest_1.test)("keeps an external validation message dismissed if the identical message text replaces it directly, without clearing first", async () => {
const input = renderTextInput({ label: "Test Label", value: "hello", validationMessage: "Server error" });
await input.type("hello there");
input.shouldNotHaveError("Server error");
input.setExternalValidationMessage("Server error");
input.shouldNotHaveError("Server error");
});
});
(0, vitest_1.describe)("prefix property", () => {
(0, vitest_1.test)("renders with string prefix", () => {
const input = renderTextInput({ label: "Test Label", prefix: "$" });
input.shouldHavePrefix("$");
});
(0, vitest_1.test)("renders with long string prefix", () => {
const longPrefix = "dollars";
const input = renderTextInput({ label: "Test Label", prefix: longPrefix });
input.shouldHavePrefix("dollars");
});
(0, vitest_1.test)("does not render prefix when not provided", () => {
const input = renderTextInput({ label: "Test Label" });
input.shouldNotHavePrefix();
});
(0, vitest_1.test)("prefix has correct accessibility attributes", () => {
const prefix = "ABCDEFG";
const input = renderTextInput({ label: "Test Label", prefix });
input.shouldHavePrefixWithTitle(prefix);
});
});
(0, vitest_1.describe)("actions property", () => {
(0, vitest_1.test)("renders a single action button", () => {
const input = renderTextInput({ label: "Test Label", actions: [(0, jsx_runtime_1.jsx)(Button_1.Button, { icon: (0, jsx_runtime_1.jsx)("span", { children: "\uD83D\uDD17" }), onClick: vitest_1.vi.fn(), importance: "ghost", accessibleName: "Bind variable" }, "bind")] });
input.shouldHaveActionButton("Bind variable");
});
(0, vitest_1.test)("renders multiple action buttons", () => {
const input = renderTextInput({
label: "Test Label",
actions: [(0, jsx_runtime_1.jsx)(Button_1.Button, { icon: (0, jsx_runtime_1.jsx)("span", { children: "#" }), onClick: vitest_1.vi.fn(), importance: "ghost", accessibleName: "Insert variable" }, "insert"), (0, jsx_runtime_1.jsx)(Button_1.Button, { icon: (0, jsx_runtime_1.jsx)("span", { children: "+" }), onClick: vitest_1.vi.fn(), importance: "ghost", accessibleName: "Add" }, "add")],
});
input.shouldHaveActionButton("Insert variable");
input.shouldHaveActionButton("Add");
});
(0, vitest_1.test)("action button is clickable", async () => {
const handleClick = vitest_1.vi.fn();
const input = renderTextInput({ label: "Test Label", actions: [(0, jsx_runtime_1.jsx)(Button_1.Button, { icon: (0, jsx_runtime_1.jsx)("span", { children: "\uD83D\uDD17" }), onClick: handleClick, importance: "ghost", accessibleName: "Bind variable" }, "bind")] });
await input.clickActionButton("Bind variable");
input.shouldHaveCalledActionClick(handleClick);
});
(0, vitest_1.test)("renders actions alongside suffix", () => {
const suffix = (0, jsx_runtime_1.jsx)(Button_1.Button, { icon: (0, jsx_runtime_1.jsx)("span", { children: "\uD83D\uDC41" }), onClick: vitest_1.vi.fn(), importance: "ghost", accessibleName: "Show password" });
const input = renderTextInput({ label: "Test Label", actions: [(0, jsx_runtime_1.jsx)(Button_1.Button, { icon: (0, jsx_runtime_1.jsx)("span", { children: "\uD83D\uDD17" }), onClick: vitest_1.vi.fn(), importance: "ghost", accessibleName: "Bind variable" }, "bind")], suffix });
input.shouldHaveActionButton("Bind variable");
input.shouldHaveActionButton("Show password");
});
(0, vitest_1.test)("does not render actions when not provided", () => {
const input = renderTextInput({ label: "Test Label" });
input.shouldNotHaveAnyButtons();
});
});
(0, vitest_1.describe)("suffix property", () => {
(0, vitest_1.test)("renders with string suffix", () => {
const input = renderTextInput({ label: "Test Label", suffix: "sec" });
input.shouldHaveSuffix("sec");
});
(0, vitest_1.test)("renders with long string suffix and truncates it", () => {
const longSuffix = "hello";
const input = renderTextInput({ label: "Test Label", suffix: longSuffix });
input.shouldHaveSuffix("hell");
});
(0, vitest_1.test)("renders with React element suffix", () => {
const buttonSuffix = (0, jsx_runtime_1.jsx)("button", { type: "button", children: "X" });
const input = renderTextInput({ label: "Test Label", suffix: buttonSuffix });
input.shouldHaveSuffixElement();
input.shouldHaveSuffixButton();
});
(0, vitest_1.test)("renders with Button component suffix", () => {
const buttonSuffix = (0, jsx_runtime_1.jsx)(Button_1.Button, { icon: (0, jsx_runtime_1.jsx)("span", { children: "\uD83D\uDD0D" }), onClick: () => { }, importance: "primary" });
const input = renderTextInput({ label: "Test Label", suffix: buttonSuffix });
input.shouldHaveSuffixElement();
input.shouldHaveSuffixButton();
});
(0, vitest_1.test)("does not render suffix when not provided", () => {
const input = renderTextInput({ label: "Test Label" });
input.shouldNotHaveSuffix();
});
(0, vitest_1.test)("suffix button is clickable", async () => {
const handleClick = vitest_1.vi.fn();
const buttonSuffix = ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: handleClick, children: "Click me" }));
const input = renderTextInput({ label: "Test Label", suffix: buttonSuffix });
await input.clickSuffixButton();
input.shouldHaveCalledSuffixClick(handleClick);
});
});
});
function kindOf(type) {
if (type === "number")
return "number";
if (type === "password")
return "password";
return "text";
}
function renderTextInput(options) {
const onChange = vitest_1.vi.fn();
const { rerender } = (0, react_1.render)((0, jsx_runtime_1.jsx)(ControlledTextField, { ...options, onChange: onChange }));
const setValidationMessage = (validationMessage) => rerender((0, jsx_runtime_1.jsx)(ControlledTextField, { ...options, onChange: onChange, validationMessage: validationMessage }));
return getTextInputInteractions(options.label, onChange, kindOf(options.type), setValidationMessage);
}
// Renders TextField directly rather than through ControlledTextField, so the value is driven purely by
// the prop and a test can change it externally via rerender, mimicking a caller setting the value.
function renderTextInputWithExternalValue(options) {
const onChange = vitest_1.vi.fn();
const { rerender } = (0, react_1.render)((0, jsx_runtime_1.jsx)(TextField_1.TextField, { ...options, onChange: onChange }));
const setValue = (value) => rerender((0, jsx_runtime_1.jsx)(TextField_1.TextField, { ...options, value: value, onChange: onChange }));
return { ...getTextInputInteractions(options.label, onChange, kindOf(options.type), () => { }), setValue };
}
// Keeps the field genuinely controlled (mirroring how a real consumer feeds onChange back into value), so
// typing accumulates correctly across keystrokes instead of resetting to the initial prop on every render.
function ControlledTextField({ onChange, value: initialValue, ...options }) {
const [value, setValue] = (0, react_2.useState)(initialValue);
return ((0, jsx_runtime_1.jsx)(TextField_1.TextField, { ...options, value: value, onChange: (newValue) => {
setValue(newValue);
onChange(newValue);
} }));
}
function getTextInputInteractions(label, onChange, kind = "text", setValidationMessage) {
// The field's accessible role (and so which domQueries getter locates it) depends on `type`: number
// inputs are "spinbutton", password inputs expose no role (queried by a dedicated helper instead), and
// everything else (text, email, tel, url, search, time) is "textbox".
const field = () => (kind === "number" ? testing_library_1.domQueries.getNumberInput(label) : kind === "password" ? testing_library_1.domQueries.getPasswordInput(label) : testing_library_1.domQueries.getTextInput(label));
return {
shouldBeInDocument: () => {
field().assertIsInTheDocument();
},
shouldHaveLabel: (labelText) => {
testing_library_1.domQueries.getTextInput(labelText).assertIsInTheDocument();
},
shouldHavePlaceholder: (placeholder) => {
(0, vitest_1.expect)(field().innerElement).toHaveAttribute("placeholder", placeholder);
},
shouldHaveValue: (value) => {
(0, vitest_1.expect)(field().innerElement).toHaveValue(value);
},
shouldHaveDescription: (description) => {
testing_library_1.domQueries.getText(description).assertIsInTheDocument();
},
shouldHaveError: (error) => {
testing_library_1.domQueries.getText(error).assertIsInTheDocument();
},
shouldNotHaveError: (error) => {
testing_library_1.domQueries.queryText(error).assertIsNotInTheDocument();
},
shouldHaveValidationMessage: (message) => {
testing_library_1.domQueries.getText(message).assertIsInTheDocument();
},
shouldShowErrorValidationState: () => {
testing_library_1.domQueries.getImage("Error").assertIsInTheDocument();
},
shouldShowSuccessValidationState: () => {
testing_library_1.domQueries.getImage("Success").assertIsInTheDocument();
},
shouldNotShowAnyValidationState: () => {
testing_library_1.domQueries.queryImage("Error").assertIsNotInTheDocument();
testing_library_1.domQueries.queryImage("Success").assertIsNotInTheDocument();
},
shouldBeDisabled: () => {
field().assertIsDisabled();
},
shouldBeReadOnly: () => {
(0, vitest_1.expect)(field().innerElement).toHaveAttribute("readonly");
},
shouldHaveFocus: () => {
field().assertHasFocus();
},
shouldHaveRequiredMarker: () => {
testing_library_1.domQueries.getText("(required)").assertIsInTheDocument();
},
shouldHaveOptionalMarker: () => {
testing_library_1.domQueries.getText("(optional)").assertIsInTheDocument();
},
shouldHaveDefaultMarker: () => {
testing_library_1.domQueries.getText("(Default)").assertIsInTheDocument();
},
shouldHaveType: (type) => {
(0, vitest_1.expect)(field().innerElement).toHaveAttribute("type", type);
},
shouldHaveName: (name) => {
(0, vitest_1.expect)(field().innerElement).toHaveAttribute("name", name);
},
shouldHaveAriaInvalid: (invalid) => {
(0, vitest_1.expect)(field().innerElement).toHaveAttribute("aria-invalid", invalid.toString());
},
shouldHaveAriaDescribedByError: () => {
const ariaDescribedBy = field().innerElement.getAttribute("aria-describedby");
(0, vitest_1.expect)(ariaDescribedBy).toContain("validation");
},
shouldHaveAriaDescribedByDescription: () => {
const ariaDescribedBy = field().innerElement.getAttribute("aria-describedby");
(0, vitest_1.expect)(ariaDescribedBy).toContain("description");
},
shouldHaveAriaDescribedByBoth: () => {
const ariaDescribedBy = field().innerElement.getAttribute("aria-describedby");
(0, vitest_1.expect)(ariaDescribedBy).toContain("description");
(0, vitest_1.expect)(ariaDescribedBy).toContain("validation");
},
type: async (text) => {
if (kind === "number") {
await testing_library_1.domQueries.getNumberInput(label).replaceNumber(Number(text));
}
else {
await testing_library_1.domQueries.getTextInput(label).replaceText(text);
}
},
clear: async () => {
if (kind === "number") {
await testing_library_1.domQueries.getNumberInput(label).clear();
}
else {
await testing_library_1.domQueries.getTextInput(label).replaceText("");
}
},
attemptToType: async (text) => {
await testing_library_1.domQueries.getTextInput(label).typeText(text);
},
shouldHaveCalledOnChangeWith: (value) => {
(0, vitest_1.expect)(onChange).toHaveBeenCalledWith(value);
},
shouldNotHaveCalledOnChange: () => {
(0, vitest_1.expect)(onChange).not.toHaveBeenCalled();
},
shouldHaveSuffix: (suffixText) => {
testing_library_1.domQueries.getText(suffixText).assertIsInTheDocument();
},
shouldHaveSuffixElement: () => {
field().assertIsInTheDocument();
},
shouldHaveSuffixButton: () => {
testing_library_1.domQueries.getButton(undefined).assertIsInTheDocument();
},
shouldNotHaveSuffix: () => {
testing_library_1.domQueries.queryButton(undefined).assertIsNotInTheDocument();
(0, vitest_1.expect)(field().innerElement).not.toHaveClass("inputStylesWithSuffix");
},
clickSuffixButton: async () => {
await testing_library_1.domQueries.getButton(undefined).click();
},
shouldHaveCalledSuffixClick: (clickHandler) => {
(0, vitest_1.expect)(clickHandler).toHaveBeenCalled();
},
shouldHaveActionButton: (accessibleName) => {
testing_library_1.domQueries.getButton(accessibleName).assertIsInTheDocument();
},
clickActionButton: (accessibleName) => testing_library_1.domQueries.getButton(accessibleName).click(),
shouldHaveCalledActionClick: (clickHandler) => {
(0, vitest_1.expect)(clickHandler).toHaveBeenCalled();
},
shouldNotHaveAnyButtons: () => {
(0, vitest_1.expect)(testing_library_1.domQueries.queryAllButtons(undefined)).toHaveLength(0);
},
shouldHavePrefix: (prefixText) => {
testing_library_1.domQueries.getText(prefixText).assertIsInTheDocument();
},
shouldNotHavePrefix: () => {
(0, vitest_1.expect)(field().innerElement).not.toHaveClass("inputStylesWithPrefix");
},
shouldHavePrefixWithTitle: (title) => {
testing_library_1.domQueries.getText(title).assertHasTitle(title);
},
setExternalValidationMessage: (validationMessage) => {
setValidationMessage(validationMessage);
},
};
}