1
1
import { breakpoints } from '@guardian/source/foundations' ;
2
2
import type { Meta , StoryObj } from '@storybook/react' ;
3
+ import { expect , userEvent , within } from '@storybook/test' ;
3
4
import { centreColumnDecorator } from '../../.storybook/decorators/gridDecorators' ;
4
5
import { LoopVideo } from './LoopVideo.importable' ;
5
6
6
- export default {
7
+ const meta = {
7
8
component : LoopVideo ,
8
9
title : 'Components/LoopVideo' ,
9
10
decorators : [ centreColumnDecorator ] ,
@@ -15,7 +16,10 @@ export default {
15
16
} ,
16
17
} satisfies Meta < typeof LoopVideo > ;
17
18
18
- export const Default = {
19
+ export default meta ;
20
+ type Story = StoryObj < typeof LoopVideo > ;
21
+
22
+ export const Default : Story = {
19
23
name : 'Default' ,
20
24
args : {
21
25
src : 'https://uploads.guim.co.uk/2025%2F06%2F20%2Ftesting+only%2C+please+ignore--3cb22b60-2c3f-48d6-8bce-38c956907cce-3.mp4' ,
@@ -26,14 +30,84 @@ export const Default = {
26
30
image : 'https://media.guim.co.uk/9bdb802e6da5d3fd249b5060f367b3a817965f0c/0_0_1800_1080/master/1800.jpg' ,
27
31
fallbackImage : '' ,
28
32
} ,
29
- } satisfies StoryObj < typeof LoopVideo > ;
33
+ } ;
30
34
31
- export const Without5to4Ratio = {
35
+ export const Without5to4Ratio : Story = {
32
36
name : 'Without 5:4 aspect ratio' ,
33
37
args : {
34
38
...Default . args ,
35
39
src : 'https://uploads.guim.co.uk/2024/10/01/241001HeleneLoop_2.mp4' ,
36
40
height : 1080 ,
37
41
width : 1920 ,
38
42
} ,
39
- } satisfies StoryObj < typeof LoopVideo > ;
43
+ } ;
44
+
45
+ export const PausePlay : Story = {
46
+ ...Default ,
47
+ play : async ( { canvasElement } ) => {
48
+ const canvas = within ( canvasElement ) ;
49
+ const videoEl = canvas . getByTestId ( 'loop-video' ) ;
50
+
51
+ await userEvent . click ( videoEl , {
52
+ delay : 300 , // Allow video to start playing.
53
+ } ) ;
54
+ await canvas . findByTestId ( 'play-icon' ) ;
55
+
56
+ const progressBar = await canvas . findByRole ( 'progressbar' ) ;
57
+ await expect ( Number ( progressBar . ariaValueNow ) ) . toBeGreaterThan ( 0 ) ;
58
+
59
+ // Play Video
60
+ await userEvent . click ( videoEl ) ;
61
+ await expect ( canvas . queryByTestId ( 'play-icon' ) ) . not . toBeInTheDocument ( ) ;
62
+ } ,
63
+ } ;
64
+
65
+ export const UnmuteMute : Story = {
66
+ ...Default ,
67
+ parameters : {
68
+ test : {
69
+ // The following error is received without this flag: "TypeError: ophan.trackClickComponentEvent is not a function"
70
+ dangerouslyIgnoreUnhandledErrors : true ,
71
+ } ,
72
+ } ,
73
+ play : async ( { canvasElement } ) => {
74
+ const canvas = within ( canvasElement ) ;
75
+
76
+ await canvas . findByTestId ( 'unmute-icon' ) ;
77
+
78
+ await userEvent . click ( canvas . getByTestId ( 'unmute-icon' ) ) ;
79
+ await canvas . findByTestId ( 'mute-icon' ) ;
80
+
81
+ await userEvent . click ( canvas . getByTestId ( 'mute-icon' ) ) ;
82
+ await canvas . findByTestId ( 'unmute-icon' ) ;
83
+ } ,
84
+ } ;
85
+
86
+ // Function to emulate pausing between interactions
87
+ function sleep ( ms : number ) {
88
+ return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
89
+ }
90
+
91
+ export const InteractionObserver : Story = {
92
+ ...Default ,
93
+ render : ( args ) => (
94
+ < div data-testid = "test-container" >
95
+ < LoopVideo { ...args } />
96
+ < div style = { { height : '100vh' } } > </ div >
97
+ < p data-testid = "page-end" > End of page</ p >
98
+ </ div >
99
+ ) ,
100
+ play : async ( { canvasElement } ) => {
101
+ const canvas = within ( canvasElement ) ;
102
+
103
+ await sleep ( 500 ) ; // Allow enough time for the autoplay video to start.
104
+ canvas . getByTestId ( 'page-end' ) . scrollIntoView ( ) ;
105
+
106
+ const progressBar = await canvas . findByRole ( 'progressbar' ) ;
107
+ const progress = Number ( progressBar . ariaValueNow ) ;
108
+
109
+ await sleep ( 500 ) ; // Allow enough time to be confident that the video is paused.
110
+ await expect ( Number ( progressBar . ariaValueNow ) ) . toEqual ( progress ) ;
111
+ await expect ( canvas . queryByTestId ( 'play-icon' ) ) . not . toBeInTheDocument ( ) ;
112
+ } ,
113
+ } ;
0 commit comments