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,5 +1,5 @@
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { useArgs } from 'storybook/preview-api';
import { useState } from 'react';
import { expect, userEvent, within } from 'storybook/test';
import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecorator';
@@ -11,16 +11,17 @@ import {
} from '@/ui/input/components/IconPicker';
import { ComponentDecorator } from 'twenty-ui/testing';
type RenderProps = IconPickerProps;
const Render = (args: RenderProps) => {
const [{ selectedIconKey }, updateArgs] = useArgs();
type IconPickerStoryProps = IconPickerProps;
const IconPickerStory = (args: IconPickerStoryProps) => {
const [selectedIconKey, setSelectedIconKey] = useState(args.selectedIconKey);
return (
<IconPicker
// eslint-disable-next-line react/jsx-props-no-spreading
{...args}
onChange={({ iconKey }) => {
updateArgs({ selectedIconKey: iconKey });
setSelectedIconKey(iconKey);
}}
selectedIconKey={selectedIconKey}
/>
@@ -31,7 +32,10 @@ const meta: Meta<typeof IconPicker> = {
title: 'UI/Input/IconPicker/IconPicker',
component: IconPicker,
decorators: [IconsProviderDecorator, ComponentDecorator],
render: Render,
render: (args: IconPickerProps) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<IconPickerStory key={args.selectedIconKey ?? 'no-selection'} {...args} />
),
};
export default meta;
@@ -40,8 +44,8 @@ type Story = StoryObj<typeof IconPicker>;
export const Default: Story = {};
export const WithOpen: Story = {
play: async () => {
const canvas = within(document.body);
play: async ({ canvasElement }) => {
const canvas = within(canvasElement.ownerDocument.body);
const iconPickerButton = await canvas.findByRole('button', {
name: 'Click to select icon (no icon selected)',
@@ -57,8 +61,8 @@ export const WithSelectedIcon: Story = {
export const WithOpenAndSelectedIcon: Story = {
...WithSelectedIcon,
play: async () => {
const canvas = within(document.body);
play: async ({ canvasElement }) => {
const canvas = within(canvasElement.ownerDocument.body);
const iconPickerButton = await canvas.findByRole('button', {
name: 'Click to select icon (selected: IconCalendarEvent)',
@@ -70,8 +74,8 @@ export const WithOpenAndSelectedIcon: Story = {
export const WithSearch: Story = {
...WithSelectedIcon,
play: async () => {
const canvas = within(document.body);
play: async ({ canvasElement }) => {
const canvas = within(canvasElement.ownerDocument.body);
const iconPickerButton = await canvas.findByRole('button', {
name: 'Click to select icon (selected: IconCalendarEvent)',
@@ -95,8 +99,8 @@ export const WithSearch: Story = {
export const WithSearchAndClose: Story = {
...WithSelectedIcon,
play: async () => {
const canvas = within(document.body);
play: async ({ canvasElement }) => {
const canvas = within(canvasElement.ownerDocument.body);
let iconPickerButton = await canvas.findByRole('button', {
name: 'Click to select icon (selected: IconCalendarEvent)',
@@ -128,8 +132,6 @@ export const WithSearchAndClose: Story = {
await userEvent.click(iconPickerButton);
await sleep(500);
searchInput = await canvas.findByRole('textbox');
expect(searchInput).toHaveValue('');
@@ -41,8 +41,8 @@ export const Disabled: Story = {
export const WithLabel: Story = {
args: { label: 'My Textarea' },
play: async () => {
const canvas = within(document.body);
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const label = await canvas.findByText('My Textarea');
@@ -1,33 +1,31 @@
import { DateTimePicker } from '@/ui/input/components/internal/date/components/DateTimePicker';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { useArgs } from 'storybook/preview-api';
import { useState } from 'react';
import { expect, userEvent, within } from 'storybook/test';
import { Temporal } from 'temporal-polyfill';
import { ComponentDecorator } from 'twenty-ui/testing';
const INITIAL_DATE = Temporal.ZonedDateTime.from(
'2023-01-01T02:00:00+00:00[UTC]',
);
const DateTimePickerStory = () => {
const [date, setDate] = useState<Temporal.ZonedDateTime | null>(INITIAL_DATE);
return (
<DateTimePicker
instanceId="story-date-time-picker"
date={date}
onChange={setDate}
/>
);
};
const meta: Meta<typeof DateTimePicker> = {
title: 'UI/Input/Internal/InternalDatePicker',
component: DateTimePicker,
decorators: [ComponentDecorator],
argTypes: {
date: { control: 'date' },
},
render: ({ date }) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [, updateArgs] = useArgs();
return (
<DateTimePicker
instanceId="story-date-time-picker"
date={date}
onChange={(newDate) => updateArgs({ date: newDate })}
/>
);
},
args: {
date: Temporal.Instant.from('2023-01-01T02:00:00Z').toZonedDateTimeISO(
'UTC',
),
},
render: () => <DateTimePickerStory />,
};
export default meta;
@@ -36,14 +34,15 @@ type Story = StoryObj<typeof DateTimePicker>;
export const Default: Story = {};
export const WithOpenMonthSelect: Story = {
play: async () => {
const canvas = within(document.body);
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const body = within(canvasElement.ownerDocument.body);
const monthSelect = await canvas.findByText('January');
await userEvent.click(monthSelect);
[
for (const monthLabel of [
'February',
'March',
'April',
@@ -55,29 +54,30 @@ export const WithOpenMonthSelect: Story = {
'October',
'November',
'December',
].forEach(async (monthLabel) =>
expect(await canvas.findByText(monthLabel)).toBeInTheDocument(),
);
]) {
expect(await body.findByText(monthLabel)).toBeInTheDocument();
}
await userEvent.click(await canvas.findByText('February'));
await userEvent.click(await body.findByText('February'));
expect(await canvas.findByText('February')).toBeInTheDocument();
},
};
export const WithOpenYearSelect: Story = {
play: async () => {
const canvas = within(document.body);
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const body = within(canvasElement.ownerDocument.body);
const yearSelect = await canvas.findByText('2023');
await userEvent.click(yearSelect);
['2024', '2025', '2026'].forEach(async (yearLabel) =>
expect(await canvas.findByText(yearLabel)).toBeInTheDocument(),
);
for (const yearLabel of ['2024', '2025', '2026']) {
expect(await body.findByText(yearLabel)).toBeInTheDocument();
}
await userEvent.click(await canvas.findByText('2024'));
await userEvent.click(await body.findByText('2024'));
expect(await canvas.findByText('2024')).toBeInTheDocument();
},