forked from cypress-io/cypress
/
debugging.ts
141 lines (108 loc) · 3.46 KB
/
debugging.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import _ from 'lodash'
import $utils from '../../cypress/utils'
import type { Log } from '../../cypress/log'
const resume = (state, resumeAll = true) => {
const onResume = state('onResume')
// dont do anything if this isnt a fn
if (!_.isFunction(onResume)) {
return
}
// nuke this out so it can only
// be called a maximum of 1 time
state('onResume', null)
// call the fn
return onResume(resumeAll)
}
const getNextQueuedCommand = (state, queue) => {
const search = (i) => {
const cmd = queue.at(i)
if (cmd && cmd.get('skip')) {
return search(i + 1)
}
return cmd
}
return search(state('index'))
}
interface InternalPauseOptions extends Partial<Cypress.Loggable> {
_log?: Log
}
interface InternalDebugOptions extends Partial<Cypress.Loggable> {
_log?: Log
}
export default (Commands, Cypress, cy, state, config) => {
Cypress.on('resume:next', () => {
return resume(state, false)
})
Cypress.on('resume:all', () => {
return resume(state)
})
Commands.addAll({ type: 'utility', prevSubject: 'optional' }, {
// pause should indefinitely pause until the user
// presses a key or clicks in the UI to continue
pause (subject, userOptions: Partial<Cypress.Loggable> = {}) {
// bail if we're in run mode, unless --headed and --no-exit flags are passed
if (!config('isInteractive') && (!config('browser').isHeaded || config('exit'))) {
return subject
}
const options: InternalPauseOptions = _.defaults({}, userOptions, { log: true })
if (options.log) {
options._log = Cypress.log({
snapshot: true,
autoEnd: false,
timeout: 0,
})
}
const onResume = (fn, timeout) => {
return state('onResume', (resumeAll) => {
if (resumeAll) {
// nuke onPause only if
// we've been told to resume
// all the commands, else
// pause on the very next one
state('onPaused', null)
if (options.log) {
options._log!.end()
}
}
// restore timeout
cy.timeout(timeout)
// invoke callback fn
return fn()
})
}
state('onPaused', (fn) => {
const next = getNextQueuedCommand(state, cy.queue)
// backup the current timeout
const timeout = cy.timeout()
// clear out the current timeout
cy.clearTimeout()
// set onResume function
onResume(fn, timeout)
Cypress.action('cy:paused', next && next.get('name'))
})
return subject
},
debug (subject, userOptions: Partial<Cypress.Loggable> = {}) {
const options: InternalDebugOptions = _.defaults({}, userOptions, {
log: true,
})
if (options.log) {
options._log = Cypress.log({
snapshot: true,
end: true,
timeout: 0,
})
}
const previous = state('current').get('prev')
$utils.log('\n%c------------------------ Debug Info ------------------------', 'font-weight: bold;')
$utils.log('Command Name: ', previous && previous.get('name'))
$utils.log('Command Args: ', previous && previous.get('args'))
$utils.log('Current Subject: ', subject)
////// HOVER OVER TO INSPECT THE CURRENT SUBJECT //////
subject
///////////////////////////////////////////////////////
debugger // eslint-disable-line no-debugger
return subject
},
})
}