forked from cypress-io/cypress
/
exec.ts
96 lines (79 loc) · 2.52 KB
/
exec.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
import _ from 'lodash'
import Promise from 'bluebird'
import $errUtils from '../../cypress/error_utils'
import type { Log } from '../../cypress/log'
interface InternalExecOptions extends Partial<Cypress.ExecOptions> {
_log?: Log
cmd?: string
}
export default (Commands, Cypress, cy) => {
Commands.addAll({
exec (cmd: string, userOptions: Partial<Cypress.ExecOptions> = {}) {
const options: InternalExecOptions = _.defaults({}, userOptions, {
log: true,
timeout: Cypress.config('execTimeout'),
failOnNonZeroExit: true,
env: {},
})
let consoleOutput
if (options.log) {
consoleOutput = {}
options._log = Cypress.log({
message: _.truncate(cmd, { length: 25 }),
timeout: options.timeout,
consoleProps () {
return consoleOutput
},
})
}
if (!cmd || !_.isString(cmd)) {
$errUtils.throwErrByPath('exec.invalid_argument', {
onFail: options._log,
args: { cmd: cmd ?? '' },
})
}
options.cmd = cmd
// need to remove the current timeout
// because we're handling timeouts ourselves
cy.clearTimeout()
return Cypress.backend('exec', _.pick(options, 'cmd', 'timeout', 'env'))
.timeout(options.timeout)
.then((result) => {
if (options._log) {
_.extend(consoleOutput, { Yielded: _.omit(result, 'shell') })
consoleOutput['Shell Used'] = result.shell
}
if ((result.code === 0) || !options.failOnNonZeroExit) {
return result
}
let output = ''
if (result.stdout) {
output += `\nStdout:\n${_.truncate(result.stdout, { length: 200 })}`
}
if (result.stderr) {
output += `\nStderr:\n${_.truncate(result.stderr, { length: 200 })}`
}
return $errUtils.throwErrByPath('exec.non_zero_exit', {
onFail: options._log,
args: { cmd, output, code: result.code },
})
})
.catch(Promise.TimeoutError, { timedOut: true }, () => {
return $errUtils.throwErrByPath('exec.timed_out', {
onFail: options._log,
args: { cmd, timeout: options.timeout },
})
})
.catch((error) => {
// re-throw if timedOut error from above
if (error.name === 'CypressError') {
throw error
}
return $errUtils.throwErrByPath('exec.failed', {
onFail: options._log,
args: { cmd, error },
})
})
},
})
}