79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
import { fireEvent, render } from "@testing-library/vue";
|
|
import { h } from "vue";
|
|
import { describe, expect, it } from "vitest";
|
|
import DsCheckbox from "../src/components/forms/DsCheckbox.vue";
|
|
import DsRadioGroup from "../src/components/forms/DsRadioGroup.vue";
|
|
import DsTextInput from "../src/components/forms/DsTextInput.vue";
|
|
|
|
describe("form controls", () => {
|
|
it("associates labels, help, errors and updates v-model", async () => {
|
|
const view = render(DsTextInput, {
|
|
props: {
|
|
label: "Correo",
|
|
description: "Usaremos tu correo de trabajo.",
|
|
error: "El correo no es válido.",
|
|
modelValue: "",
|
|
},
|
|
});
|
|
const input = view.getByLabelText("Correo (Opcional)") as HTMLInputElement;
|
|
expect(input.getAttribute("aria-invalid")).toBe("true");
|
|
expect(input.getAttribute("aria-describedby")).toContain("description");
|
|
expect(input.getAttribute("aria-describedby")).toContain("error");
|
|
await fireEvent.update(input, "omar@example.com");
|
|
expect(view.emitted()["update:modelValue"]?.[0]).toEqual([
|
|
"omar@example.com",
|
|
]);
|
|
});
|
|
|
|
it("supports a boolean v-model and disabled state", async () => {
|
|
const view = render(DsCheckbox, {
|
|
props: { label: "Acepto", modelValue: false },
|
|
});
|
|
await fireEvent.click(view.getByRole("checkbox", { name: "Acepto" }));
|
|
expect(view.emitted()["update:modelValue"]?.[0]).toEqual([true]);
|
|
await view.rerender({ disabled: true });
|
|
expect((view.getByRole("checkbox") as HTMLInputElement).disabled).toBe(
|
|
true,
|
|
);
|
|
});
|
|
|
|
it("associates checkbox descriptions and errors at the same time", () => {
|
|
const view = render(DsCheckbox, {
|
|
props: {
|
|
label: "Acepto",
|
|
description: "Lee las condiciones.",
|
|
error: "Debes aceptar.",
|
|
},
|
|
});
|
|
const checkbox = view.getByRole("checkbox");
|
|
const describedBy = checkbox.getAttribute("aria-describedby") ?? "";
|
|
expect(describedBy).toContain("description");
|
|
expect(describedBy).toContain("error");
|
|
expect(checkbox.getAttribute("aria-invalid")).toBe("true");
|
|
});
|
|
|
|
it("gives radio groups unique descriptions and exposes invalid state", () => {
|
|
const props = {
|
|
legend: "Plan",
|
|
name: "plan",
|
|
options: [{ label: "Profesional", value: "pro" }],
|
|
description: "Elige un plan.",
|
|
error: "Selecciona una opción.",
|
|
};
|
|
const view = render({
|
|
setup: () => () =>
|
|
h("div", [h(DsRadioGroup, props), h(DsRadioGroup, props)]),
|
|
});
|
|
const groups = view.getAllByRole("group");
|
|
const describedBy = groups.map((group) =>
|
|
group.getAttribute("aria-describedby"),
|
|
);
|
|
expect(describedBy[0]).not.toBe(describedBy[1]);
|
|
expect(describedBy[0]).toContain("description");
|
|
expect(describedBy[0]).toContain("error");
|
|
expect(view.getAllByRole("radio")[0]?.getAttribute("aria-invalid")).toBe(
|
|
"true",
|
|
);
|
|
});
|
|
});
|