diff --git a/tests/integration/input/ExampleInput.svelte b/tests/integration/input/ExampleInput.svelte new file mode 100644 index 00000000..fb2d20b3 --- /dev/null +++ b/tests/integration/input/ExampleInput.svelte @@ -0,0 +1,22 @@ + + + + {#snippet buttonContent()} + This is the button + {/snippet} + diff --git a/tests/integration/input/input.test.ts b/tests/integration/input/input.test.ts new file mode 100644 index 00000000..3947a426 --- /dev/null +++ b/tests/integration/input/input.test.ts @@ -0,0 +1,107 @@ +import Input from "$lib/components/composites/input/Input.svelte"; +import { render, screen, waitFor } from "@testing-library/svelte"; +import { describe, expect, test } from "vitest"; +import { z } from "zod"; +import ExampleInput from "./ExampleInput.svelte"; + +describe("Input", () => { + test("When props are provided, then label, link and input is shown", () => { + const input = render(Input, { + target: document.body, + props: { + inputId: "input", + label: "Input Label", + placeholder: "Input", + required: true, + type: "text", + link: { + href: "https://example.com", + text: "Example Link", + }, + schema: z.string().min(1).max(10), + value: "Example", + }, + }); + + // Label exists + const label = document.getElementsByTagName("label")[0]; + expect(label).toBeInTheDocument(); + expect(label).toHaveTextContent("Input Label"); + + // Link exists + const link = screen.getByRole("link"); + expect(link).toBeInTheDocument(); + expect(link).toHaveTextContent("Example Link"); + expect(link).toHaveAttribute("href", "https://example.com"); + + // Input exists + const inputElement = document.getElementById("input"); + expect(inputElement).toBeInTheDocument(); + expect(inputElement).toHaveAttribute("placeholder", "Input"); + expect(inputElement).toHaveAttribute("required"); + expect(inputElement).toHaveAttribute("type", "text"); + expect(inputElement).toHaveValue("Example"); + + // Error messages do not exist + let errorMessages = document.getElementsByTagName("p"); + expect(errorMessages).toHaveLength(0); + + // When input is validated, then no error messages are shown + expect(input.component.validate()).toBe(true); + errorMessages = document.getElementsByTagName("p"); + expect(errorMessages).toHaveLength(0); + expect(input.component.getValue()).toBe("Example"); + }); + + test("When props are provided and input is invalid, then error messages are shown", async () => { + const input = render(Input, { + target: document.body, + props: { + inputId: "input", + label: "Input", + placeholder: "Input", + required: true, + type: "text", + link: { + href: "https://example.com", + text: "Example Link", + }, + schema: z.string().min(10).max(20), + value: "Example", + }, + }); + + // Error messages do not exist + let errorMessages = document.getElementsByTagName("p"); + expect(errorMessages).toHaveLength(0); + + // When input is validated, then error messages are shown + expect(input.component.validate()).toBe(false); + await waitFor(() => { + errorMessages = document.getElementsByTagName("p"); + expect(errorMessages).toHaveLength(1); + }); + expect(errorMessages[0]).toHaveTextContent("String must contain at least 10 character(s)"); + }); + + test("When a button is provided, then button is shown", () => { + let isClicked = false; + render(ExampleInput, { + target: document.body, + props: { + onClick: () => { + isClicked = true; + }, + }, + }); + + // Button exists + const button = screen.getByRole("button"); + expect(button).toBeInTheDocument(); + expect(button).toHaveTextContent("This is the button"); + + // When button is clicked, then onClick is called + button.click(); + expect(isClicked).toBe(true); + }); +}); diff --git a/tests/integration/input/password-input.test.ts b/tests/integration/input/password-input.test.ts new file mode 100644 index 00000000..1c1aa2f3 --- /dev/null +++ b/tests/integration/input/password-input.test.ts @@ -0,0 +1,79 @@ +import PasswordInput from "$lib/components/composites/input/PasswordInput.svelte"; +import { render, screen, waitFor } from "@testing-library/svelte"; +import { describe, expect, test } from "vitest"; + +describe("PasswordInput", () => { + const validPassword = "z's?c].e2x<@($\"<#;\\A]]3D@F)/^v^!"; + + test("When props are provided, then label and input are shown", () => { + const input = render(PasswordInput, { + target: document.body, + props: { + value: validPassword, + }, + }); + + // Label exists + const label = document.getElementsByTagName("label")[0]; + expect(label).toBeInTheDocument(); + expect(label).toHaveTextContent("Password"); + + // Input exists + const inputElement = document.getElementById("password"); + expect(inputElement).toBeInTheDocument(); + expect(inputElement).toHaveAttribute("placeholder", ""); + expect(inputElement).toHaveAttribute("required"); + expect(inputElement).toHaveAttribute("type", "password"); + + // Error messages do not exist + let errorMessages = document.getElementsByTagName("p"); + expect(errorMessages).toHaveLength(0); + + // When input is validated, then no error messages are shown + expect(input.component.validate()).toBe(true); + errorMessages = document.getElementsByTagName("p"); + expect(errorMessages).toHaveLength(0); + expect(input.component.getValue()).toBe(validPassword); + }); + + test("When valid password is inserted, then no error messages are shown", async () => { + const input = render(PasswordInput, { + target: document.body, + props: { + value: validPassword, + }, + }); + + // When input is validated, then no error messages are shown + expect(input.component.validate()).toBe(true); + const errorMessages = document.getElementsByTagName("p"); + expect(errorMessages).toHaveLength(0); + expect(input.component.getValue()).toBe(validPassword); + }); + + test("When button is clicked, then password is displayed as text", async () => { + render(PasswordInput, { + target: document.body, + props: { + value: "Example", + }, + }); + + const button = screen.getByRole("button"); + expect(button).toBeInTheDocument(); + + const input = document.getElementById("password"); + + expect(input).toHaveAttribute("type", "password"); + + button.click(); + await waitFor(() => { + expect(input).toHaveAttribute("type", "text"); + }); + + button.click(); + await waitFor(() => { + expect(input).toHaveAttribute("type", "password"); + }); + }); +});