From d5bbdbb8b2273645716a1902484fbdb825dd859c Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Sat, 31 Aug 2024 13:03:49 -0700 Subject: [PATCH] feat: add retries for hard failures --- examples/webapp/currents.config.js | 5 ++- packages/cypress-cloud/lib/config/config.ts | 5 +++ packages/cypress-cloud/lib/cypress/cypress.ts | 35 +++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/examples/webapp/currents.config.js b/examples/webapp/currents.config.js index 332fe16b..c6fe8fc0 100644 --- a/examples/webapp/currents.config.js +++ b/examples/webapp/currents.config.js @@ -9,5 +9,8 @@ module.exports = { ? "Ij0RfK" : "Ij0RfK", // cloudServiceUrl: "http://localhost:1234", - userAgent: "custom", + // userAgent: "custom", + retry: { + hardFailureMaxRetries: 2, + }, }; diff --git a/packages/cypress-cloud/lib/config/config.ts b/packages/cypress-cloud/lib/config/config.ts index e1d0cf82..08c2317a 100644 --- a/packages/cypress-cloud/lib/config/config.ts +++ b/packages/cypress-cloud/lib/config/config.ts @@ -14,6 +14,10 @@ export type E2EConfig = { export type ComponentConfig = { batchSize: number; }; + +type RetryConfig = { + hardFailureMaxRetries: number; +}; export type CurrentsConfig = { projectId?: string; recordKey?: string; @@ -21,6 +25,7 @@ export type CurrentsConfig = { e2e: E2EConfig; component: ComponentConfig; networkHeaders?: Record; + retry?: RetryConfig; }; let _config: CurrentsConfig | null = null; diff --git a/packages/cypress-cloud/lib/cypress/cypress.ts b/packages/cypress-cloud/lib/cypress/cypress.ts index 5ad3c30e..24a18194 100644 --- a/packages/cypress-cloud/lib/cypress/cypress.ts +++ b/packages/cypress-cloud/lib/cypress/cypress.ts @@ -6,7 +6,7 @@ import { } from "cypress-cloud/types"; import Debug from "debug"; import _ from "lodash"; -import { getCypressRunAPIParams } from "../config"; +import { getCurrentsConfig, getCypressRunAPIParams } from "../config"; import { safe } from "../lang"; import { warn } from "../log"; import { getWSSPort } from "../ws"; @@ -53,8 +53,38 @@ export async function runSpecFile( }, spec, }; + debug("running cypress with options %o", options); - const result = await cypress.run(options); + let result = await cypress.run(options); + + let retries = 0; + const currentsConfig = await getCurrentsConfig(); + while ( + currentsConfig.retry && + retries < currentsConfig.retry.hardFailureMaxRetries && + result.status === "failed" + ) { + warn("Cypress runner failed with message: %s", result.message); + warn( + "[retry %d/%d] Retrying the following spec files because of retry config: %s", + retries + 1, + currentsConfig.retry.hardFailureMaxRetries, + spec + .split(",") + .map((i) => `\n - ${i}`) + .join("") + ); + result = await cypress.run(options); + retries++; + } + + if (currentsConfig.retry && retries > 0) { + warn( + "Exhausted max retries: %d/%d", + retries, + currentsConfig.retry.hardFailureMaxRetries + ); + } if (result.status === "failed") { warn('Cypress runner failed with message: "%s"', result.message); @@ -66,6 +96,7 @@ export async function runSpecFile( .join("") ); } + debug("cypress run result %o", result); return result; }