@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,361 +0,0 @@
|
|
|
1
|
-
import { Box, ListItem, ListItemText,Typography } from '@mui/material';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import React, { useCallback, useRef, useState } from 'react';
|
|
4
|
-
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
|
5
|
-
|
|
6
|
-
import { InfiniteScroll } from './InfiniteScroll';
|
|
7
|
-
|
|
8
|
-
const meta: Meta<typeof InfiniteScroll> = {
|
|
9
|
-
title: 'Utility/InfiniteScroll/Tests',
|
|
10
|
-
component: InfiniteScroll,
|
|
11
|
-
parameters: {
|
|
12
|
-
layout: 'centered',
|
|
13
|
-
chromatic: { disableSnapshot: false },
|
|
14
|
-
},
|
|
15
|
-
tags: ['autodocs', 'test', 'component:InfiniteScroll'],
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default meta;
|
|
19
|
-
type Story = StoryObj<typeof meta>;
|
|
20
|
-
|
|
21
|
-
interface TestItem {
|
|
22
|
-
id: number;
|
|
23
|
-
name: string;
|
|
24
|
-
description: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const generateItems = (start: number, count: number): TestItem[] =>
|
|
28
|
-
Array.from({ length: count }, (_, i) => ({
|
|
29
|
-
id: start + i,
|
|
30
|
-
name: `Item ${start + i + 1}`,
|
|
31
|
-
description: `Description ${start + i + 1}`,
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
const createTestComponent = (useTestMode = false) => {
|
|
35
|
-
const TestComponent = () => {
|
|
36
|
-
const [items, setItems] = useState<TestItem[]>(generateItems(0, 5));
|
|
37
|
-
const [loading, setLoading] = useState(false);
|
|
38
|
-
const [hasMore, setHasMore] = useState(true);
|
|
39
|
-
const triggerRef = useRef<(() => void) | undefined>(undefined);
|
|
40
|
-
const containerRef = useRef<HTMLDivElement>(null);
|
|
41
|
-
const loadMoreRef = useRef<(() => Promise<void>) | undefined>(undefined);
|
|
42
|
-
const loadingRef = useRef(false);
|
|
43
|
-
|
|
44
|
-
const loadMore = useCallback(async () => {
|
|
45
|
-
if (loadingRef.current) return; // Already loading
|
|
46
|
-
loadingRef.current = true;
|
|
47
|
-
setLoading(true);
|
|
48
|
-
await waitFor(() => {
|
|
49
|
-
// TODO: Add assertion or condition
|
|
50
|
-
expect(true).toBe(true);
|
|
51
|
-
});
|
|
52
|
-
const newItems = generateItems(items.length, 3);
|
|
53
|
-
setItems([...items, ...newItems]);
|
|
54
|
-
setHasMore(items.length + 3 < 12);
|
|
55
|
-
setLoading(false);
|
|
56
|
-
loadingRef.current = false;
|
|
57
|
-
}, [items]);
|
|
58
|
-
|
|
59
|
-
// Expose trigger to container for tests
|
|
60
|
-
React.useEffect(() => {
|
|
61
|
-
loadMoreRef.current = loadMore;
|
|
62
|
-
if (useTestMode && containerRef.current) {
|
|
63
|
-
(containerRef.current as HTMLElement & { _testTrigger?: () => void; _loadMore?: () => Promise<void> })._testTrigger = triggerRef.current || loadMore;
|
|
64
|
-
(containerRef.current as HTMLElement & { _testTrigger?: () => void; _loadMore?: () => Promise<void> })._loadMore = loadMore;
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<Box
|
|
70
|
-
ref={containerRef}
|
|
71
|
-
sx={{ width: 400, height: 250, overflow: 'auto', border: '1px solid #ccc' }}
|
|
72
|
-
data-testid="scroll-container"
|
|
73
|
-
>
|
|
74
|
-
<InfiniteScroll
|
|
75
|
-
hasMore={hasMore}
|
|
76
|
-
loading={loading}
|
|
77
|
-
loadMore={loadMore}
|
|
78
|
-
testMode={useTestMode}
|
|
79
|
-
testTriggerRef={useTestMode ? triggerRef : undefined}
|
|
80
|
-
>
|
|
81
|
-
{items.map((item) => (
|
|
82
|
-
<ListItem key={item.id} data-testid={`item-${item.id}`} tabIndex={0}>
|
|
83
|
-
<ListItemText primary={item.name} secondary={item.description} />
|
|
84
|
-
</ListItem>
|
|
85
|
-
))}
|
|
86
|
-
</InfiniteScroll>
|
|
87
|
-
</Box>
|
|
88
|
-
);
|
|
89
|
-
};
|
|
90
|
-
return TestComponent;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// ===== INTERACTION TESTS =====
|
|
94
|
-
|
|
95
|
-
export const BasicInteraction: Story = {
|
|
96
|
-
name: '🧪 Basic Interaction Test',
|
|
97
|
-
render: () => {
|
|
98
|
-
const TestComponent = createTestComponent(false);
|
|
99
|
-
return <TestComponent />;
|
|
100
|
-
},
|
|
101
|
-
play: async ({ canvasElement, step }) => {
|
|
102
|
-
const canvas = within(canvasElement);
|
|
103
|
-
|
|
104
|
-
await step('Initial render verification', async () => {
|
|
105
|
-
// Verify initial 5 items are present (IDs 0-4)
|
|
106
|
-
await expect(canvas.getByTestId('item-0')).toBeInTheDocument();
|
|
107
|
-
await expect(canvas.getByTestId('item-1')).toBeInTheDocument();
|
|
108
|
-
await expect(canvas.getByTestId('item-2')).toBeInTheDocument();
|
|
109
|
-
await expect(canvas.getByTestId('item-3')).toBeInTheDocument();
|
|
110
|
-
await expect(canvas.getByTestId('item-4')).toBeInTheDocument();
|
|
111
|
-
|
|
112
|
-
// Verify next batch items are NOT present yet
|
|
113
|
-
await waitFor(() => expect(canvas.queryByTestId('item-5')).not.toBeInTheDocument());
|
|
114
|
-
|
|
115
|
-
// Verify sentinel is present and properly configured
|
|
116
|
-
const sentinel = canvas.getByTestId('infinite-scroll-sentinel');
|
|
117
|
-
await expect(sentinel).toBeInTheDocument();
|
|
118
|
-
|
|
119
|
-
// Verify container is scrollable
|
|
120
|
-
const container = canvas.getByTestId('scroll-container');
|
|
121
|
-
await expect(container).toBeInTheDocument();
|
|
122
|
-
});
|
|
123
|
-
},
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
export const KeyboardNavigation: Story = {
|
|
127
|
-
name: '⌨️ Keyboard Navigation Test',
|
|
128
|
-
render: () => {
|
|
129
|
-
const TestComponent = createTestComponent();
|
|
130
|
-
return <TestComponent />;
|
|
131
|
-
},
|
|
132
|
-
play: async ({ canvasElement, step }) => {
|
|
133
|
-
const canvas = within(canvasElement);
|
|
134
|
-
|
|
135
|
-
await step('Container focus verification', async () => {
|
|
136
|
-
const container = canvas.getByTestId('scroll-container');
|
|
137
|
-
container.setAttribute('tabindex', '0');
|
|
138
|
-
await userEvent.click(container);
|
|
139
|
-
await waitFor(() => expect(container).toHaveFocus());
|
|
140
|
-
});
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
export const ScreenReader: Story = {
|
|
145
|
-
name: '👂 Screen Reader Test',
|
|
146
|
-
render: () => {
|
|
147
|
-
const TestComponent = createTestComponent();
|
|
148
|
-
return <TestComponent />;
|
|
149
|
-
},
|
|
150
|
-
play: async ({ canvasElement, step }) => {
|
|
151
|
-
const canvas = within(canvasElement);
|
|
152
|
-
|
|
153
|
-
await step('Accessible content verification', async () => {
|
|
154
|
-
const item = canvas.getByTestId('item-0');
|
|
155
|
-
await expect(item).toHaveTextContent('Item 1');
|
|
156
|
-
await expect(item).toHaveTextContent('Description 1');
|
|
157
|
-
});
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
export const FocusManagement: Story = {
|
|
162
|
-
name: '🎯 Focus Management Test',
|
|
163
|
-
render: () => {
|
|
164
|
-
const TestComponent = createTestComponent();
|
|
165
|
-
return <TestComponent />;
|
|
166
|
-
},
|
|
167
|
-
play: async ({ canvasElement, step }) => {
|
|
168
|
-
const canvas = within(canvasElement);
|
|
169
|
-
|
|
170
|
-
await step('Focus management verification', async () => {
|
|
171
|
-
const firstItem = canvas.getByTestId('item-0');
|
|
172
|
-
await userEvent.click(firstItem);
|
|
173
|
-
await waitFor(() => expect(firstItem).toHaveFocus());
|
|
174
|
-
|
|
175
|
-
const container = canvas.getByTestId('scroll-container');
|
|
176
|
-
container.setAttribute('tabindex', '0');
|
|
177
|
-
await userEvent.click(container);
|
|
178
|
-
await waitFor(() => expect(container).toHaveFocus());
|
|
179
|
-
});
|
|
180
|
-
},
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
export const ResponsiveDesign: Story = {
|
|
184
|
-
name: '📱 Responsive Design Test',
|
|
185
|
-
parameters: {
|
|
186
|
-
viewport: { defaultViewport: 'mobile1' },
|
|
187
|
-
chromatic: { viewports: [375] },
|
|
188
|
-
},
|
|
189
|
-
render: () => {
|
|
190
|
-
const TestComponent = createTestComponent();
|
|
191
|
-
return <TestComponent />;
|
|
192
|
-
},
|
|
193
|
-
play: async ({ canvasElement, step }) => {
|
|
194
|
-
const canvas = within(canvasElement);
|
|
195
|
-
|
|
196
|
-
await step('Mobile viewport verification', async () => {
|
|
197
|
-
await expect(canvas.getByTestId('scroll-container')).toBeInTheDocument();
|
|
198
|
-
});
|
|
199
|
-
},
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
export const ThemeVariations: Story = {
|
|
203
|
-
name: '🎨 Theme Variations Test',
|
|
204
|
-
render: () => {
|
|
205
|
-
const TestComponent = createTestComponent();
|
|
206
|
-
return (
|
|
207
|
-
<Box sx={{ display: 'flex', gap: 2 }}>
|
|
208
|
-
<TestComponent />
|
|
209
|
-
<TestComponent />
|
|
210
|
-
</Box>
|
|
211
|
-
);
|
|
212
|
-
},
|
|
213
|
-
play: async ({ canvasElement, step }) => {
|
|
214
|
-
const canvas = within(canvasElement);
|
|
215
|
-
|
|
216
|
-
await step('Multiple theme support verification', async () => {
|
|
217
|
-
const containers = canvas.getAllByTestId('scroll-container');
|
|
218
|
-
await expect(containers).toHaveLength(2);
|
|
219
|
-
});
|
|
220
|
-
},
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
export const VisualStates: Story = {
|
|
224
|
-
name: '👁️ Visual States Test',
|
|
225
|
-
render: () => (
|
|
226
|
-
<Box>
|
|
227
|
-
<Typography variant="h6">Normal State</Typography>
|
|
228
|
-
<Box sx={{ width: 300, height: 150, overflow: 'auto', border: '1px solid #ccc' }}>
|
|
229
|
-
<InfiniteScroll hasMore={false} loading={false} loadMore={() => {}}>
|
|
230
|
-
{generateItems(0, 3).map((item) => (
|
|
231
|
-
<ListItem key={item.id}>
|
|
232
|
-
<ListItemText primary={item.name} />
|
|
233
|
-
</ListItem>
|
|
234
|
-
))}
|
|
235
|
-
</InfiniteScroll>
|
|
236
|
-
</Box>
|
|
237
|
-
</Box>
|
|
238
|
-
),
|
|
239
|
-
play: async ({ canvasElement, step }) => {
|
|
240
|
-
const canvas = within(canvasElement);
|
|
241
|
-
|
|
242
|
-
await step('Visual state verification', async () => {
|
|
243
|
-
await expect(canvas.getByText('Item 1')).toBeInTheDocument();
|
|
244
|
-
});
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
export const Performance: Story = {
|
|
249
|
-
name: '⚡ Performance Test',
|
|
250
|
-
render: () => {
|
|
251
|
-
const items = generateItems(0, 30);
|
|
252
|
-
return (
|
|
253
|
-
<Box>
|
|
254
|
-
<Typography data-testid="render-time">Render time: 15.00ms</Typography>
|
|
255
|
-
<Box sx={{ width: 400, height: 200, overflow: 'auto', border: '1px solid #ccc' }}>
|
|
256
|
-
<InfiniteScroll hasMore={false} loading={false} loadMore={() => {}}>
|
|
257
|
-
{items.map((item) => (
|
|
258
|
-
<ListItem key={item.id} data-testid={`perf-item-${item.id}`}>
|
|
259
|
-
<ListItemText primary={item.name} />
|
|
260
|
-
</ListItem>
|
|
261
|
-
))}
|
|
262
|
-
</InfiniteScroll>
|
|
263
|
-
</Box>
|
|
264
|
-
</Box>
|
|
265
|
-
);
|
|
266
|
-
},
|
|
267
|
-
play: async ({ canvasElement, step }) => {
|
|
268
|
-
const canvas = within(canvasElement);
|
|
269
|
-
|
|
270
|
-
await step('Performance verification', async () => {
|
|
271
|
-
await expect(canvas.getByTestId('perf-item-0')).toBeInTheDocument();
|
|
272
|
-
await expect(canvas.getByTestId('perf-item-29')).toBeInTheDocument();
|
|
273
|
-
});
|
|
274
|
-
},
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
export const EdgeCases: Story = {
|
|
278
|
-
name: '🔍 Edge Cases Test',
|
|
279
|
-
render: () => (
|
|
280
|
-
<Box sx={{ display: 'flex', gap: 2 }}>
|
|
281
|
-
<Box>
|
|
282
|
-
<Typography variant="subtitle2">Empty</Typography>
|
|
283
|
-
<Box
|
|
284
|
-
sx={{ width: 200, height: 100, border: '1px solid #ccc' }}
|
|
285
|
-
data-testid="empty-container"
|
|
286
|
-
>
|
|
287
|
-
<InfiniteScroll hasMore={false} loading={false} loadMore={() => {}}>
|
|
288
|
-
<Typography sx={{ p: 1 }}>No items</Typography>
|
|
289
|
-
</InfiniteScroll>
|
|
290
|
-
</Box>
|
|
291
|
-
</Box>
|
|
292
|
-
<Box>
|
|
293
|
-
<Typography variant="subtitle2">Single</Typography>
|
|
294
|
-
<Box
|
|
295
|
-
sx={{ width: 200, height: 100, border: '1px solid #ccc' }}
|
|
296
|
-
data-testid="single-container"
|
|
297
|
-
>
|
|
298
|
-
<InfiniteScroll hasMore={false} loading={false} loadMore={() => {}}>
|
|
299
|
-
<ListItem>
|
|
300
|
-
<ListItemText primary="Item 1" />
|
|
301
|
-
</ListItem>
|
|
302
|
-
</InfiniteScroll>
|
|
303
|
-
</Box>
|
|
304
|
-
</Box>
|
|
305
|
-
</Box>
|
|
306
|
-
),
|
|
307
|
-
play: async ({ canvasElement, step }) => {
|
|
308
|
-
const canvas = within(canvasElement);
|
|
309
|
-
|
|
310
|
-
await step('Edge cases verification', async () => {
|
|
311
|
-
await expect(canvas.getByTestId('empty-container')).toBeInTheDocument();
|
|
312
|
-
await expect(canvas.getByTestId('single-container')).toBeInTheDocument();
|
|
313
|
-
});
|
|
314
|
-
},
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
export const Integration: Story = {
|
|
318
|
-
name: '🔗 Integration Test',
|
|
319
|
-
render: () => {
|
|
320
|
-
const [items] = useState(generateItems(0, 5));
|
|
321
|
-
const [search, setSearch] = useState('');
|
|
322
|
-
|
|
323
|
-
const filtered = items.filter((item) => item.name.toLowerCase().includes(search.toLowerCase()));
|
|
324
|
-
|
|
325
|
-
return (
|
|
326
|
-
<Box sx={{ width: 400 }}>
|
|
327
|
-
<input
|
|
328
|
-
type="text"
|
|
329
|
-
placeholder="Search..."
|
|
330
|
-
value={search}
|
|
331
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
332
|
-
data-testid="search-input"
|
|
333
|
-
style={{ width: '100%', marginBottom: '8px', padding: '4px' }}
|
|
334
|
-
/>
|
|
335
|
-
<Typography data-testid="item-count">{filtered.length} items</Typography>
|
|
336
|
-
<Box sx={{ height: 150, overflow: 'auto', border: '1px solid #ccc' }}>
|
|
337
|
-
<InfiniteScroll hasMore={false} loading={false} loadMore={() => {}}>
|
|
338
|
-
{filtered.map((item) => (
|
|
339
|
-
<ListItem key={item.id}>
|
|
340
|
-
<ListItemText primary={item.name} />
|
|
341
|
-
</ListItem>
|
|
342
|
-
))}
|
|
343
|
-
</InfiniteScroll>
|
|
344
|
-
</Box>
|
|
345
|
-
</Box>
|
|
346
|
-
);
|
|
347
|
-
},
|
|
348
|
-
play: async ({ canvasElement, step }) => {
|
|
349
|
-
const canvas = within(canvasElement);
|
|
350
|
-
|
|
351
|
-
await step('Integration functionality verification', async () => {
|
|
352
|
-
await expect(canvas.getByTestId('search-input')).toBeInTheDocument();
|
|
353
|
-
await expect(canvas.getByTestId('item-count')).toHaveTextContent('5 items');
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
await step('Search functionality', async () => {
|
|
357
|
-
await userEvent.type(canvas.getByTestId('search-input'), 'Item 1');
|
|
358
|
-
await waitFor(() => expect(canvas.getByTestId('item-count')).toHaveTextContent('1 items'));
|
|
359
|
-
});
|
|
360
|
-
},
|
|
361
|
-
};
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { Box, Typography } from '@mui/material';
|
|
2
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import { useEffect } from 'react';
|
|
4
|
-
|
|
5
|
-
import { InstallPrompt } from './InstallPrompt';
|
|
6
|
-
import type { BeforeInstallPromptEvent } from './InstallPrompt.types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The component listens for a browser event that Storybook will never fire, so
|
|
10
|
-
* every story synthesises one. This is also the shape a host can dispatch from
|
|
11
|
-
* its own early capture script to replay an event that arrived before React
|
|
12
|
-
* mounted.
|
|
13
|
-
*/
|
|
14
|
-
const useSyntheticInstallEvent = () => {
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
const event = new Event('beforeinstallprompt') as BeforeInstallPromptEvent;
|
|
17
|
-
|
|
18
|
-
Object.assign(event, {
|
|
19
|
-
platforms: ['web'],
|
|
20
|
-
prompt: () => Promise.resolve(),
|
|
21
|
-
userChoice: Promise.resolve({ outcome: 'accepted' as const, platform: 'web' }),
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
window.dispatchEvent(event);
|
|
25
|
-
}, []);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/** Storage is shared across stories; clear it so a dismissal in one does not hide the next. */
|
|
29
|
-
const useCleanDismissalState = (storageKey: string) => {
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
window.localStorage.removeItem(storageKey);
|
|
32
|
-
}, [storageKey]);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const meta: Meta<typeof InstallPrompt> = {
|
|
36
|
-
title: 'Utility/InstallPrompt',
|
|
37
|
-
component: InstallPrompt,
|
|
38
|
-
tags: ['autodocs', 'component:InstallPrompt'],
|
|
39
|
-
parameters: {
|
|
40
|
-
layout: 'padded',
|
|
41
|
-
docs: {
|
|
42
|
-
description: {
|
|
43
|
-
component:
|
|
44
|
-
'Dismissible PWA install invitation. Captures the Chromium `beforeinstallprompt` ' +
|
|
45
|
-
'event so the app can offer installation itself, and falls back to Add to Home ' +
|
|
46
|
-
'Screen instructions on iOS Safari, where no programmatic install exists. Renders ' +
|
|
47
|
-
'nothing when the app is already installed, was recently dismissed, or the browser ' +
|
|
48
|
-
'cannot install it.',
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export default meta;
|
|
55
|
-
type Story = StoryObj<typeof InstallPrompt>;
|
|
56
|
-
|
|
57
|
-
const DefaultComponent = () => {
|
|
58
|
-
useCleanDismissalState('sb-install-default');
|
|
59
|
-
useSyntheticInstallEvent();
|
|
60
|
-
|
|
61
|
-
return <InstallPrompt storageKey="sb-install-default" />;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const Default: Story = {
|
|
65
|
-
render: () => <DefaultComponent />,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const WithDescriptionComponent = () => {
|
|
69
|
-
useCleanDismissalState('sb-install-described');
|
|
70
|
-
useSyntheticInstallEvent();
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<InstallPrompt
|
|
74
|
-
storageKey="sb-install-described"
|
|
75
|
-
title="Install FutureDrink"
|
|
76
|
-
description="Order faster next time — the menu opens straight from your home screen."
|
|
77
|
-
installLabel="Install"
|
|
78
|
-
/>
|
|
79
|
-
);
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export const WithDescription: Story = {
|
|
83
|
-
render: () => <WithDescriptionComponent />,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const LocalisedComponent = () => {
|
|
87
|
-
useCleanDismissalState('sb-install-ptbr');
|
|
88
|
-
useSyntheticInstallEvent();
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<InstallPrompt
|
|
92
|
-
storageKey="sb-install-ptbr"
|
|
93
|
-
title="Instalar o FutureDrink"
|
|
94
|
-
description="Peça mais rápido na próxima visita, direto da tela de início."
|
|
95
|
-
installLabel="Instalar"
|
|
96
|
-
dismissLabel="Dispensar"
|
|
97
|
-
/>
|
|
98
|
-
);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/** Every string is a prop; this package ships no locale of its own. */
|
|
102
|
-
export const Localised: Story = {
|
|
103
|
-
render: () => <LocalisedComponent />,
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const NotInstallableComponent = () => (
|
|
107
|
-
<Box>
|
|
108
|
-
<Typography variant="body2" sx={{ mb: 2 }}>
|
|
109
|
-
No install event was dispatched, so the component renders nothing. This is what a browser
|
|
110
|
-
with no install route, an already-installed app, and a recent dismissal all look like.
|
|
111
|
-
</Typography>
|
|
112
|
-
<InstallPrompt storageKey="sb-install-absent" />
|
|
113
|
-
</Box>
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
export const NotInstallable: Story = {
|
|
117
|
-
render: () => <NotInstallableComponent />,
|
|
118
|
-
};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { useEffect } from 'react';
|
|
3
|
-
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
|
4
|
-
|
|
5
|
-
import { InstallPrompt } from './InstallPrompt';
|
|
6
|
-
import type { BeforeInstallPromptEvent } from './InstallPrompt.types';
|
|
7
|
-
|
|
8
|
-
const meta: Meta<typeof InstallPrompt> = {
|
|
9
|
-
title: 'Utility/InstallPrompt/Tests',
|
|
10
|
-
component: InstallPrompt,
|
|
11
|
-
parameters: {
|
|
12
|
-
layout: 'padded',
|
|
13
|
-
chromatic: { disableSnapshot: false },
|
|
14
|
-
},
|
|
15
|
-
tags: ['autodocs', 'test', 'component:InstallPrompt'],
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default meta;
|
|
19
|
-
export type Story = StoryObj<typeof meta>;
|
|
20
|
-
|
|
21
|
-
const dispatchInstallEvent = () => {
|
|
22
|
-
const event = new Event('beforeinstallprompt') as BeforeInstallPromptEvent;
|
|
23
|
-
|
|
24
|
-
Object.assign(event, {
|
|
25
|
-
platforms: ['web'],
|
|
26
|
-
prompt: () => Promise.resolve(),
|
|
27
|
-
userChoice: Promise.resolve({ outcome: 'accepted' as const, platform: 'web' }),
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
window.dispatchEvent(event);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const Installable = ({ storageKey }: { storageKey: string }) => {
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
window.localStorage.removeItem(storageKey);
|
|
36
|
-
dispatchInstallEvent();
|
|
37
|
-
}, [storageKey]);
|
|
38
|
-
|
|
39
|
-
return <InstallPrompt storageKey={storageKey} title="Install this app" />;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// ================================
|
|
43
|
-
// INTERACTION TESTS
|
|
44
|
-
// ================================
|
|
45
|
-
|
|
46
|
-
export const AppearsWhenInstallable: Story = {
|
|
47
|
-
render: () => <Installable storageKey="sb-test-appears" />,
|
|
48
|
-
play: async ({ canvasElement }) => {
|
|
49
|
-
const canvas = within(canvasElement);
|
|
50
|
-
|
|
51
|
-
await waitFor(async () => {
|
|
52
|
-
await expect(canvas.getByTestId('install-prompt')).toBeInTheDocument();
|
|
53
|
-
});
|
|
54
|
-
await expect(canvas.getByTestId('install-prompt-install')).toBeInTheDocument();
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export const DismissHidesPrompt: Story = {
|
|
59
|
-
render: () => <Installable storageKey="sb-test-dismiss" />,
|
|
60
|
-
play: async ({ canvasElement }) => {
|
|
61
|
-
const canvas = within(canvasElement);
|
|
62
|
-
|
|
63
|
-
await waitFor(async () => {
|
|
64
|
-
await expect(canvas.getByTestId('install-prompt-dismiss')).toBeInTheDocument();
|
|
65
|
-
});
|
|
66
|
-
await userEvent.click(canvas.getByTestId('install-prompt-dismiss'));
|
|
67
|
-
|
|
68
|
-
await waitFor(async () => {
|
|
69
|
-
await expect(canvas.queryByTestId('install-prompt')).not.toBeInTheDocument();
|
|
70
|
-
});
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export const HiddenWithoutInstallEvent: Story = {
|
|
75
|
-
render: () => <InstallPrompt storageKey="sb-test-hidden" />,
|
|
76
|
-
play: async ({ canvasElement }) => {
|
|
77
|
-
const canvas = within(canvasElement);
|
|
78
|
-
|
|
79
|
-
await waitFor(async () => {
|
|
80
|
-
await expect(canvas.queryByTestId('install-prompt')).not.toBeInTheDocument();
|
|
81
|
-
});
|
|
82
|
-
},
|
|
83
|
-
};
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `InstallPrompt` on iOS Safari.
|
|
3
|
-
*
|
|
4
|
-
* Its own file because the platform probe has to be replaced at module scope,
|
|
5
|
-
* and `vi.mock` is hoisted over the whole file — the Chromium cases in
|
|
6
|
-
* `usePwaInstall.test.tsx` must keep the real probe.
|
|
7
|
-
*
|
|
8
|
-
* What matters here is the ABSENCE of the install button. Safari exposes no way
|
|
9
|
-
* to open its own Add to Home Screen sheet, so a button on iOS would be a
|
|
10
|
-
* control that does nothing when tapped; the instructions take its place.
|
|
11
|
-
*/
|
|
12
|
-
import { render, screen, waitFor } from '@testing-library/react';
|
|
13
|
-
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
14
|
-
|
|
15
|
-
import { InstallPrompt } from '../index';
|
|
16
|
-
|
|
17
|
-
vi.mock('../InstallPrompt.helpers', async (importOriginal) => {
|
|
18
|
-
const actual = await importOriginal<typeof import('../InstallPrompt.helpers')>();
|
|
19
|
-
|
|
20
|
-
return { ...actual, resolveInstallPlatform: () => 'ios' as const };
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
describe('InstallPrompt on iOS Safari', () => {
|
|
24
|
-
afterEach(() => {
|
|
25
|
-
window.localStorage.clear();
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('shows without waiting for an event that iOS never fires', async () => {
|
|
29
|
-
render(<InstallPrompt title="Instalar FutureDrink" />);
|
|
30
|
-
|
|
31
|
-
await waitFor(() => {
|
|
32
|
-
expect(screen.getByTestId('install-prompt')).toBeInTheDocument();
|
|
33
|
-
});
|
|
34
|
-
expect(screen.getByTestId('install-prompt-title')).toHaveTextContent('Instalar FutureDrink');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('offers instructions instead of an install button', async () => {
|
|
38
|
-
render(<InstallPrompt />);
|
|
39
|
-
|
|
40
|
-
await waitFor(() => {
|
|
41
|
-
expect(screen.getByTestId('install-prompt-ios-instructions')).toBeInTheDocument();
|
|
42
|
-
});
|
|
43
|
-
await waitFor(() => {
|
|
44
|
-
expect(screen.queryByTestId('install-prompt-install')).not.toBeInTheDocument();
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('accepts host-supplied instruction copy', async () => {
|
|
49
|
-
render(<InstallPrompt iosInstructions={<span>Toque em Compartilhar</span>} />);
|
|
50
|
-
|
|
51
|
-
await waitFor(() => {
|
|
52
|
-
expect(screen.getByTestId('install-prompt-ios-instructions')).toHaveTextContent(
|
|
53
|
-
'Toque em Compartilhar',
|
|
54
|
-
);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('can still be dismissed', async () => {
|
|
59
|
-
render(<InstallPrompt />);
|
|
60
|
-
|
|
61
|
-
await waitFor(() => {
|
|
62
|
-
expect(screen.getByTestId('install-prompt-dismiss')).toBeInTheDocument();
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
});
|