33 */
44import { act , type ReactNode } from 'react'
55import { createRoot } from 'react-dom/client'
6- import { afterEach , describe , expect , it , vi } from 'vitest'
6+ import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
7+
8+ const motionPreference = vi . hoisted ( ( ) => ( { reduced : false } ) )
79
810vi . mock ( '@sim/emcn' , ( ) => ( {
911 Button : ( props : React . ButtonHTMLAttributes < HTMLButtonElement > ) => < button { ...props } /> ,
1012 ChipTag : ( { children } : { children : ReactNode } ) => < span > { children } </ span > ,
1113 cn : ( ...values : Array < string | false | null | undefined > ) => values . filter ( Boolean ) . join ( ' ' ) ,
14+ usePrefersReducedMotion : ( ) => motionPreference . reduced ,
1215 Tooltip : {
1316 Root : ( { children } : { children : ReactNode } ) => children ,
1417 Trigger : ( { children } : { children : ReactNode } ) => children ,
@@ -31,8 +34,15 @@ vi.mock('@sim/emcn/icons', () => ({
3134
3235import { FeaturedCustomer } from '@/app/(landing)/components/featured-customer/featured-customer'
3336
37+ beforeEach ( ( ) => {
38+ motionPreference . reduced = false
39+ vi . spyOn ( HTMLMediaElement . prototype , 'play' ) . mockResolvedValue ( undefined )
40+ vi . spyOn ( HTMLMediaElement . prototype , 'pause' ) . mockImplementation ( ( ) => { } )
41+ } )
42+
3443afterEach ( ( ) => {
3544 vi . useRealTimers ( )
45+ vi . restoreAllMocks ( )
3646 document . body . replaceChildren ( )
3747} )
3848
@@ -56,6 +66,10 @@ describe('FeaturedCustomer', () => {
5666 '[data-customer-story-content="true"]'
5767 ) as HTMLElement
5868 const carouselRail = host . querySelector ( '[data-customer-carousel-rail="true"]' ) as HTMLElement
69+ const video = rivian . querySelector ( 'video' ) as HTMLVideoElement
70+ video . currentTime = 12
71+
72+ expect ( video . play ) . toHaveBeenCalledOnce ( )
5973
6074 expect ( rivian . querySelector ( 'img[alt="Rivian | Volkswagen Group Technologies"]' ) ) . not . toBeNull ( )
6175 expect ( host . querySelector ( 'blockquote' ) ) . toBeNull ( )
@@ -113,9 +127,8 @@ describe('FeaturedCustomer', () => {
113127 expect ( expRealty . className ) . toContain ( 'opacity-100' )
114128 expect ( expRealtyContent . className ) . toContain ( 'translate-y-0' )
115129 expect ( expRealtyContent . className ) . toContain ( 'opacity-100' )
116- expect ( expRealtyContent . className ) . toContain ( 'delay-150' )
117- expect ( carouselRail . className ) . toContain ( 'xl:pl-24' )
118- expect ( carouselRail . className ) . not . toContain ( 'xl:pr-24' )
130+ expect ( carouselRail . className ) . toContain ( 'xl:translate-x-24' )
131+ expect ( carouselRail . className ) . toContain ( 'xl:pr-24' )
119132 const previousButton = host . querySelector (
120133 '[aria-label="View Rivian customer story"]'
121134 ) as HTMLButtonElement
@@ -125,7 +138,9 @@ describe('FeaturedCustomer', () => {
125138 ) as HTMLButtonElement
126139 expect ( disabledNext . disabled ) . toBe ( true )
127140 expect ( expRealty . querySelector ( 'img[alt="eXp Realty"]' ) ) . not . toBeNull ( )
128- expect ( host . querySelector ( 'video' ) ) . toBeNull ( )
141+ expect ( host . querySelector ( 'video' ) ) . toBe ( video )
142+ expect ( video . currentTime ) . toBe ( 12 )
143+ expect ( video . pause ) . toHaveBeenCalledOnce ( )
129144 expect (
130145 [ ...expRealty . querySelectorAll ( 'img' ) ] . map ( ( image ) => image . getAttribute ( 'src' ) )
131146 ) . toEqual ( [ '/landing/logos/exp-realty.svg' ] )
@@ -139,12 +154,38 @@ describe('FeaturedCustomer', () => {
139154
140155 expect ( rivian . getAttribute ( 'aria-current' ) ) . toBe ( 'true' )
141156 expect ( expRealty . getAttribute ( 'aria-current' ) ) . toBeNull ( )
157+ expect ( rivian . querySelector ( 'video' ) ) . toBe ( video )
158+ expect ( video . currentTime ) . toBe ( 12 )
159+ expect ( video . play ) . toHaveBeenCalledTimes ( 2 )
142160
143161 act ( ( ) => {
144162 root . unmount ( )
145163 } )
146164 } )
147165
166+ it ( 'keeps video paused with reduced motion and responds to preference changes' , ( ) => {
167+ motionPreference . reduced = true
168+ ; ( globalThis as { IS_REACT_ACT_ENVIRONMENT ?: boolean } ) . IS_REACT_ACT_ENVIRONMENT = true
169+ const host = document . createElement ( 'div' )
170+ document . body . appendChild ( host )
171+ const root = createRoot ( host )
172+
173+ act ( ( ) => root . render ( < FeaturedCustomer /> ) )
174+ const video = host . querySelector ( 'video' ) as HTMLVideoElement
175+ expect ( video . play ) . not . toHaveBeenCalled ( )
176+ expect ( video . pause ) . toHaveBeenCalledOnce ( )
177+
178+ motionPreference . reduced = false
179+ act ( ( ) => root . render ( < FeaturedCustomer /> ) )
180+ expect ( video . play ) . toHaveBeenCalledOnce ( )
181+
182+ motionPreference . reduced = true
183+ act ( ( ) => root . render ( < FeaturedCustomer /> ) )
184+ expect ( video . pause ) . toHaveBeenCalledTimes ( 2 )
185+
186+ act ( ( ) => root . unmount ( ) )
187+ } )
188+
148189 it ( 'emphasizes and selects the neighboring customer story' , ( ) => {
149190 ; ( globalThis as { IS_REACT_ACT_ENVIRONMENT ?: boolean } ) . IS_REACT_ACT_ENVIRONMENT = true
150191 const host = document . createElement ( 'div' )
0 commit comments