First commit
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import { render } from "@testing-library/vue";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import DsButton from "../src/components/actions/DsButton.vue";
|
||||
|
||||
describe("DsButton", () => {
|
||||
it("preserves its accessible name while loading and prevents duplicate actions", async () => {
|
||||
const view = render(DsButton, {
|
||||
props: { loading: true },
|
||||
slots: { default: "Guardar" },
|
||||
});
|
||||
const button = view.getByRole("button", {
|
||||
name: /guardar/i,
|
||||
}) as HTMLButtonElement;
|
||||
expect(button.disabled).toBe(true);
|
||||
expect(button.getAttribute("aria-busy")).toBe("true");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { fireEvent, render, waitFor } from "@testing-library/vue";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import DsDialog from "../src/components/overlays/DsDialog.vue";
|
||||
|
||||
describe("DsDialog", () => {
|
||||
it("opens modally, has an accessible name and handles Escape cancellation", async () => {
|
||||
const view = render(DsDialog, {
|
||||
props: {
|
||||
modelValue: true,
|
||||
title: "Editar perfil",
|
||||
description: "Actualiza tus datos.",
|
||||
},
|
||||
slots: { default: "Contenido" },
|
||||
});
|
||||
const dialog = view.getByRole("dialog", {
|
||||
hidden: true,
|
||||
}) as HTMLDialogElement;
|
||||
await waitFor(() =>
|
||||
expect(dialog.open || dialog.hasAttribute("open")).toBe(true),
|
||||
);
|
||||
expect(view.getByRole("dialog", { name: "Editar perfil" })).toBe(dialog);
|
||||
await fireEvent(dialog, new Event("cancel", { cancelable: true }));
|
||||
expect(view.emitted()["update:modelValue"]?.at(-1)).toEqual([false]);
|
||||
expect(view.emitted().cancel).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
import { fireEvent, render } from "@testing-library/vue";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import DsCheckbox from "../src/components/forms/DsCheckbox.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,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import pkg from "../package.json";
|
||||
|
||||
describe("package contract", () => {
|
||||
it("publishes an explicit stylesheet and preserves CSS side effects", () => {
|
||||
expect(pkg.exports["./style.css"]).toBe("./dist/design-system.css");
|
||||
expect(pkg.sideEffects).toContain("**/*.css");
|
||||
expect(pkg.peerDependencies.vue).toMatch(/^\^3/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import * as designSystem from "../src";
|
||||
|
||||
describe("public API", () => {
|
||||
it("exports the documented components and plugin", () => {
|
||||
expect(designSystem.DsButton).toBeDefined();
|
||||
expect(designSystem.DsTextInput).toBeDefined();
|
||||
expect(designSystem.DsTabs).toBeDefined();
|
||||
expect(designSystem.DsDialog).toBeDefined();
|
||||
expect(designSystem.DesignSystem).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { afterEach } from "vitest";
|
||||
import { cleanup } from "@testing-library/vue";
|
||||
|
||||
afterEach(() => cleanup());
|
||||
|
||||
HTMLDialogElement.prototype.showModal = function showModal() {
|
||||
this.setAttribute("open", "");
|
||||
};
|
||||
|
||||
HTMLDialogElement.prototype.close = function close() {
|
||||
this.removeAttribute("open");
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
import { fireEvent, render } from "@testing-library/vue";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import DsTabs from "../src/components/navigation/DsTabs.vue";
|
||||
|
||||
describe("DsTabs", () => {
|
||||
it("uses arrow, Home and End keys with automatic activation", async () => {
|
||||
const view = render(DsTabs, {
|
||||
props: {
|
||||
label: "Cuenta",
|
||||
modelValue: "profile",
|
||||
items: [
|
||||
{ id: "profile", label: "Perfil" },
|
||||
{ id: "security", label: "Seguridad" },
|
||||
{ id: "billing", label: "Facturación" },
|
||||
],
|
||||
},
|
||||
slots: {
|
||||
profile: "Perfil",
|
||||
security: "Seguridad",
|
||||
billing: "Facturación",
|
||||
},
|
||||
});
|
||||
const profile = view.getByRole("tab", { name: "Perfil" });
|
||||
await fireEvent.keyDown(profile, { key: "ArrowRight" });
|
||||
expect(view.emitted()["update:modelValue"]?.at(-1)).toEqual(["security"]);
|
||||
await view.rerender({ modelValue: "security" });
|
||||
await fireEvent.keyDown(view.getByRole("tab", { name: "Seguridad" }), {
|
||||
key: "End",
|
||||
});
|
||||
expect(view.emitted()["update:modelValue"]?.at(-1)).toEqual(["billing"]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user