@12-apps/ui 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +17 -9
- package/src/button/index.ts +1 -0
- package/src/social-login-button/index.ts +1 -0
- package/src/{social-login-button.tsx → social-login-button/social-login-button.tsx} +5 -5
- package/src/user-avatar/index.ts +1 -0
- package/src/{user-avatar.tsx → user-avatar/user-avatar.tsx} +4 -4
- package/eslint.config.js +0 -89
- package/src/__tests__/data-grid.test.tsx +0 -125
- package/src/__tests__/package-wiring.test.ts +0 -41
- package/src/__tests__/setup.ts +0 -1
- package/src/__tests__/social-login-button.test.tsx +0 -186
- package/src/__tests__/user-avatar.test.tsx +0 -195
- package/src/__tests__/viewport.test.ts +0 -50
- package/src/components/command/__tests__/command.test.tsx +0 -112
- package/src/components/data-display/Alert/Alert.stories.tsx +0 -559
- package/src/components/data-display/Alert/Alert.test.stories.tsx +0 -707
- package/src/components/data-display/AlertDialog/AlertDialog.stories.tsx +0 -362
- package/src/components/data-display/AlertDialog/AlertDialog.test.stories.tsx +0 -763
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.stories.tsx +0 -230
- package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.test.stories.tsx +0 -270
- package/src/components/data-display/Avatar/Avatar.stories.tsx +0 -721
- package/src/components/data-display/Avatar/Avatar.test.stories.tsx +0 -822
- package/src/components/data-display/Badge/Badge.stories.tsx +0 -1134
- package/src/components/data-display/Badge/Badge.test.stories.tsx +0 -1194
- package/src/components/data-display/Banner/Banner.stories.tsx +0 -528
- package/src/components/data-display/Banner/Banner.test.stories.tsx +0 -511
- package/src/components/data-display/Carousel/Carousel.stories.tsx +0 -607
- package/src/components/data-display/Carousel/Carousel.test.stories.tsx +0 -701
- package/src/components/data-display/Chart/Chart.stories.tsx +0 -568
- package/src/components/data-display/Chart/Chart.test.stories.tsx +0 -174
- package/src/components/data-display/Chart/SpecChart.stories.tsx +0 -150
- package/src/components/data-display/Chart/SpecChart.test.stories.tsx +0 -56
- package/src/components/data-display/Chart/__tests__/SpecChart.test.tsx +0 -60
- package/src/components/data-display/Chart/__tests__/chart-format.test.ts +0 -43
- package/src/components/data-display/Chart/__tests__/chart-spec.test.ts +0 -119
- package/src/components/data-display/Chip/Chip.stories.tsx +0 -252
- package/src/components/data-display/Chip/Chip.test.stories.tsx +0 -266
- package/src/components/data-display/DataGrid/DataGrid.stories.tsx +0 -515
- package/src/components/data-display/DataGrid/DataGrid.test.stories.tsx +0 -653
- package/src/components/data-display/DataViews/__tests__/DataViewsGrid.test.tsx +0 -271
- package/src/components/data-display/DataViews/__tests__/DataViewsTableBase.test.tsx +0 -134
- package/src/components/data-display/DataViews/__tests__/SaveViewModal.test.tsx +0 -83
- package/src/components/data-display/DataViews/__tests__/data-views-filter.test.ts +0 -115
- package/src/components/data-display/DataViews/__tests__/data-views-preview.test.ts +0 -53
- package/src/components/data-display/DataViews/__tests__/range-pill.test.tsx +0 -114
- package/src/components/data-display/DataViews/base-card.stories.tsx +0 -136
- package/src/components/data-display/DescriptionItem/DescriptionItem.stories.tsx +0 -254
- package/src/components/data-display/EmptyState/EmptyState.stories.tsx +0 -282
- package/src/components/data-display/EmptyState/EmptyState.test.stories.tsx +0 -441
- package/src/components/data-display/ErrorState/ErrorState.stories.tsx +0 -110
- package/src/components/data-display/ErrorState/ErrorState.test.stories.tsx +0 -133
- package/src/components/data-display/HoverCard/HoverCard.stories.tsx +0 -650
- package/src/components/data-display/HoverCard/HoverCard.test.stories.tsx +0 -929
- package/src/components/data-display/InteractiveTooltip/InteractiveTooltip.stories.tsx +0 -411
- package/src/components/data-display/LazyImage/LazyImage.stories.tsx +0 -387
- package/src/components/data-display/Lightbox/Lightbox.stories.tsx +0 -315
- package/src/components/data-display/Lightbox/Lightbox.test.stories.tsx +0 -598
- package/src/components/data-display/LoadingState/LoadingState.stories.tsx +0 -124
- package/src/components/data-display/LoadingState/LoadingState.test.stories.tsx +0 -99
- package/src/components/data-display/MapPreview/MapPreview.stories.tsx +0 -458
- package/src/components/data-display/MapPreview/MapPreview.test.stories.tsx +0 -394
- package/src/components/data-display/Popover/Popover.stories.tsx +0 -295
- package/src/components/data-display/Popover/Popover.test.stories.tsx +0 -1162
- package/src/components/data-display/Progress/Progress.stories.tsx +0 -481
- package/src/components/data-display/Progress/Progress.test.stories.tsx +0 -2070
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.stories.tsx +0 -160
- package/src/components/data-display/SectionOnboarding/SectionOnboarding.test.stories.tsx +0 -190
- package/src/components/data-display/Sheet/Sheet.stories.tsx +0 -883
- package/src/components/data-display/Sheet/Sheet.test.stories.tsx +0 -1105
- package/src/components/data-display/StatCard/StatCard.stories.tsx +0 -167
- package/src/components/data-display/StatCard/StatCard.test.stories.tsx +0 -240
- package/src/components/data-display/Stepper/Stepper.stories.tsx +0 -540
- package/src/components/data-display/Stepper/Stepper.test.stories.tsx +0 -600
- package/src/components/data-display/Table/Table.stories.tsx +0 -803
- package/src/components/data-display/Table/Table.test.stories.tsx +0 -369
- package/src/components/data-display/Timeline/Timeline.stories.tsx +0 -442
- package/src/components/data-display/Timeline/Timeline.test.stories.tsx +0 -930
- package/src/components/data-display/TimingDiagram/TimingDiagram.stories.tsx +0 -475
- package/src/components/data-display/TimingDiagram/TimingDiagram.test.stories.tsx +0 -734
- package/src/components/data-display/Tooltip/Tooltip.stories.tsx +0 -468
- package/src/components/data-display/Tooltip/Tooltip.test.stories.tsx +0 -1154
- package/src/components/feedback/ConfirmAction/ConfirmAction.stories.tsx +0 -146
- package/src/components/feedback/ConfirmAction/ConfirmAction.test.stories.tsx +0 -114
- package/src/components/feedback/ConfirmAction/__tests__/confirm-action.test.tsx +0 -288
- package/src/components/feedback/Dialog/Dialog.stories.tsx +0 -833
- package/src/components/feedback/Dialog/Dialog.test.stories.tsx +0 -964
- package/src/components/feedback/Dialog/__tests__/dialog-content-spacing.test.tsx +0 -66
- package/src/components/feedback/Modal/Modal.stories.tsx +0 -765
- package/src/components/feedback/Modal/Modal.test.stories.tsx +0 -251
- package/src/components/feedback/Sonner/Sonner.stories.tsx +0 -698
- package/src/components/feedback/Sonner/Sonner.test.stories.tsx +0 -896
- package/src/components/feedback/StackedModal/StackedModal.stories.tsx +0 -1783
- package/src/components/feedback/StackedModal/StackedModal.test.stories.tsx +0 -973
- package/src/components/feedback/StackedModal/__tests__/stacked-modal-viewport.test.tsx +0 -104
- package/src/components/feedback/Toast/Toast.stories.tsx +0 -548
- package/src/components/feedback/Toast/Toast.test.stories.tsx +0 -834
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.stories.tsx +0 -691
- package/src/components/feedback/TutorialOverlay/TutorialOverlay.test.stories.tsx +0 -634
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.stories.tsx +0 -665
- package/src/components/form/AddressAutocomplete/AddressAutocomplete.test.stories.tsx +0 -727
- package/src/components/form/Autocomplete/Autocomplete.stories.tsx +0 -715
- package/src/components/form/Autocomplete/Autocomplete.test.stories.tsx +0 -825
- package/src/components/form/Button/Button.stories.tsx +0 -365
- package/src/components/form/Button/Button.test.stories.tsx +0 -607
- package/src/components/form/Calendar/Calendar.stories.tsx +0 -349
- package/src/components/form/Calendar/Calendar.test.stories.tsx +0 -464
- package/src/components/form/CepField/CepField.stories.tsx +0 -138
- package/src/components/form/CepField/CepField.test.stories.tsx +0 -281
- package/src/components/form/Checkbox/Checkbox.stories.tsx +0 -265
- package/src/components/form/Checkbox/Checkbox.test.stories.tsx +0 -181
- package/src/components/form/CodeEditor/CodeEditor.stories.tsx +0 -871
- package/src/components/form/CodeEditor/CodeEditor.test.stories.tsx +0 -574
- package/src/components/form/Command/Command.stories.tsx +0 -580
- package/src/components/form/Command/Command.test.stories.tsx +0 -215
- package/src/components/form/CreatableSelect/CreatableSelect.stories.tsx +0 -112
- package/src/components/form/CreatableSelect/CreatableSelect.test.stories.tsx +0 -134
- package/src/components/form/Form/Form.stories.tsx +0 -687
- package/src/components/form/Form/Form.test.stories.tsx +0 -601
- package/src/components/form/Input/Input.stories.tsx +0 -260
- package/src/components/form/Input/Input.test.stories.tsx +0 -1191
- package/src/components/form/InputOTP/InputOTP.stories.tsx +0 -774
- package/src/components/form/InputOTP/InputOTP.test.stories.tsx +0 -588
- package/src/components/form/Label/Label.stories.tsx +0 -473
- package/src/components/form/Label/Label.test.stories.tsx +0 -915
- package/src/components/form/Menubar/Menubar.stories.tsx +0 -472
- package/src/components/form/Menubar/Menubar.test.stories.tsx +0 -584
- package/src/components/form/PasswordStrength/PasswordStrength.stories.tsx +0 -562
- package/src/components/form/PasswordStrength/PasswordStrength.test.stories.tsx +0 -327
- package/src/components/form/PhoneInput/PhoneInput.stories.tsx +0 -495
- package/src/components/form/PhoneInput/PhoneInput.test.stories.tsx +0 -666
- package/src/components/form/RadioGroup/RadioGroup.stories.tsx +0 -518
- package/src/components/form/RadioGroup/RadioGroup.test.stories.tsx +0 -685
- package/src/components/form/RichTextEditor/RichTextEditor.stories.tsx +0 -261
- package/src/components/form/RichTextEditor/RichTextEditor.test.stories.tsx +0 -491
- package/src/components/form/SearchPalette/SearchPalette.stories.tsx +0 -135
- package/src/components/form/Select/Select.stories.tsx +0 -364
- package/src/components/form/Select/Select.test.stories.tsx +0 -985
- package/src/components/form/Slider/Slider.stories.tsx +0 -418
- package/src/components/form/Slider/Slider.test.stories.tsx +0 -1042
- package/src/components/form/Switch/Switch.stories.tsx +0 -697
- package/src/components/form/Switch/Switch.test.stories.tsx +0 -597
- package/src/components/form/Textarea/Textarea.stories.tsx +0 -473
- package/src/components/form/Textarea/Textarea.test.stories.tsx +0 -702
- package/src/components/form/Toggle/Toggle.stories.tsx +0 -638
- package/src/components/form/Toggle/Toggle.test.stories.tsx +0 -1159
- package/src/components/form/ToggleGroup/ToggleGroup.stories.tsx +0 -617
- package/src/components/form/ToggleGroup/ToggleGroup.test.stories.tsx +0 -915
- package/src/components/form/UploadButton/UploadButton.stories.tsx +0 -367
- package/src/components/form/UploadButton/UploadButton.test.stories.tsx +0 -573
- package/src/components/form/total-form/total-form.test.tsx +0 -214
- package/src/components/layout/Accordion/Accordion.stories.tsx +0 -694
- package/src/components/layout/Accordion/Accordion.test.stories.tsx +0 -1344
- package/src/components/layout/Card/Card.stories.tsx +0 -591
- package/src/components/layout/Card/Card.test.stories.tsx +0 -1134
- package/src/components/layout/CardGrid/__tests__/CardGrid.test.tsx +0 -92
- package/src/components/layout/Collapsible/Collapsible.stories.tsx +0 -180
- package/src/components/layout/Collapsible/Collapsible.test.stories.tsx +0 -308
- package/src/components/layout/Container/Container.stories.tsx +0 -557
- package/src/components/layout/Container/Container.test.stories.tsx +0 -745
- package/src/components/layout/ContentToolbar/ContentToolbar.stories.tsx +0 -129
- package/src/components/layout/ContentToolbar/ContentToolbar.test.stories.tsx +0 -251
- package/src/components/layout/ContentToolbar/__tests__/ColumnsMenu.test.tsx +0 -39
- package/src/components/layout/ContentToolbar/__tests__/MultiSelectDropdown.test.tsx +0 -131
- package/src/components/layout/ContentToolbar/__tests__/SavedViewsMenu.test.tsx +0 -99
- package/src/components/layout/Dashboard/Dashboard.stories.tsx +0 -104
- package/src/components/layout/Dashboard/Dashboard.test.stories.tsx +0 -190
- package/src/components/layout/Drawer/Drawer.stories.tsx +0 -658
- package/src/components/layout/Drawer/Drawer.test.stories.tsx +0 -1343
- package/src/components/layout/Resizable/Resizable.stories.tsx +0 -1039
- package/src/components/layout/Resizable/Resizable.test.stories.tsx +0 -754
- package/src/components/layout/ScrollArea/ScrollArea.stories.tsx +0 -651
- package/src/components/layout/ScrollArea/ScrollArea.test.stories.tsx +0 -619
- package/src/components/layout/Separator/Separator.stories.tsx +0 -563
- package/src/components/layout/Separator/Separator.test.stories.tsx +0 -518
- package/src/components/layout/SettingsLayout/SettingsLayout.stories.tsx +0 -192
- package/src/components/layout/SettingsLayout/SettingsLayout.test.stories.tsx +0 -175
- package/src/components/layout/Sidebar/Sidebar.stories.tsx +0 -609
- package/src/components/layout/Sidebar/Sidebar.test.stories.tsx +0 -1324
- package/src/components/layout/Skeleton/Skeleton.stories.tsx +0 -689
- package/src/components/layout/Skeleton/Skeleton.test.stories.tsx +0 -521
- package/src/components/layout/Spacer/Spacer.stories.tsx +0 -502
- package/src/components/layout/Spacer/Spacer.test.stories.tsx +0 -474
- package/src/components/layout/TableFilter/TableFilter.stories.tsx +0 -82
- package/src/components/layout/TableFilter/TableFilter.test.stories.tsx +0 -87
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.stories.tsx +0 -638
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.test.stories.tsx +0 -1008
- package/src/components/navigation/CommandPalette/CommandPalette.stories.tsx +0 -386
- package/src/components/navigation/CommandPalette/CommandPalette.test.stories.tsx +0 -435
- package/src/components/navigation/ContextMenu/ContextMenu.stories.tsx +0 -614
- package/src/components/navigation/ContextMenu/ContextMenu.test.stories.tsx +0 -845
- package/src/components/navigation/DropdownMenu/DropdownMenu.stories.tsx +0 -578
- package/src/components/navigation/DropdownMenu/DropdownMenu.test.stories.tsx +0 -660
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.stories.tsx +0 -516
- package/src/components/navigation/NavigationMenu/stories/NavigationMenu.test.stories.tsx +0 -935
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuHorizontal.stories.tsx +0 -501
- package/src/components/navigation/NavigationMenu/stories/NavigationMenuVertical.stories.tsx +0 -453
- package/src/components/navigation/Pagination/Pagination.stories.tsx +0 -602
- package/src/components/navigation/Pagination/Pagination.test.stories.tsx +0 -520
- package/src/components/navigation/Tabs/Tabs.stories.tsx +0 -1004
- package/src/components/navigation/Tabs/Tabs.test.stories.tsx +0 -1225
- package/src/components/typography/Blockquote/Blockquote.stories.tsx +0 -359
- package/src/components/typography/Blockquote/Blockquote.test.stories.tsx +0 -432
- package/src/components/typography/Code/Code.stories.tsx +0 -686
- package/src/components/typography/Code/Code.test.stories.tsx +0 -703
- package/src/components/typography/Heading/Heading.stories.tsx +0 -451
- package/src/components/typography/Heading/Heading.test.stories.tsx +0 -830
- package/src/components/typography/Paragraph/Paragraph.stories.tsx +0 -280
- package/src/components/typography/Paragraph/Paragraph.test.stories.tsx +0 -231
- package/src/components/typography/Text/Text.stories.tsx +0 -359
- package/src/components/typography/Text/Text.test.stories.tsx +0 -759
- package/src/components/utility/AnimatedIcon/AnimatedIcon.stories.tsx +0 -945
- package/src/components/utility/AnimatedIcon/AnimatedIcon.test.stories.tsx +0 -603
- package/src/components/utility/AspectRatio/AspectRatio.stories.tsx +0 -414
- package/src/components/utility/AspectRatio/AspectRatio.test.stories.tsx +0 -859
- package/src/components/utility/InfiniteScroll/InfiniteScroll.stories.tsx +0 -620
- package/src/components/utility/InfiniteScroll/InfiniteScroll.test.stories.tsx +0 -361
- package/src/components/utility/InstallPrompt/InstallPrompt.stories.tsx +0 -118
- package/src/components/utility/InstallPrompt/InstallPrompt.test.stories.tsx +0 -83
- package/src/components/utility/InstallPrompt/__tests__/InstallPrompt.ios.test.tsx +0 -65
- package/src/components/utility/InstallPrompt/__tests__/usePwaInstall.test.tsx +0 -271
- package/src/components/utility/Portal/Portal.stories.tsx +0 -340
- package/src/components/utility/Portal/Portal.test.stories.tsx +0 -2086
- package/src/components/utility/Transition/Transition.stories.tsx +0 -493
- package/src/components/utility/Transition/Transition.test.stories.tsx +0 -854
- package/src/components/utility/VirtualList/VirtualList.stories.tsx +0 -1073
- package/src/components/utility/VirtualList/VirtualList.test.stories.tsx +0 -1085
- package/src/components/utility/WorkflowStep/WorkflowStep.stories.tsx +0 -431
- package/src/components/utility/WorkflowStep/WorkflowStep.test.stories.tsx +0 -364
- /package/src/{button.tsx → button/button.tsx} +0 -0
|
@@ -1,702 +0,0 @@
|
|
|
1
|
-
import { Box, createTheme,ThemeProvider } from '@mui/material';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
|
4
|
-
|
|
5
|
-
import { Textarea } from './Textarea';
|
|
6
|
-
|
|
7
|
-
const meta: Meta<typeof Textarea> = {
|
|
8
|
-
title: 'Form/Textarea/Tests',
|
|
9
|
-
component: Textarea,
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: 'centered',
|
|
12
|
-
chromatic: { disableSnapshot: false },
|
|
13
|
-
},
|
|
14
|
-
tags: ['autodocs', 'test', 'component:Textarea'],
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export default meta;
|
|
18
|
-
type Story = StoryObj<typeof meta>;
|
|
19
|
-
|
|
20
|
-
// 1. Basic Interaction Tests
|
|
21
|
-
export const BasicInteraction: Story = {
|
|
22
|
-
args: {
|
|
23
|
-
placeholder: 'Type your message here...',
|
|
24
|
-
'dataTestId': 'basic-textarea',
|
|
25
|
-
},
|
|
26
|
-
play: async ({ canvasElement, step }) => {
|
|
27
|
-
const canvas = within(canvasElement);
|
|
28
|
-
|
|
29
|
-
await step('Find textarea element', async () => {
|
|
30
|
-
const textarea = canvas.getByRole('textbox');
|
|
31
|
-
expect(textarea).toBeInTheDocument();
|
|
32
|
-
expect(textarea).toHaveAttribute('placeholder', 'Type your message here...');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
await step('Type text into textarea', async () => {
|
|
36
|
-
const textarea = canvas.getByRole('textbox');
|
|
37
|
-
await userEvent.click(textarea);
|
|
38
|
-
await userEvent.type(textarea, 'Hello World!\nThis is a second line.');
|
|
39
|
-
expect(textarea).toHaveValue('Hello World!\nThis is a second line.');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
await step('Clear and retype text', async () => {
|
|
43
|
-
const textarea = canvas.getByRole('textbox');
|
|
44
|
-
await userEvent.clear(textarea);
|
|
45
|
-
await userEvent.type(textarea, 'New content');
|
|
46
|
-
expect(textarea).toHaveValue('New content');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
await step('Verify special character input', async () => {
|
|
50
|
-
const textarea = canvas.getByRole('textbox');
|
|
51
|
-
await userEvent.clear(textarea);
|
|
52
|
-
// Test various special characters without problematic brackets
|
|
53
|
-
await userEvent.type(textarea, 'Special chars: @#$%^&*()_+-=;:,.<>?/~`');
|
|
54
|
-
expect(textarea).toHaveValue('Special chars: @#$%^&*()_+-=;:,.<>?/~`');
|
|
55
|
-
});
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// 2. Form Interaction Tests
|
|
60
|
-
export const FormInteraction: Story = {
|
|
61
|
-
args: {
|
|
62
|
-
placeholder: 'Enter form message...',
|
|
63
|
-
name: 'message',
|
|
64
|
-
required: true,
|
|
65
|
-
'dataTestId': 'form-textarea',
|
|
66
|
-
},
|
|
67
|
-
decorators: [
|
|
68
|
-
(Story) => (
|
|
69
|
-
<form>
|
|
70
|
-
<Story />
|
|
71
|
-
<button type="submit">Submit</button>
|
|
72
|
-
</form>
|
|
73
|
-
),
|
|
74
|
-
],
|
|
75
|
-
play: async ({ canvasElement, step }) => {
|
|
76
|
-
const canvas = within(canvasElement);
|
|
77
|
-
|
|
78
|
-
await step('Interact with textarea in form context', async () => {
|
|
79
|
-
const textarea = canvas.getByRole('textbox');
|
|
80
|
-
const submitButton = canvas.getByRole('button', { name: 'Submit' });
|
|
81
|
-
|
|
82
|
-
expect(textarea).toBeInTheDocument();
|
|
83
|
-
expect(textarea).toHaveAttribute('name', 'message');
|
|
84
|
-
expect(textarea).toHaveAttribute('required');
|
|
85
|
-
expect(submitButton).toBeInTheDocument();
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
await step('Fill textarea and verify form data', async () => {
|
|
89
|
-
const textarea = canvas.getByRole('textbox');
|
|
90
|
-
await userEvent.click(textarea);
|
|
91
|
-
await userEvent.type(textarea, 'Form submission test\nMultiple lines supported');
|
|
92
|
-
expect(textarea).toHaveValue('Form submission test\nMultiple lines supported');
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
await step('Test form validation behavior', async () => {
|
|
96
|
-
const textarea = canvas.getByRole('textbox');
|
|
97
|
-
await userEvent.clear(textarea);
|
|
98
|
-
|
|
99
|
-
// Required field should trigger validation when empty
|
|
100
|
-
expect(textarea).toHaveValue('');
|
|
101
|
-
expect(textarea).toHaveAttribute('required');
|
|
102
|
-
});
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
// 3. Rich Text Editor Tests
|
|
107
|
-
export const RichTextEditor: Story = {
|
|
108
|
-
args: {
|
|
109
|
-
variant: 'rich',
|
|
110
|
-
placeholder: 'Rich text editor...',
|
|
111
|
-
label: 'Rich Text Content',
|
|
112
|
-
'dataTestId': 'rich-textarea',
|
|
113
|
-
},
|
|
114
|
-
play: async ({ canvasElement, step }) => {
|
|
115
|
-
const canvas = within(canvasElement);
|
|
116
|
-
|
|
117
|
-
await step('Find rich text editor components', async () => {
|
|
118
|
-
const label = canvas.getByText('Rich Text Content');
|
|
119
|
-
expect(label).toBeInTheDocument();
|
|
120
|
-
|
|
121
|
-
// Look for toolbar buttons
|
|
122
|
-
const boldButton = canvas.getByRole('button', { name: /bold/i });
|
|
123
|
-
const italicButton = canvas.getByRole('button', { name: /italic/i });
|
|
124
|
-
expect(boldButton).toBeInTheDocument();
|
|
125
|
-
expect(italicButton).toBeInTheDocument();
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
await step('Test rich text toolbar interactions', async () => {
|
|
129
|
-
const boldButton = canvas.getByRole('button', { name: /bold/i });
|
|
130
|
-
const italicButton = canvas.getByRole('button', { name: /italic/i });
|
|
131
|
-
|
|
132
|
-
// Click toolbar buttons
|
|
133
|
-
await userEvent.click(boldButton);
|
|
134
|
-
await userEvent.click(italicButton);
|
|
135
|
-
|
|
136
|
-
// Toolbar buttons should be interactive
|
|
137
|
-
expect(boldButton).toBeEnabled();
|
|
138
|
-
expect(italicButton).toBeEnabled();
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
await step('Test content editing in rich text mode', async () => {
|
|
142
|
-
// Find the contenteditable div
|
|
143
|
-
const editableArea =
|
|
144
|
-
canvas.getByRole('textbox') || canvasElement.querySelector('[contenteditable="true"]');
|
|
145
|
-
|
|
146
|
-
if (editableArea) {
|
|
147
|
-
await userEvent.click(editableArea);
|
|
148
|
-
// Rich text editor should be focusable
|
|
149
|
-
await waitFor(() => expect(document.activeElement).toBe(editableArea));
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// 4. Keyboard Navigation Tests
|
|
156
|
-
export const KeyboardNavigation: Story = {
|
|
157
|
-
args: {
|
|
158
|
-
placeholder: 'Test keyboard navigation...',
|
|
159
|
-
'dataTestId': 'keyboard-textarea',
|
|
160
|
-
},
|
|
161
|
-
play: async ({ canvasElement, step }) => {
|
|
162
|
-
const canvas = within(canvasElement);
|
|
163
|
-
|
|
164
|
-
await step('Focus textarea with Tab key', async () => {
|
|
165
|
-
const textarea = canvas.getByRole('textbox');
|
|
166
|
-
|
|
167
|
-
// Tab to focus
|
|
168
|
-
await userEvent.tab();
|
|
169
|
-
await waitFor(() => expect(textarea).toHaveFocus());
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
await step('Test Enter key behavior', async () => {
|
|
173
|
-
const textarea = canvas.getByRole('textbox');
|
|
174
|
-
await userEvent.click(textarea);
|
|
175
|
-
await userEvent.type(textarea, 'First line');
|
|
176
|
-
await userEvent.keyboard('{Enter}');
|
|
177
|
-
await userEvent.type(textarea, 'Second line');
|
|
178
|
-
|
|
179
|
-
expect(textarea).toHaveValue('First line\nSecond line');
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
await step('Test text selection with keyboard shortcuts', async () => {
|
|
183
|
-
const textarea = canvas.getByRole('textbox');
|
|
184
|
-
await userEvent.click(textarea);
|
|
185
|
-
await userEvent.clear(textarea);
|
|
186
|
-
await userEvent.type(textarea, 'Select this text');
|
|
187
|
-
|
|
188
|
-
// Select all text with Ctrl+A
|
|
189
|
-
await userEvent.keyboard('{Control>}a{/Control}');
|
|
190
|
-
|
|
191
|
-
// Text should be selected (we can't directly test selection, but the command should execute)
|
|
192
|
-
expect(textarea).toHaveValue('Select this text');
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
await step('Test Escape key behavior', async () => {
|
|
196
|
-
const textarea = canvas.getByRole('textbox');
|
|
197
|
-
await userEvent.click(textarea);
|
|
198
|
-
await userEvent.keyboard('{Escape}');
|
|
199
|
-
|
|
200
|
-
// Textarea should still be accessible after Escape
|
|
201
|
-
expect(textarea).toBeInTheDocument();
|
|
202
|
-
});
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
// 5. Screen Reader Tests
|
|
207
|
-
export const ScreenReader: Story = {
|
|
208
|
-
args: {
|
|
209
|
-
placeholder: 'Screen reader accessible textarea',
|
|
210
|
-
label: 'Accessible Textarea',
|
|
211
|
-
helperText: 'This textarea is accessible to screen readers',
|
|
212
|
-
'aria-describedby': 'helper-text',
|
|
213
|
-
'dataTestId': 'sr-textarea',
|
|
214
|
-
},
|
|
215
|
-
play: async ({ canvasElement, step }) => {
|
|
216
|
-
const canvas = within(canvasElement);
|
|
217
|
-
|
|
218
|
-
await step('Verify ARIA attributes', async () => {
|
|
219
|
-
const textarea = canvas.getByRole('textbox');
|
|
220
|
-
const label = canvas.getByText('Accessible Textarea');
|
|
221
|
-
const helperText = canvas.getByText('This textarea is accessible to screen readers');
|
|
222
|
-
|
|
223
|
-
expect(textarea).toBeInTheDocument();
|
|
224
|
-
expect(label).toBeInTheDocument();
|
|
225
|
-
expect(helperText).toBeInTheDocument();
|
|
226
|
-
|
|
227
|
-
// Check accessibility attributes
|
|
228
|
-
expect(textarea).toHaveAccessibleName('Accessible Textarea');
|
|
229
|
-
expect(textarea).toHaveAttribute('aria-describedby');
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
await step('Test screen reader announcements', async () => {
|
|
233
|
-
const textarea = canvas.getByRole('textbox');
|
|
234
|
-
|
|
235
|
-
// Focus should announce the textarea
|
|
236
|
-
await userEvent.click(textarea);
|
|
237
|
-
await waitFor(() => expect(textarea).toHaveFocus());
|
|
238
|
-
|
|
239
|
-
// Type content and verify it's available to screen readers
|
|
240
|
-
await userEvent.type(textarea, 'Screen reader content');
|
|
241
|
-
expect(textarea).toHaveValue('Screen reader content');
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
await step('Test error state accessibility', async () => {
|
|
245
|
-
const textarea = canvas.getByRole('textbox');
|
|
246
|
-
|
|
247
|
-
// Textarea should be accessible and have proper state information
|
|
248
|
-
expect(textarea).toBeInTheDocument();
|
|
249
|
-
expect(textarea).not.toHaveAttribute('aria-invalid', 'true');
|
|
250
|
-
});
|
|
251
|
-
},
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
// 6. Focus Management Tests
|
|
255
|
-
export const FocusManagement: Story = {
|
|
256
|
-
decorators: [
|
|
257
|
-
(Story) => (
|
|
258
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
259
|
-
<input placeholder="Previous input" data-testid="prev-input" />
|
|
260
|
-
<Story />
|
|
261
|
-
<input placeholder="Next input" data-testid="next-input" />
|
|
262
|
-
</Box>
|
|
263
|
-
),
|
|
264
|
-
],
|
|
265
|
-
args: {
|
|
266
|
-
placeholder: 'Focus management test...',
|
|
267
|
-
'dataTestId': 'focus-textarea',
|
|
268
|
-
},
|
|
269
|
-
play: async ({ canvasElement, step }) => {
|
|
270
|
-
const canvas = within(canvasElement);
|
|
271
|
-
|
|
272
|
-
await step('Test focus sequence', async () => {
|
|
273
|
-
const prevInput = canvas.getByTestId('prev-input');
|
|
274
|
-
const textarea = canvas.getByTestId('focus-textarea');
|
|
275
|
-
const nextInput = canvas.getByTestId('next-input');
|
|
276
|
-
|
|
277
|
-
// Start with previous input
|
|
278
|
-
await userEvent.click(prevInput);
|
|
279
|
-
await waitFor(() => expect(prevInput).toHaveFocus());
|
|
280
|
-
|
|
281
|
-
// Tab to textarea
|
|
282
|
-
await userEvent.tab();
|
|
283
|
-
await waitFor(() => expect(textarea).toHaveFocus());
|
|
284
|
-
|
|
285
|
-
// Tab to next input
|
|
286
|
-
await userEvent.tab();
|
|
287
|
-
await waitFor(() => expect(nextInput).toHaveFocus());
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
await step('Test focus retention during interaction', async () => {
|
|
291
|
-
const textarea = canvas.getByTestId('focus-textarea');
|
|
292
|
-
|
|
293
|
-
await userEvent.click(textarea);
|
|
294
|
-
await waitFor(() => expect(textarea).toHaveFocus());
|
|
295
|
-
|
|
296
|
-
await userEvent.type(textarea, 'Typing should maintain focus');
|
|
297
|
-
await waitFor(() => expect(textarea).toHaveFocus());
|
|
298
|
-
expect(textarea).toHaveValue('Typing should maintain focus');
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
await step('Test blur behavior', async () => {
|
|
302
|
-
const textarea = canvas.getByTestId('focus-textarea');
|
|
303
|
-
const nextInput = canvas.getByTestId('next-input');
|
|
304
|
-
|
|
305
|
-
await userEvent.click(textarea);
|
|
306
|
-
await waitFor(() => expect(textarea).toHaveFocus());
|
|
307
|
-
|
|
308
|
-
// Click outside to blur
|
|
309
|
-
await userEvent.click(nextInput);
|
|
310
|
-
await waitFor(() => expect(textarea).not.toHaveFocus());
|
|
311
|
-
await waitFor(() => expect(nextInput).toHaveFocus());
|
|
312
|
-
});
|
|
313
|
-
},
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
// 7. Responsive Design Tests
|
|
317
|
-
export const ResponsiveDesign: Story = {
|
|
318
|
-
parameters: {
|
|
319
|
-
viewport: {
|
|
320
|
-
viewports: {
|
|
321
|
-
mobile: { name: 'Mobile', styles: { width: '375px', height: '667px' } },
|
|
322
|
-
tablet: { name: 'Tablet', styles: { width: '768px', height: '1024px' } },
|
|
323
|
-
desktop: { name: 'Desktop', styles: { width: '1200px', height: '800px' } },
|
|
324
|
-
},
|
|
325
|
-
},
|
|
326
|
-
},
|
|
327
|
-
args: {
|
|
328
|
-
placeholder: 'Responsive textarea...',
|
|
329
|
-
size: 'md',
|
|
330
|
-
'dataTestId': 'responsive-textarea',
|
|
331
|
-
},
|
|
332
|
-
play: async ({ canvasElement, step }) => {
|
|
333
|
-
const canvas = within(canvasElement);
|
|
334
|
-
|
|
335
|
-
await step('Verify textarea renders on different viewports', async () => {
|
|
336
|
-
const textarea = canvas.getByRole('textbox');
|
|
337
|
-
expect(textarea).toBeInTheDocument();
|
|
338
|
-
expect(textarea).toBeVisible();
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
await step('Test interaction on small screens', async () => {
|
|
342
|
-
const textarea = canvas.getByRole('textbox');
|
|
343
|
-
|
|
344
|
-
await userEvent.click(textarea);
|
|
345
|
-
await userEvent.type(textarea, 'Mobile responsive content');
|
|
346
|
-
expect(textarea).toHaveValue('Mobile responsive content');
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
await step('Verify accessibility on touch devices', async () => {
|
|
350
|
-
const textarea = canvas.getByRole('textbox');
|
|
351
|
-
|
|
352
|
-
// Touch target should be large enough - we verify the element exists and is accessible
|
|
353
|
-
expect(textarea).toBeInTheDocument();
|
|
354
|
-
expect(textarea).toBeVisible();
|
|
355
|
-
// Note: We can't easily test computed dimensions in Storybook tests
|
|
356
|
-
});
|
|
357
|
-
},
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
// 8. Theme Variations Tests
|
|
361
|
-
export const ThemeVariations: Story = {
|
|
362
|
-
decorators: [
|
|
363
|
-
(Story) => {
|
|
364
|
-
const lightTheme = createTheme({ palette: { mode: 'light' } });
|
|
365
|
-
const darkTheme = createTheme({ palette: { mode: 'dark' } });
|
|
366
|
-
|
|
367
|
-
return (
|
|
368
|
-
<Box sx={{ display: 'flex', gap: 3, flexWrap: 'wrap' }}>
|
|
369
|
-
<Box>
|
|
370
|
-
<h3>Light Theme</h3>
|
|
371
|
-
<ThemeProvider theme={lightTheme}>
|
|
372
|
-
<Story />
|
|
373
|
-
</ThemeProvider>
|
|
374
|
-
</Box>
|
|
375
|
-
<Box>
|
|
376
|
-
<h3>Dark Theme</h3>
|
|
377
|
-
<ThemeProvider theme={darkTheme}>
|
|
378
|
-
<Story />
|
|
379
|
-
</ThemeProvider>
|
|
380
|
-
</Box>
|
|
381
|
-
</Box>
|
|
382
|
-
);
|
|
383
|
-
},
|
|
384
|
-
],
|
|
385
|
-
args: {
|
|
386
|
-
placeholder: 'Theme test textarea...',
|
|
387
|
-
label: 'Theme Textarea',
|
|
388
|
-
color: 'primary',
|
|
389
|
-
'dataTestId': 'theme-textarea',
|
|
390
|
-
},
|
|
391
|
-
play: async ({ canvasElement, step }) => {
|
|
392
|
-
const canvas = within(canvasElement);
|
|
393
|
-
|
|
394
|
-
await step('Find textareas in both themes', async () => {
|
|
395
|
-
const textareas = canvas.getAllByRole('textbox');
|
|
396
|
-
expect(textareas).toHaveLength(2); // Light and dark theme versions
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
await step('Test interaction in both themes', async () => {
|
|
400
|
-
const textareas = canvas.getAllByRole('textbox');
|
|
401
|
-
|
|
402
|
-
for (const textarea of textareas) {
|
|
403
|
-
await userEvent.click(textarea);
|
|
404
|
-
await userEvent.type(textarea, 'Theme test');
|
|
405
|
-
expect(textarea).toHaveValue('Theme test');
|
|
406
|
-
await userEvent.clear(textarea);
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
await step('Verify theme-specific styling', async () => {
|
|
411
|
-
const textareas = canvas.getAllByRole('textbox');
|
|
412
|
-
|
|
413
|
-
// Both textareas should be rendered and functional
|
|
414
|
-
textareas.forEach((textarea) => {
|
|
415
|
-
expect(textarea).toBeVisible();
|
|
416
|
-
expect(textarea).not.toHaveAttribute('disabled');
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
},
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
// 9. Visual States Tests
|
|
423
|
-
export const VisualStates: Story = {
|
|
424
|
-
render: () => (
|
|
425
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
|
426
|
-
<Box>
|
|
427
|
-
<h4>Default State</h4>
|
|
428
|
-
<Textarea placeholder="Default state..." dataTestId="default-textarea" />
|
|
429
|
-
</Box>
|
|
430
|
-
<Box>
|
|
431
|
-
<h4>Disabled State</h4>
|
|
432
|
-
<Textarea placeholder="Disabled state..." disabled dataTestId="disabled-textarea" />
|
|
433
|
-
</Box>
|
|
434
|
-
<Box>
|
|
435
|
-
<h4>Error State</h4>
|
|
436
|
-
<Textarea
|
|
437
|
-
placeholder="Error state..."
|
|
438
|
-
error
|
|
439
|
-
helperText="This field has an error"
|
|
440
|
-
dataTestId="error-textarea"
|
|
441
|
-
/>
|
|
442
|
-
</Box>
|
|
443
|
-
<Box>
|
|
444
|
-
<h4>Glass Effect</h4>
|
|
445
|
-
<Textarea placeholder="Glass effect..." glass dataTestId="glass-textarea" />
|
|
446
|
-
</Box>
|
|
447
|
-
</Box>
|
|
448
|
-
),
|
|
449
|
-
play: async ({ canvasElement, step }) => {
|
|
450
|
-
const canvas = within(canvasElement);
|
|
451
|
-
|
|
452
|
-
await step('Verify all visual states render', async () => {
|
|
453
|
-
const defaultTextarea = canvas.getByTestId('default-textarea');
|
|
454
|
-
const disabledTextarea = canvas.getByTestId('disabled-textarea');
|
|
455
|
-
const errorTextarea = canvas.getByTestId('error-textarea');
|
|
456
|
-
const glassTextarea = canvas.getByTestId('glass-textarea');
|
|
457
|
-
|
|
458
|
-
expect(defaultTextarea).toBeInTheDocument();
|
|
459
|
-
expect(disabledTextarea).toBeInTheDocument();
|
|
460
|
-
expect(errorTextarea).toBeInTheDocument();
|
|
461
|
-
expect(glassTextarea).toBeInTheDocument();
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
await step('Test disabled state behavior', async () => {
|
|
465
|
-
const disabledTextarea = canvas.getByTestId('disabled-textarea');
|
|
466
|
-
|
|
467
|
-
expect(disabledTextarea).toBeDisabled();
|
|
468
|
-
|
|
469
|
-
// Should not accept input when disabled
|
|
470
|
-
await userEvent.click(disabledTextarea);
|
|
471
|
-
await waitFor(() => expect(disabledTextarea).not.toHaveFocus());
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
await step('Test interactive states', async () => {
|
|
475
|
-
const defaultTextarea = canvas.getByTestId('default-textarea');
|
|
476
|
-
const errorTextarea = canvas.getByTestId('error-textarea');
|
|
477
|
-
const glassTextarea = canvas.getByTestId('glass-textarea');
|
|
478
|
-
|
|
479
|
-
// Test focus states
|
|
480
|
-
await userEvent.click(defaultTextarea);
|
|
481
|
-
await waitFor(() => expect(defaultTextarea).toHaveFocus());
|
|
482
|
-
|
|
483
|
-
await userEvent.click(errorTextarea);
|
|
484
|
-
await waitFor(() => expect(errorTextarea).toHaveFocus());
|
|
485
|
-
|
|
486
|
-
await userEvent.click(glassTextarea);
|
|
487
|
-
await waitFor(() => expect(glassTextarea).toHaveFocus());
|
|
488
|
-
});
|
|
489
|
-
|
|
490
|
-
await step('Test error state helper text', async () => {
|
|
491
|
-
const helperText = canvas.getByText('This field has an error');
|
|
492
|
-
expect(helperText).toBeInTheDocument();
|
|
493
|
-
});
|
|
494
|
-
},
|
|
495
|
-
};
|
|
496
|
-
|
|
497
|
-
// 10. Performance Tests
|
|
498
|
-
export const Performance: Story = {
|
|
499
|
-
args: {
|
|
500
|
-
placeholder: 'Performance test textarea...',
|
|
501
|
-
'dataTestId': 'performance-textarea',
|
|
502
|
-
},
|
|
503
|
-
play: async ({ canvasElement, step }) => {
|
|
504
|
-
const canvas = within(canvasElement);
|
|
505
|
-
|
|
506
|
-
await step('Measure initial render performance', async () => {
|
|
507
|
-
const textarea = canvas.getByTestId('performance-textarea');
|
|
508
|
-
|
|
509
|
-
expect(textarea).toBeInTheDocument();
|
|
510
|
-
expect(endTime - startTime).toBeLessThan(100); // Should render quickly
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
await step('Test typing performance with large content', async () => {
|
|
514
|
-
const textarea = canvas.getByTestId('performance-textarea');
|
|
515
|
-
// Reduced from 1000 to 200 characters for faster test execution
|
|
516
|
-
const longText = 'A'.repeat(200);
|
|
517
|
-
|
|
518
|
-
await userEvent.click(textarea);
|
|
519
|
-
await userEvent.type(textarea, longText, { delay: 0 });
|
|
520
|
-
|
|
521
|
-
expect(textarea).toHaveValue(longText);
|
|
522
|
-
expect(endTime - startTime).toBeLessThan(10000); // Reduced from 30s to 10s
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
await step('Test multiple rapid interactions', async () => {
|
|
526
|
-
const textarea = canvas.getByTestId('performance-textarea');
|
|
527
|
-
|
|
528
|
-
// Reduced from 10 to 5 iterations for faster test execution
|
|
529
|
-
for (let i = 0; i < 5; i++) {
|
|
530
|
-
await userEvent.clear(textarea);
|
|
531
|
-
await userEvent.type(textarea, `Content ${i}`, { delay: 0 });
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
expect(textarea).toHaveValue('Content 4');
|
|
535
|
-
expect(endTime - startTime).toBeLessThan(10000); // Reduced from 30s to 10s
|
|
536
|
-
});
|
|
537
|
-
},
|
|
538
|
-
parameters: {
|
|
539
|
-
test: {
|
|
540
|
-
timeout: 10000, // 10 second timeout for performance tests
|
|
541
|
-
},
|
|
542
|
-
},
|
|
543
|
-
};
|
|
544
|
-
|
|
545
|
-
// 11. Edge Cases Tests
|
|
546
|
-
export const EdgeCases: Story = {
|
|
547
|
-
decorators: [
|
|
548
|
-
() => (
|
|
549
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
|
550
|
-
<Box>
|
|
551
|
-
<h4>Empty State</h4>
|
|
552
|
-
<Textarea placeholder="Empty placeholder..." dataTestId="empty-textarea" />
|
|
553
|
-
</Box>
|
|
554
|
-
<Box>
|
|
555
|
-
<h4>With Max Length</h4>
|
|
556
|
-
<Textarea placeholder="Max 10 chars..." maxLength={10} dataTestId="maxlength-textarea" />
|
|
557
|
-
</Box>
|
|
558
|
-
<Box>
|
|
559
|
-
<h4>Pre-filled Content</h4>
|
|
560
|
-
<Textarea defaultValue="Pre-filled content here" dataTestId="prefilled-textarea" />
|
|
561
|
-
</Box>
|
|
562
|
-
</Box>
|
|
563
|
-
),
|
|
564
|
-
],
|
|
565
|
-
play: async ({ canvasElement, step }) => {
|
|
566
|
-
const canvas = within(canvasElement);
|
|
567
|
-
|
|
568
|
-
await step('Test empty state behavior', async () => {
|
|
569
|
-
const emptyTextarea = canvas.getByTestId('empty-textarea');
|
|
570
|
-
|
|
571
|
-
expect(emptyTextarea).toHaveValue('');
|
|
572
|
-
expect(emptyTextarea).toHaveAttribute('placeholder', 'Empty placeholder...');
|
|
573
|
-
});
|
|
574
|
-
|
|
575
|
-
await step('Test max length constraint', async () => {
|
|
576
|
-
const maxLengthTextarea = canvas.getByTestId<HTMLTextAreaElement>('maxlength-textarea');
|
|
577
|
-
|
|
578
|
-
await userEvent.click(maxLengthTextarea);
|
|
579
|
-
await userEvent.type(maxLengthTextarea, 'This text is longer than 10 characters', { delay: 0 });
|
|
580
|
-
|
|
581
|
-
// Should be truncated to max length
|
|
582
|
-
const value = maxLengthTextarea.value;
|
|
583
|
-
expect(value.length).toBeLessThanOrEqual(10);
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
await step('Test pre-filled content', async () => {
|
|
587
|
-
const prefilledTextarea = canvas.getByTestId('prefilled-textarea');
|
|
588
|
-
|
|
589
|
-
expect(prefilledTextarea).toHaveValue('Pre-filled content here');
|
|
590
|
-
|
|
591
|
-
// Should be able to edit pre-filled content
|
|
592
|
-
await userEvent.click(prefilledTextarea);
|
|
593
|
-
await userEvent.clear(prefilledTextarea);
|
|
594
|
-
await userEvent.type(prefilledTextarea, 'New content', { delay: 0 });
|
|
595
|
-
expect(prefilledTextarea).toHaveValue('New content');
|
|
596
|
-
});
|
|
597
|
-
|
|
598
|
-
await step('Test special character input', async () => {
|
|
599
|
-
const emptyTextarea = canvas.getByTestId('empty-textarea');
|
|
600
|
-
|
|
601
|
-
await userEvent.clear(emptyTextarea);
|
|
602
|
-
// Simplified test text for faster execution
|
|
603
|
-
await userEvent.type(emptyTextarea, 'Special: @#$ abc', { delay: 0 });
|
|
604
|
-
expect(emptyTextarea).toHaveValue('Special: @#$ abc');
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
await step('Test newline handling', async () => {
|
|
608
|
-
const emptyTextarea = canvas.getByTestId('empty-textarea');
|
|
609
|
-
|
|
610
|
-
await userEvent.clear(emptyTextarea);
|
|
611
|
-
await userEvent.type(emptyTextarea, 'Line 1\nLine 2', { delay: 0 });
|
|
612
|
-
expect(emptyTextarea).toHaveValue('Line 1\nLine 2');
|
|
613
|
-
});
|
|
614
|
-
},
|
|
615
|
-
parameters: {
|
|
616
|
-
test: {
|
|
617
|
-
timeout: 10000, // 10 second timeout for edge case tests
|
|
618
|
-
},
|
|
619
|
-
},
|
|
620
|
-
};
|
|
621
|
-
|
|
622
|
-
// 12. Integration Tests
|
|
623
|
-
export const Integration: Story = {
|
|
624
|
-
decorators: [
|
|
625
|
-
(Story) => (
|
|
626
|
-
<Box component="form" sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
627
|
-
<input placeholder="Name" data-testid="name-input" />
|
|
628
|
-
<Story />
|
|
629
|
-
<Textarea placeholder="Additional comments..." data-testid="comments-textarea" />
|
|
630
|
-
<button type="submit">Submit Form</button>
|
|
631
|
-
</Box>
|
|
632
|
-
),
|
|
633
|
-
],
|
|
634
|
-
args: {
|
|
635
|
-
placeholder: 'Main message...',
|
|
636
|
-
name: 'message',
|
|
637
|
-
required: true,
|
|
638
|
-
label: 'Message',
|
|
639
|
-
helperText: 'Please enter your message',
|
|
640
|
-
'dataTestId': 'integration-textarea',
|
|
641
|
-
},
|
|
642
|
-
play: async ({ canvasElement, step }) => {
|
|
643
|
-
const canvas = within(canvasElement);
|
|
644
|
-
|
|
645
|
-
await step('Verify form integration setup', async () => {
|
|
646
|
-
const nameInput = canvas.getByTestId('name-input');
|
|
647
|
-
const messageTextarea = canvas.getByTestId('integration-textarea');
|
|
648
|
-
const commentsTextarea = canvas.getByTestId('comments-textarea');
|
|
649
|
-
const submitButton = canvas.getByRole('button', { name: 'Submit Form' });
|
|
650
|
-
|
|
651
|
-
expect(nameInput).toBeInTheDocument();
|
|
652
|
-
expect(messageTextarea).toBeInTheDocument();
|
|
653
|
-
expect(commentsTextarea).toBeInTheDocument();
|
|
654
|
-
expect(submitButton).toBeInTheDocument();
|
|
655
|
-
});
|
|
656
|
-
|
|
657
|
-
await step('Test tab navigation through form', async () => {
|
|
658
|
-
const nameInput = canvas.getByTestId('name-input');
|
|
659
|
-
const messageTextarea = canvas.getByTestId('integration-textarea');
|
|
660
|
-
const commentsTextarea = canvas.getByTestId('comments-textarea');
|
|
661
|
-
const submitButton = canvas.getByRole('button', { name: 'Submit Form' });
|
|
662
|
-
|
|
663
|
-
await userEvent.click(nameInput);
|
|
664
|
-
await waitFor(() => expect(nameInput).toHaveFocus());
|
|
665
|
-
|
|
666
|
-
await userEvent.tab();
|
|
667
|
-
await waitFor(() => expect(messageTextarea).toHaveFocus());
|
|
668
|
-
|
|
669
|
-
await userEvent.tab();
|
|
670
|
-
await waitFor(() => expect(commentsTextarea).toHaveFocus());
|
|
671
|
-
|
|
672
|
-
await userEvent.tab();
|
|
673
|
-
await waitFor(() => expect(submitButton).toHaveFocus());
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
await step('Fill form with data', async () => {
|
|
677
|
-
const nameInput = canvas.getByTestId('name-input');
|
|
678
|
-
const messageTextarea = canvas.getByTestId('integration-textarea');
|
|
679
|
-
const commentsTextarea = canvas.getByTestId('comments-textarea');
|
|
680
|
-
|
|
681
|
-
await userEvent.click(nameInput);
|
|
682
|
-
await userEvent.type(nameInput, 'John Doe');
|
|
683
|
-
expect(nameInput).toHaveValue('John Doe');
|
|
684
|
-
|
|
685
|
-
await userEvent.click(messageTextarea);
|
|
686
|
-
await userEvent.type(messageTextarea, 'This is the main message\nwith multiple lines.');
|
|
687
|
-
expect(messageTextarea).toHaveValue('This is the main message\nwith multiple lines.');
|
|
688
|
-
|
|
689
|
-
await userEvent.click(commentsTextarea);
|
|
690
|
-
await userEvent.type(commentsTextarea, 'Additional comments here.');
|
|
691
|
-
expect(commentsTextarea).toHaveValue('Additional comments here.');
|
|
692
|
-
});
|
|
693
|
-
|
|
694
|
-
await step('Test form validation integration', async () => {
|
|
695
|
-
const messageTextarea = canvas.getByTestId('integration-textarea');
|
|
696
|
-
const helperText = canvas.getByText('Please enter your message');
|
|
697
|
-
|
|
698
|
-
expect(messageTextarea).toHaveAttribute('required');
|
|
699
|
-
expect(helperText).toBeInTheDocument();
|
|
700
|
-
});
|
|
701
|
-
},
|
|
702
|
-
};
|