Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

misc: convert server/lib/modes files to ts + add more cli options to Cloud terminal error outputs #31211

Merged
merged 6 commits into from
Mar 6, 2025
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
4 changes: 4 additions & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

_Released 3/11/2025 (PENDING)_

**Misc:**

- Additional CLI options will be displayed in the terminal for some Cloud error messages. Addressed in [#31211](https://github.com/cypress-io/cypress/pull/31211).

**Dependency Updates:**

- Upgraded `cli-table3` from `0.5.1` to `0.6.5`. Addressed in [#31166](https://github.com/cypress-io/cypress/pull/31166).
Expand Down
16 changes: 8 additions & 8 deletions packages/errors/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export const AllCypressErrors = {

https://on.cypress.io/stale-run`
},
CLOUD_ALREADY_COMPLETE: (props: {runUrl: string}) => {
CLOUD_ALREADY_COMPLETE: (props: {runUrl: string, tags: string, group: string, parallel: string, ciBuildId: string}) => {
return errTemplate`\
The run you are attempting to access is already complete and will not accept new groups.

Expand All @@ -257,7 +257,7 @@ export const AllCypressErrors = {

https://on.cypress.io/already-complete`
},
CLOUD_PARALLEL_REQUIRED: (arg1: {runUrl: string}) => {
CLOUD_PARALLEL_REQUIRED: (arg1: {tags: string, group: string, runUrl: string, ciBuildId: string }) => {
return errTemplate`\
You did not pass the ${fmt.flag(`--parallel`)} flag, but this run's group was originally created with the --parallel flag.

Expand All @@ -274,13 +274,14 @@ export const AllCypressErrors = {

https://on.cypress.io/parallel-required`
},
CLOUD_PARALLEL_DISALLOWED: (arg1: {runUrl: string}) => {
CLOUD_PARALLEL_DISALLOWED: (arg1: {tags: string, group: string, runUrl: string, ciBuildId: string}) => {
return errTemplate`\
You passed the ${fmt.flag(`--parallel`)} flag, but this run group was originally created without the --parallel flag.

The existing run is: ${fmt.url(arg1.runUrl)}

${fmt.listFlags(arg1, {
tags: '--tag',
group: '--group',
parallel: '--parallel',
ciBuildId: '--ciBuildId',
Expand All @@ -290,7 +291,7 @@ export const AllCypressErrors = {

https://on.cypress.io/parallel-disallowed`
},
CLOUD_PARALLEL_GROUP_PARAMS_MISMATCH: (arg1: {runUrl: string, parameters: any, payload: any }) => {
CLOUD_PARALLEL_GROUP_PARAMS_MISMATCH: (arg1: {group: string, runUrl: string, ciBuildId: string, parameters: any, payload: any }) => {
let params: any = arg1.parameters

if (arg1.payload?.differentParams) {
Expand Down Expand Up @@ -344,7 +345,7 @@ export const AllCypressErrors = {

https://on.cypress.io/parallel-group-params-mismatch`
},
CLOUD_RUN_GROUP_NAME_NOT_UNIQUE: (arg1: {runUrl: string, ciBuildId?: string | null}) => {
CLOUD_RUN_GROUP_NAME_NOT_UNIQUE: (arg1: {group: string, runUrl: string, ciBuildId?: string | null}) => {
return errTemplate`\
You passed the ${fmt.flag(`--group`)} flag, but this group name has already been used for this run.

Expand All @@ -370,7 +371,7 @@ export const AllCypressErrors = {

${fmt.off(arg1.link)}`
},
CLOUD_AUTO_CANCEL_MISMATCH: (arg1: {runUrl: string}) => {
CLOUD_AUTO_CANCEL_MISMATCH: (arg1: {runUrl: string, tags: string, group: string, parallel: string, ciBuildId: string, autoCancelAfterFailures: string }) => {
return errTemplate`\
You passed the ${fmt.flag(`--auto-cancel-after-failures`)} flag, but this run originally started with a different value for the ${fmt.flag(`--auto-cancel-after-failures`)} flag.

Expand Down Expand Up @@ -1397,7 +1398,6 @@ export const AllCypressErrors = {
https://on.cypress.io/test-retries
`
},
// TODO: test this
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a test for this!

INVALID_CONFIG_OPTION: (arg1: string[]) => {
const phrase = arg1.length > 1 ? 'options are' : 'option is'

Expand Down Expand Up @@ -1886,7 +1886,7 @@ export const AllCypressErrors = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _typeCheck: Record<keyof AllCypressErrorObj, (...args: any[]) => ErrTemplateResult> = AllCypressErrors

type AllCypressErrorObj = typeof AllCypressErrors
export type AllCypressErrorObj = typeof AllCypressErrors

export type AllCypressErrorNames = keyof typeof AllCypressErrors

Expand Down
12 changes: 12 additions & 0 deletions packages/server/__snapshots__/cypress_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ exports['RECORD_PARAMS_WITHOUT_RECORDING-ciBuildId 1'] = `
You passed the --ci-build-id, --group, --tag, --parallel, or --auto-cancel-after-failures flag without also passing the --record flag.

The --ci-build-id flag you passed was: ciBuildId123
The --parallel flag you passed was: undefined
The --auto-cancel-after-failures flag you passed was: undefined

These flags can only be used when recording to Cypress Cloud.

Expand All @@ -22,6 +24,8 @@ exports['RECORD_PARAMS_WITHOUT_RECORDING-group 1'] = `
You passed the --ci-build-id, --group, --tag, --parallel, or --auto-cancel-after-failures flag without also passing the --record flag.

The --group flag you passed was: e2e-tests
The --parallel flag you passed was: undefined
The --auto-cancel-after-failures flag you passed was: undefined

These flags can only be used when recording to Cypress Cloud.

Expand All @@ -32,6 +36,7 @@ exports['RECORD_PARAMS_WITHOUT_RECORDING-parallel 1'] = `
You passed the --ci-build-id, --group, --tag, --parallel, or --auto-cancel-after-failures flag without also passing the --record flag.

The --parallel flag you passed was: true
The --auto-cancel-after-failures flag you passed was: undefined

These flags can only be used when recording to Cypress Cloud.

Expand All @@ -43,6 +48,7 @@ You passed the --ci-build-id, --group, --tag, --parallel, or --auto-cancel-after

The --group flag you passed was: electron-smoke-tests
The --parallel flag you passed was: true
The --auto-cancel-after-failures flag you passed was: undefined

These flags can only be used when recording to Cypress Cloud.

Expand All @@ -53,6 +59,7 @@ exports['INDETERMINATE_CI_BUILD_ID-group 1'] = `
You passed the --group or --parallel flag but we could not automatically determine or generate a ciBuildId.

The --group flag you passed was: e2e-tests
The --parallel flag you passed was: undefined

In order to use either of these features a ciBuildId must be determined.

Expand Down Expand Up @@ -221,6 +228,7 @@ You passed the --parallel flag, but this run group was originally created withou

The existing run is: https://cloud.cypress.io/runs/12345

The --tag flag you passed was:
The --group flag you passed was: electron-smoke-tests
The --ciBuildId flag you passed was: ciBuildId123

Expand Down Expand Up @@ -275,6 +283,9 @@ https://on.cypress.io/stale-run
exports['RECORD_PARAMS_WITHOUT_RECORDING-tag 1'] = `
You passed the --ci-build-id, --group, --tag, --parallel, or --auto-cancel-after-failures flag without also passing the --record flag.

The --parallel flag you passed was: undefined
The --auto-cancel-after-failures flag you passed was: undefined

These flags can only be used when recording to Cypress Cloud.

https://on.cypress.io/record-params-without-recording
Expand Down Expand Up @@ -422,6 +433,7 @@ https://on.cypress.io/record-params-without-recording
exports['RECORD_PARAMS_WITHOUT_RECORDING-auto-cancel-after-failures 1'] = `
You passed the --ci-build-id, --group, --tag, --parallel, or --auto-cancel-after-failures flag without also passing the --record flag.

The --parallel flag you passed was: undefined
The --auto-cancel-after-failures flag you passed was: 4

These flags can only be used when recording to Cypress Cloud.
Expand Down
6 changes: 5 additions & 1 deletion packages/server/lib/cloud/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,10 @@ const isRetriableError = (err) => {

export type CreateRunOptions = {
projectRoot: string
ci: string
ci: {
params: string
provider: string
}
ciBuildId: string
projectId: string
recordKey: string
Expand All @@ -253,6 +256,7 @@ export type CreateRunOptions = {
testingType: 'e2e' | 'component'
timeout?: number
project: ProjectBase
autoCancelAfterFailures?: number | undefined
}

type CreateRunResponse = {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/lib/cloud/artifacts/upload_artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const toUploadReportPayload = (acc: {
type UploadArtifactOptions = {
protocolManager?: ProtocolManager
videoUploadUrl?: string
video?: string // filepath to the video artifact
video?: string | null // filepath to the video artifact
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw where we set this null in another file, so this is possible

screenshots?: {
screenshotId: string
path: string
Expand Down
56 changes: 30 additions & 26 deletions packages/server/lib/cypress.js → packages/server/lib/cypress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ require('./environment')
// essentially do it all again when we boot the correct
// mode.

const Promise = require('bluebird')
const debug = require('debug')('cypress:server:cypress')
const { getPublicConfigKeys } = require('@packages/config')
const argsUtils = require('./util/args')
const { telemetry } = require('@packages/telemetry')
const { getCtx, hasCtx } = require('@packages/data-context')

const warning = (code, args) => {
return require('./errors').warning(code, args)
}
import Promise from 'bluebird'
import Debug from 'debug'
import { getPublicConfigKeys } from '@packages/config'
import argsUtils from './util/args'
import { telemetry } from '@packages/telemetry'
import { getCtx, hasCtx } from '@packages/data-context'
import { warning as errorsWarning } from './errors'

const debug = Debug('cypress:server:cypress')

type Mode = 'exit' | 'info' | 'interactive' | 'pkg' | 'record' | 'results' | 'run' | 'smokeTest' | 'version' | 'returnPkg' | 'exitWithCode'
Copy link
Member Author

@jennifer-shehane jennifer-shehane Mar 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type may be more than is actually supported. It was hard to tell the definitive list by how this is called.


const exit = async (code = 0) => {
// TODO: we shouldn't have to do this
Expand All @@ -27,7 +28,7 @@ const exit = async (code = 0) => {
debug('about to exit with code', code)

if (hasCtx()) {
await getCtx().lifecycleManager.mainProcessWillDisconnect().catch((err) => {
await getCtx().lifecycleManager.mainProcessWillDisconnect().catch((err: any) => {
debug('mainProcessWillDisconnect errored with: ', err)
})
}
Expand All @@ -37,14 +38,14 @@ const exit = async (code = 0) => {
span?.setAttribute('exitCode', code)
span?.end()

await telemetry.shutdown().catch((err) => {
await telemetry.shutdown().catch((err: any) => {
debug('telemetry shutdown errored with: ', err)
})

return process.exit(code)
}

const showWarningForInvalidConfig = (options) => {
const showWarningForInvalidConfig = (options: any) => {
const publicConfigKeys = getPublicConfigKeys()
const invalidConfigOptions = require('lodash').keys(options.config).reduce((invalid, option) => {
if (!publicConfigKeys.find((configKey) => configKey === option)) {
Expand All @@ -55,15 +56,17 @@ const showWarningForInvalidConfig = (options) => {
}, [])

if (invalidConfigOptions.length && options.invokedFromCli) {
return warning('INVALID_CONFIG_OPTION', invalidConfigOptions)
return errorsWarning('INVALID_CONFIG_OPTION', invalidConfigOptions)
}

return undefined
}

const exit0 = () => {
return exit(0)
}

const exitErr = (err) => {
const exitErr = (err: any) => {
// log errors to the console
// and potentially raygun
// and exit with 1
Expand All @@ -77,12 +80,12 @@ const exitErr = (err) => {
})
}

module.exports = {
export = {
isCurrentlyRunningElectron () {
return require('./util/electron-app').isRunning()
},

runElectron (mode, options) {
runElectron (mode: Mode, options: any) {
// wrap all of this in a promise to force the
// promise interface - even if it doesn't matter
// in dev mode due to cp.spawn
Expand All @@ -95,7 +98,7 @@ module.exports = {
// if we weren't invoked from the CLI
// then display a warning to the user
if (!options.invokedFromCli) {
warning('INVOKED_BINARY_OUTSIDE_NPM_MODULE')
errorsWarning('INVOKED_BINARY_OUTSIDE_NPM_MODULE')
}

debug('running Electron currently')
Expand All @@ -107,7 +110,7 @@ module.exports = {
debug('starting Electron')
const cypressElectron = require('@packages/electron')

const fn = (code) => {
const fn = (code: number) => {
// juggle up the totalFailed since our outer
// promise is expecting this object structure
debug('electron finished with', code)
Expand All @@ -131,7 +134,7 @@ module.exports = {
})
},

start (argv = []) {
start (argv: any = []) {
debug('starting cypress with argv %o', argv)

// if the CLI passed "--" somewhere, we need to remove it
Expand All @@ -144,7 +147,7 @@ module.exports = {
options = argsUtils.toObject(argv)

showWarningForInvalidConfig(options)
} catch (argumentsError) {
} catch (argumentsError: any) {
debug('could not parse CLI arguments: %o', argv)

// note - this is promise-returned call
Expand All @@ -153,6 +156,7 @@ module.exports = {

debug('from argv %o got options %o', argv, options)

// @ts-expect-error TODO: Fix type that says attachRecordKey is not a function
telemetry.exporter()?.attachRecordKey(options.key)

if (options.headless) {
Expand Down Expand Up @@ -202,14 +206,14 @@ module.exports = {
})
},

startInMode (mode, options) {
startInMode (mode: Mode, options: any) {
debug('starting in mode %s with options %o', mode, options)

switch (mode) {
case 'version':
return require('./modes/pkg')(options)
.get('version')
.then((version) => {
.then((version: any) => {
return console.log(version) // eslint-disable-line no-console
}).then(exit0)
.catch(exitErr)
Expand All @@ -221,7 +225,7 @@ module.exports = {

case 'smokeTest':
return this.runElectron(mode, options)
.then((pong) => {
.then((pong: any) => {
if (!this.isCurrentlyRunningElectron()) {
return pong
}
Expand All @@ -236,7 +240,7 @@ module.exports = {

case 'returnPkg':
return require('./modes/pkg')(options)
.then((pkg) => {
.then((pkg: any) => {
return console.log(JSON.stringify(pkg)) // eslint-disable-line no-console
}).then(exit0)
.catch(exitErr)
Expand All @@ -250,7 +254,7 @@ module.exports = {
// run headlessly and exit
// with num of totalFailed
return this.runElectron(mode, options)
.then((results) => {
.then((results: any) => {
if (results.runs) {
const isCanceled = results.runs.filter((run) => run.skippedSpec).length

Expand Down
8 changes: 0 additions & 8 deletions packages/server/lib/modes/exit.js

This file was deleted.

8 changes: 8 additions & 0 deletions packages/server/lib/modes/exit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { toNumber } from 'lodash'
import Promise from 'bluebird'

export = (options) => {
return Promise.try(() => {
return toNumber(options.exitWithCode)
})
}
Loading
Loading