Skip to content

Instantly share code, notes, and snippets.

@ekafyi
Last active May 30, 2023 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ekafyi/74ca5c88639814cd7161bf473e0b0bab to your computer and use it in GitHub Desktop.
Save ekafyi/74ca5c88639814cd7161bf473e0b0bab to your computer and use it in GitHub Desktop.
Sample test assets Cypress + Vitest
// Button.tsx
"use client";
export interface ButtonProps {
/** Fooooo */
primary?: boolean;
/** Barrrr */
size?: "small" | "large";
/** Bazzzz */
label?: string;
}
/**
* A button! How fancy!
*/
export const Button = ({
primary = false,
label = "Boop",
size = "small",
}: ButtonProps) => {
return (
<button
style={{
backgroundColor: primary ? "tomato" : "skyblue",
fontSize: size === "large" ? "24px" : "14px",
}}
onClick={() => console.log("clicked")}
>
{label}
</button>
);
};
// !! -------------------- !!
// Button.test.tsx
import { render, screen } from "@testing-library/react";
import { Button } from "./Button";
// !! enable after setting `environment` field in vitest config
it("should simulate browser environment", () => {
expect(typeof window).not.toBe("undefined");
});
// !! -------------------- !!
describe("<Button />", () => {
const BTN_TEXT = "Hello Button";
// !! enable after installing @testing-library/* dependencies
beforeEach(() => {
render(<Button label={BTN_TEXT} />);
});
it("renders button", () => {
const btn = screen.getByRole("button", { name: /hello button/i });
expect(btn).toBeDefined();
});
// !! -------------------- !!
// !! enable after installing @testing-library/jest-dom
it("shows correct label", () => {
const btn = screen.getByRole("button", { name: /hello button/i });
expect(btn).toHaveTextContent(BTN_TEXT);
});
// !! -------------------- !!
});
// !! (later) FUTURE IMPROVEMENT
// - create reusable function to render with provider (eg. for theming, layout, other context)
// - fireEvent (included in @testing-library/react), userEvent (separate library @testing-library/user-event) usage
import { formatDate } from "./datetime";
const SAMPLE_DATE = new Date("2021-10-30");
describe("formatDate", () => {
it("should convert YYYY-MM-DD to localized string", () => {
const one = formatDate(SAMPLE_DATE, "id");
const two = formatDate(SAMPLE_DATE, "en");
const three = formatDate(SAMPLE_DATE, "en-GB");
expect(one).toMatchInlineSnapshot('"30 Okt 2021"');
expect(two).toMatchInlineSnapshot('"Oct 30, 2021"');
expect(three).toMatchInlineSnapshot('"30 Oct 2021"');
});
});
const defaultLocale = "en-GB"; // 'en', 'en-US', 'en-GB', 'id'
const defaultLocaleOptions = {
day: "numeric",
month: "short",
year: "numeric",
} as Intl.DateTimeFormatOptions;
/**
* Convert a Date object to locale formatted string.
*/
export const formatDate = (
date: Date | string,
locale = defaultLocale,
localeOptions = defaultLocaleOptions
) => {
if (typeof date == "string") {
return new Date(date).toLocaleDateString(locale, localeOptions);
} else if (typeof date == "object") {
return date.toLocaleDateString(locale, localeOptions);
}
return "";
};
// Remove / comment out everything once done checking
describe("First: Run test", () => {
it("Does not do much!", () => {
expect(true).to.equal(true);
});
it("Visits Cypress test page", () => {
cy.visit("https://example.cypress.io");
});
// !! enable after...
// - setting baseUrl in cypress.config
// - running local app (eg. turbo dev cy:open)
// it("Visits local Home page", () => {
// cy.visit("/");
// });
// !! -------------------- !!
});
// !! enable after...
// - ensuring Home page title matches the assertion
// - adding testing-library commands to cypress/support/commands.ts
describe("Second: Page Content", () => {
// it("Renders title (default)", () => {
// cy.visit("/").get("h1").should("have.text", "Web");
// });
// it("Renders title (testing-library)", () => {
// // ⚠️ Chaining commands not supported.
// // @link https://github.com/testing-library/cypress-testing-library/issues/142#issuecomment-648401469
// cy.visit("/");
// cy.findByRole("heading", { level: 1 }).should("have.text", "Web");
// });
});
// !! -------------------- !!
// !! enable after...
// - adding "about" page route
// - adding links between Home & About
describe("Third: Navigation", () => {
const HOME_PATH = "/";
const ABOUT_PATH = "/about";
// it("Renders link to About page", () => {
// cy.visit(HOME_PATH);
// cy.findByRole("link", { name: /about/i }).click();
// cy.url().should("eq", Cypress.config().baseUrl + ABOUT_PATH);
// });
// it("Renders link to Home page", () => {
// // !! enable to check if eslint is working
// // (should show error from cypress/recommended plugin)
// cy.wait(1000);
// // !! -------------------- !!
// cy.visit(ABOUT_PATH);
// cy.findByRole("link", { name: /home/i }).click();
// cy.url().should("eq", Cypress.config().baseUrl + HOME_PATH);
// });
});
// !! -------------------- !!
import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
test: {
globals: true,
coverage: { provider: "c8" }, // Supported values: c8 or istanbul
// !! enable after installing:
// - `jsdom` or `happy-dom` to test DOM elements
// - (if applicable) @testing-library/* to render React components and simulate user interactions
// environment: "happy-dom",
// !! -------------------- !!
// !! enable after installing
// - @testing-library/jest-dom to add custom jest matchers
// - @types/testing-library__jest-dom for type defs
// setupFiles: "./vitest.setup.ts",
// !! -------------------- !!
},
});
import "@testing-library/jest-dom/extend-expect";
// !! enable after installing @types/testing-library__jest-dom
// import type { TestingLibraryMatchers } from "@testing-library/jest-dom/matchers";
// declare module "vitest" {
// interface Assertion<T = any>
// extends jest.Matchers<void, T>,
// TestingLibraryMatchers<T, void> {}
// }
// !! -------------------- !!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment