From 6b97d7e085f9ecd099453e35877996c863614f61 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Tue, 7 Nov 2023 14:06:29 -0800 Subject: [PATCH] chore: wip --- packages/cypress-cloud/bin/lib/program.ts | 27 ++++++++++++++++--- packages/cypress-cloud/lib/api/types/run.ts | 7 ++++- .../cypress-cloud/lib/bootstrap/serializer.ts | 2 +- packages/cypress-cloud/lib/run.ts | 2 ++ packages/cypress-cloud/types.ts | 9 +++++++ 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/packages/cypress-cloud/bin/lib/program.ts b/packages/cypress-cloud/bin/lib/program.ts index 0d976bc6..a456694c 100644 --- a/packages/cypress-cloud/bin/lib/program.ts +++ b/packages/cypress-cloud/bin/lib/program.ts @@ -2,6 +2,7 @@ // keep the local copy to prevent from importing // commander.js from the global node_modules import { getLegalNotice } from "../../legal"; +import { ValidationError } from "../../lib/errors"; import { DebugMode } from "../../types"; import { Command, Option } from "./@commander-js/extra-typings"; @@ -124,15 +125,33 @@ ${getLegalNotice()} ) .addOption( new Option( - `--experimental-coverage-recording [bool]`, + `--experimental-coverage-recording`, `Enable recording coverage results, specify the "coverageFile" Cypress environment variable for a custom coverage file, default is "./.nyc_output/out.json"` + ).default(false) + ) + .addOption( + new Option( + `--cloud-timeout-mode `, + `Enable ci runner to pass/fail but no error even if the run timed out` ) - .default(undefined) - .argParser((i) => (i === "false" ? false : true)) + .default("hard") + .argParser(parseTimeoutMode) ); export const program = createProgram(); +function parseTimeoutMode(value: string) { + const validValues = ["soft", "hard"]; + if (validValues.includes(value)) { + return value; + } + throw new ValidationError( + `Invalid argument --cloud-timeout-mode provided. Must be one of ${validValues.join( + ", " + )}` + ); +} + function parseCommaSeparatedList(value: string, previous: string[] = []) { if (value) { return previous.concat(value.split(",").map((t) => t.trim())); @@ -148,7 +167,7 @@ function parseAutoCancelFailures(value: string): number | false { const parsedValue = parseInt(value, 10); if (isNaN(parsedValue) || parsedValue < 1) { - throw new Error( + throw new ValidationError( "Invalid argument provided. Must be a positive integer or 'false'." ); } diff --git a/packages/cypress-cloud/lib/api/types/run.ts b/packages/cypress-cloud/lib/api/types/run.ts index 57b54e73..9fad749d 100644 --- a/packages/cypress-cloud/lib/api/types/run.ts +++ b/packages/cypress-cloud/lib/api/types/run.ts @@ -1,5 +1,9 @@ import { CiParams, CiProvider } from "cypress-cloud/lib/ciProvider"; -import { Platform, ValidatedCurrentsParameters } from "cypress-cloud/types"; +import { + Platform, + TimeoutMode, + ValidatedCurrentsParameters, +} from "cypress-cloud/types"; export type CreateRunPayload = { ci: { @@ -23,6 +27,7 @@ export type CreateRunPayload = { batchSize?: number; autoCancelAfterFailures: ValidatedCurrentsParameters["autoCancelAfterFailures"]; coverageEnabled?: boolean; + timeoutMode?: TimeoutMode; }; export type CloudWarning = { diff --git a/packages/cypress-cloud/lib/bootstrap/serializer.ts b/packages/cypress-cloud/lib/bootstrap/serializer.ts index 20cb9d55..341f8034 100644 --- a/packages/cypress-cloud/lib/bootstrap/serializer.ts +++ b/packages/cypress-cloud/lib/bootstrap/serializer.ts @@ -67,7 +67,7 @@ function getCypressCLIParams( } : {}; return { - ..._.omit(result, "testingType"), + ..._.omit(result, "testingType", "cloudTimeoutMode"), ...testingType, }; } diff --git a/packages/cypress-cloud/lib/run.ts b/packages/cypress-cloud/lib/run.ts index 1610f160..4f04ddd4 100644 --- a/packages/cypress-cloud/lib/run.ts +++ b/packages/cypress-cloud/lib/run.ts @@ -66,6 +66,7 @@ export async function run(params: CurrentsRunParameters = {}) { batchSize, autoCancelAfterFailures, experimentalCoverageRecording, + cloudTimeoutMode, } = validatedParams; const config = await getMergedConfig(validatedParams); @@ -109,6 +110,7 @@ export async function run(params: CurrentsRunParameters = {}) { batchSize, autoCancelAfterFailures, coverageEnabled: experimentalCoverageRecording, + timeoutMode: cloudTimeoutMode, }); setRunId(run.runId); diff --git a/packages/cypress-cloud/types.ts b/packages/cypress-cloud/types.ts index 8c0dfd35..d7489dd3 100644 --- a/packages/cypress-cloud/types.ts +++ b/packages/cypress-cloud/types.ts @@ -99,6 +99,8 @@ export enum DebugMode { CommitInfo = "commit-info", } +export type TimeoutMode = "hard" | "soft"; + // Explicitly filter cypress record-related flags - prevent triggering recording mode to avoid confusion export type StrippedCypressModuleAPIOptions = Omit< Partial, @@ -181,6 +183,13 @@ export type CurrentsRunParameters = StrippedCypressModuleAPIOptions & { * Whether to record coverage results. If set, must be a boolean, defaults to false. */ experimentalCoverageRecording?: boolean; + + /** + * Set the timeout mode for the cloud orchestration service. If set, must be either "hard" or "soft", defaults to "hard". + * Hard mode - a timed out run will be marked as "failed" regardless of the test results. + * Soft mode - a timed out run will be marked as failed only if there are failed tests. + */ + cloudTimeoutMode?: TimeoutMode; }; // User-facing `run` interface