diff --git a/front/.storybook/main.js b/front/.storybook/main.js index 7b43a5b0b..ac92a99d0 100644 --- a/front/.storybook/main.js +++ b/front/.storybook/main.js @@ -1,63 +1,73 @@ const path = require('path'); module.exports = { - webpackFinal: config => { + webpackFinal: (config) => { config.module.rules.push({ test: /\.tsx?$/, exclude: /node_modules/, - use: [{ - loader: require.resolve('babel-loader'), - options: { - presets: [require('@babel/preset-typescript').default, [require('@babel/preset-react').default, { - runtime: 'automatic' - }], require('@babel/preset-env').default] - } - }] + use: [ + { + loader: require.resolve('babel-loader'), + options: { + presets: [ + require('@babel/preset-typescript').default, + [ + require('@babel/preset-react').default, + { + runtime: 'automatic', + }, + ], + require('@babel/preset-env').default, + ], + }, + }, + ], }); config.resolve.extensions.push('.ts', '.tsx'); config.module.rules.push({ test: /\.mjs$/, include: /node_modules/, - type: 'javascript/auto' + type: 'javascript/auto', }); config.module.rules.push({ test: /\.svg$/, use: [ { - loader: '@svgr/webpack' + loader: '@svgr/webpack', }, { loader: 'file-loader', options: { - name: 'static/media/[path][name].[ext]' - } - } + name: 'static/media/[path][name].[ext]', + }, + }, ], type: 'javascript/auto', issuer: { - and: [/\.(ts|tsx|js|jsx|md|mdx)$/] - } + and: [/\.(ts|tsx|js|jsx|md|mdx)$/], + }, }); config.resolve.extensions.push('.mjs'); config.resolve.alias = { ...config.resolve.alias, - '~': path.resolve(__dirname, "../src"), - '@': path.resolve(__dirname, "../src/modules"), + '~': path.resolve(__dirname, '../src'), + '@': path.resolve(__dirname, '../src/modules'), }; return config; }, - stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], addons: [ - "@storybook/addon-links", - "@storybook/addon-essentials", - "@storybook/addon-interactions", - "@storybook/addon-coverage", - "@storybook/addon-styling", - "storybook-addon-pseudo-states", - "storybook-addon-cookie", + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/addon-interactions', + '@storybook/addon-coverage', + '@storybook/addon-styling', + 'storybook-addon-pseudo-states', + 'storybook-addon-cookie', ], + docs: { autodocs: true }, framework: { name: '@storybook/react-webpack5', - options: {} + options: {}, }, -}; \ No newline at end of file +}; diff --git a/front/src/__stories__/App.darkMode.stories.tsx b/front/src/__stories__/App.darkMode.stories.tsx deleted file mode 100644 index 53abdf2f4..000000000 --- a/front/src/__stories__/App.darkMode.stories.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Meta } from '@storybook/react'; - -import { App } from '~/App'; -import { graphqlMocks } from '~/testing/graphqlMocks'; - -import { Story } from './App.stories'; -import { renderWithDarkMode } from './shared'; - -const meta: Meta = { - title: 'App/App/DarkMode', - component: App, -}; - -export default meta; - -export const DarkMode: Story = { - render: () => renderWithDarkMode(true), - parameters: { - msw: graphqlMocks, - }, -}; diff --git a/front/src/__stories__/App.stories.tsx b/front/src/__stories__/App.stories.tsx index 226525fc8..db8ef3f47 100644 --- a/front/src/__stories__/App.stories.tsx +++ b/front/src/__stories__/App.stories.tsx @@ -1,21 +1,52 @@ +import { MemoryRouter } from 'react-router-dom'; import type { Meta, StoryObj } from '@storybook/react'; +import { useRecoilState } from 'recoil'; +import { currentUserState } from '@/auth/states/currentUserState'; +import { isAuthenticatingState } from '@/auth/states/isAuthenticatingState'; import { App } from '~/App'; +import { FullHeightStorybookLayout } from '~/testing/FullHeightStorybookLayout'; import { graphqlMocks } from '~/testing/graphqlMocks'; +import { mockedUsersData } from '~/testing/mock-data/users'; -import { render } from './shared'; +const MockedAuth: React.FC = ({ children }) => { + const [, setCurrentUser] = useRecoilState(currentUserState); + const [, setIsAuthenticating] = useRecoilState(isAuthenticatingState); + + setCurrentUser(mockedUsersData[0]); + setIsAuthenticating(false); + + return <>{children}; +}; const meta: Meta = { title: 'App/App', component: App, + decorators: [ + (Story) => ( + + + + + + + + ), + ], + parameters: { + msw: graphqlMocks, + }, }; export default meta; export type Story = StoryObj; -export const Default: Story = { - render, +export const Default: Story = {}; + +export const DarkMode: Story = { parameters: { - msw: graphqlMocks, + theming: { + themeOverride: 'dark', + }, }, }; diff --git a/front/src/__stories__/shared.tsx b/front/src/__stories__/shared.tsx deleted file mode 100644 index b00a83017..000000000 --- a/front/src/__stories__/shared.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { MemoryRouter } from 'react-router-dom'; -import { ThemeProvider } from '@emotion/react'; -import { useRecoilState } from 'recoil'; - -import { currentUserState } from '@/auth/states/currentUserState'; -import { isAuthenticatingState } from '@/auth/states/isAuthenticatingState'; -import { darkTheme } from '@/ui/themes/themes'; -import { App } from '~/App'; -import { FullHeightStorybookLayout } from '~/testing/FullHeightStorybookLayout'; -import { mockedUsersData } from '~/testing/mock-data/users'; - -export const render = () => renderWithDarkMode(false); - -const MockedAuth: React.FC = ({ children }) => { - const [, setCurrentUser] = useRecoilState(currentUserState); - const [, setIsAuthenticating] = useRecoilState(isAuthenticatingState); - - setCurrentUser(mockedUsersData[0]); - setIsAuthenticating(false); - - return <>{children}; -}; - -export const renderWithDarkMode = (forceDarkMode?: boolean) => { - const AppInStoryBook = ( - - - - - - ); - - return ( - - {forceDarkMode ? ( - {AppInStoryBook} - ) : ( - AppInStoryBook - )} - - ); -}; diff --git a/front/src/modules/ui/button/components/__stories__/RoundedIconButton.stories.tsx b/front/src/modules/ui/button/components/__stories__/RoundedIconButton.stories.tsx index b2cea53cb..85c86e444 100644 --- a/front/src/modules/ui/button/components/__stories__/RoundedIconButton.stories.tsx +++ b/front/src/modules/ui/button/components/__stories__/RoundedIconButton.stories.tsx @@ -13,6 +13,7 @@ const meta: Meta = { title: 'UI/Button/RoundedIconButton', component: RoundedIconButton, decorators: [ComponentDecorator], + argTypes: { icon: { control: false } }, args: { onClick: clickJestFn, icon: }, }; diff --git a/front/src/modules/ui/table/table-header/components/__stories__/TableHeader.stories.tsx b/front/src/modules/ui/table/table-header/components/__stories__/TableHeader.stories.tsx index 9b5f75b79..c511d8466 100644 --- a/front/src/modules/ui/table/table-header/components/__stories__/TableHeader.stories.tsx +++ b/front/src/modules/ui/table/table-header/components/__stories__/TableHeader.stories.tsx @@ -2,37 +2,45 @@ import type { Meta, StoryObj } from '@storybook/react'; import { userEvent, within } from '@storybook/testing-library'; import { IconList } from '@/ui/icon/index'; +import { RecoilScope } from '@/ui/recoil-scope/components/RecoilScope'; +import { companiesFilters } from '~/pages/companies/companies-filters'; import { availableSorts } from '~/pages/companies/companies-sorts'; -import { getRenderWrapperForEntityTableComponent } from '~/testing/renderWrappers'; +import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; +import { HooksEntityTable } from '../../../components/HooksEntityTable'; +import { TableContext } from '../../../states/TableContext'; import { TableHeader } from '../TableHeader'; const meta: Meta = { title: 'UI/Table/TableHeader', component: TableHeader, + decorators: [ + (Story) => ( + + {/* TODO: add company mocked loader + + + ), + ComponentDecorator, + ], + argTypes: { viewIcon: { control: false } }, + args: { + viewName: 'ViewName', + viewIcon: , + availableSorts, + }, }; export default meta; type Story = StoryObj; -export const Empty: Story = { - render: getRenderWrapperForEntityTableComponent( - } - availableSorts={availableSorts} - />, - ), -}; +export const Empty: Story = {}; export const WithSortsAndFilters: Story = { - render: getRenderWrapperForEntityTableComponent( - } - availableSorts={availableSorts} - />, - ), play: async ({ canvasElement }) => { const canvas = within(canvasElement); const outsideClick = await canvas.findByText('ViewName'); diff --git a/front/src/pages/auth/__stories__/CreateProfile.stories.tsx b/front/src/pages/auth/__stories__/CreateProfile.stories.tsx index 7ec507db4..72a40a548 100644 --- a/front/src/pages/auth/__stories__/CreateProfile.stories.tsx +++ b/front/src/pages/auth/__stories__/CreateProfile.stories.tsx @@ -3,24 +3,22 @@ import type { Meta, StoryObj } from '@storybook/react'; import { within } from '@storybook/testing-library'; import { graphql } from 'msw'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; +import { mockedOnboardingUsersData } from '~/testing/mock-data/users'; import { GET_CURRENT_USER } from '../../../modules/users/queries'; -import { mockedOnboardingUsersData } from '../../../testing/mock-data/users'; import { CreateProfile } from '../CreateProfile'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Auth/CreateProfile', component: CreateProfile, -}; - -export default meta; - -export type Story = StoryObj; - -export const Default: Story = { - render: getRenderWrapperForPage(, '/create/profile'), + decorators: [PageDecorator], + args: { currentPath: '/create/profile' }, parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, msw: [ graphql.query( getOperationName(GET_CURRENT_USER) ?? '', @@ -34,6 +32,13 @@ export const Default: Story = { ), ], }, +}; + +export default meta; + +export type Story = StoryObj; + +export const Default: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); await canvas.findByText('Create profile'); diff --git a/front/src/pages/auth/__stories__/CreateWorkspace.stories.tsx b/front/src/pages/auth/__stories__/CreateWorkspace.stories.tsx index 616323593..80b43cf1c 100644 --- a/front/src/pages/auth/__stories__/CreateWorkspace.stories.tsx +++ b/front/src/pages/auth/__stories__/CreateWorkspace.stories.tsx @@ -3,24 +3,22 @@ import type { Meta, StoryObj } from '@storybook/react'; import { within } from '@storybook/testing-library'; import { graphql } from 'msw'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; +import { mockedOnboardingUsersData } from '~/testing/mock-data/users'; import { GET_CURRENT_USER } from '../../../modules/users/queries'; -import { mockedOnboardingUsersData } from '../../../testing/mock-data/users'; import { CreateWorkspace } from '../CreateWorkspace'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Auth/CreateWorkspace', component: CreateWorkspace, -}; - -export default meta; - -export type Story = StoryObj; - -export const Default: Story = { - render: getRenderWrapperForPage(, '/create/workspace'), + decorators: [PageDecorator], + args: { currentPath: '/create/workspace' }, parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, msw: [ graphql.query( getOperationName(GET_CURRENT_USER) ?? '', @@ -34,6 +32,13 @@ export const Default: Story = { ), ], }, +}; + +export default meta; + +export type Story = StoryObj; + +export const Default: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); await canvas.findByText('Create your workspace'); diff --git a/front/src/pages/auth/__stories__/SignInUp.stories.tsx b/front/src/pages/auth/__stories__/SignInUp.stories.tsx index 68032d93e..cee551bd5 100644 --- a/front/src/pages/auth/__stories__/SignInUp.stories.tsx +++ b/front/src/pages/auth/__stories__/SignInUp.stories.tsx @@ -1,14 +1,26 @@ import type { Meta, StoryObj } from '@storybook/react'; import { fireEvent, within } from '@storybook/testing-library'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { SignInUp } from '../SignInUp'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Auth/SignInUp', component: SignInUp, + decorators: [PageDecorator], + args: { currentPath: '/sign-in' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + cookie: { + tokenPair: '{}', + }, + }, }; export default meta; @@ -16,13 +28,6 @@ export default meta; export type Story = StoryObj; export const Default: Story = { - render: getRenderWrapperForPage(, '/sign-in'), - parameters: { - msw: graphqlMocks, - cookie: { - tokenPair: '{}', - }, - }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); const continueWithEmailButton = await canvas.findByText( diff --git a/front/src/pages/companies/__stories__/Companies.filterBy.stories.tsx b/front/src/pages/companies/__stories__/Companies.filterBy.stories.tsx index 501825f2c..834ae192a 100644 --- a/front/src/pages/companies/__stories__/Companies.filterBy.stories.tsx +++ b/front/src/pages/companies/__stories__/Companies.filterBy.stories.tsx @@ -3,23 +3,31 @@ import type { Meta } from '@storybook/react'; import { userEvent, within } from '@storybook/testing-library'; import assert from 'assert'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { sleep } from '~/testing/sleep'; import { Companies } from '../Companies'; import { Story } from './Companies.stories'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Companies/FilterBy', component: Companies, + decorators: [PageDecorator], + args: { currentPath: '/companies' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export const FilterByName: Story = { - render: getRenderWrapperForPage(, '/companies'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -50,13 +58,9 @@ export const FilterByName: Story = { expect(await canvas.findByText('Name:')).toBeInTheDocument(); expect(await canvas.findByText('Contains Air')).toBeInTheDocument(); }, - parameters: { - msw: graphqlMocks, - }, }; export const FilterByAccountOwner: Story = { - render: getRenderWrapperForPage(, '/companies'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -99,7 +103,4 @@ export const FilterByAccountOwner: Story = { expect(await canvas.findByText('Account owner:')).toBeInTheDocument(); expect(await canvas.findByText('Is Charles Test')).toBeInTheDocument(); }, - parameters: { - msw: graphqlMocks, - }, }; diff --git a/front/src/pages/companies/__stories__/Companies.sortBy.stories.tsx b/front/src/pages/companies/__stories__/Companies.sortBy.stories.tsx index 636eeac89..49b906dba 100644 --- a/front/src/pages/companies/__stories__/Companies.sortBy.stories.tsx +++ b/front/src/pages/companies/__stories__/Companies.sortBy.stories.tsx @@ -2,22 +2,30 @@ import { expect } from '@storybook/jest'; import type { Meta } from '@storybook/react'; import { userEvent, within } from '@storybook/testing-library'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { Companies } from '../Companies'; import { Story } from './Companies.stories'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Companies/SortBy', component: Companies, + decorators: [PageDecorator], + args: { currentPath: '/companies' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export const SortByName: Story = { - render: getRenderWrapperForPage(, '/companies'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -36,7 +44,4 @@ export const SortByName: Story = { await expect(canvas.queryAllByTestId('remove-icon-name')).toStrictEqual([]); }, - parameters: { - msw: graphqlMocks, - }, }; diff --git a/front/src/pages/companies/__stories__/Companies.stories.tsx b/front/src/pages/companies/__stories__/Companies.stories.tsx index 46f5bcba1..dd33f97dc 100644 --- a/front/src/pages/companies/__stories__/Companies.stories.tsx +++ b/front/src/pages/companies/__stories__/Companies.stories.tsx @@ -1,22 +1,26 @@ import type { Meta, StoryObj } from '@storybook/react'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { Companies } from '../Companies'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Companies', component: Companies, + decorators: [PageDecorator], + args: { currentPath: '/companies' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export type Story = StoryObj; -export const Default: Story = { - render: getRenderWrapperForPage(, '/companies'), - parameters: { - msw: graphqlMocks, - }, -}; +export const Default: Story = {}; diff --git a/front/src/pages/companies/__stories__/Company.stories.tsx b/front/src/pages/companies/__stories__/Company.stories.tsx index 02a9ca4f9..4adc139c3 100644 --- a/front/src/pages/companies/__stories__/Company.stories.tsx +++ b/front/src/pages/companies/__stories__/Company.stories.tsx @@ -10,57 +10,53 @@ import { } from '@/activities/queries'; import { CREATE_COMMENT_THREAD_WITH_COMMENT } from '@/activities/queries/create'; import { GET_COMPANY } from '@/companies/queries'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; import { mockedCommentThreads } from '~/testing/mock-data/comment-threads'; import { mockedCompaniesData } from '~/testing/mock-data/companies'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { CompanyShow } from '../CompanyShow'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Companies/Company', component: CompanyShow, + decorators: [PageDecorator], + args: { currentPath: '/companies/89bb825c-171e-4bcc-9cf7-43448d6fb278' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: [ + ...graphqlMocks, + graphql.query( + getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', + (req, res, ctx) => { + return res( + ctx.data({ + findManyCommentThreads: mockedCommentThreads, + }), + ); + }, + ), + graphql.query(getOperationName(GET_COMPANY) ?? '', (req, res, ctx) => { + return res( + ctx.data({ + findUniqueCompany: mockedCompaniesData[0], + }), + ); + }), + ], + }, }; export default meta; export type Story = StoryObj; -const companyShowCommonGraphqlMocks = [ - graphql.query( - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', - (req, res, ctx) => { - return res( - ctx.data({ - findManyCommentThreads: mockedCommentThreads, - }), - ); - }, - ), - graphql.query(getOperationName(GET_COMPANY) ?? '', (req, res, ctx) => { - return res( - ctx.data({ - findUniqueCompany: mockedCompaniesData[0], - }), - ); - }), -]; - -export const Default: Story = { - render: getRenderWrapperForPage( - , - '/companies/89bb825c-171e-4bcc-9cf7-43448d6fb278', - ), - parameters: { - msw: [...graphqlMocks, ...companyShowCommonGraphqlMocks], - }, -}; +export const Default: Story = {}; export const EditNote: Story = { - render: getRenderWrapperForPage( - , - '/companies/89bb825c-171e-4bcc-9cf7-43448d6fb278', - ), play: async ({ canvasElement }) => { const canvas = within(canvasElement); const firstNoteTitle = await canvas.findByText('My very first note'); @@ -84,8 +80,7 @@ export const EditNote: Story = { }, parameters: { msw: [ - ...graphqlMocks, - ...companyShowCommonGraphqlMocks, + ...meta.parameters?.msw, graphql.mutation( getOperationName(CREATE_COMMENT_THREAD_WITH_COMMENT) ?? '', (req, res, ctx) => { diff --git a/front/src/pages/opportunities/__stories__/Opportunities.stories.tsx b/front/src/pages/opportunities/__stories__/Opportunities.stories.tsx index 535ce77c6..b3abbf2a5 100644 --- a/front/src/pages/opportunities/__stories__/Opportunities.stories.tsx +++ b/front/src/pages/opportunities/__stories__/Opportunities.stories.tsx @@ -1,14 +1,23 @@ import type { Meta, StoryObj } from '@storybook/react'; import { within } from '@storybook/testing-library'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { Opportunities } from '../Opportunities'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Opportunities/Default', component: Opportunities, + decorators: [PageDecorator], + args: { currentPath: '/opportunities' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; @@ -16,10 +25,6 @@ export default meta; export type Story = StoryObj; export const Default: Story = { - render: getRenderWrapperForPage(, '/opportunities'), - parameters: { - msw: graphqlMocks, - }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await canvas.findByText('All opportunities'); diff --git a/front/src/pages/people/__stories__/People.filterBy.stories.tsx b/front/src/pages/people/__stories__/People.filterBy.stories.tsx index b16e1a48e..7da95d508 100644 --- a/front/src/pages/people/__stories__/People.filterBy.stories.tsx +++ b/front/src/pages/people/__stories__/People.filterBy.stories.tsx @@ -3,23 +3,31 @@ import type { Meta } from '@storybook/react'; import { userEvent, within } from '@storybook/testing-library'; import assert from 'assert'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { sleep } from '~/testing/sleep'; import { People } from '../People'; import { Story } from './People.stories'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/People/FilterBy', component: People, + decorators: [PageDecorator], + args: { currentPath: '/people' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export const Email: Story = { - render: getRenderWrapperForPage(, '/people'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -49,13 +57,9 @@ export const Email: Story = { expect(await canvas.findByText('Email:')).toBeInTheDocument(); expect(await canvas.findByText('Contains al')).toBeInTheDocument(); }, - parameters: { - msw: graphqlMocks, - }, }; export const CompanyName: Story = { - render: getRenderWrapperForPage(, '/people'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -98,7 +102,4 @@ export const CompanyName: Story = { expect(await canvas.findByText('Company:')).toBeInTheDocument(); expect(await canvas.findByText('Is Qonto')).toBeInTheDocument(); }, - parameters: { - msw: graphqlMocks, - }, }; diff --git a/front/src/pages/people/__stories__/People.inputs.stories.tsx b/front/src/pages/people/__stories__/People.inputs.stories.tsx index 657d634a6..b9a30ee02 100644 --- a/front/src/pages/people/__stories__/People.inputs.stories.tsx +++ b/front/src/pages/people/__stories__/People.inputs.stories.tsx @@ -7,26 +7,34 @@ import { graphql } from 'msw'; import { UPDATE_ONE_PERSON } from '@/people/queries'; import { SEARCH_COMPANY_QUERY } from '@/search/queries/search'; import { Company } from '~/generated/graphql'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; import { fetchOneFromData } from '~/testing/mock-data'; import { mockedCompaniesData } from '~/testing/mock-data/companies'; import { mockedPeopleData } from '~/testing/mock-data/people'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { sleep } from '~/testing/sleep'; import { People } from '../People'; import { Story } from './People.stories'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/People/Input', component: People, + decorators: [PageDecorator], + args: { currentPath: '/people' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export const InteractWithManyRows: Story = { - render: getRenderWrapperForPage(, '/people'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -64,13 +72,9 @@ export const InteractWithManyRows: Story = { canvas.queryByTestId('editable-cell-edit-mode-container'), ).toBeInTheDocument(); }, - parameters: { - msw: graphqlMocks, - }, }; export const CheckCheckboxes: Story = { - render: getRenderWrapperForPage(, '/people'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -95,9 +99,6 @@ export const CheckCheckboxes: Story = { expect(secondCheckbox.checked).toBe(false); }, - parameters: { - msw: graphqlMocks, - }, }; const editRelationMocks = ( @@ -185,7 +186,6 @@ const editRelationMocks = ( ]; export const EditRelation: Story = { - render: getRenderWrapperForPage(, '/people'), play: async ({ canvasElement, step }) => { const canvas = within(canvasElement); @@ -229,7 +229,6 @@ export const EditRelation: Story = { }); }, parameters: { - actions: {}, msw: editRelationMocks('Qonto', ['Airbnb', 'Aircall'], { name: 'Airbnb', domainName: 'airbnb.com', @@ -238,7 +237,6 @@ export const EditRelation: Story = { }; export const SelectRelationWithKeys: Story = { - render: getRenderWrapperForPage(, '/people'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -274,7 +272,6 @@ export const SelectRelationWithKeys: Story = { expect(allAirbns.length).toBe(1); }, parameters: { - actions: {}, msw: editRelationMocks('Qonto', ['Airbnb', 'Aircall'], { name: 'Aircall', domainName: 'aircall.io', diff --git a/front/src/pages/people/__stories__/People.sortBy.stories.tsx b/front/src/pages/people/__stories__/People.sortBy.stories.tsx index 4e2943d15..a5dfae896 100644 --- a/front/src/pages/people/__stories__/People.sortBy.stories.tsx +++ b/front/src/pages/people/__stories__/People.sortBy.stories.tsx @@ -2,23 +2,31 @@ import { expect } from '@storybook/jest'; import type { Meta } from '@storybook/react'; import { userEvent, within } from '@storybook/testing-library'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { sleep } from '~/testing/sleep'; import { People } from '../People'; import { Story } from './People.stories'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/People/SortBy', component: People, + decorators: [PageDecorator], + args: { currentPath: '/people' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export const Email: Story = { - render: getRenderWrapperForPage(, '/people'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -32,13 +40,9 @@ export const Email: Story = { expect(await canvas.findByText('Alexandre Prot')).toBeInTheDocument(); }, - parameters: { - msw: graphqlMocks, - }, }; export const Cancel: Story = { - render: getRenderWrapperForPage(, '/people'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); @@ -59,7 +63,4 @@ export const Cancel: Story = { [], ); }, - parameters: { - msw: graphqlMocks, - }, }; diff --git a/front/src/pages/people/__stories__/People.stories.tsx b/front/src/pages/people/__stories__/People.stories.tsx index 3dcbb42d8..07b4cf1f4 100644 --- a/front/src/pages/people/__stories__/People.stories.tsx +++ b/front/src/pages/people/__stories__/People.stories.tsx @@ -1,22 +1,26 @@ import type { Meta, StoryObj } from '@storybook/react'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { People } from '../People'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/People', component: People, + decorators: [PageDecorator], + args: { currentPath: '/people' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export type Story = StoryObj; -export const Default: Story = { - render: getRenderWrapperForPage(, '/people'), - parameters: { - msw: graphqlMocks, - }, -}; +export const Default: Story = {}; diff --git a/front/src/pages/people/__stories__/Person.stories.tsx b/front/src/pages/people/__stories__/Person.stories.tsx index 1cb16fc9e..5835ba544 100644 --- a/front/src/pages/people/__stories__/Person.stories.tsx +++ b/front/src/pages/people/__stories__/Person.stories.tsx @@ -1,30 +1,35 @@ import { Route, Routes } from 'react-router-dom'; import type { Meta, StoryObj } from '@storybook/react'; -import {} from '@storybook/react'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; import { mockedPeopleData } from '~/testing/mock-data/people'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { PersonShow } from '../PersonShow'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/People/Person', component: PersonShow, + decorators: [ + (Story) => ( + + } /> + + ), + PageDecorator, + ], + args: { currentPath: `/person/${mockedPeopleData[0].id}` }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export type Story = StoryObj; -export const Default: Story = { - render: getRenderWrapperForPage( - - } /> - , - `/person/${mockedPeopleData[0].id}`, - ), - parameters: { - msw: graphqlMocks, - }, -}; +export const Default: Story = {}; diff --git a/front/src/pages/settings/__stories__/SettingsProfile.stories.tsx b/front/src/pages/settings/__stories__/SettingsProfile.stories.tsx index fbd1ff2c2..7906be53b 100644 --- a/front/src/pages/settings/__stories__/SettingsProfile.stories.tsx +++ b/front/src/pages/settings/__stories__/SettingsProfile.stories.tsx @@ -1,35 +1,35 @@ import type { Meta, StoryObj } from '@storybook/react'; import { within } from '@storybook/testing-library'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { SettingsProfile } from '../SettingsProfile'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Settings/SettingsProfile', component: SettingsProfile, + decorators: [PageDecorator], + args: { currentPath: '/settings/profile' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; export type Story = StoryObj; -export const Default: Story = { - render: getRenderWrapperForPage(, '/settings/profile'), - parameters: { - msw: graphqlMocks, - }, -}; +export const Default: Story = {}; export const LogOut: Story = { - render: getRenderWrapperForPage(, '/settings/profile'), play: async ({ canvasElement }) => { const canvas = within(canvasElement); const logoutButton = await canvas.findByText('Logout'); await logoutButton.click(); }, - parameters: { - msw: graphqlMocks, - }, }; diff --git a/front/src/pages/settings/__stories__/SettingsWorkspaceMembers.stories.tsx b/front/src/pages/settings/__stories__/SettingsWorkspaceMembers.stories.tsx index b1f695bf8..3354a3ab7 100644 --- a/front/src/pages/settings/__stories__/SettingsWorkspaceMembers.stories.tsx +++ b/front/src/pages/settings/__stories__/SettingsWorkspaceMembers.stories.tsx @@ -1,14 +1,23 @@ import type { Meta, StoryObj } from '@storybook/react'; import { within } from '@storybook/testing-library'; +import { + PageDecorator, + type PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { getRenderWrapperForPage } from '~/testing/renderWrappers'; import { SettingsWorkspaceMembers } from '../SettingsWorkspaceMembers'; -const meta: Meta = { +const meta: Meta = { title: 'Pages/Settings/SettingsWorkspaceMembers', component: SettingsWorkspaceMembers, + decorators: [PageDecorator], + args: { currentPath: '/settings/workspace-members' }, + parameters: { + docs: { story: 'inline', iframeHeight: '500px' }, + msw: graphqlMocks, + }, }; export default meta; @@ -16,13 +25,6 @@ export default meta; export type Story = StoryObj; export const Default: Story = { - render: getRenderWrapperForPage( - , - '/settings/workspace-members', - ), - parameters: { - msw: graphqlMocks, - }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await canvas.findByText('Copy link'); diff --git a/front/src/testing/decorators/PageDecorator.tsx b/front/src/testing/decorators/PageDecorator.tsx new file mode 100644 index 000000000..4d9117172 --- /dev/null +++ b/front/src/testing/decorators/PageDecorator.tsx @@ -0,0 +1,30 @@ +import { HotkeysProvider } from 'react-hotkeys-hook'; +import { MemoryRouter } from 'react-router-dom'; +import { Decorator } from '@storybook/react'; + +import { ClientConfigProvider } from '../../modules/client-config/components/ClientConfigProvider'; +import { INITIAL_HOTKEYS_SCOPES } from '../../modules/ui/hotkey/constants'; +import { DefaultLayout } from '../../modules/ui/layout/components/DefaultLayout'; +import { UserProvider } from '../../modules/users/components/UserProvider'; +import { FullHeightStorybookLayout } from '../FullHeightStorybookLayout'; + +export type PageDecoratorArgs = { currentPath: string }; + +export const PageDecorator: Decorator<{ currentPath: string }> = ( + Story, + { args }, +) => ( + + + + + + + + + + + + + +); diff --git a/front/src/testing/renderWrappers.tsx b/front/src/testing/renderWrappers.tsx deleted file mode 100644 index 79f0698d0..000000000 --- a/front/src/testing/renderWrappers.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import { HotkeysProvider } from 'react-hotkeys-hook'; -import { MemoryRouter } from 'react-router-dom'; - -import { ClientConfigProvider } from '@/client-config/components/ClientConfigProvider'; -import { INITIAL_HOTKEYS_SCOPES } from '@/ui/hotkey/constants'; -import { DefaultLayout } from '@/ui/layout/components/DefaultLayout'; -import { RecoilScope } from '@/ui/recoil-scope/components/RecoilScope'; -import { HooksEntityTable } from '@/ui/table/components/HooksEntityTable'; -import { TableContext } from '@/ui/table/states/TableContext'; -import { UserProvider } from '@/users/components/UserProvider'; -import { companiesFilters } from '~/pages/companies/companies-filters'; - -import { ComponentStorybookLayout } from './ComponentStorybookLayout'; -import { FullHeightStorybookLayout } from './FullHeightStorybookLayout'; - -export function getRenderWrapperForPage( - children: React.ReactElement, - currentPath: string, -) { - return function render() { - return ( - - - - - - {children} - - - - - - ); - }; -} - -export function getRenderWrapperForEntityTableComponent( - children: React.ReactElement, -) { - return function Render() { - return ( - - {/* - TODO: add company mocked loader - - {children} - - ); - }; -}