@@ -4,36 +4,45 @@ import { waitForRoute } from '../net-stubbing/wait-for-route'
4
4
import { isDynamicAliasingPossible } from '../net-stubbing/aliasing'
5
5
import ordinal from 'ordinal'
6
6
7
- import $errUtils from '../../cypress/error_utils'
7
+ import $errUtils , { type CypressError , type InternalCypressError } from '../../cypress/error_utils'
8
+ import type { $Cy } from '../../cypress/cy'
9
+ import type { StateFunc } from '../../cypress/state'
10
+ import type { Log } from '../../cypress/log'
11
+
12
+ type waitOptions = {
13
+ _log ?: Cypress . Log
14
+ _runnableTimeout ?: number
15
+ error ?: CypressError | InternalCypressError
16
+ isCrossOriginSpecBridge ?: boolean
17
+ log : boolean
18
+ requestTimeout ?: number
19
+ responseTimeout ?: number
20
+ timeout : number
21
+ type ?: 'request' | 'response'
22
+ }
8
23
9
- const getNumRequests = ( state , alias ) => {
10
- const requests = state ( 'aliasRequests' ) || { }
24
+ const getNumRequests = ( state : StateFunc , alias : string ) => {
25
+ const requests = state ( 'aliasRequests' ) ?? { }
11
26
12
- requests [ alias ] = requests [ alias ] || 0
27
+ requests [ alias ] = requests [ alias ] ?? 0
13
28
14
29
const index = requests [ alias ]
15
30
16
31
requests [ alias ] += 1
17
32
18
33
state ( 'aliasRequests' , requests )
19
34
20
- return [ index , ordinal ( requests [ alias ] ) ]
35
+ return [ index , ordinal ( requests [ alias ] ) ] as const
21
36
}
22
37
23
- const throwErr = ( arg ) => {
38
+ const throwErr = ( arg : string ) => {
24
39
$errUtils . throwErrByPath ( 'wait.invalid_1st_arg' , { args : { arg } } )
25
40
}
26
41
27
- type Alias = {
28
- name : string
29
- cardinal : number
30
- ordinal : number
31
- }
32
-
33
- export default ( Commands , Cypress , cy , state ) => {
34
- const waitNumber = ( subject , ms , options ) => {
42
+ export default ( Commands : Cypress . Commands , Cypress : Cypress . Cypress , cy : $Cy , state : StateFunc ) => {
43
+ const waitNumber = ( subject : unknown , ms : number , options : waitOptions ) => {
35
44
// increase the timeout by the delta
36
- cy . timeout ( ms , true , 'wait' )
45
+ cy . timeout ( ms , true )
37
46
38
47
options . _log = Cypress . log ( {
39
48
hidden : options . log === false ,
@@ -51,7 +60,7 @@ export default (Commands, Cypress, cy, state) => {
51
60
. return ( subject )
52
61
}
53
62
54
- const waitString = ( subject , str , options ) => {
63
+ const waitString = async ( str : string | string [ ] , options : waitOptions ) => {
55
64
// if this came from the spec bridge, we need to set a few additional properties to ensure the log displays correctly
56
65
// otherwise, these props will be pulled from the current command which will be cy.origin on the primary
57
66
const log = options . _log = Cypress . log ( {
@@ -69,7 +78,13 @@ export default (Commands, Cypress, cy, state) => {
69
78
} )
70
79
}
71
80
72
- const checkForXhr = async function ( alias , type , index , num , options ) {
81
+ const checkForXhr = async function (
82
+ alias : string ,
83
+ type : 'request' | 'response' ,
84
+ index : number ,
85
+ num : string ,
86
+ options : waitOptions ,
87
+ ) {
73
88
options . error = $errUtils . errByPath ( 'wait.timed_out' , {
74
89
timeout : options . timeout ,
75
90
alias,
@@ -98,15 +113,16 @@ export default (Commands, Cypress, cy, state) => {
98
113
return xhr
99
114
}
100
115
101
- const args : [ any , any , any , any , any ] = [ alias , type , index , num , options ]
102
-
103
116
return cy . retry ( ( ) => {
104
- return checkForXhr . apply ( window , args )
105
- } , options )
117
+ return checkForXhr . apply ( window , [ alias , type , index , num , options ] )
118
+ } ,
119
+ // TODO: What should `_log`'s type be?
120
+ // @ts -expect-error - Incompatible types.
121
+ options )
106
122
}
107
123
108
- const waitForXhr = function ( str , options ) {
109
- let specifier
124
+ const waitForXhr = async function ( str : string , options : Omit < waitOptions , 'error' > ) {
125
+ let specifier : string | null | undefined
110
126
111
127
// we always want to strip everything after the last '.'
112
128
// since we support alias property 'request'
@@ -126,7 +142,7 @@ export default (Commands, Cypress, cy, state) => {
126
142
}
127
143
}
128
144
129
- let aliasObj
145
+ let aliasObj : { alias : string , command ?: unknown }
130
146
131
147
try {
132
148
aliasObj = cy . getAlias ( str , 'wait' , log )
@@ -161,8 +177,8 @@ export default (Commands, Cypress, cy, state) => {
161
177
// build up an array of referencesAlias
162
178
// because wait can reference an array of aliases
163
179
if ( log ) {
164
- const referencesAlias = log . get ( 'referencesAlias' ) || [ ]
165
- const aliases : Array < Alias > = [ ] . concat ( referencesAlias )
180
+ const referencesAlias = log . get ( 'referencesAlias' ) ?? [ ]
181
+ const aliases = [ ... referencesAlias ]
166
182
167
183
if ( str ) {
168
184
aliases . push ( {
@@ -182,13 +198,13 @@ export default (Commands, Cypress, cy, state) => {
182
198
return commandsThatCreateNetworkIntercepts . includes ( commandName )
183
199
}
184
200
185
- const findInterceptAlias = ( alias ) => {
186
- const routes = cy . state ( 'routes' ) || { }
201
+ const findInterceptAlias = ( alias : string ) => {
202
+ const routes = cy . state ( 'routes' ) ?? { }
187
203
188
204
return _ . find ( _ . values ( routes ) , { alias } )
189
205
}
190
206
191
- const isInterceptAlias = ( alias ) => Boolean ( findInterceptAlias ( alias ) )
207
+ const isInterceptAlias = ( alias : string ) => Boolean ( findInterceptAlias ( alias ) )
192
208
193
209
if ( command && ! isNetworkInterceptCommand ( command ) ) {
194
210
if ( ! isInterceptAlias ( alias ) ) {
@@ -203,11 +219,15 @@ export default (Commands, Cypress, cy, state) => {
203
219
// but slice out the error since we may set
204
220
// the error related to a previous xhr
205
221
const { timeout } = options
222
+ // TODO: If `options.requestTimeout` and `options.responseTimeout` are
223
+ // `0`, is this code going to work the way it was intended to?
206
224
const requestTimeout = options . requestTimeout || timeout
207
225
const responseTimeout = options . responseTimeout || timeout
208
226
209
227
const waitForRequest = ( ) => {
210
228
options = _ . omit ( options , '_runnableTimeout' )
229
+ // TODO: If `requestTimeout` is `0`, is this code going to work the way
230
+ // it was intended to?
211
231
options . timeout = requestTimeout || Cypress . config ( 'requestTimeout' )
212
232
213
233
if ( log ) {
@@ -219,6 +239,8 @@ export default (Commands, Cypress, cy, state) => {
219
239
220
240
const waitForResponse = ( ) => {
221
241
options = _ . omit ( options , '_runnableTimeout' )
242
+ // TODO: If `responseTimeout` is `0`, is this code going to work the way
243
+ // it was intended to?
222
244
options . timeout = responseTimeout || Cypress . config ( 'responseTimeout' )
223
245
224
246
if ( log ) {
@@ -237,8 +259,7 @@ export default (Commands, Cypress, cy, state) => {
237
259
return waitForRequest ( ) . then ( waitForResponse )
238
260
}
239
261
240
- return Promise
241
- . map ( [ ] . concat ( str ) , ( str ) => {
262
+ return Promise . map ( ( [ ] as string [ ] ) . concat ( str ) , ( str ) => {
242
263
// we may get back an xhr value instead
243
264
// of a promise, so we have to wrap this
244
265
// in another promise :-(
@@ -285,26 +306,32 @@ export default (Commands, Cypress, cy, state) => {
285
306
} )
286
307
}
287
308
288
- Cypress . primaryOriginCommunicator . on ( 'wait:for:xhr' , ( { args : [ str , options ] } , { origin } ) => {
289
- options . isCrossOriginSpecBridge = true
290
- waitString ( null , str , options ) . then ( ( responses ) => {
291
- Cypress . primaryOriginCommunicator . toSpecBridge ( origin , 'wait:for:xhr:end' , responses )
292
- } ) . catch ( ( err ) => {
293
- options . _log ?. error ( err )
294
- err . hasSpecBridgeError = true
295
- Cypress . primaryOriginCommunicator . toSpecBridge ( origin , 'wait:for:xhr:end' , err )
296
- } )
297
- } )
309
+ Cypress . primaryOriginCommunicator . on (
310
+ 'wait:for:xhr' ,
311
+ (
312
+ { args : [ str , options ] } : { args : [ string | string [ ] , waitOptions ] } ,
313
+ { origin } ,
314
+ ) => {
315
+ options . isCrossOriginSpecBridge = true
316
+ waitString ( str , options ) . then ( ( responses ) => {
317
+ Cypress . primaryOriginCommunicator . toSpecBridge ( origin , 'wait:for:xhr:end' , responses )
318
+ } ) . catch ( ( err ) => {
319
+ options . _log ?. error ( err )
320
+ err . hasSpecBridgeError = true
321
+ Cypress . primaryOriginCommunicator . toSpecBridge ( origin , 'wait:for:xhr:end' , err )
322
+ } )
323
+ } ,
324
+ )
298
325
299
- const delegateToPrimaryOrigin = ( [ _subject , str , options ] ) => {
326
+ const delegateToPrimaryOrigin = ( str : string | string [ ] , options : waitOptions ) => {
300
327
return new Promise ( ( resolve , reject ) => {
301
328
Cypress . specBridgeCommunicator . once ( 'wait:for:xhr:end' , ( responsesOrErr ) => {
302
329
// determine if this is an error by checking if there is a spec bridge error
303
330
if ( responsesOrErr . hasSpecBridgeError ) {
304
331
delete responsesOrErr . hasSpecBridgeError
305
332
if ( options . log ) {
306
333
// skip this 'wait' log since it was already added through the primary
307
- Cypress . state ( 'onBeforeLog' , ( log ) => {
334
+ Cypress . state ( 'onBeforeLog' , ( log : Log ) => {
308
335
if ( log . get ( 'name' ) === 'wait' ) {
309
336
// unbind this function so we don't impact any other logs
310
337
cy . state ( 'onBeforeLog' , null )
@@ -328,7 +355,7 @@ export default (Commands, Cypress, cy, state) => {
328
355
}
329
356
330
357
Commands . addAll ( { prevSubject : 'optional' } , {
331
- wait ( subject , msOrAlias , options : { log ?: boolean } = { } ) {
358
+ wait ( subject : unknown , msOrAlias : number | string | string [ ] , options : waitOptions ) {
332
359
// check to ensure options is an object
333
360
// if its a string the user most likely is trying
334
361
// to wait on multiple aliases and forget to make this
@@ -342,19 +369,18 @@ export default (Commands, Cypress, cy, state) => {
342
369
}
343
370
344
371
options = _ . defaults ( { } , options , { log : true } )
345
- const args : any = [ subject , msOrAlias , options ]
346
372
347
373
try {
348
- if ( _ . isFinite ( msOrAlias ) ) {
349
- return waitNumber . apply ( window , args )
374
+ if ( typeof msOrAlias === 'number' && _ . isFinite ( msOrAlias ) ) {
375
+ return waitNumber . apply ( window , [ subject , msOrAlias , options ] )
350
376
}
351
377
352
378
if ( _ . isString ( msOrAlias ) || ( _ . isArray ( msOrAlias ) && ! _ . isEmpty ( msOrAlias ) ) ) {
353
379
if ( Cypress . isCrossOriginSpecBridge ) {
354
- return delegateToPrimaryOrigin ( args )
380
+ return delegateToPrimaryOrigin ( msOrAlias , options )
355
381
}
356
382
357
- return waitString . apply ( window , args )
383
+ return waitString . apply ( window , [ msOrAlias , options ] )
358
384
}
359
385
360
386
// figure out why this error failed
@@ -370,7 +396,7 @@ export default (Commands, Cypress, cy, state) => {
370
396
throwErr ( msOrAlias . toString ( ) )
371
397
}
372
398
373
- let arg
399
+ let arg : string
374
400
375
401
try {
376
402
arg = JSON . stringify ( msOrAlias )
@@ -379,7 +405,7 @@ export default (Commands, Cypress, cy, state) => {
379
405
}
380
406
381
407
return throwErr ( arg )
382
- } catch ( err : any ) {
408
+ } catch ( err ) {
383
409
if ( err . name === 'CypressError' ) {
384
410
throw err
385
411
} else {
0 commit comments