Replace test-runner with vitest for storybook (#17187)

This commit is contained in:
Abdullah.
2026-01-18 08:25:45 +05:00
committed by GitHub
parent c737028dd6
commit 92eff62523
56 changed files with 4999 additions and 715 deletions
@@ -1,6 +1,7 @@
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { LayoutRenderingProvider } from '@/ui/layout/contexts/LayoutRenderingContext';
import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
@@ -9,6 +10,7 @@ import { getCompaniesMock } from '~/testing/mock-data/companies';
import { RecordDetailDuplicatesSection } from '@/object-record/record-field-list/record-detail-section/duplicate/components/RecordDetailDuplicatesSection';
import { ComponentDecorator } from 'twenty-ui/testing';
import { PageLayoutType } from '~/generated/graphql';
const companiesMock = getCompaniesMock();
@@ -17,6 +19,22 @@ const meta: Meta<typeof RecordDetailDuplicatesSection> = {
'Modules/ObjectRecord/RecordShow/RecordDetailSection/RecordDetailDuplicatesSection',
component: RecordDetailDuplicatesSection,
decorators: [
(Story) => (
<LayoutRenderingProvider
value={{
targetRecordIdentifier: {
id: companiesMock[0].id,
targetObjectNameSingular: 'company',
},
layoutType: PageLayoutType.RECORD_PAGE,
isInRightDrawer: false,
// TODO: Remove once the traditional record show page is removed.
isLegacyRecordShowPage: true,
}}
>
<Story />
</LayoutRenderingProvider>
),
ComponentDecorator,
ObjectMetadataItemsDecorator,
SnackBarDecorator,
@@ -2,7 +2,6 @@ import { FormArrayFieldInput } from '@/object-record/record-field/ui/form-types/
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
import { isDefined } from 'twenty-shared/utils';
import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing';
import { WorkflowStepDecorator } from '~/testing/decorators/WorkflowStepDecorator';
import { MOCKED_STEP_ID } from '~/testing/mock-data/workflow';
@@ -44,7 +43,7 @@ export const AddTwoItems: Story = {
});
const addItemButton = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Add item');
await userEvent.click(addItemButton);
@@ -54,7 +53,7 @@ export const AddTwoItems: Story = {
});
const newItemInput = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByRole('textbox');
await userEvent.type(newItemInput, 'Second item{enter}');
@@ -69,7 +68,7 @@ export const AddTwoItems: Story = {
const secondItemMenuItem = await waitFor(() => {
const allSecondItems = within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).getAllByText('Second item');
expect(allSecondItems).toHaveLength(2);
@@ -95,7 +94,7 @@ export const EditExistingItem: Story = {
await userEvent.click(firstItemChip);
const openSecondItemMenuButton = await waitFor(() => {
const button = getCanvasElementForDropdownTesting().querySelector(
const button = canvasElement.ownerDocument.body.querySelector(
'[aria-controls$="-1-options"] > button',
);
@@ -109,13 +108,13 @@ export const EditExistingItem: Story = {
await userEvent.click(openSecondItemMenuButton);
const editSecondItemButton = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Edit');
await userEvent.click(editSecondItemButton);
const editSecondItemInput = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByRole('textbox');
expect(editSecondItemInput).toHaveValue('Second item');
@@ -152,7 +151,7 @@ export const DeleteExistingItem: Story = {
await userEvent.click(firstItemChip);
const openSecondItemMenuButton = await waitFor(() => {
const button = getCanvasElementForDropdownTesting().querySelector(
const button = canvasElement.ownerDocument.body.querySelector(
'[aria-controls$="-1-options"] > button',
);
@@ -166,7 +165,7 @@ export const DeleteExistingItem: Story = {
await userEvent.click(openSecondItemMenuButton);
const deleteSecondItemButton = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Delete');
await userEvent.click(deleteSecondItemButton);
@@ -1,7 +1,6 @@
import { FormBooleanFieldInput } from '@/object-record/record-field/ui/form-types/components/FormBooleanFieldInput';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing';
import { WorkflowStepDecorator } from '~/testing/decorators/WorkflowStepDecorator';
import { MOCKED_STEP_ID } from '~/testing/mock-data/workflow';
@@ -118,7 +117,7 @@ export const ChangesValueToTrue: Story = {
await userEvent.click(select);
const trueOption = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('True');
await userEvent.click(trueOption);
@@ -143,7 +142,7 @@ export const ChangesValueToFalse: Story = {
await userEvent.click(select);
const falseOption = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('False');
await userEvent.click(falseOption);
@@ -1,7 +1,6 @@
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { useEffect } from 'react';
import { expect, fn, userEvent, within } from 'storybook/test';
import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing';
import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext';
import { useEmailsField } from '@/object-record/record-field/ui/meta-types/hooks/useEmailsField';
@@ -170,13 +169,13 @@ export const CanNotSetPrimaryLinkAsPrimaryLink: Story = {
await userEvent.click(openDropdownButtons[0]);
const editOption = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Edit');
expect(editOption).toBeVisible();
const setPrimaryOption = within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).queryByText('Set as Primary');
expect(setPrimaryOption).not.toBeInTheDocument();
@@ -11,7 +11,6 @@ import { RECORD_TABLE_CELL_INPUT_ID_PREFIX } from '@/object-record/record-table/
import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId';
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing';
import { FieldMetadataType } from '~/generated-metadata/graphql';
const updateRecord = fn();
@@ -296,7 +295,7 @@ export const DeletePrimaryLink: Story = {
await userEvent.click(openDropdownButton);
const deleteOption = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Delete');
await userEvent.click(deleteOption);
@@ -335,7 +334,7 @@ export const DeletePrimaryLinkAndUseSecondaryLinkAsTheNewPrimaryLink: Story = {
await userEvent.click(openDropdownButtons[0]);
const deleteOption = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Delete');
await userEvent.click(deleteOption);
@@ -377,7 +376,7 @@ export const DeleteSecondaryLink: Story = {
await userEvent.click(openDropdownButtons[1]);
const deleteOption = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Delete');
await userEvent.click(deleteOption);
@@ -485,7 +484,7 @@ export const MakeSecondaryLinkPrimary: Story = {
await userEvent.click(openDropdownButtons[1]); // Click the secondary link's dropdown
const setPrimaryOption = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Set as Primary');
await userEvent.click(setPrimaryOption);
},
@@ -514,7 +513,7 @@ export const CanNotSetPrimaryLinkAsPrimaryLink: Story = {
// Should not see "Set as Primary" option for primary link
const setPrimaryOption = within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).queryByText('Set as Primary');
expect(setPrimaryOption).not.toBeInTheDocument();
},
@@ -1,7 +1,6 @@
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { useEffect } from 'react';
import { expect, userEvent, within } from 'storybook/test';
import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing';
import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext';
import { usePhonesField } from '@/object-record/record-field/ui/meta-types/hooks/usePhonesField';
@@ -185,13 +184,13 @@ export const CanNotSetPrimaryLinkAsPrimaryLink: Story = {
await userEvent.click(openDropdownButtons[0]);
const editOption = await within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).findByText('Edit');
expect(editOption).toBeVisible();
const setPrimaryOption = within(
getCanvasElementForDropdownTesting(),
canvasElement.ownerDocument.body,
).queryByText('Set as Primary');
expect(setPrimaryOption).not.toBeInTheDocument();
@@ -25,7 +25,6 @@ import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePush
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { FieldMetadataType } from 'twenty-shared/types';
import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing';
import { RelationManyToOneFieldInput } from '@/object-record/record-field/ui/meta-types/input/components/RelationManyToOneFieldInput';
import { getFieldInputEventContextProviderWithJestMocks } from './utils/getFieldInputEventContextProviderWithJestMocks';
@@ -158,8 +157,8 @@ type Story = StoryObj<typeof RelationManyToOneFieldInputWithContext>;
export const Default: Story = {};
export const Submit: Story = {
play: async () => {
const canvas = within(getCanvasElementForDropdownTesting());
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(handleSubmitMocked).toHaveBeenCalledTimes(0);
@@ -176,8 +175,8 @@ export const Submit: Story = {
};
export const Cancel: Story = {
play: async () => {
const canvas = within(getCanvasElementForDropdownTesting());
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(handleCancelMocked).toHaveBeenCalledTimes(0);
await canvas.findByText('Linkedin', undefined, { timeout: 3000 });
@@ -47,15 +47,16 @@ export const Default: Story = {
};
export const HeaderMenuOpen: Story = {
play: async () => {
const canvas = within(document.body);
await canvas.findByText('Linkedin', {}, { timeout: 3000 });
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const body = within(canvasElement.ownerDocument.body);
await canvas.findAllByText('Linkedin', {}, { timeout: 3000 });
const headerMenuButton = await canvas.findByText('Domain Name');
await userEvent.click(headerMenuButton);
await canvas.findByText('Move right');
await body.findByText('Move right');
},
};
@@ -65,11 +66,11 @@ export const ScrolledLeft: Story = {
width: 1000,
},
},
play: async () => {
const canvas = within(document.body);
await canvas.findByText('Linkedin', {}, { timeout: 3000 });
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findAllByText('Linkedin', {}, { timeout: 3000 });
const scrollWrapper = document.body.querySelector(
const scrollWrapper = canvasElement.ownerDocument.body.querySelector(
'.scroll-wrapper-x-enabled',
);
@@ -95,11 +96,11 @@ export const ScrolledBottom: Story = {
height: 300,
},
},
play: async () => {
const canvas = within(document.body);
await canvas.findByText('Linkedin', {}, { timeout: 3000 });
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findAllByText('Linkedin', {}, { timeout: 3000 });
const scrollWrapper = document.body.querySelector(
const scrollWrapper = canvasElement.ownerDocument.body.querySelector(
'.scroll-wrapper-y-enabled',
);