@12-apps/ui 1.4.1 → 1.5.1
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 -8
- 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 -77
- 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 -753
- 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 -503
- package/src/components/data-display/Carousel/Carousel.stories.tsx +0 -607
- package/src/components/data-display/Carousel/Carousel.test.stories.tsx +0 -691
- 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 -1101
- 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 -955
- 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 -975
- 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 -909
- 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 -918
- 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 -750
- 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 -472
- 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 -762
- 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,750 +0,0 @@
|
|
|
1
|
-
import { Box, Paper,Typography } from '@mui/material';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import React, { useState } from 'react';
|
|
4
|
-
import { expect, fn,userEvent, waitFor, within } from 'storybook/test';
|
|
5
|
-
|
|
6
|
-
import { Resizable } from './Resizable';
|
|
7
|
-
|
|
8
|
-
const meta: Meta<typeof Resizable> = {
|
|
9
|
-
title: 'Layout/Resizable/Tests',
|
|
10
|
-
component: Resizable,
|
|
11
|
-
parameters: {
|
|
12
|
-
layout: 'centered',
|
|
13
|
-
chromatic: { disableSnapshot: false },
|
|
14
|
-
},
|
|
15
|
-
tags: ['autodocs', 'test', 'component:Resizable'],
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default meta;
|
|
19
|
-
type Story = StoryObj<typeof meta>;
|
|
20
|
-
|
|
21
|
-
// Test content component
|
|
22
|
-
interface TestContentProps {
|
|
23
|
-
testId?: string;
|
|
24
|
-
label?: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const TestContent: React.FC<TestContentProps> = ({
|
|
28
|
-
testId = 'test-content',
|
|
29
|
-
label = 'Test Content',
|
|
30
|
-
}) => (
|
|
31
|
-
<Box
|
|
32
|
-
sx={{ p: 2, bgcolor: 'primary.50', height: '100%', display: 'flex', flexDirection: 'column' }}
|
|
33
|
-
data-testid={testId}
|
|
34
|
-
>
|
|
35
|
-
<Typography variant="h6" gutterBottom>
|
|
36
|
-
{label}
|
|
37
|
-
</Typography>
|
|
38
|
-
<Typography variant="body2">Resize test content area</Typography>
|
|
39
|
-
<Box sx={{ flex: 1, bgcolor: 'grey.100', borderRadius: 1, p: 1, mt: 1 }}>
|
|
40
|
-
<Typography variant="caption">Content fills available space</Typography>
|
|
41
|
-
</Box>
|
|
42
|
-
</Box>
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
// 🧪 INTERACTION TESTS
|
|
46
|
-
|
|
47
|
-
export const BasicInteraction: Story = {
|
|
48
|
-
name: '🧪 Basic Interaction Test',
|
|
49
|
-
args: {
|
|
50
|
-
variant: 'both',
|
|
51
|
-
width: 300,
|
|
52
|
-
height: 200,
|
|
53
|
-
onResize: fn(),
|
|
54
|
-
children: <TestContent testId="basic-interaction-content" label="Basic Interaction" />,
|
|
55
|
-
},
|
|
56
|
-
play: async ({ canvasElement, step, args }) => {
|
|
57
|
-
const canvas = within(canvasElement);
|
|
58
|
-
|
|
59
|
-
await step('Initial render verification', async () => {
|
|
60
|
-
const container = canvas.getByTestId('basic-interaction-content');
|
|
61
|
-
await expect(container).toBeInTheDocument();
|
|
62
|
-
|
|
63
|
-
// Verify initial dimensions
|
|
64
|
-
const resizableContainer = container.closest('[data-testid]')?.parentElement;
|
|
65
|
-
if (resizableContainer) {
|
|
66
|
-
const computedStyle = window.getComputedStyle(resizableContainer);
|
|
67
|
-
await expect(computedStyle.width).toBe('300px');
|
|
68
|
-
await expect(computedStyle.height).toBe('200px');
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
await step('Hover shows resize handles', async () => {
|
|
73
|
-
const container = canvas.getByTestId('basic-interaction-content');
|
|
74
|
-
const resizableContainer = container.closest('[data-testid]')?.parentElement;
|
|
75
|
-
|
|
76
|
-
if (resizableContainer) {
|
|
77
|
-
await userEvent.hover(resizableContainer);
|
|
78
|
-
// Handles become visible on hover
|
|
79
|
-
const handles = resizableContainer.querySelectorAll('.resize-handle');
|
|
80
|
-
await expect(handles.length).toBeGreaterThan(0);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
await step('Resize callback is triggered', async () => {
|
|
85
|
-
// Note: Actual drag simulation is complex in testing environment
|
|
86
|
-
// This test verifies the callback is properly set up
|
|
87
|
-
await expect(args.onResize).toBeDefined();
|
|
88
|
-
});
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const StateChangeTestComponent: React.FC = () => {
|
|
93
|
-
const [size, setSize] = useState({ width: 250, height: 150 });
|
|
94
|
-
const [disabled, setDisabled] = useState(false);
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, alignItems: 'center' }}>
|
|
98
|
-
<Box sx={{ display: 'flex', gap: 2 }}>
|
|
99
|
-
<button onClick={() => setSize({ width: 400, height: 300 })} data-testid="resize-to-large">
|
|
100
|
-
Resize to Large
|
|
101
|
-
</button>
|
|
102
|
-
<button onClick={() => setSize({ width: 200, height: 100 })} data-testid="resize-to-small">
|
|
103
|
-
Resize to Small
|
|
104
|
-
</button>
|
|
105
|
-
<button onClick={() => setDisabled(!disabled)} data-testid="toggle-disabled">
|
|
106
|
-
Toggle Disabled
|
|
107
|
-
</button>
|
|
108
|
-
</Box>
|
|
109
|
-
|
|
110
|
-
<Typography variant="body2">
|
|
111
|
-
Size: {size.width} × {size.height}
|
|
112
|
-
</Typography>
|
|
113
|
-
|
|
114
|
-
<Resizable
|
|
115
|
-
variant="both"
|
|
116
|
-
width={size.width}
|
|
117
|
-
height={size.height}
|
|
118
|
-
disabled={disabled}
|
|
119
|
-
onResize={(width, height) => setSize({ width, height })}
|
|
120
|
-
data-testid="stateful-resizable"
|
|
121
|
-
>
|
|
122
|
-
<TestContent testId="state-change-content" label={disabled ? 'Disabled' : 'Enabled'} />
|
|
123
|
-
</Resizable>
|
|
124
|
-
</Box>
|
|
125
|
-
);
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
export const StateChangeTest: Story = {
|
|
129
|
-
name: '🔄 State Change Test',
|
|
130
|
-
render: () => <StateChangeTestComponent />,
|
|
131
|
-
play: async ({ canvasElement, step }) => {
|
|
132
|
-
const canvas = within(canvasElement);
|
|
133
|
-
|
|
134
|
-
await step('Verify initial state', async () => {
|
|
135
|
-
const resizableItem = canvas.getByTestId('stateful-resizable');
|
|
136
|
-
await expect(resizableItem).toBeInTheDocument();
|
|
137
|
-
await expect(resizableItem).toHaveStyle({ width: '250px', height: '150px' });
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
await step('Change size to large', async () => {
|
|
141
|
-
const resizeLargeBtn = canvas.getByTestId('resize-to-large');
|
|
142
|
-
await userEvent.click(resizeLargeBtn);
|
|
143
|
-
|
|
144
|
-
await waitFor(async () => {
|
|
145
|
-
const resizableItem = canvas.getByTestId('stateful-resizable');
|
|
146
|
-
await expect(resizableItem).toBeInTheDocument();
|
|
147
|
-
await expect(resizableItem).toHaveStyle({ width: '400px', height: '300px' });
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
await step('Change size to small', async () => {
|
|
152
|
-
const resizeSmallBtn = canvas.getByTestId('resize-to-small');
|
|
153
|
-
await userEvent.click(resizeSmallBtn);
|
|
154
|
-
|
|
155
|
-
await waitFor(async () => {
|
|
156
|
-
const resizableItem = canvas.getByTestId('stateful-resizable');
|
|
157
|
-
await expect(resizableItem).toHaveStyle({ width: '200px', height: '100px' });
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
await step('Toggle disabled state', async () => {
|
|
162
|
-
const toggleBtn = canvas.getByTestId('toggle-disabled');
|
|
163
|
-
await userEvent.click(toggleBtn);
|
|
164
|
-
|
|
165
|
-
await waitFor(async () => {
|
|
166
|
-
const content = canvas.getByTestId('state-change-content');
|
|
167
|
-
await expect(content).toHaveTextContent('Disabled');
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// ⌨️ ACCESSIBILITY TESTS
|
|
174
|
-
|
|
175
|
-
export const KeyboardNavigation: Story = {
|
|
176
|
-
name: '⌨️ Keyboard Navigation Test',
|
|
177
|
-
args: {
|
|
178
|
-
variant: 'both',
|
|
179
|
-
width: 300,
|
|
180
|
-
height: 200,
|
|
181
|
-
children: (
|
|
182
|
-
<Box
|
|
183
|
-
sx={{ p: 2, bgcolor: 'info.50', height: '100%' }}
|
|
184
|
-
role="region"
|
|
185
|
-
aria-label="Resizable content area"
|
|
186
|
-
data-testid="keyboard-content"
|
|
187
|
-
>
|
|
188
|
-
<Typography variant="h6">Keyboard Navigation</Typography>
|
|
189
|
-
<button data-testid="focus-target">Focusable Element</button>
|
|
190
|
-
</Box>
|
|
191
|
-
),
|
|
192
|
-
},
|
|
193
|
-
parameters: {
|
|
194
|
-
a11y: {
|
|
195
|
-
element: '#storybook-root',
|
|
196
|
-
config: {
|
|
197
|
-
rules: [
|
|
198
|
-
{ id: 'color-contrast', enabled: true },
|
|
199
|
-
{ id: 'aria-required-attr', enabled: true },
|
|
200
|
-
{ id: 'aria-roles', enabled: true },
|
|
201
|
-
{ id: 'aria-valid-attr-value', enabled: true },
|
|
202
|
-
{ id: 'button-name', enabled: true },
|
|
203
|
-
],
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
play: async ({ canvasElement, step }) => {
|
|
208
|
-
const canvas = within(canvasElement);
|
|
209
|
-
|
|
210
|
-
await step('Content is focusable', async () => {
|
|
211
|
-
const focusTarget = canvas.getByTestId('focus-target');
|
|
212
|
-
focusTarget.focus();
|
|
213
|
-
await expect(focusTarget).toHaveFocus();
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
await step('Tab navigation works', async () => {
|
|
217
|
-
const focusTarget = canvas.getByTestId('focus-target');
|
|
218
|
-
focusTarget.focus();
|
|
219
|
-
await userEvent.tab();
|
|
220
|
-
// Tab should move focus away from the button
|
|
221
|
-
await expect(focusTarget).not.toHaveFocus();
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
await step('Container has proper ARIA attributes', async () => {
|
|
225
|
-
const content = canvas.getByTestId('keyboard-content');
|
|
226
|
-
await expect(content).toHaveAttribute('role', 'region');
|
|
227
|
-
await expect(content).toHaveAttribute('aria-label', 'Resizable content area');
|
|
228
|
-
});
|
|
229
|
-
},
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
export const ScreenReaderTest: Story = {
|
|
233
|
-
name: '🔊 Screen Reader Test',
|
|
234
|
-
args: {
|
|
235
|
-
variant: 'both',
|
|
236
|
-
width: 300,
|
|
237
|
-
height: 200,
|
|
238
|
-
children: (
|
|
239
|
-
<Box
|
|
240
|
-
sx={{ p: 2, bgcolor: 'secondary.50', height: '100%' }}
|
|
241
|
-
role="region"
|
|
242
|
-
aria-label="Resizable panel"
|
|
243
|
-
aria-describedby="panel-description"
|
|
244
|
-
data-testid="screen-reader-content"
|
|
245
|
-
>
|
|
246
|
-
<Typography variant="h6" id="panel-title">
|
|
247
|
-
Panel Title
|
|
248
|
-
</Typography>
|
|
249
|
-
<Typography variant="body2" id="panel-description">
|
|
250
|
-
This panel can be resized by dragging the handles
|
|
251
|
-
</Typography>
|
|
252
|
-
<div role="status" aria-live="polite" data-testid="live-region">
|
|
253
|
-
Status updates appear here
|
|
254
|
-
</div>
|
|
255
|
-
</Box>
|
|
256
|
-
),
|
|
257
|
-
},
|
|
258
|
-
play: async ({ canvasElement, step }) => {
|
|
259
|
-
const canvas = within(canvasElement);
|
|
260
|
-
|
|
261
|
-
await step('Verify ARIA labels', async () => {
|
|
262
|
-
const content = canvas.getByLabelText('Resizable panel');
|
|
263
|
-
await expect(content).toBeInTheDocument();
|
|
264
|
-
await expect(content).toHaveAttribute('role', 'region');
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
await step('Verify ARIA descriptions', async () => {
|
|
268
|
-
const content = canvas.getByTestId('screen-reader-content');
|
|
269
|
-
await expect(content).toHaveAttribute('aria-describedby', 'panel-description');
|
|
270
|
-
|
|
271
|
-
const description = canvas.getByText('This panel can be resized by dragging the handles');
|
|
272
|
-
await expect(description).toBeInTheDocument();
|
|
273
|
-
await expect(description).toHaveAttribute('id', 'panel-description');
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
await step('Verify live regions', async () => {
|
|
277
|
-
const liveRegion = canvas.getByTestId('live-region');
|
|
278
|
-
await expect(liveRegion).toHaveAttribute('role', 'status');
|
|
279
|
-
await expect(liveRegion).toHaveAttribute('aria-live', 'polite');
|
|
280
|
-
});
|
|
281
|
-
},
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
// 👁️ VISUAL TESTS
|
|
285
|
-
|
|
286
|
-
export const ResponsiveDesign: Story = {
|
|
287
|
-
name: '📱 Responsive Design Test',
|
|
288
|
-
args: {
|
|
289
|
-
variant: 'both',
|
|
290
|
-
width: 250,
|
|
291
|
-
height: 180,
|
|
292
|
-
children: <TestContent testId="responsive-content" label="Responsive Test" />,
|
|
293
|
-
},
|
|
294
|
-
parameters: {
|
|
295
|
-
viewport: {
|
|
296
|
-
viewports: {
|
|
297
|
-
mobile: {
|
|
298
|
-
name: 'Mobile',
|
|
299
|
-
styles: { width: '375px', height: '667px' },
|
|
300
|
-
type: 'mobile',
|
|
301
|
-
},
|
|
302
|
-
tablet: {
|
|
303
|
-
name: 'Tablet',
|
|
304
|
-
styles: { width: '768px', height: '1024px' },
|
|
305
|
-
type: 'tablet',
|
|
306
|
-
},
|
|
307
|
-
desktop: {
|
|
308
|
-
name: 'Desktop',
|
|
309
|
-
styles: { width: '1920px', height: '1080px' },
|
|
310
|
-
type: 'desktop',
|
|
311
|
-
},
|
|
312
|
-
},
|
|
313
|
-
defaultViewport: 'mobile',
|
|
314
|
-
},
|
|
315
|
-
chromatic: {
|
|
316
|
-
viewports: [375, 768, 1920],
|
|
317
|
-
delay: 300,
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
play: async ({ canvasElement, step }) => {
|
|
321
|
-
const canvas = within(canvasElement);
|
|
322
|
-
|
|
323
|
-
await step('Component renders on mobile viewport', async () => {
|
|
324
|
-
const content = canvas.getByTestId('responsive-content');
|
|
325
|
-
await expect(content).toBeInTheDocument();
|
|
326
|
-
|
|
327
|
-
// Verify the component adapts to smaller screen
|
|
328
|
-
const container = content.closest('[data-testid]')?.parentElement;
|
|
329
|
-
if (container && window.innerWidth <= 768) {
|
|
330
|
-
const computedStyle = window.getComputedStyle(container);
|
|
331
|
-
await expect(computedStyle.position).toBe('relative');
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
},
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
const VisualStatesComponent: React.FC = () => {
|
|
338
|
-
const [isHovered, setIsHovered] = useState(false);
|
|
339
|
-
const [isActive, setIsActive] = useState(false);
|
|
340
|
-
|
|
341
|
-
return (
|
|
342
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, alignItems: 'center' }}>
|
|
343
|
-
<Box sx={{ display: 'flex', gap: 2 }}>
|
|
344
|
-
<button onClick={() => setIsActive(!isActive)} data-testid="toggle-active">
|
|
345
|
-
Toggle Active
|
|
346
|
-
</button>
|
|
347
|
-
</Box>
|
|
348
|
-
|
|
349
|
-
<Box onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
|
|
350
|
-
<Resizable variant="both" width={300} height={200} data-testid="visual-states-resizable">
|
|
351
|
-
<Box
|
|
352
|
-
sx={{
|
|
353
|
-
p: 2,
|
|
354
|
-
bgcolor: isActive ? 'success.50' : isHovered ? 'warning.50' : 'primary.50',
|
|
355
|
-
height: '100%',
|
|
356
|
-
transition: 'background-color 0.2s',
|
|
357
|
-
}}
|
|
358
|
-
data-testid="visual-states-content"
|
|
359
|
-
>
|
|
360
|
-
<Typography variant="h6">Visual States</Typography>
|
|
361
|
-
<Typography variant="body2">
|
|
362
|
-
State: {isActive ? 'Active' : isHovered ? 'Hovered' : 'Default'}
|
|
363
|
-
</Typography>
|
|
364
|
-
</Box>
|
|
365
|
-
</Resizable>
|
|
366
|
-
</Box>
|
|
367
|
-
</Box>
|
|
368
|
-
);
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
export const VisualStates: Story = {
|
|
372
|
-
name: '👁️ Visual States Test',
|
|
373
|
-
render: () => <VisualStatesComponent />,
|
|
374
|
-
play: async ({ canvasElement, step }) => {
|
|
375
|
-
const canvas = within(canvasElement);
|
|
376
|
-
|
|
377
|
-
await step('Default state', async () => {
|
|
378
|
-
const content = canvas.getByTestId('visual-states-content');
|
|
379
|
-
await expect(content).toHaveTextContent('Default');
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
await step('Hover state', async () => {
|
|
383
|
-
const resizable = canvas.getByTestId('visual-states-resizable');
|
|
384
|
-
await userEvent.hover(resizable);
|
|
385
|
-
|
|
386
|
-
await waitFor(async () => {
|
|
387
|
-
const content = canvas.getByTestId('visual-states-content');
|
|
388
|
-
await expect(content).toHaveTextContent('Hovered');
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
await step('Active state', async () => {
|
|
393
|
-
const toggleBtn = canvas.getByTestId('toggle-active');
|
|
394
|
-
await userEvent.click(toggleBtn);
|
|
395
|
-
|
|
396
|
-
await waitFor(async () => {
|
|
397
|
-
const content = canvas.getByTestId('visual-states-content');
|
|
398
|
-
await expect(content).toHaveTextContent('Active');
|
|
399
|
-
});
|
|
400
|
-
});
|
|
401
|
-
},
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
// ⚡ PERFORMANCE TESTS
|
|
405
|
-
|
|
406
|
-
const PerformanceTestComponent: React.FC = () => {
|
|
407
|
-
const [renderTime, setRenderTime] = useState<number | null>(null);
|
|
408
|
-
const [items] = useState(() =>
|
|
409
|
-
Array.from({ length: 100 }, (_, i) => ({
|
|
410
|
-
id: i,
|
|
411
|
-
name: `Item ${i + 1}`,
|
|
412
|
-
})),
|
|
413
|
-
);
|
|
414
|
-
|
|
415
|
-
React.useEffect(() => {
|
|
416
|
-
const startTime = window.performance.now();
|
|
417
|
-
|
|
418
|
-
// Use requestAnimationFrame for reliable timing after render
|
|
419
|
-
const frameId = window.requestAnimationFrame(() => {
|
|
420
|
-
const endTime = window.performance.now();
|
|
421
|
-
setRenderTime(endTime - startTime);
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
return () => window.cancelAnimationFrame(frameId);
|
|
425
|
-
}, []);
|
|
426
|
-
|
|
427
|
-
return (
|
|
428
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, alignItems: 'center' }}>
|
|
429
|
-
<Typography variant="body2" data-testid="performance-info">
|
|
430
|
-
Render time: {renderTime !== null ? `${renderTime.toFixed(2)}ms` : 'Measuring...'}
|
|
431
|
-
</Typography>
|
|
432
|
-
|
|
433
|
-
<Resizable variant="both" width={400} height={300} data-testid="performance-resizable">
|
|
434
|
-
<Box sx={{ p: 2, bgcolor: 'info.50', height: '100%', overflow: 'auto' }}>
|
|
435
|
-
<Typography variant="h6" gutterBottom>
|
|
436
|
-
Performance Test
|
|
437
|
-
</Typography>
|
|
438
|
-
<Box
|
|
439
|
-
sx={{
|
|
440
|
-
display: 'grid',
|
|
441
|
-
gridTemplateColumns: 'repeat(auto-fill, minmax(100px, 1fr))',
|
|
442
|
-
gap: 1,
|
|
443
|
-
}}
|
|
444
|
-
>
|
|
445
|
-
{items.map((item) => (
|
|
446
|
-
<Paper
|
|
447
|
-
key={item.id}
|
|
448
|
-
sx={{ p: 1, textAlign: 'center' }}
|
|
449
|
-
data-testid={`item-${item.id}`}
|
|
450
|
-
>
|
|
451
|
-
<Typography variant="caption">{item.name}</Typography>
|
|
452
|
-
</Paper>
|
|
453
|
-
))}
|
|
454
|
-
</Box>
|
|
455
|
-
</Box>
|
|
456
|
-
</Resizable>
|
|
457
|
-
</Box>
|
|
458
|
-
);
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
export const PerformanceTest: Story = {
|
|
462
|
-
name: '⚡ Performance Test',
|
|
463
|
-
render: () => <PerformanceTestComponent />,
|
|
464
|
-
play: async ({ canvasElement, step }) => {
|
|
465
|
-
const canvas = within(canvasElement);
|
|
466
|
-
|
|
467
|
-
await step('Measure render performance', async () => {
|
|
468
|
-
await waitFor(
|
|
469
|
-
async () => {
|
|
470
|
-
const performanceInfo = canvas.getByTestId('performance-info');
|
|
471
|
-
const text = performanceInfo.textContent || '';
|
|
472
|
-
// Verify we have actual render time (contains 'ms' and not 'Measuring...')
|
|
473
|
-
expect(text).toMatch(/Render time: \d+\.\d{2}ms/);
|
|
474
|
-
},
|
|
475
|
-
{
|
|
476
|
-
timeout: 5000,
|
|
477
|
-
interval: 100,
|
|
478
|
-
},
|
|
479
|
-
);
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
await step('Verify all items rendered', async () => {
|
|
483
|
-
const items = canvas.getAllByTestId(/item-/);
|
|
484
|
-
await expect(items).toHaveLength(100);
|
|
485
|
-
});
|
|
486
|
-
},
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
// 🔧 EDGE CASES TESTS
|
|
490
|
-
|
|
491
|
-
const EdgeCasesComponent: React.FC = () => {
|
|
492
|
-
const [scenario, setScenario] = useState<'normal' | 'minimal' | 'maximal' | 'extreme'>('normal');
|
|
493
|
-
|
|
494
|
-
const getProps = (): {
|
|
495
|
-
width: number;
|
|
496
|
-
height: number;
|
|
497
|
-
minWidth: number;
|
|
498
|
-
minHeight: number;
|
|
499
|
-
maxWidth: number;
|
|
500
|
-
maxHeight: number;
|
|
501
|
-
} => {
|
|
502
|
-
switch (scenario) {
|
|
503
|
-
case 'minimal':
|
|
504
|
-
return {
|
|
505
|
-
width: 50,
|
|
506
|
-
height: 50,
|
|
507
|
-
minWidth: 50,
|
|
508
|
-
minHeight: 50,
|
|
509
|
-
maxWidth: 100,
|
|
510
|
-
maxHeight: 100,
|
|
511
|
-
};
|
|
512
|
-
case 'maximal':
|
|
513
|
-
return {
|
|
514
|
-
width: 800,
|
|
515
|
-
height: 600,
|
|
516
|
-
minWidth: 700,
|
|
517
|
-
minHeight: 500,
|
|
518
|
-
maxWidth: 900,
|
|
519
|
-
maxHeight: 700,
|
|
520
|
-
};
|
|
521
|
-
case 'extreme':
|
|
522
|
-
return { width: 1, height: 1, minWidth: 1, minHeight: 1, maxWidth: 2000, maxHeight: 2000 };
|
|
523
|
-
default:
|
|
524
|
-
return {
|
|
525
|
-
width: 250,
|
|
526
|
-
height: 180,
|
|
527
|
-
minWidth: 100,
|
|
528
|
-
minHeight: 80,
|
|
529
|
-
maxWidth: 500,
|
|
530
|
-
maxHeight: 400,
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
};
|
|
534
|
-
|
|
535
|
-
const props = getProps();
|
|
536
|
-
|
|
537
|
-
return (
|
|
538
|
-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, alignItems: 'center' }}>
|
|
539
|
-
<Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
|
|
540
|
-
{['normal', 'minimal', 'maximal', 'extreme'].map((s) => (
|
|
541
|
-
<button
|
|
542
|
-
key={s}
|
|
543
|
-
onClick={() => setScenario(s as 'normal' | 'minimal' | 'maximal' | 'extreme')}
|
|
544
|
-
data-testid={`scenario-${s}`}
|
|
545
|
-
style={{
|
|
546
|
-
backgroundColor: scenario === s ? '#1976d2' : '#e0e0e0',
|
|
547
|
-
color: scenario === s ? 'white' : 'black',
|
|
548
|
-
border: 'none',
|
|
549
|
-
padding: '4px 8px',
|
|
550
|
-
borderRadius: '4px',
|
|
551
|
-
cursor: 'pointer',
|
|
552
|
-
}}
|
|
553
|
-
>
|
|
554
|
-
{s}
|
|
555
|
-
</button>
|
|
556
|
-
))}
|
|
557
|
-
</Box>
|
|
558
|
-
|
|
559
|
-
<Typography variant="body2" data-testid="scenario-info">
|
|
560
|
-
{}
|
|
561
|
-
Scenario: {scenario} - Size: {props.width}×{props.height}
|
|
562
|
-
</Typography>
|
|
563
|
-
|
|
564
|
-
<Resizable variant="both" {...props} data-testid="edge-case-resizable">
|
|
565
|
-
<Box
|
|
566
|
-
sx={{
|
|
567
|
-
p: scenario === 'minimal' ? 0.5 : 2,
|
|
568
|
-
bgcolor: 'warning.50',
|
|
569
|
-
height: '100%',
|
|
570
|
-
minWidth: 0,
|
|
571
|
-
minHeight: 0,
|
|
572
|
-
overflow: 'hidden',
|
|
573
|
-
}}
|
|
574
|
-
>
|
|
575
|
-
<Typography
|
|
576
|
-
variant={scenario === 'minimal' ? 'caption' : 'h6'}
|
|
577
|
-
data-testid="edge-case-content"
|
|
578
|
-
>
|
|
579
|
-
{scenario === 'extreme' ? '!' : scenario === 'minimal' ? 'Min' : 'Edge Cases'}
|
|
580
|
-
</Typography>
|
|
581
|
-
{scenario !== 'minimal' && scenario !== 'extreme' && (
|
|
582
|
-
<Typography variant="caption">Testing boundary conditions</Typography>
|
|
583
|
-
)}
|
|
584
|
-
</Box>
|
|
585
|
-
</Resizable>
|
|
586
|
-
</Box>
|
|
587
|
-
);
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
export const EdgeCases: Story = {
|
|
591
|
-
name: '🔧 Edge Cases Test',
|
|
592
|
-
render: () => <EdgeCasesComponent />,
|
|
593
|
-
play: async ({ canvasElement, step }) => {
|
|
594
|
-
const canvas = within(canvasElement);
|
|
595
|
-
|
|
596
|
-
await step('Test normal scenario', async () => {
|
|
597
|
-
const scenarioInfo = canvas.getByTestId('scenario-info');
|
|
598
|
-
await expect(scenarioInfo).toHaveTextContent('normal');
|
|
599
|
-
|
|
600
|
-
const content = canvas.getByTestId('edge-case-content');
|
|
601
|
-
await expect(content).toBeInTheDocument();
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
await step('Test minimal scenario', async () => {
|
|
605
|
-
const minimalBtn = canvas.getByTestId('scenario-minimal');
|
|
606
|
-
await userEvent.click(minimalBtn);
|
|
607
|
-
|
|
608
|
-
await waitFor(async () => {
|
|
609
|
-
const scenarioInfo = canvas.getByTestId('scenario-info');
|
|
610
|
-
await expect(scenarioInfo).toHaveTextContent('minimal');
|
|
611
|
-
await expect(scenarioInfo).toHaveTextContent('50×50');
|
|
612
|
-
});
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
await step('Test maximal scenario', async () => {
|
|
616
|
-
const maximalBtn = canvas.getByTestId('scenario-maximal');
|
|
617
|
-
await userEvent.click(maximalBtn);
|
|
618
|
-
|
|
619
|
-
await waitFor(async () => {
|
|
620
|
-
const scenarioInfo = canvas.getByTestId('scenario-info');
|
|
621
|
-
await expect(scenarioInfo).toHaveTextContent('maximal');
|
|
622
|
-
await expect(scenarioInfo).toHaveTextContent('800×600');
|
|
623
|
-
});
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
await step('Test extreme scenario', async () => {
|
|
627
|
-
const extremeBtn = canvas.getByTestId('scenario-extreme');
|
|
628
|
-
await userEvent.click(extremeBtn);
|
|
629
|
-
|
|
630
|
-
await waitFor(async () => {
|
|
631
|
-
const scenarioInfo = canvas.getByTestId('scenario-info');
|
|
632
|
-
await expect(scenarioInfo).toHaveTextContent('extreme');
|
|
633
|
-
await expect(scenarioInfo).toHaveTextContent('1×1');
|
|
634
|
-
});
|
|
635
|
-
});
|
|
636
|
-
},
|
|
637
|
-
};
|
|
638
|
-
|
|
639
|
-
// 🔗 INTEGRATION TESTS
|
|
640
|
-
|
|
641
|
-
const IntegrationTestComponent: React.FC = () => {
|
|
642
|
-
const [leftWidth, setLeftWidth] = useState(200);
|
|
643
|
-
const [rightWidth, setRightWidth] = useState(200);
|
|
644
|
-
const [bottomHeight, setBottomHeight] = useState(100);
|
|
645
|
-
|
|
646
|
-
return (
|
|
647
|
-
<Box
|
|
648
|
-
sx={{
|
|
649
|
-
display: 'flex',
|
|
650
|
-
flexDirection: 'column',
|
|
651
|
-
height: 400,
|
|
652
|
-
border: 1,
|
|
653
|
-
borderColor: 'divider',
|
|
654
|
-
}}
|
|
655
|
-
>
|
|
656
|
-
<Typography variant="h6" sx={{ p: 1, borderBottom: 1, borderColor: 'divider' }}>
|
|
657
|
-
Multi-Panel Layout
|
|
658
|
-
</Typography>
|
|
659
|
-
|
|
660
|
-
<Box sx={{ display: 'flex', flex: 1 }}>
|
|
661
|
-
{/* Left Panel */}
|
|
662
|
-
<Resizable
|
|
663
|
-
variant="horizontal"
|
|
664
|
-
width={leftWidth}
|
|
665
|
-
height={200}
|
|
666
|
-
minWidth={150}
|
|
667
|
-
maxWidth={300}
|
|
668
|
-
onResize={(width) => setLeftWidth(width)}
|
|
669
|
-
data-testid="left-panel"
|
|
670
|
-
>
|
|
671
|
-
<Box sx={{ p: 2, bgcolor: 'primary.50', height: '100%' }}>
|
|
672
|
-
<Typography variant="subtitle2">Left Panel</Typography>
|
|
673
|
-
<Typography variant="caption">Width: {leftWidth}px</Typography>
|
|
674
|
-
</Box>
|
|
675
|
-
</Resizable>
|
|
676
|
-
|
|
677
|
-
<Box sx={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
|
|
678
|
-
{/* Main Content */}
|
|
679
|
-
<Box sx={{ flex: 1, p: 2, bgcolor: 'grey.50' }}>
|
|
680
|
-
<Typography variant="h6">Main Content</Typography>
|
|
681
|
-
<Typography variant="body2">
|
|
682
|
-
Available width: {400 - leftWidth - rightWidth}px
|
|
683
|
-
</Typography>
|
|
684
|
-
</Box>
|
|
685
|
-
|
|
686
|
-
{/* Bottom Panel */}
|
|
687
|
-
<Resizable
|
|
688
|
-
variant="vertical"
|
|
689
|
-
width={300}
|
|
690
|
-
height={bottomHeight}
|
|
691
|
-
minHeight={60}
|
|
692
|
-
maxHeight={200}
|
|
693
|
-
onResize={(_, height) => setBottomHeight(height)}
|
|
694
|
-
data-testid="bottom-panel"
|
|
695
|
-
>
|
|
696
|
-
<Box sx={{ p: 1, bgcolor: 'info.50', height: '100%' }}>
|
|
697
|
-
<Typography variant="caption">Bottom Panel - Height: {bottomHeight}px</Typography>
|
|
698
|
-
</Box>
|
|
699
|
-
</Resizable>
|
|
700
|
-
</Box>
|
|
701
|
-
|
|
702
|
-
{/* Right Panel */}
|
|
703
|
-
<Resizable
|
|
704
|
-
variant="horizontal"
|
|
705
|
-
width={rightWidth}
|
|
706
|
-
height={200}
|
|
707
|
-
minWidth={150}
|
|
708
|
-
maxWidth={300}
|
|
709
|
-
onResize={(width) => setRightWidth(width)}
|
|
710
|
-
data-testid="right-panel"
|
|
711
|
-
>
|
|
712
|
-
<Box sx={{ p: 2, bgcolor: 'secondary.50', height: '100%' }}>
|
|
713
|
-
<Typography variant="subtitle2">Right Panel</Typography>
|
|
714
|
-
<Typography variant="caption">Width: {rightWidth}px</Typography>
|
|
715
|
-
</Box>
|
|
716
|
-
</Resizable>
|
|
717
|
-
</Box>
|
|
718
|
-
</Box>
|
|
719
|
-
);
|
|
720
|
-
};
|
|
721
|
-
|
|
722
|
-
export const IntegrationTest: Story = {
|
|
723
|
-
name: '🔗 Integration Test',
|
|
724
|
-
render: () => <IntegrationTestComponent />,
|
|
725
|
-
play: async ({ canvasElement, step }) => {
|
|
726
|
-
const canvas = within(canvasElement);
|
|
727
|
-
|
|
728
|
-
await step('All panels render correctly', async () => {
|
|
729
|
-
const leftPanel = canvas.getByTestId('left-panel');
|
|
730
|
-
const rightPanel = canvas.getByTestId('right-panel');
|
|
731
|
-
const bottomPanel = canvas.getByTestId('bottom-panel');
|
|
732
|
-
|
|
733
|
-
await expect(leftPanel).toBeInTheDocument();
|
|
734
|
-
await expect(rightPanel).toBeInTheDocument();
|
|
735
|
-
await expect(bottomPanel).toBeInTheDocument();
|
|
736
|
-
});
|
|
737
|
-
|
|
738
|
-
await step('Panel dimensions are displayed', async () => {
|
|
739
|
-
const widthElements = canvas.getAllByText(/Width:\s*200\s*px/);
|
|
740
|
-
// Fixed: Only 2 panels (left and right) show width
|
|
741
|
-
await expect(widthElements.length).toBe(2);
|
|
742
|
-
await expect(canvas.getByText(/Height:\s*100\s*px/)).toBeInTheDocument();
|
|
743
|
-
});
|
|
744
|
-
|
|
745
|
-
await step('Main content area adapts to panel sizes', async () => {
|
|
746
|
-
const mainContent = canvas.getByText(/Available width:/);
|
|
747
|
-
await expect(mainContent).toBeInTheDocument();
|
|
748
|
-
});
|
|
749
|
-
},
|
|
750
|
-
};
|