@@ -14,6 +14,215 @@ import (
14
14
"github.com/grafana/xk6-browser/common"
15
15
)
16
16
17
+ func TestLifecycleWaitForLoadStateLoad (t * testing.T ) {
18
+ // Test description
19
+ //
20
+ // 1. goto /home and wait for the load lifecycle event.
21
+ // 2. use WaitForLoadState with load to ensure that load
22
+ // lifecycle event has already fired.
23
+ //
24
+ // Success criteria: We don't wait for all network requests to
25
+ // complete, but we are interested in waiting
26
+ // for all async scripts to have fully loaded
27
+ // (which is when load is fired). We also want
28
+ // to ensure that the load event is stored
29
+ // internally, and we don't block on WaitForLoadState.
30
+
31
+ t .Parallel ()
32
+
33
+ tb := newTestBrowser (t , withFileServer ())
34
+ p := tb .NewPage (nil )
35
+ tb .withHandler ("/home" , func (w http.ResponseWriter , r * http.Request ) {
36
+ http .Redirect (w , r , tb .staticURL ("wait_for_nav_lifecycle.html" ), http .StatusMovedPermanently )
37
+ })
38
+
39
+ var counter int64
40
+ var counterMu sync.Mutex
41
+ tb .withHandler ("/ping" , func (w http.ResponseWriter , _ * http.Request ) {
42
+ counterMu .Lock ()
43
+ defer counterMu .Unlock ()
44
+
45
+ time .Sleep (time .Millisecond * 100 )
46
+
47
+ counter ++
48
+ fmt .Fprintf (w , "pong %d" , counter )
49
+ })
50
+
51
+ tb .withHandler ("/ping.js" , func (w http.ResponseWriter , _ * http.Request ) {
52
+ fmt .Fprintf (w , `
53
+ var pingJSTextOutput = document.getElementById("pingJSText");
54
+ pingJSTextOutput.innerText = "ping.js loaded from server";
55
+ ` )
56
+ })
57
+
58
+ waitUntil := common .LifecycleEventLoad
59
+ assertHome (t , tb , p , waitUntil , func () {
60
+ result := p .TextContent ("#pingRequestText" , nil )
61
+ assert .NotEqualValues (t , "Waiting... pong 10 - for loop complete" , result )
62
+
63
+ result = p .TextContent ("#pingJSText" , nil )
64
+ assert .EqualValues (t , "ping.js loaded from server" , result )
65
+
66
+ // This shouldn't block and return after calling hasLifecycleEventFired.
67
+ p .WaitForLoadState (waitUntil .String (), nil )
68
+ })
69
+ }
70
+
71
+ func TestLifecycleWaitForLoadStateDOMContentLoaded (t * testing.T ) {
72
+ // Test description
73
+ //
74
+ // 1. goto /home and wait for the domcontentloaded lifecycle event.
75
+ // 2. use WaitForLoadState with domcontentloaded to ensure that
76
+ // domcontentloaded lifecycle event has already fired.
77
+ //
78
+ // Success criteria: We don't wait for all network requests or the
79
+ // async scripts to complete, and we're only
80
+ // interested in the html file being loaded. We
81
+ // also want to ensure that the domcontentloaded
82
+ // event is stored internally, and we don't block
83
+ // on WaitForLoadState.
84
+
85
+ t .Parallel ()
86
+
87
+ tb := newTestBrowser (t , withFileServer ())
88
+ p := tb .NewPage (nil )
89
+ tb .withHandler ("/home" , func (w http.ResponseWriter , r * http.Request ) {
90
+ http .Redirect (w , r , tb .staticURL ("wait_for_nav_lifecycle.html" ), http .StatusMovedPermanently )
91
+ })
92
+
93
+ var counter int64
94
+ var counterMu sync.Mutex
95
+ tb .withHandler ("/ping" , func (w http.ResponseWriter , _ * http.Request ) {
96
+ counterMu .Lock ()
97
+ defer counterMu .Unlock ()
98
+
99
+ time .Sleep (time .Millisecond * 100 )
100
+
101
+ counter ++
102
+ fmt .Fprintf (w , "pong %d" , counter )
103
+ })
104
+
105
+ tb .withHandler ("/ping.js" , func (w http.ResponseWriter , _ * http.Request ) {
106
+ fmt .Fprintf (w , `
107
+ await new Promise(resolve => setTimeout(resolve, 1000));
108
+
109
+ var pingJSTextOutput = document.getElementById("pingJSText");
110
+ pingJSTextOutput.innerText = "ping.js loaded from server";
111
+ ` )
112
+ })
113
+
114
+ waitUntil := common .LifecycleEventDOMContentLoad
115
+ assertHome (t , tb , p , waitUntil , func () {
116
+ result := p .TextContent ("#pingRequestText" , nil )
117
+ assert .NotEqualValues (t , "Waiting... pong 10 - for loop complete" , result )
118
+
119
+ result = p .TextContent ("#pingJSText" , nil )
120
+ assert .EqualValues (t , "Waiting..." , result )
121
+
122
+ // This shouldn't block and return after calling hasLifecycleEventFired.
123
+ p .WaitForLoadState (waitUntil .String (), nil )
124
+ })
125
+ }
126
+
127
+ func TestLifecycleWaitForLoadStateNetworkIdle (t * testing.T ) {
128
+ // Test description
129
+ //
130
+ // 1. goto /home and wait for the networkidle lifecycle event.
131
+ // 2. use WaitForLoadState with networkidle to ensure that
132
+ // networkidle lifecycle event has already fired.
133
+ //
134
+ // Success criteria: We wait for all network requests and async
135
+ // scripts to complete. We also want to ensure
136
+ // that the networkidle event is stored internally,
137
+ // and we don't block on WaitForLoadState.
138
+
139
+ t .Parallel ()
140
+
141
+ tb := newTestBrowser (t , withFileServer ())
142
+ p := tb .NewPage (nil )
143
+ tb .withHandler ("/home" , func (w http.ResponseWriter , r * http.Request ) {
144
+ http .Redirect (w , r , tb .staticURL ("wait_for_nav_lifecycle.html" ), http .StatusMovedPermanently )
145
+ })
146
+
147
+ var counter int64
148
+ var counterMu sync.Mutex
149
+ tb .withHandler ("/ping" , func (w http.ResponseWriter , _ * http.Request ) {
150
+ counterMu .Lock ()
151
+ defer counterMu .Unlock ()
152
+
153
+ counter ++
154
+ fmt .Fprintf (w , "pong %d" , counter )
155
+ })
156
+
157
+ tb .withHandler ("/ping.js" , func (w http.ResponseWriter , _ * http.Request ) {
158
+ fmt .Fprintf (w , `
159
+ var pingJSTextOutput = document.getElementById("pingJSText");
160
+ pingJSTextOutput.innerText = "ping.js loaded from server";
161
+ ` )
162
+ })
163
+
164
+ waitUntil := common .LifecycleEventNetworkIdle
165
+ assertHome (t , tb , p , waitUntil , func () {
166
+ result := p .TextContent ("#pingRequestText" , nil )
167
+ assert .EqualValues (t , "Waiting... pong 10 - for loop complete" , result )
168
+
169
+ result = p .TextContent ("#pingJSText" , nil )
170
+ assert .EqualValues (t , "ping.js loaded from server" , result )
171
+
172
+ // This shouldn't block and return after calling hasLifecycleEventFired.
173
+ p .WaitForLoadState (waitUntil .String (), nil )
174
+ })
175
+ }
176
+
177
+ func TestLifecycleWaitForLoadStateDOMContentLoadedThenNetworkIdle (t * testing.T ) {
178
+ // Test description
179
+ //
180
+ // 1. goto /home and wait for the domcontentloaded lifecycle event.
181
+ // 2. use WaitForLoadState with networkidle to now wait for the
182
+ // lifecycle event from the browser.
183
+ //
184
+ // Success criteria: We want to quickly move to calling WaitForLoadState
185
+ // so that we block until a networkidle lifecycle
186
+ // event is received from the browser.
187
+
188
+ t .Parallel ()
189
+
190
+ tb := newTestBrowser (t , withFileServer ())
191
+ p := tb .NewPage (nil )
192
+ tb .withHandler ("/home" , func (w http.ResponseWriter , r * http.Request ) {
193
+ http .Redirect (w , r , tb .staticURL ("wait_for_nav_lifecycle.html" ), http .StatusMovedPermanently )
194
+ })
195
+
196
+ var counter int64
197
+ var counterMu sync.Mutex
198
+ tb .withHandler ("/ping" , func (w http.ResponseWriter , _ * http.Request ) {
199
+ counterMu .Lock ()
200
+ defer counterMu .Unlock ()
201
+
202
+ time .Sleep (time .Millisecond * 100 )
203
+
204
+ counter ++
205
+ fmt .Fprintf (w , "pong %d" , counter )
206
+ })
207
+
208
+ tb .withHandler ("/ping.js" , func (w http.ResponseWriter , _ * http.Request ) {
209
+ fmt .Fprintf (w , `
210
+ var pingJSTextOutput = document.getElementById("pingJSText");
211
+ pingJSTextOutput.innerText = "ping.js loaded from server";
212
+ ` )
213
+ })
214
+
215
+ assertHome (t , tb , p , common .LifecycleEventDOMContentLoad , func () {
216
+ p .WaitForLoadState (common .LifecycleEventNetworkIdle .String (), nil )
217
+
218
+ result := p .TextContent ("#pingRequestText" , nil )
219
+ assert .EqualValues (t , "Waiting... pong 10 - for loop complete" , result )
220
+
221
+ result = p .TextContent ("#pingJSText" , nil )
222
+ assert .EqualValues (t , "ping.js loaded from server" , result )
223
+ })
224
+ }
225
+
17
226
func TestLifecycleReloadLoad (t * testing.T ) {
18
227
t .Parallel ()
19
228
0 commit comments