11import { mount } from '@vue/test-utils'
2- import PrimeVue from 'primevue/config'
3- import ImageCompare from 'primevue/imagecompare'
42import { describe , expect , it } from 'vitest'
53
64import type { SimplifiedWidget } from '@/types/simplifiedWidget'
@@ -25,8 +23,9 @@ describe('WidgetImageCompare Display', () => {
2523 ) => {
2624 return mount ( WidgetImageCompare , {
2725 global : {
28- plugins : [ PrimeVue ] ,
29- components : { ImageCompare }
26+ mocks : {
27+ $t : ( key : string ) => key
28+ }
3029 } ,
3130 props : {
3231 widget,
@@ -36,29 +35,23 @@ describe('WidgetImageCompare Display', () => {
3635 }
3736
3837 describe ( 'Component Rendering' , ( ) => {
39- it ( 'renders imagecompare component with proper structure and styling' , ( ) => {
38+ it ( 'renders with proper structure and styling when images are provided ' , ( ) => {
4039 const value : ImageCompareValue = {
4140 before : 'https://example.com/before.jpg' ,
4241 after : 'https://example.com/after.jpg'
4342 }
4443 const widget = createMockWidget ( value )
4544 const wrapper = mountComponent ( widget )
4645
47- // Component exists
48- const imageCompare = wrapper . findComponent ( { name : 'ImageCompare' } )
49- expect ( imageCompare . exists ( ) ) . toBe ( true )
50-
51- // Renders both images with correct URLs
5246 const images = wrapper . findAll ( 'img' )
5347 expect ( images ) . toHaveLength ( 2 )
54- expect ( images [ 0 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/before.jpg' )
55- expect ( images [ 1 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/after.jpg' )
5648
57- // Images have proper styling classes
49+ // In the new implementation: after image is first (background), before image is second (overlay)
50+ expect ( images [ 0 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/after.jpg' )
51+ expect ( images [ 1 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/before.jpg' )
52+
5853 images . forEach ( ( img ) => {
59- expect ( img . classes ( ) ) . toContain ( 'object-cover' )
60- expect ( img . classes ( ) ) . toContain ( 'w-full' )
61- expect ( img . classes ( ) ) . toContain ( 'h-full' )
54+ expect ( img . classes ( ) ) . toContain ( 'object-contain' )
6255 } )
6356 } )
6457 } )
@@ -74,8 +67,9 @@ describe('WidgetImageCompare Display', () => {
7467 }
7568 const customWrapper = mountComponent ( createMockWidget ( customAltValue ) )
7669 const customImages = customWrapper . findAll ( 'img' )
77- expect ( customImages [ 0 ] . attributes ( 'alt' ) ) . toBe ( 'Original design' )
78- expect ( customImages [ 1 ] . attributes ( 'alt' ) ) . toBe ( 'Updated design' )
70+ // DOM order: [after, before]
71+ expect ( customImages [ 0 ] . attributes ( 'alt' ) ) . toBe ( 'Updated design' )
72+ expect ( customImages [ 1 ] . attributes ( 'alt' ) ) . toBe ( 'Original design' )
7973
8074 // Test default alt text
8175 const defaultAltValue : ImageCompareValue = {
@@ -84,8 +78,8 @@ describe('WidgetImageCompare Display', () => {
8478 }
8579 const defaultWrapper = mountComponent ( createMockWidget ( defaultAltValue ) )
8680 const defaultImages = defaultWrapper . findAll ( 'img' )
87- expect ( defaultImages [ 0 ] . attributes ( 'alt' ) ) . toBe ( 'Before image' )
88- expect ( defaultImages [ 1 ] . attributes ( 'alt' ) ) . toBe ( 'After image' )
81+ expect ( defaultImages [ 0 ] . attributes ( 'alt' ) ) . toBe ( 'After image' )
82+ expect ( defaultImages [ 1 ] . attributes ( 'alt' ) ) . toBe ( 'Before image' )
8983
9084 // Test empty string alt text (falls back to default)
9185 const emptyAltValue : ImageCompareValue = {
@@ -96,29 +90,36 @@ describe('WidgetImageCompare Display', () => {
9690 }
9791 const emptyWrapper = mountComponent ( createMockWidget ( emptyAltValue ) )
9892 const emptyImages = emptyWrapper . findAll ( 'img' )
99- expect ( emptyImages [ 0 ] . attributes ( 'alt' ) ) . toBe ( 'Before image' )
100- expect ( emptyImages [ 1 ] . attributes ( 'alt' ) ) . toBe ( 'After image' )
93+ expect ( emptyImages [ 0 ] . attributes ( 'alt' ) ) . toBe ( 'After image' )
94+ expect ( emptyImages [ 1 ] . attributes ( 'alt' ) ) . toBe ( 'Before image' )
10195 } )
10296
103- it ( 'handles missing and partial image URLs gracefully' , ( ) => {
104- // Missing URLs
105- const missingValue : ImageCompareValue = { before : '' , after : '' }
106- const missingWrapper = mountComponent ( createMockWidget ( missingValue ) )
107- const missingImages = missingWrapper . findAll ( 'img' )
108- expect ( missingImages [ 0 ] . attributes ( 'src' ) ) . toBe ( '' )
109- expect ( missingImages [ 1 ] . attributes ( 'src' ) ) . toBe ( '' )
110-
111- // Partial URLs
112- const partialValue : ImageCompareValue = {
97+ it ( 'handles partial image URLs gracefully' , ( ) => {
98+ // Only before image provided
99+ const beforeOnlyValue : ImageCompareValue = {
113100 before : 'https://example.com/before.jpg' ,
114101 after : ''
115102 }
116- const partialWrapper = mountComponent ( createMockWidget ( partialValue ) )
117- const partialImages = partialWrapper . findAll ( 'img' )
118- expect ( partialImages [ 0 ] . attributes ( 'src' ) ) . toBe (
103+ const beforeOnlyWrapper = mountComponent (
104+ createMockWidget ( beforeOnlyValue )
105+ )
106+ const beforeOnlyImages = beforeOnlyWrapper . findAll ( 'img' )
107+ expect ( beforeOnlyImages ) . toHaveLength ( 1 )
108+ expect ( beforeOnlyImages [ 0 ] . attributes ( 'src' ) ) . toBe (
119109 'https://example.com/before.jpg'
120110 )
121- expect ( partialImages [ 1 ] . attributes ( 'src' ) ) . toBe ( '' )
111+
112+ // Only after image provided
113+ const afterOnlyValue : ImageCompareValue = {
114+ before : '' ,
115+ after : 'https://example.com/after.jpg'
116+ }
117+ const afterOnlyWrapper = mountComponent ( createMockWidget ( afterOnlyValue ) )
118+ const afterOnlyImages = afterOnlyWrapper . findAll ( 'img' )
119+ expect ( afterOnlyImages ) . toHaveLength ( 1 )
120+ expect ( afterOnlyImages [ 0 ] . attributes ( 'src' ) ) . toBe (
121+ 'https://example.com/after.jpg'
122+ )
122123 } )
123124 } )
124125
@@ -129,121 +130,54 @@ describe('WidgetImageCompare Display', () => {
129130 const wrapper = mountComponent ( widget )
130131
131132 const images = wrapper . findAll ( 'img' )
133+ expect ( images ) . toHaveLength ( 1 )
132134 expect ( images [ 0 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/single.jpg' )
133- expect ( images [ 1 ] . attributes ( 'src' ) ) . toBe ( '' )
134- } )
135-
136- it ( 'uses default alt text for string values' , ( ) => {
137- const value = 'https://example.com/single.jpg'
138- const widget = createMockWidget ( value )
139- const wrapper = mountComponent ( widget )
140-
141- const images = wrapper . findAll ( 'img' )
142135 expect ( images [ 0 ] . attributes ( 'alt' ) ) . toBe ( 'Before image' )
143- expect ( images [ 1 ] . attributes ( 'alt' ) ) . toBe ( 'After image' )
144- } )
145- } )
146-
147- describe ( 'Widget Options Handling' , ( ) => {
148- it ( 'passes through accessibility options' , ( ) => {
149- const value : ImageCompareValue = {
150- before : 'https://example.com/before.jpg' ,
151- after : 'https://example.com/after.jpg'
152- }
153- const widget = createMockWidget ( value , {
154- tabindex : 1 ,
155- ariaLabel : 'Compare images' ,
156- ariaLabelledby : 'compare-label'
157- } )
158- const wrapper = mountComponent ( widget )
159-
160- const imageCompare = wrapper . findComponent ( { name : 'ImageCompare' } )
161- expect ( imageCompare . props ( 'tabindex' ) ) . toBe ( 1 )
162- expect ( imageCompare . props ( 'ariaLabel' ) ) . toBe ( 'Compare images' )
163- expect ( imageCompare . props ( 'ariaLabelledby' ) ) . toBe ( 'compare-label' )
164- } )
165-
166- it ( 'uses default tabindex when not provided' , ( ) => {
167- const value : ImageCompareValue = {
168- before : 'https://example.com/before.jpg' ,
169- after : 'https://example.com/after.jpg'
170- }
171- const widget = createMockWidget ( value )
172- const wrapper = mountComponent ( widget )
173-
174- const imageCompare = wrapper . findComponent ( { name : 'ImageCompare' } )
175- expect ( imageCompare . props ( 'tabindex' ) ) . toBe ( 0 )
176- } )
177-
178- it ( 'passes through PrimeVue specific options' , ( ) => {
179- const value : ImageCompareValue = {
180- before : 'https://example.com/before.jpg' ,
181- after : 'https://example.com/after.jpg'
182- }
183- const widget = createMockWidget ( value , {
184- unstyled : true ,
185- pt : { root : { class : 'custom-class' } } ,
186- ptOptions : { mergeSections : true }
187- } )
188- const wrapper = mountComponent ( widget )
189-
190- const imageCompare = wrapper . findComponent ( { name : 'ImageCompare' } )
191- expect ( imageCompare . props ( 'unstyled' ) ) . toBe ( true )
192- expect ( imageCompare . props ( 'pt' ) ) . toEqual ( {
193- root : { class : 'custom-class' }
194- } )
195- expect ( imageCompare . props ( 'ptOptions' ) ) . toEqual ( { mergeSections : true } )
196136 } )
197137 } )
198138
199139 describe ( 'Readonly Mode' , ( ) => {
200- it ( 'renders normally in readonly mode (no interaction restrictions) ' , ( ) => {
140+ it ( 'renders normally in readonly mode' , ( ) => {
201141 const value : ImageCompareValue = {
202142 before : 'https://example.com/before.jpg' ,
203143 after : 'https://example.com/after.jpg'
204144 }
205145 const widget = createMockWidget ( value )
206146 const wrapper = mountComponent ( widget , true )
207147
208- // ImageCompare is display-only, readonly doesn't affect rendering
209- const imageCompare = wrapper . findComponent ( { name : 'ImageCompare' } )
210- expect ( imageCompare . exists ( ) ) . toBe ( true )
211-
212148 const images = wrapper . findAll ( 'img' )
213149 expect ( images ) . toHaveLength ( 2 )
214150 } )
215151 } )
216152
217153 describe ( 'Edge Cases' , ( ) => {
218- it ( 'handles null or undefined widget value' , ( ) => {
154+ it ( 'shows no images message when widget value is empty string ' , ( ) => {
219155 const widget = createMockWidget ( '' )
220156 const wrapper = mountComponent ( widget )
221157
222158 const images = wrapper . findAll ( 'img' )
223- expect ( images [ 0 ] . attributes ( 'src' ) ) . toBe ( '' )
224- expect ( images [ 1 ] . attributes ( 'src' ) ) . toBe ( '' )
225- expect ( images [ 0 ] . attributes ( 'alt' ) ) . toBe ( 'Before image' )
226- expect ( images [ 1 ] . attributes ( 'alt' ) ) . toBe ( 'After image' )
159+ expect ( images ) . toHaveLength ( 0 )
160+ expect ( wrapper . text ( ) ) . toContain ( 'imageCompare.noImages' )
227161 } )
228162
229- it ( 'handles empty object value ' , ( ) => {
230- const value : ImageCompareValue = { } as ImageCompareValue
163+ it ( 'shows no images message when both URLs are empty ' , ( ) => {
164+ const value : ImageCompareValue = { before : '' , after : '' }
231165 const widget = createMockWidget ( value )
232166 const wrapper = mountComponent ( widget )
233167
234168 const images = wrapper . findAll ( 'img' )
235- expect ( images [ 0 ] . attributes ( 'src' ) ) . toBe ( '' )
236- expect ( images [ 1 ] . attributes ( 'src' ) ) . toBe ( ' ')
169+ expect ( images ) . toHaveLength ( 0 )
170+ expect ( wrapper . text ( ) ) . toContain ( 'imageCompare.noImages ')
237171 } )
238172
239- it ( 'handles malformed object value' , ( ) => {
240- const value = { randomProp : 'test' , before : '' , after : '' }
173+ it ( 'shows no images message for empty object value' , ( ) => {
174+ const value : ImageCompareValue = { } as ImageCompareValue
241175 const widget = createMockWidget ( value )
242176 const wrapper = mountComponent ( widget )
243177
244178 const images = wrapper . findAll ( 'img' )
245- expect ( images [ 0 ] . attributes ( 'src' ) ) . toBe ( '' )
246- expect ( images [ 1 ] . attributes ( 'src' ) ) . toBe ( ' ')
179+ expect ( images ) . toHaveLength ( 0 )
180+ expect ( wrapper . text ( ) ) . toContain ( 'imageCompare.noImages ')
247181 } )
248182
249183 it ( 'handles special content - long URLs, special characters, and long alt text' , ( ) => {
@@ -290,7 +224,7 @@ describe('WidgetImageCompare Display', () => {
290224 } )
291225
292226 describe ( 'Template Structure' , ( ) => {
293- it ( 'correctly assigns images to left and right template slots ' , ( ) => {
227+ it ( 'correctly renders after image as background and before image as overlay ' , ( ) => {
294228 const value : ImageCompareValue = {
295229 before : 'https://example.com/before.jpg' ,
296230 after : 'https://example.com/after.jpg'
@@ -299,10 +233,11 @@ describe('WidgetImageCompare Display', () => {
299233 const wrapper = mountComponent ( widget )
300234
301235 const images = wrapper . findAll ( 'img' )
302- // First image (before) should be in left template slot
303- expect ( images [ 0 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/before.jpg' )
304- // Second image (after) should be in right template slot
305- expect ( images [ 1 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/after.jpg' )
236+ // After image is rendered first as background
237+ expect ( images [ 0 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/after.jpg' )
238+ // Before image is rendered second as overlay with clipPath
239+ expect ( images [ 1 ] . attributes ( 'src' ) ) . toBe ( 'https://example.com/before.jpg' )
240+ expect ( images [ 1 ] . classes ( ) ) . toContain ( 'absolute' )
306241 } )
307242 } )
308243
@@ -333,4 +268,27 @@ describe('WidgetImageCompare Display', () => {
333268 expect ( blobUrlImages [ 1 ] . attributes ( 'src' ) ) . toBe ( blobUrl )
334269 } )
335270 } )
271+
272+ describe ( 'Slider Element' , ( ) => {
273+ it ( 'renders slider divider when images are present' , ( ) => {
274+ const value : ImageCompareValue = {
275+ before : 'https://example.com/before.jpg' ,
276+ after : 'https://example.com/after.jpg'
277+ }
278+ const widget = createMockWidget ( value )
279+ const wrapper = mountComponent ( widget )
280+
281+ const slider = wrapper . find ( '[role="presentation"]' )
282+ expect ( slider . exists ( ) ) . toBe ( true )
283+ expect ( slider . classes ( ) ) . toContain ( 'bg-white' )
284+ } )
285+
286+ it ( 'does not render slider when no images' , ( ) => {
287+ const widget = createMockWidget ( '' )
288+ const wrapper = mountComponent ( widget )
289+
290+ const slider = wrapper . find ( '[role="presentation"]' )
291+ expect ( slider . exists ( ) ) . toBe ( false )
292+ } )
293+ } )
336294} )
0 commit comments