Skip to content

Commit

Permalink
feat: use chromatic parameter in stories instead of separate viewpo…
Browse files Browse the repository at this point in the history
…rt stories (#302)

This PR includes several updates to the Storybook configuration and related files to improve the development and testing workflow in the Studio application.

### What changed?

1. **Storybook Configuration**: Significant updates have been made to `.storybook/main.ts` and `.storybook/preview.tsx`, including the addition of `mswLoader` and `withChromaticModes` for improved addon integration and testing.
2. **Package Updates**: New packages have been added to `package.json`, including `@isomer/storybook-config`, and corresponding updates have been made to `package-lock.json`.
3. **Component and Story Updates**: Updates to various components and stories, such as `DashboardTable.tsx` and `LandingPage.stories.ts`, to align with the new Storybook and Chromatic configurations.
4. **Tooling**: Added a new `@isomer/storybook-config` package under the `tooling/` directory to centralize Storybook configurations.

### How to test?

1. Checkout this branch.
2. Install the new dependencies: `npm install`.
3. Run Storybook: `npm run storybook`.
4. Verify that all stories load correctly and that Chromatic snapshots are taken as expected.

### Why make this change?

To enhance the developer experience by centralizing Storybook configurations, improving Chromatic integration, and ensuring consistent testing and linting across the project.

---
  • Loading branch information
karrui authored Jul 19, 2024
1 parent 1d68b8d commit 403c7cf
Show file tree
Hide file tree
Showing 20 changed files with 361 additions and 493 deletions.
4 changes: 2 additions & 2 deletions apps/studio/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const config: StorybookConfig = {
],

framework: {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
// @ts-expect-error type mismatch
name: getAbsolutePath("@storybook/nextjs"),
options: {},
},
Expand Down Expand Up @@ -42,6 +42,6 @@ const config: StorybookConfig = {
}
export default config

function getAbsolutePath(value: string): any {
function getAbsolutePath(value: string) {
return dirname(require.resolve(join(value, "package.json")))
}
25 changes: 22 additions & 3 deletions apps/studio/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ import { createTRPCReact } from "@trpc/react-query"
import { format } from "date-fns/format"
import { merge } from "lodash"
import mockdate from "mockdate"
import { initialize, mswDecorator } from "msw-storybook-addon"
import { initialize, mswLoader } from "msw-storybook-addon"
import { ErrorBoundary } from "react-error-boundary"
import superjson from "superjson"
import { z } from "zod"

import { viewport, withChromaticModes } from "@isomer/storybook-config"

import type { EnvContextReturn } from "~/components/AppProviders"
import { EnvProvider, FeatureContext } from "~/components/AppProviders"
import { DefaultFallback } from "~/components/ErrorBoundary"
Expand Down Expand Up @@ -127,7 +129,7 @@ export const MockFeatureFlagsDecorator: Decorator<Args> = (

const LoginStateDecorator: Decorator<Args> = (story, { parameters }) => {
const [hasLoginStateFlag, setLoginStateFlag] = useState(
Boolean(parameters.loginState),
Boolean(parameters.loginState ?? true),
)

const setHasLoginStateFlag = useCallback(() => {
Expand Down Expand Up @@ -158,6 +160,7 @@ export const MockDateDecorator: Decorator<Args> = (story, { parameters }) => {
return story()
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
mockdate.set(parameters.mockdate)

const mockedDate = format(parameters.mockdate, "dd-mm-yyyy HH:mma")
Expand Down Expand Up @@ -194,12 +197,28 @@ const decorators: Decorator[] = [
Provider: ThemeProvider,
}) as Decorator, // FIXME: Remove this cast when types are fixed
MockDateDecorator,
mswDecorator,
]

const preview: Preview = {
loaders: [mswLoader],
decorators,
parameters: {
viewport,
/**
* If tablet view is needed, add it on a per-story basis.
* @example
* ```
* export const SomeStory: Story = {
* parameters: {
* chromatic: withChromaticModes(["gsib", "desktop", "tablet"]),
* }
* }
* ```
*/
chromatic: {
...withChromaticModes(["gsib"]),
prefersReducedMotion: "reduce",
},
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
Expand Down
1 change: 1 addition & 0 deletions apps/studio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"@chakra-ui/cli": "^2.4.1",
"@isomer/eslint-config": "*",
"@isomer/prettier-config": "*",
"@isomer/storybook-config": "*",
"@isomer/tsconfig": "*",
"@playwright/test": "^1.40.1",
"@storybook/addon-a11y": "^8.1.10",
Expand Down
4 changes: 2 additions & 2 deletions apps/studio/src/features/dashboard/DashboardTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ export const DashboardTable = (): JSX.Element => {
(pageNumber - 1) * entriesPerPage,
pageNumber * entriesPerPage,
)
.map((element) => {
.map((element, index) => {
return (
<Tr>
<Tr key={index}>
<Td w="min-content">
<Checkbox size="sm" w="fit-content" h="fit-content" />
</Td>
Expand Down
8 changes: 5 additions & 3 deletions apps/studio/src/pages/sites/[siteId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import _ from "lodash"
import { DashboardTable } from "~/features/dashboard/DashboardTable"
import PageCreateModal from "~/features/editing-experience/components/PageCreateModal"
import { type NextPageWithLayout } from "~/lib/types"
import { AdminLayout } from "~/templates/layouts/AdminLayout"

const Dashboard: NextPageWithLayout = () => {
const SitePage: NextPageWithLayout = () => {
const {
isOpen: isPageCreateModalOpen,
onOpen: onPageCreateModalOpen,
onClose: onpageCreateModalClose,
} = useDisclosure()
return (
<VStack bgColor="#F3F5F7" w="100%" p="1.75rem" minH="100vh">
<VStack w="100%" p="1.75rem">
<Text
alignSelf="flex-start"
textColor="base.content.default"
Expand Down Expand Up @@ -46,4 +47,5 @@ const Dashboard: NextPageWithLayout = () => {
)
}

export default Dashboard
SitePage.getLayout = AdminLayout
export default SitePage
4 changes: 3 additions & 1 deletion apps/studio/src/stories/Page/DashboardPage.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ const meta: Meta<typeof DashboardPage> = {
export default meta
type Story = StoryObj<typeof DashboardPage>

export const Default: Story = {}
export const Default: Story = {
name: "Dashboard Page",
}
12 changes: 7 additions & 5 deletions apps/studio/src/stories/Page/LandingPage.stories.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Meta, StoryObj } from "@storybook/react"

import { withChromaticModes } from "@isomer/storybook-config"

import LandingPage from "~/pages/index"
import { getMobileViewParameters } from "../utils/viewports"

const meta: Meta<typeof LandingPage> = {
title: "Pages/Landing Page",
Expand All @@ -15,8 +16,9 @@ const meta: Meta<typeof LandingPage> = {
export default meta
type Story = StoryObj<typeof LandingPage>

export const Desktop: Story = {}

export const Mobile: Story = {
parameters: getMobileViewParameters(),
export const Default: Story = {
name: "Landing Page",
parameters: {
chromatic: withChromaticModes(["gsib", "mobile"]),
},
}
22 changes: 9 additions & 13 deletions apps/studio/src/stories/Page/SignInPage.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { expect, userEvent, within } from "@storybook/test"
import { authEmailHandlers } from "tests/msw/handlers/auth/email"
import { meHandlers } from "tests/msw/handlers/me"

import { withChromaticModes } from "@isomer/storybook-config"

import SignInPage from "~/pages/sign-in"
import { getMobileViewParameters } from "../utils/viewports"

const VALID_AUTH_EMAIL = "[email protected]"

Expand All @@ -14,6 +15,7 @@ const meta: Meta<typeof SignInPage> = {
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
layout: "fullscreen",
loginState: false,
msw: {
handlers: [
meHandlers.unauthorized(),
Expand All @@ -29,27 +31,21 @@ const meta: Meta<typeof SignInPage> = {
export default meta
type Story = StoryObj<typeof SignInPage>

export const Default: Story = {}
export const Default: Story = {
parameters: {
chromatic: withChromaticModes(["gsib", "mobile"]),
},
}

export const WithSgidLogin: Story = {
parameters: {
chromatic: withChromaticModes(["gsib", "mobile"]),
features: {
sgid: true,
},
},
}

export const Mobile: Story = {
parameters: getMobileViewParameters(),
}

export const MobileWithSgid: Story = {
parameters: {
...WithSgidLogin.parameters,
...Mobile.parameters,
},
}

export const InputValidation: Story = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement)
Expand Down
20 changes: 20 additions & 0 deletions apps/studio/src/stories/Page/SitePage.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta, StoryObj } from "@storybook/react"

import SitePage from "~/pages/sites/[siteId]"
import { AdminLayout } from "~/templates/layouts/AdminLayout"

const meta: Meta<typeof SitePage> = {
title: "pages/site/[siteId]",
component: SitePage,
parameters: {
getLayout: AdminLayout,
},
decorators: [],
}

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = {
args: {},
}
13 changes: 8 additions & 5 deletions apps/studio/src/stories/components/VersionModal.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Box } from "@chakra-ui/react"
import { type Meta, type StoryObj } from "@storybook/react"

import { withChromaticModes } from "@isomer/storybook-config"

import { VersionModal } from "~/components/VersionWrapper/VersionModal"
import { getMobileViewParameters } from "../utils/viewports"

const meta: Meta<typeof VersionModal> = {
title: "Components/Version Modal",
title: "Components/VersionModal",
component: VersionModal,
// Required for Chromatic to know the dimensions of the snapshot to take,
// since the modal is rendered in a portal and Chromatic only detects the
Expand All @@ -32,7 +33,9 @@ export default meta

type Story = StoryObj<typeof VersionModal>

export const Default: Story = {}
export const Mobile: Story = {
parameters: getMobileViewParameters(),
export const Default: Story = {
name: "VersionModal",
parameters: {
chromatic: withChromaticModes(["gsib", "mobile"]),
},
}
44 changes: 0 additions & 44 deletions apps/studio/src/stories/utils/viewports.ts

This file was deleted.

Loading

0 comments on commit 403c7cf

Please sign in to comment.