Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions cli/.mocharc.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
module.exports = {
// hardcoding the spec file names as they will be converted 1 by 1 to vitest
spec: [
'test/lib/exec/info.spec.ts',
'test/lib/exec/open.spec.ts',
'test/lib/exec/run.spec.ts',
'test/lib/exec/spawn.spec.ts',
'test/lib/exec/versions.spec.ts',
'test/lib/exec/xvfb.spec.ts',
'test/lib/tasks/cache.spec.ts',
'test/lib/tasks/dependency.spec.ts',
'test/lib/tasks/download.spec.ts',
Expand Down
27 changes: 0 additions & 27 deletions cli/__snapshots__/run.spec.ts.js

This file was deleted.

35 changes: 0 additions & 35 deletions cli/__snapshots__/spawn.spec.ts.js

This file was deleted.

7 changes: 4 additions & 3 deletions cli/lib/exec/open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const processOpenOptions = (options: any = {}): string[] => {
return args
}

export const start = (options: any = {}): any => {
export const start = async (options: any = {}): Promise<any> => {
function open (): any {
try {
const args = processOpenOptions(options)
Expand All @@ -96,8 +96,9 @@ export const start = (options: any = {}): any => {
return open()
}

return verifyModule.start()
.then(open)
await verifyModule.start()

return open()
}

export default {
Expand Down
7 changes: 4 additions & 3 deletions cli/lib/exec/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const runModule = {
processRunOptions,
isValidProject,
// resolves with the number of failed tests
start (options: any = {}): any {
async start (options: any = {}): Promise<any> {
_.defaults(options, {
key: null,
spec: null,
Expand Down Expand Up @@ -195,8 +195,9 @@ const runModule = {
return run()
}

return verifyModule.start()
.then(run)
await verifyModule.start()

return run()
},
}

Expand Down
60 changes: 38 additions & 22 deletions cli/lib/exec/spawn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import xvfb from './xvfb'
import verifyModule from '../tasks/verify'
import { throwFormErrorText, getError, errors } from '../errors'
import readline from 'readline'
import { stdin, stdout, stderr } from 'process'

const debug = Debug('cypress:cli')

Expand Down Expand Up @@ -50,7 +51,7 @@ function getStdio (needsXvfb: boolean): any {
}

const spawnModule = {
start (args: any, options: any = {}): any {
async start (args: any, options: any = {}): Promise<any> {
const needsXvfb = xvfb.isNeeded()
let executable = state.getPathToExecutable(state.getBinaryDir())

Expand Down Expand Up @@ -149,13 +150,15 @@ const spawnModule = {
const child = cp.spawn(executable, args, stdioOptions)

function resolveOn (event: any): any {
return function (code: any, signal: any): any {
return async function (code: any, signal: any): Promise<any> {
debug('child event fired %o', { event, code, signal })

if (code === null) {
const errorObject = errors.childProcessKilled(event, signal)

return getError(errorObject).then(reject)
const err = await getError(errorObject)

return reject(err)
}

resolve(code)
Expand All @@ -168,8 +171,8 @@ const spawnModule = {

if (isPlatform('win32')) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
input: stdin,
output: stdout,
})

// on windows, SIGINT does not propagate to the child process when ctrl+c is pressed
Expand All @@ -188,12 +191,12 @@ const spawnModule = {
// child STDERR => process STDERR with additional filtering
if (child.stdin) {
debug('piping process STDIN into child STDIN')
process.stdin.pipe(child.stdin)
stdin.pipe(child.stdin)
}

if (child.stdout) {
debug('piping child STDOUT to process STDOUT')
child.stdout.pipe(process.stdout)
child.stdout.pipe(stdout)
}

// if this is defined then we are manually piping for linux
Expand All @@ -210,7 +213,7 @@ const spawnModule = {
}

// else pass it along!
process.stderr.write(data)
stderr.write(data)
})
}

Expand All @@ -221,7 +224,7 @@ const spawnModule = {
// into the child process. unpiping does not seem
// to have any effect. so we're just catching the
// error here and not doing anything.
process.stdin.on('error', (err: any) => {
stdin.on('error', (err: any) => {
if (['EPIPE', 'ENOTCONN'].includes(err.code)) {
return
}
Expand All @@ -235,17 +238,22 @@ const spawnModule = {
})
}

const spawnInXvfb = (): any => {
return xvfb
.start()
.then(userFriendlySpawn)
.finally(xvfb.stop)
const spawnInXvfb = async (): Promise<number> => {
try {
await xvfb.start()

const code = await userFriendlySpawn()

return code
} finally {
await xvfb.stop()
}
}

const userFriendlySpawn = (linuxWithDisplayEnv: any): any => {
const userFriendlySpawn = async (linuxWithDisplayEnv?: any): Promise<any> => {
debug('spawning, should retry on display problem?', Boolean(linuxWithDisplayEnv))

let brokenGtkDisplay: boolean
let brokenGtkDisplay: boolean = false

const overrides: any = {}

Expand All @@ -262,19 +270,27 @@ const spawnModule = {
})
}

return spawn(overrides)
.then((code: any) => {
try {
const code: number = await spawn(overrides)

if (code !== 0 && brokenGtkDisplay) {
util.logBrokenGtkDisplayWarning()

return spawnInXvfb()
}

return code
})
// we can format and handle an error message from the code above
// prevent wrapping error again by using "known: undefined" filter
.catch({ known: undefined }, throwFormErrorText(errors.unexpected))
} catch (error: any) {
// we can format and handle an error message from the code above
// prevent wrapping error again by using "known: undefined" filter
if ((error as any).known === undefined) {
const raiseErrorFn = throwFormErrorText(errors.unexpected)

await raiseErrorFn(error.message)
}

throw error
}
}

if (needsXvfb) {
Expand Down
86 changes: 44 additions & 42 deletions cli/lib/exec/versions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Bluebird from 'bluebird'
import Debug from 'debug'
import path from 'path'
import util from '../util'
Expand All @@ -7,59 +6,62 @@ import { throwFormErrorText, errors } from '../errors'

const debug = Debug('cypress:cli')

const getVersions = (): any => {
return Bluebird.try(() => {
if (util.getEnv('CYPRESS_RUN_BINARY')) {
let envBinaryPath = path.resolve(util.getEnv('CYPRESS_RUN_BINARY') as string)
const getBinaryDirectory = async (): Promise<string> => {
if (util.getEnv('CYPRESS_RUN_BINARY')) {
let envBinaryPath = path.resolve(util.getEnv('CYPRESS_RUN_BINARY') as string)

return state.parseRealPlatformBinaryFolderAsync(envBinaryPath)
.then((envBinaryDir: any) => {
if (!envBinaryDir) {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))()
}
try {
const envBinaryDir = await state.parseRealPlatformBinaryFolderAsync(envBinaryPath)

debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir)
if (!envBinaryDir) {
const raiseErrorFn = throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))

return envBinaryDir
})
.catch({ code: 'ENOENT' }, (err: any) => {
return throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))(err.message)
})
}
await raiseErrorFn()
}

debug('CYPRESS_RUN_BINARY has binaryDir:', envBinaryDir)

return envBinaryDir
} catch (err: any) {
const raiseErrorFn = throwFormErrorText(errors.CYPRESS_RUN_BINARY.notValid(envBinaryPath))

return state.getBinaryDir()
})
.then(state.getBinaryPkgAsync)
.then((pkg: any) => {
const versions = {
binary: state.getBinaryPkgVersion(pkg),
electronVersion: state.getBinaryElectronVersion(pkg),
electronNodeVersion: state.getBinaryElectronNodeVersion(pkg),
await raiseErrorFn(err.message)
}
}

debug('binary versions %o', versions)
return state.getBinaryDir()
}

return versions
})
.then((binaryVersions: any) => {
const buildInfo = util.pkgBuildInfo()
const getVersions = async (): Promise<any> => {
const binDir = await getBinaryDirectory()

let packageVersion = util.pkgVersion()
const pkg = await state.getBinaryPkgAsync(binDir)

if (!buildInfo) packageVersion += ' (development)'
else if (!buildInfo.stable) packageVersion += ' (pre-release)'
const versions = {
binary: state.getBinaryPkgVersion(pkg),
electronVersion: state.getBinaryElectronVersion(pkg),
electronNodeVersion: state.getBinaryElectronNodeVersion(pkg),
}

const versions = {
package: packageVersion,
binary: binaryVersions.binary || 'not installed',
electronVersion: binaryVersions.electronVersion || 'not found',
electronNodeVersion: binaryVersions.electronNodeVersion || 'not found',
}
debug('binary versions %o', versions)

const buildInfo = util.pkgBuildInfo()

let packageVersion = util.pkgVersion()

if (!buildInfo) packageVersion += ' (development)'
else if (!buildInfo.stable) packageVersion += ' (pre-release)'

const versionsFinal = {
package: packageVersion,
binary: versions.binary || 'not installed',
electronVersion: versions.electronVersion || 'not found',
electronNodeVersion: versions.electronNodeVersion || 'not found',
}

debug('combined versions %o', versions)
debug('combined versions %o', versions)

return versions
})
return versionsFinal
}

const versionsModule = {
Expand Down
Loading