Replace test-runner with vitest for storybook (#17187)
This commit is contained in:
+18
-16
@@ -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('');
|
||||
|
||||
+2
-2
@@ -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');
|
||||
|
||||
|
||||
+33
-33
@@ -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();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user