logo My Digital Garden

Vite Test

By James Kolean on Sep 8, 2022
Source repository: https://gitlab.com/jameskolean/vite-test
ReactRestTools
banner

Quick Vite Test working example I can refer to later.

Create React Application with Vite

> npm init vite vite-test
Need to install the following packages:
  create-vite@3.1.0
Ok to proceed? (y)
 Select a framework: React
 Select a variant: TypeScript

> cd vite-test
> npm install
> npm run dev
> open http://localhost:5173/

Install dependencies

npm install -D vitest react-test-renderer jsdom @testing-library/react @testing-library/user-event @testing-library/jest-dom @vitest/ui @vitest/coverage-c8

Configure

// vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: "jsdom",
    setupFiles: "./src/test/setup.ts",
    // you might want to disable it, if you don't have tests that rely on CSS
    // since parsing CSS is slow
    css: true,
  },
});

Add scripts to package.json

  "scripts": {
...
    "test": "vitest",
    "coverage": "vitest run --coverage",
    "test:ui": "vitest --ui"
  },

Create a component to test

// src/components/Input.tsx
type InputProps = {
  label: string;
  name: string;
  error?: string | undefined;
} & React.DetailedHTMLProps<
  React.InputHTMLAttributes<HTMLInputElement>,
  HTMLInputElement
>;

export const Input = ({ label, name, error, ...props }: InputProps) => {
  return (
    <>
      <label htmlFor={name}>{label}</label>
      <input name={name} id={name} {...props} />
      {error ? <span role="alert">{error}</span> : null}
    </>
  );
};

Create a test

// src/components/input.test.tsx
import "@testing-library/jest-dom";
import { render, screen, userEvent } from "../utils/test-utils";
import { Input } from "./Input";

describe("Input", async () => {
  it("should render the input", () => {
    render(
      <Input
        name="email"
        type="email"
        error={undefined}
        placeholder="Email"
        label="Email Address"
        aria-label="Email Address"
      />
    );
    expect(screen.getByText("Email Address")).toBeInTheDocument();
    expect(
      screen.getByRole("textbox", {
        name: /email address/i,
      })
    ).toBeInTheDocument();
  });
  it("should change input value", async () => {
    render(
      <Input
        name="email"
        type="email"
        error={undefined}
        placeholder="Email"
        label="Email Address"
        aria-label="Email Address"
      />
    );

    screen.logTestingPlaygroundURL();

    const input = screen.getByRole("textbox", {
      name: /email address/i,
    });
    expect(input).toBeInTheDocument();
    await userEvent.type(input, "1337");
    expect(input).toHaveValue("1337");
  });
  it("should render the input with error", () => {
    render(
      <Input
        name="email"
        type="email"
        placeholder="Email"
        label="Email Address"
        aria-label="Email Address"
        error="Please enter your email"
      />
    );
    expect(
      screen.getByRole("textbox", {
        name: /email address/i,
      })
    ).toBeInTheDocument();
    expect(screen.getByRole("alert")).toHaveTextContent(
      "Please enter your email"
    );
  });
});

Add some test utilities

// src/test/setup.ts
import "@testing-library/jest-dom";
// src/utils/test-utils.ts
/* eslint-disable import/export */
import { cleanup, render } from "@testing-library/react";
import { afterEach } from "vitest";

afterEach(() => {
  cleanup();
});

const customRender = (ui: React.ReactElement, options = {}) =>
  render(ui, {
    // wrap provider(s) here if needed
    wrapper: ({ children }) => children,
    ...options,
  });

export * from "@testing-library/react";
export { default as userEvent } from "@testing-library/user-event";
// override render export
export { customRender as render };
© Copyright 2024 Digital Garden cultivated by James Kolean.