@zap-wunschlachen/wl-shared-components 1.0.25 → 1.0.26
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/.github/workflows/playwright.yml +205 -205
- package/.github/workflows/static.yml +61 -61
- package/.github/workflows/update-snapshots.yml +37 -37
- package/.prettierrc +5 -5
- package/.storybook/main.ts +18 -18
- package/.storybook/preview.ts +37 -37
- package/.storybook/storyWrapper.vue +18 -18
- package/.storybook/withVuetifyTheme.decorator.ts +21 -21
- package/App.vue +34 -176
- package/README.md +56 -56
- package/heroicons.ts +75 -75
- package/index.html +19 -19
- package/package.json +67 -67
- package/playwright.config.ts +48 -48
- package/public/background.svg +60 -60
- package/public/style.css +187 -187
- package/public/technologies.svg +22 -22
- package/src/assets/css/base.css +235 -235
- package/src/assets/css/variables.css +107 -96
- package/src/components/Accordion/Accordion.css +59 -59
- package/src/components/Accordion/AccordionGroup.vue +51 -51
- package/src/components/Accordion/AccordionItem.vue +66 -66
- package/src/components/Appointment/Card/Actions.css +54 -54
- package/src/components/Appointment/Card/Actions.vue +99 -99
- package/src/components/Appointment/Card/AnamneseNotification.css +15 -15
- package/src/components/Appointment/Card/AnamneseNotification.vue +23 -23
- package/src/components/Appointment/Card/Card.css +80 -80
- package/src/components/Appointment/Card/Card.vue +93 -93
- package/src/components/Appointment/Card/Details.css +50 -50
- package/src/components/Appointment/Card/Details.vue +43 -43
- package/src/components/Audio/Audio.vue +187 -187
- package/src/components/Audio/Waveform.vue +117 -117
- package/src/components/Background/Background.css +39 -0
- package/src/components/Background/Background.vue +19 -0
- package/src/components/Background/WhiteCocoonBackground.vue +9 -0
- package/src/components/Background/WunschlachenBackground.vue +11 -0
- package/src/components/Button/Button.vue +119 -119
- package/src/components/CheckBox/CheckBox.css +185 -185
- package/src/components/CheckBox/Checkbox.vue +130 -130
- package/src/components/DateInput/DateInput.css +2 -2
- package/src/components/DateInput/DateInput.vue +262 -262
- package/src/components/Dialog/Dialog.css +6 -6
- package/src/components/Dialog/Dialog.vue +29 -29
- package/src/components/EditField/EditField.css +19 -19
- package/src/components/EditField/EditField.vue +202 -202
- package/src/components/ErrorPage/ErrorPage.css +124 -0
- package/src/components/ErrorPage/ErrorPage.vue +45 -0
- package/src/components/ErrorPage/ErrorPageLogo.vue +26 -0
- package/src/components/IconBullet/IconBullet.vue +86 -86
- package/src/components/IconBullet/IconBulletList.vue +41 -41
- package/src/components/Icons/AdvanceAppointments.vue +153 -153
- package/src/components/Icons/Audio/CloudFailed.vue +20 -20
- package/src/components/Icons/Audio/CloudSaved.vue +21 -21
- package/src/components/Icons/Audio/Delete.vue +15 -15
- package/src/components/Icons/Audio/Pause.vue +18 -18
- package/src/components/Icons/Audio/Play.vue +15 -15
- package/src/components/Icons/CalendarNotification.vue +126 -126
- package/src/components/Icons/Chair.vue +32 -32
- package/src/components/Icons/ChairNotification.vue +35 -35
- package/src/components/Icons/Circle.vue +66 -66
- package/src/components/Icons/FavIcon.vue +22 -22
- package/src/components/Icons/FilledCircle.vue +11 -11
- package/src/components/Icons/Group3.vue +46 -46
- package/src/components/Icons/Logo.vue +108 -0
- package/src/components/Icons/RingNotification.vue +54 -54
- package/src/components/Icons/SolidArrowRight.vue +14 -14
- package/src/components/Icons/calendar.vue +17 -17
- package/src/components/Icons/checkbox.vue +19 -19
- package/src/components/Icons/outlineChecked.vue +27 -27
- package/src/components/Icons/play.vue +5 -5
- package/src/components/Input/Input.css +187 -187
- package/src/components/Input/Input.vue +247 -247
- package/src/components/Laboratory/AppointmentCard/AppointmentCard.css +7 -7
- package/src/components/Laboratory/AppointmentCard/AppointmentCard.vue +116 -116
- package/src/components/Laboratory/ChatBoxImage/ChatBoxImage.vue +81 -81
- package/src/components/Laboratory/ChatMessage/ChatMessage.vue +113 -113
- package/src/components/Laboratory/ChatMessage/ChatMessageBadge.css +4 -4
- package/src/components/Laboratory/ChatMessage/ChatMessageBadge.vue +99 -99
- package/src/components/Laboratory/ChatNotification/ChatNotification.vue +130 -130
- package/src/components/Laboratory/DocumentCard/DocumentCard.css +3 -3
- package/src/components/Laboratory/DocumentCard/DocumentCard.vue +50 -50
- package/src/components/Laboratory/DocumentCard/DocumentCardItem.vue +53 -53
- package/src/components/Laboratory/InfoCard/InfoCard.vue +162 -162
- package/src/components/Laboratory/MainColumnsBar/MainColumnsBar.vue +102 -102
- package/src/components/Laboratory/ProgressCircle/ProgressCircle.vue +152 -152
- package/src/components/Laboratory/ProgressLinear/ProgressLinear.css +33 -33
- package/src/components/Laboratory/ProgressLinear/ProgressLinear.vue +75 -75
- package/src/components/Laboratory/SelectionColumnBar/SelectionColumnBar.vue +92 -92
- package/src/components/Laboratory/StatusNotification/StatusNotification.vue +49 -49
- package/src/components/Laboratory/TagLabel/TagLabel.vue +126 -126
- package/src/components/Laboratory/TagLabelGroup/TagLabelGroup.vue +97 -97
- package/src/components/Laboratory/TicketCard/TicketCard.css +3 -3
- package/src/components/Laboratory/TicketCard/TicketCard.vue +143 -143
- package/src/components/Laboratory/TimeLine/TimeLineEvent.css +18 -18
- package/src/components/Laboratory/TimeLine/TimeLineEvent.vue +119 -119
- package/src/components/Laboratory/TimeLine/Timeline.css +4 -4
- package/src/components/Laboratory/TimeLine/Timeline.vue +30 -30
- package/src/components/Loader/Loader.css +51 -51
- package/src/components/MaintenanceBanner/MaintenanceBanner.css +289 -0
- package/src/components/MaintenanceBanner/MaintenanceBanner.vue +127 -0
- package/src/components/MaintenanceBanner/MaintenanceIllustration.vue +54 -0
- package/src/components/Modal/Modal.css +5 -5
- package/src/components/Modal/Modal.vue +22 -22
- package/src/components/NotificationBubble/NotificationBubble.css +4 -4
- package/src/components/NotificationBubble/NotificationBubble.vue +90 -90
- package/src/components/OtpInput/OtpInput.css +39 -39
- package/src/components/OtpInput/OtpInput.vue +143 -143
- package/src/components/PhoneInput/PhoneInput.css +31 -31
- package/src/components/PhoneInput/PhoneInput.vue +113 -113
- package/src/components/Select/Select.css +150 -150
- package/src/components/Select/Select.vue +315 -315
- package/src/components/TextArea/TextArea.css +3 -3
- package/src/components/TextArea/TextArea.vue +126 -126
- package/src/components/TickBox/TickBox.css +49 -49
- package/src/components/TickBox/TickBox.vue +126 -126
- package/src/components/index.ts +26 -24
- package/src/constants/iconEnums.ts +3 -3
- package/src/i18n/i18n.ts +15 -15
- package/src/i18n/locales/de.json +30 -30
- package/src/i18n/locales/en.json +30 -30
- package/src/index.ts +34 -34
- package/src/main.ts +11 -11
- package/src/plugins/vuetify.ts +139 -131
- package/src/shims-vue.d.ts +10 -10
- package/src/stories/Accordion.stories.ts +650 -650
- package/src/stories/Audio.stories.ts +28 -28
- package/src/stories/Button.stories.ts +263 -263
- package/src/stories/CheckBox.stories.ts +348 -348
- package/src/stories/DateInput.stories.ts +53 -53
- package/src/stories/Dialog.stories.ts +147 -147
- package/src/stories/EditField.stories.ts +78 -78
- package/src/stories/IconBullet/IconBullet.stories.ts +201 -201
- package/src/stories/IconBullet/IconBulletList.stories.ts +275 -275
- package/src/stories/Input.stories.ts +351 -351
- package/src/stories/Laboratory/Cards/AppointmentCard/AppointmentCard.stories.ts +260 -260
- package/src/stories/Laboratory/Cards/DocumentCard/DocumentCard.stories.ts +176 -176
- package/src/stories/Laboratory/Cards/DocumentCard/DocumentCardItem.stories.ts +119 -119
- package/src/stories/Laboratory/Cards/InfoCard/InfoCard.stories.ts +320 -320
- package/src/stories/Laboratory/Cards/TicketCard/TicketCard.stories.ts +335 -335
- package/src/stories/Laboratory/Chat/ChatBoxImage.stories.ts +82 -82
- package/src/stories/Laboratory/Chat/ChatMessage.stories.ts +198 -198
- package/src/stories/Laboratory/Chat/ChatMessageBadge.stories.ts +204 -204
- package/src/stories/Laboratory/Chat/ChatNotification.stories.ts +144 -144
- package/src/stories/Laboratory/Chat/ProgressLinear.stories.ts +186 -186
- package/src/stories/Laboratory/Chat/StatusNotification.stories.ts +111 -111
- package/src/stories/Laboratory/MainColumnsBar.stories.ts +48 -48
- package/src/stories/Laboratory/ProgressCircle.stories.ts +261 -261
- package/src/stories/Laboratory/SelectionColumnBar.stories.ts +234 -234
- package/src/stories/Laboratory/TagLabel.stories.ts +418 -418
- package/src/stories/Laboratory/TagLabelGroup.stories.ts +234 -234
- package/src/stories/Laboratory/Timeline.stories.ts +403 -403
- package/src/stories/NotificationBubble.stories.ts +194 -194
- package/src/stories/OtpInput.stories.ts +100 -100
- package/src/stories/PhoneInput.stories.ts +52 -52
- package/src/stories/Select.stories.ts +419 -419
- package/src/stories/TextArea.stories.ts +112 -112
- package/src/stories/TickBox.stories.ts +294 -294
- package/src/stories/v-icon.stories.ts +91 -91
- package/src/utils/index.ts +106 -100
- package/src/vite-env.d.ts +1 -1
- package/tests/e2e/README.md +220 -220
- package/tests/e2e/accessibility.spec.ts +638 -638
- package/tests/e2e/accordion.spec.ts +42 -42
- package/tests/e2e/additional-components.spec.ts +437 -437
- package/tests/e2e/all-components.spec.ts +135 -135
- package/tests/e2e/appointment-card.spec.ts +816 -816
- package/tests/e2e/button-fixed.spec.ts +58 -58
- package/tests/e2e/button.spec.ts +76 -76
- package/tests/e2e/checkbox.spec.ts +50 -50
- package/tests/e2e/date-input.spec.ts +46 -46
- package/tests/e2e/debug.spec.ts +51 -51
- package/tests/e2e/dialog.spec.ts +58 -58
- package/tests/e2e/input.spec.ts +55 -55
- package/tests/e2e/laboratory-components.spec.ts +320 -320
- package/tests/e2e/otp-input.spec.ts +50 -50
- package/tests/e2e/select.spec.ts +52 -52
- package/tests/e2e/storybook-utils.ts +59 -59
- package/tests/e2e/test-basic.spec.ts +33 -33
- package/tests/e2e/visual-regression.spec.ts +350 -350
- package/tests/unit/components/Accordion/AccordionGroup.spec.ts.skip +342 -342
- package/tests/unit/components/Accordion/AccordionItem.spec.ts.skip +383 -383
- package/tests/unit/components/Appointment/Card/Actions.spec.ts +407 -407
- package/tests/unit/components/Appointment/Card/Card.spec.ts +485 -485
- package/tests/unit/components/Appointment/Card/Details.spec.ts +397 -397
- package/tests/unit/components/Audio/Audio.spec.ts +403 -403
- package/tests/unit/components/Audio/Waveform.spec.ts +483 -483
- package/tests/unit/components/Core/Button.spec.ts +336 -336
- package/tests/unit/components/Core/Checkbox.spec.ts +544 -544
- package/tests/unit/components/Core/DateInput.spec.ts +690 -690
- package/tests/unit/components/Core/Dialog.spec.ts +485 -485
- package/tests/unit/components/Core/EditField.spec.ts +782 -782
- package/tests/unit/components/Core/Input.spec.ts +512 -512
- package/tests/unit/components/Core/Modal.spec.ts +518 -518
- package/tests/unit/components/Core/NotificationBubble.spec.ts +606 -606
- package/tests/unit/components/Core/OtpInput.spec.ts +708 -708
- package/tests/unit/components/Core/PhoneInput.spec.ts +619 -619
- package/tests/unit/components/Core/Select.spec.ts +712 -712
- package/tests/unit/components/Core/TextArea.spec.ts +565 -565
- package/tests/unit/components/Core/TickBox.spec.ts +779 -779
- package/tests/unit/components/IconBullet/IconBullet.spec.ts +356 -356
- package/tests/unit/components/IconBullet/IconBulletList.spec.ts +371 -371
- package/tests/unit/components/Icons/Audio/CloudFailed.spec.ts +108 -108
- package/tests/unit/components/Icons/Audio/CloudSaved.spec.ts +149 -149
- package/tests/unit/components/Icons/Audio/Delete.spec.ts +158 -158
- package/tests/unit/components/Icons/Audio/Pause.spec.ts +208 -208
- package/tests/unit/components/Icons/Audio/Play.spec.ts +217 -217
- package/tests/unit/components/Icons/CalendarNotification.spec.ts +186 -186
- package/tests/unit/components/Icons/Chair.spec.ts +234 -234
- package/tests/unit/components/Icons/ChairNotification.spec.ts +311 -311
- package/tests/unit/components/Icons/Circle.spec.ts +255 -255
- package/tests/unit/components/Icons/FavIcon.spec.ts +251 -251
- package/tests/unit/components/Icons/FilledCircle.spec.ts +274 -274
- package/tests/unit/components/Icons/Group3.spec.ts +355 -355
- package/tests/unit/components/Icons/RingNotification.spec.ts +393 -393
- package/tests/unit/components/Icons/calendar.spec.ts +286 -286
- package/tests/unit/components/Icons/checkbox.spec.ts +315 -315
- package/tests/unit/components/Icons/outlineChecked.spec.ts +434 -434
- package/tests/unit/components/Icons/play.spec.ts +308 -308
- package/tests/unit/components/Laboratory/AppointmentCard.spec.ts +167 -167
- package/tests/unit/components/Laboratory/ChatBoxImage.spec.ts +179 -179
- package/tests/unit/components/Laboratory/ChatMessage.spec.ts +263 -263
- package/tests/unit/components/Laboratory/ChatMessageBadge.spec.ts +282 -282
- package/tests/unit/components/Laboratory/ChatNotification.spec.ts +256 -256
- package/tests/unit/components/Laboratory/DocumentCard.spec.ts +228 -228
- package/tests/unit/components/Laboratory/DocumentCardItem.spec.ts +236 -236
- package/tests/unit/components/Laboratory/InfoCard.spec.ts +308 -308
- package/tests/unit/components/Laboratory/MainColumnsBar.spec.ts +251 -251
- package/tests/unit/components/Laboratory/ProgressCircle.spec.ts +290 -290
- package/tests/unit/components/Laboratory/ProgressLinear.spec.ts +275 -275
- package/tests/unit/components/Laboratory/SelectionColumnBar.spec.ts +288 -288
- package/tests/unit/components/Laboratory/StatusNotification.spec.ts +296 -296
- package/tests/unit/components/Laboratory/TagLabel.spec.ts +353 -353
- package/tests/unit/components/Laboratory/TagLabelGroup.spec.ts +377 -377
- package/tests/unit/components/Laboratory/TicketCard.spec.ts +351 -351
- package/tests/unit/components/Laboratory/TimeLineEvent.spec.ts +381 -381
- package/tests/unit/components/Laboratory/Timeline.spec.ts +419 -419
- package/tests/unit/constants/iconEnums.spec.ts +39 -39
- package/tests/unit/i18n/i18n.spec.ts +88 -88
- package/tests/unit/plugins/vuetify.spec.ts +220 -220
- package/tests/unit/setup.ts +189 -189
- package/tests/unit/src/components/index.spec.ts.skip +192 -192
- package/tests/unit/src/index.spec.ts.skip +182 -182
- package/tests/unit/src/main.spec.ts +151 -151
- package/tsconfig.json +26 -26
- package/vite.config.ts +29 -29
- package/vitest.config.ts +83 -83
|
@@ -1,316 +1,316 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { mount } from '@vue/test-utils';
|
|
3
|
-
import Checkbox from '@components/Icons/checkbox.vue';
|
|
4
|
-
|
|
5
|
-
describe('Checkbox Icon', () => {
|
|
6
|
-
describe('Rendering', () => {
|
|
7
|
-
it('renders as SVG element', () => {
|
|
8
|
-
const wrapper = mount(Checkbox);
|
|
9
|
-
expect(wrapper.find('svg').exists()).toBe(true);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('has correct SVG attributes', () => {
|
|
13
|
-
const wrapper = mount(Checkbox);
|
|
14
|
-
const svg = wrapper.find('svg');
|
|
15
|
-
|
|
16
|
-
expect(svg.attributes('width')).toBe('16');
|
|
17
|
-
expect(svg.attributes('height')).toBe('16');
|
|
18
|
-
expect(svg.attributes('viewBox')).toBe('0 0 16 16');
|
|
19
|
-
expect(svg.attributes('fill')).toBe('none');
|
|
20
|
-
expect(svg.attributes('xmlns')).toBe('http://www.w3.org/2000/svg');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('contains exactly 1 rect element', () => {
|
|
24
|
-
const wrapper = mount(Checkbox);
|
|
25
|
-
const rects = wrapper.findAll('rect');
|
|
26
|
-
expect(rects).toHaveLength(1);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('Rectangle Properties', () => {
|
|
31
|
-
it('rect is properly positioned', () => {
|
|
32
|
-
const wrapper = mount(Checkbox);
|
|
33
|
-
const rect = wrapper.find('rect');
|
|
34
|
-
|
|
35
|
-
expect(rect.attributes('x')).toBe('0.5');
|
|
36
|
-
expect(rect.attributes('y')).toBe('0.5');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('rect has correct dimensions', () => {
|
|
40
|
-
const wrapper = mount(Checkbox);
|
|
41
|
-
const rect = wrapper.find('rect');
|
|
42
|
-
|
|
43
|
-
expect(rect.attributes('width')).toBe('15');
|
|
44
|
-
expect(rect.attributes('height')).toBe('15');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('rect has rounded corners', () => {
|
|
48
|
-
const wrapper = mount(Checkbox);
|
|
49
|
-
const rect = wrapper.find('rect');
|
|
50
|
-
|
|
51
|
-
expect(rect.attributes('rx')).toBe('3.5');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('rect has white fill', () => {
|
|
55
|
-
const wrapper = mount(Checkbox);
|
|
56
|
-
const rect = wrapper.find('rect');
|
|
57
|
-
|
|
58
|
-
expect(rect.attributes('fill')).toBe('white');
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('rect has gray stroke', () => {
|
|
62
|
-
const wrapper = mount(Checkbox);
|
|
63
|
-
const rect = wrapper.find('rect');
|
|
64
|
-
|
|
65
|
-
expect(rect.attributes('stroke')).toBe('#C1C1C2');
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('Visual Properties', () => {
|
|
70
|
-
it('represents unchecked state', () => {
|
|
71
|
-
const wrapper = mount(Checkbox);
|
|
72
|
-
const rect = wrapper.find('rect');
|
|
73
|
-
|
|
74
|
-
// White fill with gray border indicates unchecked
|
|
75
|
-
expect(rect.attributes('fill')).toBe('white');
|
|
76
|
-
expect(rect.attributes('stroke')).toBe('#C1C1C2');
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('has no checkmark or fill pattern', () => {
|
|
80
|
-
const wrapper = mount(Checkbox);
|
|
81
|
-
|
|
82
|
-
// Should only contain the rect element (no paths, circles, etc.)
|
|
83
|
-
expect(wrapper.findAll('path')).toHaveLength(0);
|
|
84
|
-
expect(wrapper.findAll('circle')).toHaveLength(0);
|
|
85
|
-
expect(wrapper.findAll('line')).toHaveLength(0);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('uses neutral colors', () => {
|
|
89
|
-
const wrapper = mount(Checkbox);
|
|
90
|
-
const rect = wrapper.find('rect');
|
|
91
|
-
|
|
92
|
-
const stroke = rect.attributes('stroke');
|
|
93
|
-
const fill = rect.attributes('fill');
|
|
94
|
-
|
|
95
|
-
expect(fill).toBe('white');
|
|
96
|
-
expect(stroke).toBe('#C1C1C2'); // Light gray
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('Dimensions', () => {
|
|
101
|
-
it('uses standard 16x16 size', () => {
|
|
102
|
-
const wrapper = mount(Checkbox);
|
|
103
|
-
const svg = wrapper.find('svg');
|
|
104
|
-
|
|
105
|
-
expect(svg.attributes('width')).toBe('16');
|
|
106
|
-
expect(svg.attributes('height')).toBe('16');
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('maintains square aspect ratio', () => {
|
|
110
|
-
const wrapper = mount(Checkbox);
|
|
111
|
-
const svg = wrapper.find('svg');
|
|
112
|
-
|
|
113
|
-
const width = svg.attributes('width');
|
|
114
|
-
const height = svg.attributes('height');
|
|
115
|
-
expect(width).toBe(height);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('rect accounts for stroke width', () => {
|
|
119
|
-
const wrapper = mount(Checkbox);
|
|
120
|
-
const rect = wrapper.find('rect');
|
|
121
|
-
|
|
122
|
-
// Positioned at 0.5,0.5 with 15x15 dimensions to account for 1px stroke
|
|
123
|
-
expect(rect.attributes('x')).toBe('0.5');
|
|
124
|
-
expect(rect.attributes('y')).toBe('0.5');
|
|
125
|
-
expect(rect.attributes('width')).toBe('15');
|
|
126
|
-
expect(rect.attributes('height')).toBe('15');
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('has matching viewBox dimensions', () => {
|
|
130
|
-
const wrapper = mount(Checkbox);
|
|
131
|
-
const svg = wrapper.find('svg');
|
|
132
|
-
|
|
133
|
-
expect(svg.attributes('viewBox')).toBe('0 0 16 16');
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
describe('Checkbox Geometry', () => {
|
|
138
|
-
it('rect fills most of viewBox', () => {
|
|
139
|
-
const wrapper = mount(Checkbox);
|
|
140
|
-
const rect = wrapper.find('rect');
|
|
141
|
-
|
|
142
|
-
const x = parseFloat(rect.attributes('x'));
|
|
143
|
-
const y = parseFloat(rect.attributes('y'));
|
|
144
|
-
const width = parseFloat(rect.attributes('width'));
|
|
145
|
-
const height = parseFloat(rect.attributes('height'));
|
|
146
|
-
|
|
147
|
-
expect(x + width).toBe(15.5); // Close to 16
|
|
148
|
-
expect(y + height).toBe(15.5); // Close to 16
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('has appropriate corner radius', () => {
|
|
152
|
-
const wrapper = mount(Checkbox);
|
|
153
|
-
const rect = wrapper.find('rect');
|
|
154
|
-
|
|
155
|
-
const rx = parseFloat(rect.attributes('rx'));
|
|
156
|
-
const width = parseFloat(rect.attributes('width'));
|
|
157
|
-
|
|
158
|
-
// Corner radius should be reasonable proportion of width
|
|
159
|
-
expect(rx / width).toBeCloseTo(0.23, 1); // About 23%
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('forms proper checkbox shape', () => {
|
|
163
|
-
const wrapper = mount(Checkbox);
|
|
164
|
-
const rect = wrapper.find('rect');
|
|
165
|
-
|
|
166
|
-
// Should be square with rounded corners
|
|
167
|
-
expect(rect.attributes('width')).toBe(rect.attributes('height'));
|
|
168
|
-
expect(parseFloat(rect.attributes('rx'))).toBeGreaterThan(0);
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe('Component Structure', () => {
|
|
173
|
-
it('suitable for form controls', () => {
|
|
174
|
-
const wrapper = mount(Checkbox);
|
|
175
|
-
|
|
176
|
-
// Standard size and appearance for form checkbox
|
|
177
|
-
expect(wrapper.find('svg').attributes('width')).toBe('16');
|
|
178
|
-
expect(wrapper.find('rect').attributes('fill')).toBe('white');
|
|
179
|
-
expect(wrapper.find('rect').attributes('stroke')).toBe('#C1C1C2');
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it('represents unchecked state clearly', () => {
|
|
183
|
-
const wrapper = mount(Checkbox);
|
|
184
|
-
const rect = wrapper.find('rect');
|
|
185
|
-
|
|
186
|
-
// Empty white box indicates unchecked
|
|
187
|
-
expect(rect.attributes('fill')).toBe('white');
|
|
188
|
-
expect(wrapper.findAll('path')).toHaveLength(0); // No checkmark
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
describe('Accessibility', () => {
|
|
193
|
-
it('svg is properly structured for screen readers', () => {
|
|
194
|
-
const wrapper = mount(Checkbox);
|
|
195
|
-
const svg = wrapper.find('svg');
|
|
196
|
-
|
|
197
|
-
expect(svg.element.tagName.toLowerCase()).toBe('svg');
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it('uses semantic checkbox appearance', () => {
|
|
201
|
-
const wrapper = mount(Checkbox);
|
|
202
|
-
const rect = wrapper.find('rect');
|
|
203
|
-
|
|
204
|
-
// Standard checkbox visual cues
|
|
205
|
-
expect(rect.attributes('rx')).toBeTruthy(); // Rounded corners
|
|
206
|
-
expect(rect.attributes('stroke')).toBeTruthy(); // Border
|
|
207
|
-
expect(rect.attributes('fill')).toBe('white'); // Empty interior
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
it('provides clear visual state', () => {
|
|
211
|
-
const wrapper = mount(Checkbox);
|
|
212
|
-
|
|
213
|
-
// Clear unchecked state (white fill, gray border, no marks)
|
|
214
|
-
expect(wrapper.find('rect').attributes('fill')).toBe('white');
|
|
215
|
-
expect(wrapper.findAll('path')).toHaveLength(0);
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
describe('Component Integration', () => {
|
|
220
|
-
it('can be mounted without props', () => {
|
|
221
|
-
expect(() => {
|
|
222
|
-
mount(Checkbox);
|
|
223
|
-
}).not.toThrow();
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('renders consistently on multiple mounts', () => {
|
|
227
|
-
const wrapper1 = mount(Checkbox);
|
|
228
|
-
const wrapper2 = mount(Checkbox);
|
|
229
|
-
|
|
230
|
-
expect(wrapper1.html()).toBe(wrapper2.html());
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it('maintains checkbox structure integrity', () => {
|
|
234
|
-
const wrapper = mount(Checkbox);
|
|
235
|
-
const rect = wrapper.find('rect');
|
|
236
|
-
|
|
237
|
-
expect(rect.exists()).toBe(true);
|
|
238
|
-
expect(rect.attributes('x')).toBeTruthy();
|
|
239
|
-
expect(rect.attributes('y')).toBeTruthy();
|
|
240
|
-
expect(rect.attributes('width')).toBeTruthy();
|
|
241
|
-
expect(rect.attributes('height')).toBeTruthy();
|
|
242
|
-
expect(rect.attributes('rx')).toBeTruthy();
|
|
243
|
-
expect(rect.attributes('fill')).toBeTruthy();
|
|
244
|
-
expect(rect.attributes('stroke')).toBeTruthy();
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
it('suitable for form checkbox implementations', () => {
|
|
248
|
-
const wrapper = mount(Checkbox);
|
|
249
|
-
|
|
250
|
-
// Standard checkbox requirements
|
|
251
|
-
expect(wrapper.find('svg').attributes('width')).toBe('16');
|
|
252
|
-
expect(wrapper.find('svg').attributes('height')).toBe('16');
|
|
253
|
-
expect(wrapper.find('rect').attributes('fill')).toBe('white');
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
describe('Icon Semantics', () => {
|
|
258
|
-
it('represents unchecked checkbox state', () => {
|
|
259
|
-
const wrapper = mount(Checkbox);
|
|
260
|
-
const rect = wrapper.find('rect');
|
|
261
|
-
|
|
262
|
-
// Visual indicators of unchecked state
|
|
263
|
-
expect(rect.attributes('fill')).toBe('white'); // Empty
|
|
264
|
-
expect(rect.attributes('stroke')).toBe('#C1C1C2'); // Inactive border
|
|
265
|
-
expect(wrapper.findAll('path')).toHaveLength(0); // No checkmark
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it('uses appropriate size for form controls', () => {
|
|
269
|
-
const wrapper = mount(Checkbox);
|
|
270
|
-
const svg = wrapper.find('svg');
|
|
271
|
-
|
|
272
|
-
// 16px is standard size for form checkboxes
|
|
273
|
-
expect(svg.attributes('width')).toBe('16');
|
|
274
|
-
expect(svg.attributes('height')).toBe('16');
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
it('provides clear interactive target', () => {
|
|
278
|
-
const wrapper = mount(Checkbox);
|
|
279
|
-
const rect = wrapper.find('rect');
|
|
280
|
-
|
|
281
|
-
// Large enough click/touch target
|
|
282
|
-
const width = parseFloat(rect.attributes('width'));
|
|
283
|
-
const height = parseFloat(rect.attributes('height'));
|
|
284
|
-
expect(width).toBeGreaterThanOrEqual(15);
|
|
285
|
-
expect(height).toBeGreaterThanOrEqual(15);
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
describe('Visual Design', () => {
|
|
290
|
-
it('provides clear unchecked appearance', () => {
|
|
291
|
-
const wrapper = mount(Checkbox);
|
|
292
|
-
const rect = wrapper.find('rect');
|
|
293
|
-
|
|
294
|
-
// Empty white appearance clearly indicates unchecked
|
|
295
|
-
expect(rect.attributes('fill')).toBe('white');
|
|
296
|
-
expect(rect.attributes('stroke')).toBeTruthy();
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
it('uses subtle styling for inactive state', () => {
|
|
300
|
-
const wrapper = mount(Checkbox);
|
|
301
|
-
const rect = wrapper.find('rect');
|
|
302
|
-
|
|
303
|
-
// Light gray border suggests inactive/unchecked
|
|
304
|
-
expect(rect.attributes('stroke')).toBe('#C1C1C2');
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
it('maintains clean minimalist design', () => {
|
|
308
|
-
const wrapper = mount(Checkbox);
|
|
309
|
-
|
|
310
|
-
// Simple single-element design
|
|
311
|
-
expect(wrapper.findAll('rect')).toHaveLength(1);
|
|
312
|
-
expect(wrapper.findAll('path')).toHaveLength(0);
|
|
313
|
-
expect(wrapper.findAll('circle')).toHaveLength(0);
|
|
314
|
-
});
|
|
315
|
-
});
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { mount } from '@vue/test-utils';
|
|
3
|
+
import Checkbox from '@components/Icons/checkbox.vue';
|
|
4
|
+
|
|
5
|
+
describe('Checkbox Icon', () => {
|
|
6
|
+
describe('Rendering', () => {
|
|
7
|
+
it('renders as SVG element', () => {
|
|
8
|
+
const wrapper = mount(Checkbox);
|
|
9
|
+
expect(wrapper.find('svg').exists()).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('has correct SVG attributes', () => {
|
|
13
|
+
const wrapper = mount(Checkbox);
|
|
14
|
+
const svg = wrapper.find('svg');
|
|
15
|
+
|
|
16
|
+
expect(svg.attributes('width')).toBe('16');
|
|
17
|
+
expect(svg.attributes('height')).toBe('16');
|
|
18
|
+
expect(svg.attributes('viewBox')).toBe('0 0 16 16');
|
|
19
|
+
expect(svg.attributes('fill')).toBe('none');
|
|
20
|
+
expect(svg.attributes('xmlns')).toBe('http://www.w3.org/2000/svg');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('contains exactly 1 rect element', () => {
|
|
24
|
+
const wrapper = mount(Checkbox);
|
|
25
|
+
const rects = wrapper.findAll('rect');
|
|
26
|
+
expect(rects).toHaveLength(1);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('Rectangle Properties', () => {
|
|
31
|
+
it('rect is properly positioned', () => {
|
|
32
|
+
const wrapper = mount(Checkbox);
|
|
33
|
+
const rect = wrapper.find('rect');
|
|
34
|
+
|
|
35
|
+
expect(rect.attributes('x')).toBe('0.5');
|
|
36
|
+
expect(rect.attributes('y')).toBe('0.5');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('rect has correct dimensions', () => {
|
|
40
|
+
const wrapper = mount(Checkbox);
|
|
41
|
+
const rect = wrapper.find('rect');
|
|
42
|
+
|
|
43
|
+
expect(rect.attributes('width')).toBe('15');
|
|
44
|
+
expect(rect.attributes('height')).toBe('15');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('rect has rounded corners', () => {
|
|
48
|
+
const wrapper = mount(Checkbox);
|
|
49
|
+
const rect = wrapper.find('rect');
|
|
50
|
+
|
|
51
|
+
expect(rect.attributes('rx')).toBe('3.5');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('rect has white fill', () => {
|
|
55
|
+
const wrapper = mount(Checkbox);
|
|
56
|
+
const rect = wrapper.find('rect');
|
|
57
|
+
|
|
58
|
+
expect(rect.attributes('fill')).toBe('white');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('rect has gray stroke', () => {
|
|
62
|
+
const wrapper = mount(Checkbox);
|
|
63
|
+
const rect = wrapper.find('rect');
|
|
64
|
+
|
|
65
|
+
expect(rect.attributes('stroke')).toBe('#C1C1C2');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('Visual Properties', () => {
|
|
70
|
+
it('represents unchecked state', () => {
|
|
71
|
+
const wrapper = mount(Checkbox);
|
|
72
|
+
const rect = wrapper.find('rect');
|
|
73
|
+
|
|
74
|
+
// White fill with gray border indicates unchecked
|
|
75
|
+
expect(rect.attributes('fill')).toBe('white');
|
|
76
|
+
expect(rect.attributes('stroke')).toBe('#C1C1C2');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('has no checkmark or fill pattern', () => {
|
|
80
|
+
const wrapper = mount(Checkbox);
|
|
81
|
+
|
|
82
|
+
// Should only contain the rect element (no paths, circles, etc.)
|
|
83
|
+
expect(wrapper.findAll('path')).toHaveLength(0);
|
|
84
|
+
expect(wrapper.findAll('circle')).toHaveLength(0);
|
|
85
|
+
expect(wrapper.findAll('line')).toHaveLength(0);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('uses neutral colors', () => {
|
|
89
|
+
const wrapper = mount(Checkbox);
|
|
90
|
+
const rect = wrapper.find('rect');
|
|
91
|
+
|
|
92
|
+
const stroke = rect.attributes('stroke');
|
|
93
|
+
const fill = rect.attributes('fill');
|
|
94
|
+
|
|
95
|
+
expect(fill).toBe('white');
|
|
96
|
+
expect(stroke).toBe('#C1C1C2'); // Light gray
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('Dimensions', () => {
|
|
101
|
+
it('uses standard 16x16 size', () => {
|
|
102
|
+
const wrapper = mount(Checkbox);
|
|
103
|
+
const svg = wrapper.find('svg');
|
|
104
|
+
|
|
105
|
+
expect(svg.attributes('width')).toBe('16');
|
|
106
|
+
expect(svg.attributes('height')).toBe('16');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('maintains square aspect ratio', () => {
|
|
110
|
+
const wrapper = mount(Checkbox);
|
|
111
|
+
const svg = wrapper.find('svg');
|
|
112
|
+
|
|
113
|
+
const width = svg.attributes('width');
|
|
114
|
+
const height = svg.attributes('height');
|
|
115
|
+
expect(width).toBe(height);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('rect accounts for stroke width', () => {
|
|
119
|
+
const wrapper = mount(Checkbox);
|
|
120
|
+
const rect = wrapper.find('rect');
|
|
121
|
+
|
|
122
|
+
// Positioned at 0.5,0.5 with 15x15 dimensions to account for 1px stroke
|
|
123
|
+
expect(rect.attributes('x')).toBe('0.5');
|
|
124
|
+
expect(rect.attributes('y')).toBe('0.5');
|
|
125
|
+
expect(rect.attributes('width')).toBe('15');
|
|
126
|
+
expect(rect.attributes('height')).toBe('15');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('has matching viewBox dimensions', () => {
|
|
130
|
+
const wrapper = mount(Checkbox);
|
|
131
|
+
const svg = wrapper.find('svg');
|
|
132
|
+
|
|
133
|
+
expect(svg.attributes('viewBox')).toBe('0 0 16 16');
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe('Checkbox Geometry', () => {
|
|
138
|
+
it('rect fills most of viewBox', () => {
|
|
139
|
+
const wrapper = mount(Checkbox);
|
|
140
|
+
const rect = wrapper.find('rect');
|
|
141
|
+
|
|
142
|
+
const x = parseFloat(rect.attributes('x'));
|
|
143
|
+
const y = parseFloat(rect.attributes('y'));
|
|
144
|
+
const width = parseFloat(rect.attributes('width'));
|
|
145
|
+
const height = parseFloat(rect.attributes('height'));
|
|
146
|
+
|
|
147
|
+
expect(x + width).toBe(15.5); // Close to 16
|
|
148
|
+
expect(y + height).toBe(15.5); // Close to 16
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('has appropriate corner radius', () => {
|
|
152
|
+
const wrapper = mount(Checkbox);
|
|
153
|
+
const rect = wrapper.find('rect');
|
|
154
|
+
|
|
155
|
+
const rx = parseFloat(rect.attributes('rx'));
|
|
156
|
+
const width = parseFloat(rect.attributes('width'));
|
|
157
|
+
|
|
158
|
+
// Corner radius should be reasonable proportion of width
|
|
159
|
+
expect(rx / width).toBeCloseTo(0.23, 1); // About 23%
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('forms proper checkbox shape', () => {
|
|
163
|
+
const wrapper = mount(Checkbox);
|
|
164
|
+
const rect = wrapper.find('rect');
|
|
165
|
+
|
|
166
|
+
// Should be square with rounded corners
|
|
167
|
+
expect(rect.attributes('width')).toBe(rect.attributes('height'));
|
|
168
|
+
expect(parseFloat(rect.attributes('rx'))).toBeGreaterThan(0);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
describe('Component Structure', () => {
|
|
173
|
+
it('suitable for form controls', () => {
|
|
174
|
+
const wrapper = mount(Checkbox);
|
|
175
|
+
|
|
176
|
+
// Standard size and appearance for form checkbox
|
|
177
|
+
expect(wrapper.find('svg').attributes('width')).toBe('16');
|
|
178
|
+
expect(wrapper.find('rect').attributes('fill')).toBe('white');
|
|
179
|
+
expect(wrapper.find('rect').attributes('stroke')).toBe('#C1C1C2');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('represents unchecked state clearly', () => {
|
|
183
|
+
const wrapper = mount(Checkbox);
|
|
184
|
+
const rect = wrapper.find('rect');
|
|
185
|
+
|
|
186
|
+
// Empty white box indicates unchecked
|
|
187
|
+
expect(rect.attributes('fill')).toBe('white');
|
|
188
|
+
expect(wrapper.findAll('path')).toHaveLength(0); // No checkmark
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe('Accessibility', () => {
|
|
193
|
+
it('svg is properly structured for screen readers', () => {
|
|
194
|
+
const wrapper = mount(Checkbox);
|
|
195
|
+
const svg = wrapper.find('svg');
|
|
196
|
+
|
|
197
|
+
expect(svg.element.tagName.toLowerCase()).toBe('svg');
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('uses semantic checkbox appearance', () => {
|
|
201
|
+
const wrapper = mount(Checkbox);
|
|
202
|
+
const rect = wrapper.find('rect');
|
|
203
|
+
|
|
204
|
+
// Standard checkbox visual cues
|
|
205
|
+
expect(rect.attributes('rx')).toBeTruthy(); // Rounded corners
|
|
206
|
+
expect(rect.attributes('stroke')).toBeTruthy(); // Border
|
|
207
|
+
expect(rect.attributes('fill')).toBe('white'); // Empty interior
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('provides clear visual state', () => {
|
|
211
|
+
const wrapper = mount(Checkbox);
|
|
212
|
+
|
|
213
|
+
// Clear unchecked state (white fill, gray border, no marks)
|
|
214
|
+
expect(wrapper.find('rect').attributes('fill')).toBe('white');
|
|
215
|
+
expect(wrapper.findAll('path')).toHaveLength(0);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe('Component Integration', () => {
|
|
220
|
+
it('can be mounted without props', () => {
|
|
221
|
+
expect(() => {
|
|
222
|
+
mount(Checkbox);
|
|
223
|
+
}).not.toThrow();
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('renders consistently on multiple mounts', () => {
|
|
227
|
+
const wrapper1 = mount(Checkbox);
|
|
228
|
+
const wrapper2 = mount(Checkbox);
|
|
229
|
+
|
|
230
|
+
expect(wrapper1.html()).toBe(wrapper2.html());
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('maintains checkbox structure integrity', () => {
|
|
234
|
+
const wrapper = mount(Checkbox);
|
|
235
|
+
const rect = wrapper.find('rect');
|
|
236
|
+
|
|
237
|
+
expect(rect.exists()).toBe(true);
|
|
238
|
+
expect(rect.attributes('x')).toBeTruthy();
|
|
239
|
+
expect(rect.attributes('y')).toBeTruthy();
|
|
240
|
+
expect(rect.attributes('width')).toBeTruthy();
|
|
241
|
+
expect(rect.attributes('height')).toBeTruthy();
|
|
242
|
+
expect(rect.attributes('rx')).toBeTruthy();
|
|
243
|
+
expect(rect.attributes('fill')).toBeTruthy();
|
|
244
|
+
expect(rect.attributes('stroke')).toBeTruthy();
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('suitable for form checkbox implementations', () => {
|
|
248
|
+
const wrapper = mount(Checkbox);
|
|
249
|
+
|
|
250
|
+
// Standard checkbox requirements
|
|
251
|
+
expect(wrapper.find('svg').attributes('width')).toBe('16');
|
|
252
|
+
expect(wrapper.find('svg').attributes('height')).toBe('16');
|
|
253
|
+
expect(wrapper.find('rect').attributes('fill')).toBe('white');
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe('Icon Semantics', () => {
|
|
258
|
+
it('represents unchecked checkbox state', () => {
|
|
259
|
+
const wrapper = mount(Checkbox);
|
|
260
|
+
const rect = wrapper.find('rect');
|
|
261
|
+
|
|
262
|
+
// Visual indicators of unchecked state
|
|
263
|
+
expect(rect.attributes('fill')).toBe('white'); // Empty
|
|
264
|
+
expect(rect.attributes('stroke')).toBe('#C1C1C2'); // Inactive border
|
|
265
|
+
expect(wrapper.findAll('path')).toHaveLength(0); // No checkmark
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('uses appropriate size for form controls', () => {
|
|
269
|
+
const wrapper = mount(Checkbox);
|
|
270
|
+
const svg = wrapper.find('svg');
|
|
271
|
+
|
|
272
|
+
// 16px is standard size for form checkboxes
|
|
273
|
+
expect(svg.attributes('width')).toBe('16');
|
|
274
|
+
expect(svg.attributes('height')).toBe('16');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('provides clear interactive target', () => {
|
|
278
|
+
const wrapper = mount(Checkbox);
|
|
279
|
+
const rect = wrapper.find('rect');
|
|
280
|
+
|
|
281
|
+
// Large enough click/touch target
|
|
282
|
+
const width = parseFloat(rect.attributes('width'));
|
|
283
|
+
const height = parseFloat(rect.attributes('height'));
|
|
284
|
+
expect(width).toBeGreaterThanOrEqual(15);
|
|
285
|
+
expect(height).toBeGreaterThanOrEqual(15);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
describe('Visual Design', () => {
|
|
290
|
+
it('provides clear unchecked appearance', () => {
|
|
291
|
+
const wrapper = mount(Checkbox);
|
|
292
|
+
const rect = wrapper.find('rect');
|
|
293
|
+
|
|
294
|
+
// Empty white appearance clearly indicates unchecked
|
|
295
|
+
expect(rect.attributes('fill')).toBe('white');
|
|
296
|
+
expect(rect.attributes('stroke')).toBeTruthy();
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('uses subtle styling for inactive state', () => {
|
|
300
|
+
const wrapper = mount(Checkbox);
|
|
301
|
+
const rect = wrapper.find('rect');
|
|
302
|
+
|
|
303
|
+
// Light gray border suggests inactive/unchecked
|
|
304
|
+
expect(rect.attributes('stroke')).toBe('#C1C1C2');
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('maintains clean minimalist design', () => {
|
|
308
|
+
const wrapper = mount(Checkbox);
|
|
309
|
+
|
|
310
|
+
// Simple single-element design
|
|
311
|
+
expect(wrapper.findAll('rect')).toHaveLength(1);
|
|
312
|
+
expect(wrapper.findAll('path')).toHaveLength(0);
|
|
313
|
+
expect(wrapper.findAll('circle')).toHaveLength(0);
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
316
|
});
|