diff --git a/README.md b/README.md index 52d176b..93a37b1 100644 --- a/README.md +++ b/README.md @@ -247,3 +247,11 @@ If you find a bug, first write a test that will fail because of the bug. Then fi If you want to add a new feature, write a test that will fail because of the missing feature. Then add the feature and make sure the test passes. New tests do not require approval. + +#### Using the right tests for the job + +1. For functionality, use unit tests (e.g. if I give this value to this function, will it return the correct result?) +2. For user interactions, use end-to-end tests (e.g. if I click this button, will it show the correct modal?) +3. For visual changes, use visual tests with Storybook (e.g. if I change this CSS, will I still see the element in the correct place? Will it still be centered?) + +Be careful not to over-test. If you find yourself testing the same thing in multiple places, you should ask yourself if you are testing the right things in the right places. Over-tested code can be hard to update and grow. \ No newline at end of file diff --git a/src/components/modals/__tests__/BaseModal.spec.ts b/src/components/modals/__tests__/BaseModal.spec.ts index 851a10b..b6f2fdc 100644 --- a/src/components/modals/__tests__/BaseModal.spec.ts +++ b/src/components/modals/__tests__/BaseModal.spec.ts @@ -28,6 +28,9 @@ describe("Base Modal", () => { }, }); + // Expect the modal to first be closed + expect(wrapper.find("dialog").attributes("open")).toBe(undefined); + // Click the modal to open it await wrapper.find("button").trigger("click"); diff --git a/src/stories/BaseModal.stories.ts b/src/stories/BaseModal.stories.ts index 298f8cf..3a561af 100644 --- a/src/stories/BaseModal.stories.ts +++ b/src/stories/BaseModal.stories.ts @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from "@storybook/vue3"; import BaseModal from "@/components/modals/BaseModal.vue"; +import { expect, within } from "@storybook/test"; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories const meta: Meta = { @@ -24,6 +25,29 @@ type Story = StoryObj; */ export const Default: Story = {}; +export const DefaultOpened: Story = { + play: async ({ canvasElement }: any) => { + const canvas = within(canvasElement); + expect(canvas.queryByText("Cancel")).not.toBeVisible(); + + // Click the button + const button = canvas.getByText("Hello World", { selector: "button" }); + await button.click(); + + // The modal, which is in `article` tag, should be in the middle of the screen + const modal = canvas.getByRole("article"); + expect(modal).toBeVisible(); + + const modalRect = modal.getBoundingClientRect(); + const canvasRect = canvasElement.getBoundingClientRect(); + + // The modals left edge to the left side of the screen should be the same as the right edge of the canvas + const leftModalDistance = modalRect.left - canvasRect.left; + const rightCanvasDistance = canvasRect.right - modalRect.right; + expect(leftModalDistance).toBe(rightCanvasDistance); + }, +}; + export const MinimumExample: Story = { args: { triggerText: undefined,