import * as React from "react"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { createSerializer } from "@emotion/jest"; import { css, cx } from "@emotion/css"; import TextInput from "../components/TextInput"; import { InputAppearance } from "../../shared/types/inputAppearance"; expect.addSnapshotSerializer(createSerializer()); describe("TextInput", () => { it("should render all appearances with props", () => { Object.keys(InputAppearance).forEach(appearance => { const { asFragment } = render( ); expect(asFragment()).toMatchSnapshot(); }); }); it("should render all appearances focus", () => { Object.keys(InputAppearance).forEach(appearance => { const { getByRole, asFragment, unmount } = render( ); const inputEl = getByRole("textbox"); inputEl.focus(); expect(asFragment()).toMatchSnapshot(); unmount(); }); }); it("should render string inputLabel", () => { const { getByText } = render( ); getByText("Test Input"); }); it("should render node as inputLabel", () => { const { getByText } = render( My Test Node} /> ); getByText("My Test Node"); }); it("should id attribute to input element", () => { const inputId = "test.input.0"; const { getByRole } = render(); const inputEl = getByRole("textbox") as HTMLInputElement; expect(inputEl.id).toEqual(inputId); }); it("should set label `for` attribute if input id set", () => { const inputId = "test.input.0"; const { getByText } = render( ); const labelEl = getByText("Test Input") as HTMLLabelElement; expect(labelEl.htmlFor).toEqual(inputId); }); it("should set tabIndex on input element", async () => { const { getByRole } = render(); const inputEl = getByRole("textbox"); await userEvent.tab(); expect(inputEl).not.toHaveFocus(); }); it("should call onFocus when input gains focus", () => { const focusFn = jest.fn(); const { getByRole } = render( ); const inputEl = getByRole("textbox"); expect(focusFn).not.toHaveBeenCalled(); inputEl.focus(); expect(focusFn).toHaveBeenCalled(); }); it("should call onBlur when input loses focus", async () => { const blurFn = jest.fn(); const { getByRole } = render(); const inputEl = getByRole("textbox"); expect(blurFn).not.toHaveBeenCalled(); inputEl.focus(); expect(blurFn).not.toHaveBeenCalled(); await userEvent.tab(); expect(blurFn).toHaveBeenCalled(); }); it("should call onChange when input changes", async () => { const changeFn = jest.fn(); const { getByRole } = render( ); const inputEl = getByRole("textbox"); expect(changeFn).not.toHaveBeenCalled(); const userInputText = "hello"; await userEvent.type(inputEl, userInputText); expect(changeFn).toHaveBeenCalledTimes(userInputText.length); }); it("should pass className to container div", () => { const widthTest = css` width: 200px; `; const { getByTestId } = render( ); const containerEl = getByTestId("textInput textInput.standard"); expect(containerEl.className).toEqual(widthTest); }); it("should hide label if `showInputLabel` set to false", () => { render( ); expect(screen.queryByText(`I'm not displayed`)).not.toBeVisible(); }); it("should display validation message if set & appearance == Error", () => { const { getByText } = render( ); getByText("This is an error message"); getByText("this is a second error message"); }); it("should not display validation message if set & appearance == Success", () => { const { queryByText } = render( ); expect(queryByText("This is an error message")).not.toBeInTheDocument(); }); it("should display icon with tooltip if tooltipText is set", async () => { const { getByTestId, getByText } = render( ); const questionIcon = getByTestId("icon"); await userEvent.hover(questionIcon); getByText("Example Tooltip"); }); it("should generate an ID if one is not passed", () => { const { getByRole } = render(); expect((getByRole("textbox") as HTMLInputElement).id).toBeDefined(); }); });