@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,607 +0,0 @@
|
|
|
1
|
-
import Delete from '@mui/icons-material/Delete';
|
|
2
|
-
import Save from '@mui/icons-material/Save';
|
|
3
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
-
import { expect, fn,userEvent, waitFor, within } from 'storybook/test';
|
|
5
|
-
|
|
6
|
-
import { Button } from './Button';
|
|
7
|
-
|
|
8
|
-
const meta: Meta<typeof Button> = {
|
|
9
|
-
title: 'Form/Button/Tests',
|
|
10
|
-
component: Button,
|
|
11
|
-
parameters: {
|
|
12
|
-
layout: 'centered',
|
|
13
|
-
chromatic: { disableSnapshot: false },
|
|
14
|
-
},
|
|
15
|
-
tags: ['autodocs', 'test', 'component:Button'],
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default meta;
|
|
19
|
-
type Story = StoryObj<typeof meta>;
|
|
20
|
-
|
|
21
|
-
// ============================================================================
|
|
22
|
-
// INTERACTION TESTS
|
|
23
|
-
// ============================================================================
|
|
24
|
-
|
|
25
|
-
export const BasicInteraction: Story = {
|
|
26
|
-
name: '🧪 Basic Interaction Test',
|
|
27
|
-
args: {
|
|
28
|
-
children: 'Click Me',
|
|
29
|
-
onClick: fn(),
|
|
30
|
-
onFocus: fn(),
|
|
31
|
-
onBlur: fn(),
|
|
32
|
-
onMouseEnter: fn(),
|
|
33
|
-
onMouseLeave: fn(),
|
|
34
|
-
'data-testid': 'basic-button',
|
|
35
|
-
},
|
|
36
|
-
play: async ({ canvasElement, step, args }) => {
|
|
37
|
-
const canvas = within(canvasElement);
|
|
38
|
-
|
|
39
|
-
await step('Initial render verification', async () => {
|
|
40
|
-
const button = canvas.getByTestId('basic-button');
|
|
41
|
-
await expect(button).toBeInTheDocument();
|
|
42
|
-
await expect(button).toHaveTextContent('Click Me');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
await step('Click interaction', async () => {
|
|
46
|
-
const button = canvas.getByTestId('basic-button');
|
|
47
|
-
await userEvent.click(button);
|
|
48
|
-
await expect(args.onClick).toHaveBeenCalledTimes(1);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
await step('Hover interaction', async () => {
|
|
52
|
-
const button = canvas.getByTestId('basic-button');
|
|
53
|
-
await userEvent.hover(button);
|
|
54
|
-
// Verify hover effects are applied (transform/shadow)
|
|
55
|
-
const computedStyle = window.getComputedStyle(button);
|
|
56
|
-
await expect(computedStyle.transform).toBeTruthy();
|
|
57
|
-
});
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export const VariantSwitching: Story = {
|
|
62
|
-
name: '🔄 Variant Switching Test',
|
|
63
|
-
args: {
|
|
64
|
-
children: 'Dynamic Button',
|
|
65
|
-
'data-testid': 'variant-button',
|
|
66
|
-
},
|
|
67
|
-
play: async ({ canvasElement, step }) => {
|
|
68
|
-
const canvas = within(canvasElement);
|
|
69
|
-
const button = canvas.getByTestId('variant-button');
|
|
70
|
-
|
|
71
|
-
await step('Verify solid variant (default)', async () => {
|
|
72
|
-
await expect(button).toBeInTheDocument();
|
|
73
|
-
// Check for solid button characteristics
|
|
74
|
-
const computedStyle = window.getComputedStyle(button);
|
|
75
|
-
await expect(computedStyle.backgroundColor).toBeTruthy();
|
|
76
|
-
});
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const LoadingStateTest: Story = {
|
|
81
|
-
name: '⏳ Loading State Test',
|
|
82
|
-
args: {
|
|
83
|
-
children: 'Loading Button',
|
|
84
|
-
loading: true,
|
|
85
|
-
'data-testid': 'loading-button',
|
|
86
|
-
},
|
|
87
|
-
play: async ({ canvasElement, step }) => {
|
|
88
|
-
const canvas = within(canvasElement);
|
|
89
|
-
|
|
90
|
-
await step('Verify loading state', async () => {
|
|
91
|
-
const button = canvas.getByTestId('loading-button');
|
|
92
|
-
await expect(button).toBeDisabled();
|
|
93
|
-
|
|
94
|
-
// Check for loading spinner
|
|
95
|
-
const spinner = canvas.getByRole('progressbar');
|
|
96
|
-
await expect(spinner).toBeInTheDocument();
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
await step('Verify text is replaced by spinner', async () => {
|
|
100
|
-
const button = canvas.getByTestId('loading-button');
|
|
101
|
-
// Text should not be visible when loading
|
|
102
|
-
await expect(button).not.toHaveTextContent('Loading Button');
|
|
103
|
-
});
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
// ============================================================================
|
|
108
|
-
// ACCESSIBILITY TESTS
|
|
109
|
-
// ============================================================================
|
|
110
|
-
|
|
111
|
-
export const KeyboardNavigation: Story = {
|
|
112
|
-
name: '⌨️ Keyboard Navigation Test',
|
|
113
|
-
args: {
|
|
114
|
-
children: 'Accessible Button',
|
|
115
|
-
onClick: fn(),
|
|
116
|
-
onFocus: fn(),
|
|
117
|
-
onBlur: fn(),
|
|
118
|
-
onKeyDown: fn(),
|
|
119
|
-
'data-testid': 'keyboard-button',
|
|
120
|
-
},
|
|
121
|
-
parameters: {
|
|
122
|
-
a11y: {
|
|
123
|
-
element: '#storybook-root',
|
|
124
|
-
config: {
|
|
125
|
-
rules: [
|
|
126
|
-
{ id: 'color-contrast', enabled: true },
|
|
127
|
-
{ id: 'button-name', enabled: true },
|
|
128
|
-
{ id: 'focusable-element', enabled: true },
|
|
129
|
-
],
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
play: async ({ canvasElement, step, args }) => {
|
|
134
|
-
const canvas = within(canvasElement);
|
|
135
|
-
|
|
136
|
-
// The story renders this single button, so one tab reaches it. Focus then
|
|
137
|
-
// stays put across the activation steps — pressing Enter or Space on a
|
|
138
|
-
// button does not move it — which is what makes this one keyboard journey
|
|
139
|
-
// rather than three re-focused fragments.
|
|
140
|
-
await step('Focus via Tab navigation', async () => {
|
|
141
|
-
const button = canvas.getByTestId('keyboard-button');
|
|
142
|
-
await userEvent.tab();
|
|
143
|
-
await waitFor(() => expect(button).toHaveFocus());
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
await step('Enter key activation', async () => {
|
|
147
|
-
const button = canvas.getByTestId('keyboard-button');
|
|
148
|
-
await waitFor(() => expect(button).toHaveFocus());
|
|
149
|
-
await userEvent.keyboard('{Enter}');
|
|
150
|
-
await expect(args.onClick).toHaveBeenCalled();
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
await step('Space key activation', async () => {
|
|
154
|
-
const button = canvas.getByTestId('keyboard-button');
|
|
155
|
-
await waitFor(() => expect(button).toHaveFocus());
|
|
156
|
-
await userEvent.keyboard(' ');
|
|
157
|
-
await expect(args.onClick).toHaveBeenCalled();
|
|
158
|
-
});
|
|
159
|
-
},
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
export const ScreenReaderTest: Story = {
|
|
163
|
-
name: '🔊 Screen Reader Test',
|
|
164
|
-
args: {
|
|
165
|
-
children: 'Screen Reader Button',
|
|
166
|
-
'aria-label': 'Custom accessible label',
|
|
167
|
-
'aria-describedby': 'button-description',
|
|
168
|
-
'data-testid': 'sr-button',
|
|
169
|
-
},
|
|
170
|
-
render: (args) => (
|
|
171
|
-
<>
|
|
172
|
-
<Button {...args} />
|
|
173
|
-
<div id="button-description" data-testid="description">
|
|
174
|
-
This button performs an important action
|
|
175
|
-
</div>
|
|
176
|
-
</>
|
|
177
|
-
),
|
|
178
|
-
play: async ({ canvasElement, step }) => {
|
|
179
|
-
const canvas = within(canvasElement);
|
|
180
|
-
|
|
181
|
-
await step('Verify ARIA labels', async () => {
|
|
182
|
-
const button = canvas.getByTestId('sr-button');
|
|
183
|
-
await expect(button).toHaveAttribute('aria-label', 'Custom accessible label');
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
await step('Verify ARIA descriptions', async () => {
|
|
187
|
-
const button = canvas.getByTestId('sr-button');
|
|
188
|
-
await expect(button).toHaveAttribute('aria-describedby', 'button-description');
|
|
189
|
-
|
|
190
|
-
const description = canvas.getByTestId('description');
|
|
191
|
-
await expect(description).toBeInTheDocument();
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
await step('Verify role attributes', async () => {
|
|
195
|
-
const button = canvas.getByTestId('sr-button');
|
|
196
|
-
await expect(button).toHaveAttribute('type', 'button');
|
|
197
|
-
});
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
export const DisabledAccessibility: Story = {
|
|
202
|
-
name: '🚫 Disabled Accessibility Test',
|
|
203
|
-
args: {
|
|
204
|
-
children: 'Disabled Button',
|
|
205
|
-
disabled: true,
|
|
206
|
-
onClick: fn(),
|
|
207
|
-
onFocus: fn(),
|
|
208
|
-
onBlur: fn(),
|
|
209
|
-
onKeyDown: fn(),
|
|
210
|
-
'data-testid': 'disabled-button',
|
|
211
|
-
},
|
|
212
|
-
play: async ({ canvasElement, step, args }) => {
|
|
213
|
-
const canvas = within(canvasElement);
|
|
214
|
-
|
|
215
|
-
await step('Verify disabled state', async () => {
|
|
216
|
-
const button = canvas.getByTestId('disabled-button');
|
|
217
|
-
await expect(button).toBeDisabled();
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
await step('Verify click is prevented', async () => {
|
|
221
|
-
const button = canvas.getByTestId('disabled-button');
|
|
222
|
-
// Disabled button has pointer-events: none, so we use pointer options to bypass
|
|
223
|
-
try {
|
|
224
|
-
await userEvent.click(button, { pointerEventsCheck: 0 });
|
|
225
|
-
} catch {
|
|
226
|
-
// Expected - disabled button should prevent interactions
|
|
227
|
-
}
|
|
228
|
-
// In any case, onClick should not have been called
|
|
229
|
-
await expect(args.onClick).not.toHaveBeenCalled();
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
await step('Verify keyboard interaction is prevented', async () => {
|
|
233
|
-
// A disabled button is not tabbable and cannot take focus, so keyboard
|
|
234
|
-
// input never reaches it. The previous version called .focus() on it,
|
|
235
|
-
// which is a no-op on a disabled element — the step passed for the wrong
|
|
236
|
-
// reason. Sending the keys with focus left on the body is the real check.
|
|
237
|
-
await userEvent.keyboard('{Enter}');
|
|
238
|
-
await userEvent.keyboard(' ');
|
|
239
|
-
await expect(args.onClick).not.toHaveBeenCalled();
|
|
240
|
-
});
|
|
241
|
-
},
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
// ============================================================================
|
|
245
|
-
// VISUAL TESTS
|
|
246
|
-
// ============================================================================
|
|
247
|
-
|
|
248
|
-
export const VisualStates: Story = {
|
|
249
|
-
name: '👁️ Visual States Test',
|
|
250
|
-
args: {
|
|
251
|
-
children: 'Visual Test Button',
|
|
252
|
-
variant: 'solid', // Explicitly set to solid to ensure hover transform works
|
|
253
|
-
'data-testid': 'visual-button',
|
|
254
|
-
},
|
|
255
|
-
play: async ({ canvasElement, step }) => {
|
|
256
|
-
const canvas = within(canvasElement);
|
|
257
|
-
|
|
258
|
-
await step('Default state', async () => {
|
|
259
|
-
const button = canvas.getByTestId('visual-button');
|
|
260
|
-
const computedStyle = window.getComputedStyle(button);
|
|
261
|
-
await expect(computedStyle.opacity).toBe('1');
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
await step('Hover state', async () => {
|
|
265
|
-
const button = canvas.getByTestId('visual-button');
|
|
266
|
-
|
|
267
|
-
// Test hover interaction - simplified approach
|
|
268
|
-
await userEvent.hover(button);
|
|
269
|
-
|
|
270
|
-
// Wait for transition to complete and just verify hover works
|
|
271
|
-
await waitFor(() => {
|
|
272
|
-
const computedStyle = window.getComputedStyle(button);
|
|
273
|
-
// Just verify that the button can be hovered and styles are applied
|
|
274
|
-
// Check for any style changes that indicate hover state
|
|
275
|
-
expect(computedStyle.cursor).toBe('pointer');
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
},
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
export const SpecialEffectsTest: Story = {
|
|
282
|
-
name: '✨ Special Effects Test',
|
|
283
|
-
render: () => (
|
|
284
|
-
<div style={{ display: 'flex', gap: '1rem', flexDirection: 'column' }}>
|
|
285
|
-
<Button glow data-testid="glow-button">
|
|
286
|
-
Glow Effect
|
|
287
|
-
</Button>
|
|
288
|
-
<Button pulse data-testid="pulse-button">
|
|
289
|
-
Pulse Animation
|
|
290
|
-
</Button>
|
|
291
|
-
<Button glow pulse data-testid="combined-button">
|
|
292
|
-
Combined Effects
|
|
293
|
-
</Button>
|
|
294
|
-
</div>
|
|
295
|
-
),
|
|
296
|
-
play: async ({ canvasElement, step }) => {
|
|
297
|
-
const canvas = within(canvasElement);
|
|
298
|
-
|
|
299
|
-
await step('Verify glow effect', async () => {
|
|
300
|
-
const glowButton = canvas.getByTestId('glow-button');
|
|
301
|
-
const computedStyle = window.getComputedStyle(glowButton);
|
|
302
|
-
await expect(computedStyle.boxShadow).toBeTruthy();
|
|
303
|
-
await expect(computedStyle.filter).toContain('brightness');
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
await step('Verify pulse animation', async () => {
|
|
307
|
-
const pulseButton = canvas.getByTestId('pulse-button');
|
|
308
|
-
// Pulse effect creates pseudo-element with animation
|
|
309
|
-
await expect(pulseButton).toBeInTheDocument();
|
|
310
|
-
// Verify button has pulse styling (position: relative for pseudo-element)
|
|
311
|
-
const computedStyle = window.getComputedStyle(pulseButton);
|
|
312
|
-
await expect(computedStyle.position).toBe('relative');
|
|
313
|
-
await expect(computedStyle.overflow).toBe('visible');
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
await step('Verify combined effects', async () => {
|
|
317
|
-
const combinedButton = canvas.getByTestId('combined-button');
|
|
318
|
-
const computedStyle = window.getComputedStyle(combinedButton);
|
|
319
|
-
await expect(computedStyle.boxShadow).toBeTruthy();
|
|
320
|
-
await expect(computedStyle.filter).toContain('brightness');
|
|
321
|
-
});
|
|
322
|
-
},
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
export const ResponsiveDesign: Story = {
|
|
326
|
-
name: '📱 Responsive Design Test',
|
|
327
|
-
args: {
|
|
328
|
-
children: 'Responsive Button',
|
|
329
|
-
'data-testid': 'responsive-button',
|
|
330
|
-
},
|
|
331
|
-
parameters: {
|
|
332
|
-
viewport: {
|
|
333
|
-
viewports: {
|
|
334
|
-
mobile: {
|
|
335
|
-
name: 'Mobile',
|
|
336
|
-
styles: { width: '375px', height: '667px' },
|
|
337
|
-
type: 'mobile',
|
|
338
|
-
},
|
|
339
|
-
tablet: {
|
|
340
|
-
name: 'Tablet',
|
|
341
|
-
styles: { width: '768px', height: '1024px' },
|
|
342
|
-
type: 'tablet',
|
|
343
|
-
},
|
|
344
|
-
desktop: {
|
|
345
|
-
name: 'Desktop',
|
|
346
|
-
styles: { width: '1920px', height: '1080px' },
|
|
347
|
-
type: 'desktop',
|
|
348
|
-
},
|
|
349
|
-
},
|
|
350
|
-
defaultViewport: 'mobile',
|
|
351
|
-
},
|
|
352
|
-
chromatic: {
|
|
353
|
-
viewports: [375, 768, 1920],
|
|
354
|
-
delay: 300,
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
|
-
play: async ({ canvasElement, step }) => {
|
|
358
|
-
const canvas = within(canvasElement);
|
|
359
|
-
|
|
360
|
-
await step('Verify button renders on mobile', async () => {
|
|
361
|
-
const button = canvas.getByTestId('responsive-button');
|
|
362
|
-
await expect(button).toBeInTheDocument();
|
|
363
|
-
|
|
364
|
-
const computedStyle = window.getComputedStyle(button);
|
|
365
|
-
await expect(computedStyle.display).toBe('inline-flex');
|
|
366
|
-
});
|
|
367
|
-
},
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
// ============================================================================
|
|
371
|
-
// EDGE CASES TESTS
|
|
372
|
-
// ============================================================================
|
|
373
|
-
|
|
374
|
-
export const EdgeCases: Story = {
|
|
375
|
-
name: '🔧 Edge Cases Test',
|
|
376
|
-
render: () => (
|
|
377
|
-
<div style={{ display: 'flex', gap: '1rem', flexDirection: 'column', maxWidth: '200px' }}>
|
|
378
|
-
<Button data-testid="empty-button"></Button>
|
|
379
|
-
<Button data-testid="long-text-button">
|
|
380
|
-
This is a very long button text that should handle overflow gracefully without breaking the
|
|
381
|
-
layout
|
|
382
|
-
</Button>
|
|
383
|
-
<Button size="xs" data-testid="tiny-button">
|
|
384
|
-
Tiny
|
|
385
|
-
</Button>
|
|
386
|
-
<Button size="xl" data-testid="huge-button">
|
|
387
|
-
Huge Button
|
|
388
|
-
</Button>
|
|
389
|
-
</div>
|
|
390
|
-
),
|
|
391
|
-
play: async ({ canvasElement, step }) => {
|
|
392
|
-
const canvas = within(canvasElement);
|
|
393
|
-
|
|
394
|
-
await step('Empty content handling', async () => {
|
|
395
|
-
const emptyButton = canvas.getByTestId('empty-button');
|
|
396
|
-
await expect(emptyButton).toBeInTheDocument();
|
|
397
|
-
// Button should still be clickable even without text
|
|
398
|
-
const computedStyle = window.getComputedStyle(emptyButton);
|
|
399
|
-
await expect(computedStyle.minHeight).toBeTruthy();
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
await step('Long text handling', async () => {
|
|
403
|
-
const longTextButton = canvas.getByTestId('long-text-button');
|
|
404
|
-
// Button should handle long text without breaking
|
|
405
|
-
await expect(longTextButton).toBeInTheDocument();
|
|
406
|
-
// Verify text doesn't overflow
|
|
407
|
-
const computedStyle = window.getComputedStyle(longTextButton);
|
|
408
|
-
await expect(computedStyle.overflow).not.toBe('visible');
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
await step('Size extremes', async () => {
|
|
412
|
-
const tinyButton = canvas.getByTestId('tiny-button');
|
|
413
|
-
const hugeButton = canvas.getByTestId('huge-button');
|
|
414
|
-
|
|
415
|
-
await expect(tinyButton).toBeInTheDocument();
|
|
416
|
-
await expect(hugeButton).toBeInTheDocument();
|
|
417
|
-
|
|
418
|
-
// Verify size differences
|
|
419
|
-
const tinyStyle = window.getComputedStyle(tinyButton);
|
|
420
|
-
const hugeStyle = window.getComputedStyle(hugeButton);
|
|
421
|
-
|
|
422
|
-
const tinyFontSize = parseFloat(tinyStyle.fontSize);
|
|
423
|
-
const hugeFontSize = parseFloat(hugeStyle.fontSize);
|
|
424
|
-
|
|
425
|
-
await expect(hugeFontSize).toBeGreaterThan(tinyFontSize);
|
|
426
|
-
});
|
|
427
|
-
},
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
// ============================================================================
|
|
431
|
-
// PERFORMANCE TESTS
|
|
432
|
-
// ============================================================================
|
|
433
|
-
|
|
434
|
-
export const PerformanceTest: Story = {
|
|
435
|
-
name: '⚡ Performance Test',
|
|
436
|
-
render: () => (
|
|
437
|
-
<div
|
|
438
|
-
data-testid="button-container"
|
|
439
|
-
style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }}
|
|
440
|
-
>
|
|
441
|
-
{Array.from({ length: 50 }, (_, i) => (
|
|
442
|
-
<Button key={i} data-testid={`perf-button-${i}`} size="sm">
|
|
443
|
-
Button {i + 1}
|
|
444
|
-
</Button>
|
|
445
|
-
))}
|
|
446
|
-
</div>
|
|
447
|
-
),
|
|
448
|
-
play: async ({ canvasElement, step }) => {
|
|
449
|
-
const canvas = within(canvasElement);
|
|
450
|
-
|
|
451
|
-
await step('All buttons rendered', async () => {
|
|
452
|
-
// The timing assertion that used to live here bracketed getAllByTestId,
|
|
453
|
-
// which queries DOM that is already rendered — it measured query time, not
|
|
454
|
-
// render time, and a 100ms wall-clock budget is exactly what a loaded CI
|
|
455
|
-
// runner blows through. The count is the part that actually held.
|
|
456
|
-
const buttons = canvas.getAllByTestId(/perf-button-/);
|
|
457
|
-
await expect(buttons.length).toBe(50);
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
await step('Test rapid interactions', async () => {
|
|
461
|
-
const buttons = canvas.getAllByTestId(/perf-button-/);
|
|
462
|
-
const sampleButton = buttons[0];
|
|
463
|
-
|
|
464
|
-
// Simulate rapid hover/unhover
|
|
465
|
-
for (let i = 0; i < 5; i++) {
|
|
466
|
-
await userEvent.hover(sampleButton);
|
|
467
|
-
await userEvent.unhover(sampleButton);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// Button should still be responsive
|
|
471
|
-
await expect(sampleButton).toBeInTheDocument();
|
|
472
|
-
});
|
|
473
|
-
},
|
|
474
|
-
};
|
|
475
|
-
|
|
476
|
-
// ============================================================================
|
|
477
|
-
// INTEGRATION TESTS
|
|
478
|
-
// ============================================================================
|
|
479
|
-
|
|
480
|
-
export const IconIntegration: Story = {
|
|
481
|
-
name: '🔗 Icon Integration Test',
|
|
482
|
-
args: {
|
|
483
|
-
children: 'Save Document',
|
|
484
|
-
icon: <Save data-testid="save-icon" />,
|
|
485
|
-
onClick: fn(),
|
|
486
|
-
onFocus: fn(),
|
|
487
|
-
onBlur: fn(),
|
|
488
|
-
'data-testid': 'icon-button',
|
|
489
|
-
},
|
|
490
|
-
play: async ({ canvasElement, step, args }) => {
|
|
491
|
-
const canvas = within(canvasElement);
|
|
492
|
-
|
|
493
|
-
await step('Verify icon and text render together', async () => {
|
|
494
|
-
const button = canvas.getByTestId('icon-button');
|
|
495
|
-
const icon = canvas.getByTestId('save-icon');
|
|
496
|
-
|
|
497
|
-
await expect(button).toBeInTheDocument();
|
|
498
|
-
await expect(icon).toBeInTheDocument();
|
|
499
|
-
await expect(button).toHaveTextContent('Save Document');
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
await step('Verify button functionality with icon', async () => {
|
|
503
|
-
const button = canvas.getByTestId('icon-button');
|
|
504
|
-
await userEvent.click(button);
|
|
505
|
-
await expect(args.onClick).toHaveBeenCalled();
|
|
506
|
-
});
|
|
507
|
-
},
|
|
508
|
-
};
|
|
509
|
-
|
|
510
|
-
export const LoadingWithIcon: Story = {
|
|
511
|
-
name: '⏳ Loading With Icon Integration',
|
|
512
|
-
args: {
|
|
513
|
-
children: 'Processing...',
|
|
514
|
-
icon: <Delete data-testid="delete-icon" />,
|
|
515
|
-
loading: true,
|
|
516
|
-
'data-testid': 'loading-icon-button',
|
|
517
|
-
},
|
|
518
|
-
play: async ({ canvasElement, step }) => {
|
|
519
|
-
const canvas = within(canvasElement);
|
|
520
|
-
|
|
521
|
-
await step('Verify icon is hidden during loading', async () => {
|
|
522
|
-
const button = canvas.getByTestId('loading-icon-button');
|
|
523
|
-
await expect(button).toBeInTheDocument();
|
|
524
|
-
|
|
525
|
-
// Assert the positive condition first: the spinner being present is what
|
|
526
|
-
// establishes that the loading state actually rendered. Without it the
|
|
527
|
-
// absence check below would also pass on a button that rendered nothing.
|
|
528
|
-
const spinner = canvas.getByRole('progressbar');
|
|
529
|
-
await expect(spinner).toBeInTheDocument();
|
|
530
|
-
|
|
531
|
-
// Icon should not be visible when loading
|
|
532
|
-
await waitFor(() => expect(canvas.queryByTestId('delete-icon')).not.toBeInTheDocument());
|
|
533
|
-
});
|
|
534
|
-
},
|
|
535
|
-
};
|
|
536
|
-
|
|
537
|
-
export const ComplexVariantTest: Story = {
|
|
538
|
-
name: '🎨 Complex Variant Combinations',
|
|
539
|
-
render: () => (
|
|
540
|
-
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '1rem' }}>
|
|
541
|
-
<Button variant="solid" color="primary" size="lg" data-testid="solid-primary-lg">
|
|
542
|
-
Solid Primary Large
|
|
543
|
-
</Button>
|
|
544
|
-
<Button
|
|
545
|
-
variant="outline"
|
|
546
|
-
color="secondary"
|
|
547
|
-
size="sm"
|
|
548
|
-
glow
|
|
549
|
-
data-testid="outline-secondary-sm-glow"
|
|
550
|
-
>
|
|
551
|
-
Outline Secondary Small Glow
|
|
552
|
-
</Button>
|
|
553
|
-
<Button variant="glass" color="success" pulse data-testid="glass-success-pulse">
|
|
554
|
-
Glass Success Pulse
|
|
555
|
-
</Button>
|
|
556
|
-
<Button variant="gradient" color="warning" size="xl" data-testid="gradient-warning-xl">
|
|
557
|
-
Gradient Warning XL
|
|
558
|
-
</Button>
|
|
559
|
-
<Button variant="ghost" color="danger" loading data-testid="ghost-danger-loading">
|
|
560
|
-
Ghost Danger Loading
|
|
561
|
-
</Button>
|
|
562
|
-
<Button variant="solid" color="neutral" disabled data-testid="solid-neutral-disabled">
|
|
563
|
-
Solid Neutral Disabled
|
|
564
|
-
</Button>
|
|
565
|
-
</div>
|
|
566
|
-
),
|
|
567
|
-
play: async ({ canvasElement, step }) => {
|
|
568
|
-
const canvas = within(canvasElement);
|
|
569
|
-
|
|
570
|
-
await step('Verify all complex variants render', async () => {
|
|
571
|
-
const buttons = [
|
|
572
|
-
'solid-primary-lg',
|
|
573
|
-
'outline-secondary-sm-glow',
|
|
574
|
-
'glass-success-pulse',
|
|
575
|
-
'gradient-warning-xl',
|
|
576
|
-
'ghost-danger-loading',
|
|
577
|
-
'solid-neutral-disabled',
|
|
578
|
-
];
|
|
579
|
-
|
|
580
|
-
for (const buttonId of buttons) {
|
|
581
|
-
const button = canvas.getByTestId(buttonId);
|
|
582
|
-
await expect(button).toBeInTheDocument();
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
await step('Verify disabled and loading states', async () => {
|
|
587
|
-
const loadingButton = canvas.getByTestId('ghost-danger-loading');
|
|
588
|
-
const disabledButton = canvas.getByTestId('solid-neutral-disabled');
|
|
589
|
-
|
|
590
|
-
await expect(loadingButton).toBeDisabled();
|
|
591
|
-
await expect(disabledButton).toBeDisabled();
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
await step('Verify special effects are applied', async () => {
|
|
595
|
-
const glowButton = canvas.getByTestId('outline-secondary-sm-glow');
|
|
596
|
-
const pulseButton = canvas.getByTestId('glass-success-pulse');
|
|
597
|
-
|
|
598
|
-
const glowStyle = window.getComputedStyle(glowButton);
|
|
599
|
-
|
|
600
|
-
await expect(glowStyle.boxShadow).toBeTruthy();
|
|
601
|
-
await expect(pulseButton).toBeInTheDocument(); // Pulse creates pseudo-element
|
|
602
|
-
// Verify pulse button has pulse styling (position: relative for pseudo-element)
|
|
603
|
-
const pulseStyle = window.getComputedStyle(pulseButton);
|
|
604
|
-
await expect(pulseStyle.position).toBe('relative');
|
|
605
|
-
});
|
|
606
|
-
},
|
|
607
|
-
};
|