From 766051c7cb2e612fde6af96dc0262820a04bfcd2 Mon Sep 17 00:00:00 2001 From: Cacie Prins Date: Tue, 26 Mar 2024 10:44:23 -0400 Subject: [PATCH] ensure system test snapshots --- .../lib/cloud/api/putProtocolArtifact.ts | 5 +- packages/server/lib/modes/record.js | 8 +- packages/server/lib/util/print-run.ts | 2 +- system-tests/__snapshots__/record_spec.js | 90 ++++++++++++++++++- system-tests/test/record_spec.js | 38 ++++++-- 5 files changed, 131 insertions(+), 12 deletions(-) diff --git a/packages/server/lib/cloud/api/putProtocolArtifact.ts b/packages/server/lib/cloud/api/putProtocolArtifact.ts index 33b78b64239b..3fb5f388b45f 100644 --- a/packages/server/lib/cloud/api/putProtocolArtifact.ts +++ b/packages/server/lib/cloud/api/putProtocolArtifact.ts @@ -1,10 +1,13 @@ import fsAsync from 'fs/promises' import fs from 'fs' - +import Debug from 'debug' import { uploadStream, geometricRetry } from '../upload/uploadStream' import { StreamActivityMonitor } from '../upload/StreamActivityMonitor' +const debug = Debug('cypress:server:cloud:api:protocol-artifact') + export const putProtocolArtifact = async (artifactPath: string, maxFileSize: number, destinationUrl: string) => { + debug(`Atttempting to upload Test Replay archive from ${artifactPath} to ${destinationUrl})`) const { size } = await fsAsync.stat(artifactPath) if (size > maxFileSize) { diff --git a/packages/server/lib/modes/record.js b/packages/server/lib/modes/record.js index 4238834f19f1..9c7ed0a4baf5 100644 --- a/packages/server/lib/modes/record.js +++ b/packages/server/lib/modes/record.js @@ -373,9 +373,15 @@ const uploadArtifactBatch = async (artifacts, protocolManager, quiet) => { if (key === 'protocol') { let { error, errorStack, allErrors } = report + debug('reducing uploadResuls: %O', report) if (allErrors) { - error = `Failed to upload after ${allErrors.length} attempts. Errors: ${allErrors.map((error) => error.message).join(', ')}` + error = allErrors.length > 1 ? + `Failed to upload Test Replay after ${allErrors.length} attempts. Errors: ${allErrors.map((error) => error.message).join(', ')}` : + `Failed to upload Test Replay: ${allErrors[0]}` + errorStack = allErrors.map((error) => error.stack).join(', ') + } else if (error) { + error = `Failed to upload Test Replay: ${error}` } return skipped && !report.error ? acc : { diff --git a/packages/server/lib/util/print-run.ts b/packages/server/lib/util/print-run.ts index d2ef8f12dce2..200f726f6841 100644 --- a/packages/server/lib/util/print-run.ts +++ b/packages/server/lib/util/print-run.ts @@ -600,7 +600,7 @@ export const printPendingArtifactUpload = (artifact: T, process.stdout.write(`- ${formatFileSize(Number(artifact.fileSize))}`) } - if (artifact.filePath) { + if (artifact.filePath && artifact.reportKey !== 'protocol') { process.stdout.write(` ${formatPath(artifact.filePath, undefined, 'cyan')}`) } diff --git a/system-tests/__snapshots__/record_spec.js b/system-tests/__snapshots__/record_spec.js index 20897f5b579e..bdafa9d8c10c 100644 --- a/system-tests/__snapshots__/record_spec.js +++ b/system-tests/__snapshots__/record_spec.js @@ -3047,7 +3047,7 @@ exports['e2e record capture-protocol enabled protocol runtime errors db size too (Uploaded Cloud Artifacts) - Screenshot - Done Uploading 1 kB in Xm, Ys ZZ.ZZms 1/2 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png - - Test Replay - Failed Uploading after Xm, Ys ZZ.ZZms 2/2 - Spec recording too large: db is 1024 bytes, limit is 200 bytes + - Test Replay - Failed Uploading after Xm, Ys ZZ.ZZms 2/2 - Spec recording too large: artifact is 1024 bytes, limit is 200 bytes ==================================================================================================== @@ -3658,7 +3658,7 @@ exports['e2e record capture-protocol enabled passing retrieves the capture proto ` -exports['capture-protocol api errors upload 500 - retries 3 times and fails continues 1'] = ` +exports['capture-protocol api errors upload 500 - does not retry continues 1'] = ` ==================================================================================================== @@ -3742,7 +3742,7 @@ exports['capture-protocol api errors upload 500 - retries 3 times and fails cont ` -exports['capture-protocol api errors upload 500 - retries 2 times and succeeds on the last call continues 1'] = ` +exports['capture-protocol api errors upload 503 - retries 2 times and succeeds on the last call continues 1'] = ` ==================================================================================================== @@ -3825,3 +3825,87 @@ exports['capture-protocol api errors upload 500 - retries 2 times and succeeds o ` + +exports['capture-protocol api errors upload 503 - tries 3 times and fails continues 1'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 1 found (record_pass.cy.js) │ + │ Searched: cypress/e2e/record_pass* │ + │ Params: Tag: false, Group: false, Parallel: false │ + │ Run URL: https://dashboard.cypress.io/projects/cjvoj7/runs/12 │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: record_pass.cy.js (1 of 1) + Estimated: X second(s) + + + record pass + ✓ passes + - is pending + + + 1 passing + 1 pending + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 2 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 1 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: false │ + │ Duration: X seconds │ + │ Estimated: X second(s) │ + │ Spec Ran: record_pass.cy.js │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png (400x1022) + + + (Uploading Cloud Artifacts) + + - Video - Nothing to upload + - Screenshot - 1 kB /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png + - Test Replay + + Uploading Cloud Artifacts: . . . . . + + (Uploaded Cloud Artifacts) + + - Screenshot - Done Uploading 1 kB in Xm, Ys ZZ.ZZms 1/2 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png + - Test Replay - Failed Uploading after Xm, Ys ZZ.ZZms 2/2 - 503 Service Unavailable (http://localhost:1234/capture-protocol/upload/?x-amz-credential=XXXXXXXX&x-amz-signature=XXXXXXXXXXXXX) + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ record_pass.cy.js XX:XX 2 1 - 1 - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✔ All specs passed! XX:XX 2 1 - 1 - + + +─────────────────────────────────────────────────────────────────────────────────────────────────────── + + Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12 + + +` diff --git a/system-tests/test/record_spec.js b/system-tests/test/record_spec.js index 3938e1f3e5af..0035ea991c5a 100644 --- a/system-tests/test/record_spec.js +++ b/system-tests/test/record_spec.js @@ -2524,7 +2524,7 @@ describe('capture-protocol api errors', () => { enableCaptureProtocol() - const stubbedServerWithErrorOn = (endpoint, numberOfFailuresBeforeSuccess = Number.MAX_SAFE_INTEGER) => { + const stubbedServerWithErrorOn = (endpoint, numberOfFailuresBeforeSuccess = Number.MAX_SAFE_INTEGER, status = 500, statusText = 'Internal Server Error') => { let failures = 0 return setupStubbedServer(createRoutes({ @@ -2532,7 +2532,7 @@ describe('capture-protocol api errors', () => { res: (req, res) => { if (failures < numberOfFailuresBeforeSuccess) { failures += 1 - res.status(500).send('500 - Internal Server Error') + res.status(status).send(`${status} - ${statusText}`) } else { routeHandlers[endpoint].res(req, res) } @@ -2541,7 +2541,7 @@ describe('capture-protocol api errors', () => { })) } - describe('upload 500 - retries 3 times and fails', () => { + describe('upload 500 - does not retry', () => { stubbedServerWithErrorOn('putCaptureProtocolUpload') it('continues', function () { process.env.API_RETRY_INTERVALS = '1000' @@ -2561,7 +2561,33 @@ describe('capture-protocol api errors', () => { expect(artifactReport?.protocol).to.exist() expect(artifactReport?.protocol?.error).to.equal( - 'Failed to upload after 3 attempts. Errors: 500 Internal Server Error (http://localhost:1234/capture-protocol/upload/?x-amz-credential=XXXXXXXX&x-amz-signature=XXXXXXXXXXXXX), 500 Internal Server Error (http://localhost:1234/capture-protocol/upload/?x-amz-credential=XXXXXXXX&x-amz-signature=XXXXXXXXXXXXX), 500 Internal Server Error (http://localhost:1234/capture-protocol/upload/?x-amz-credential=XXXXXXXX&x-amz-signature=XXXXXXXXXXXXX)', + 'Failed to upload Test Replay: 500 Internal Server Error (http://localhost:1234/capture-protocol/upload/?x-amz-credential=XXXXXXXX&x-amz-signature=XXXXXXXXXXXXX)', + ) + }) + }) + }) + + describe('upload 503 - tries 3 times and fails', () => { + stubbedServerWithErrorOn('putCaptureProtocolUpload', Number.MAX_SAFE_INTEGER, 503, 'Service Unavailable') + it('continues', function () { + process.env.API_RETRY_INTERVALS = '1000' + + return systemTests.exec(this, { + key: 'f858a2bc-b469-4e48-be67-0876339ee7e1', + configFile: 'cypress-with-project-id.config.js', + spec: 'record_pass*', + record: true, + snapshot: true, + }).then(() => { + const urls = getRequestUrls() + + expect(urls).to.include.members([`PUT /instances/${instanceId}/artifacts`]) + + const artifactReport = getRequests().find(({ url }) => url === `PUT /instances/${instanceId}/artifacts`)?.body + + expect(artifactReport?.protocol).to.exist() + expect(artifactReport?.protocol?.error).to.equal( + 'Failed to upload Test Replay after 3 attempts. Errors: 503 Service Unavailable (http://localhost:1234/capture-protocol/upload/?x-amz-credential=XXXXXXXX&x-amz-signature=XXXXXXXXXXXXX), 503 Service Unavailable (http://localhost:1234/capture-protocol/upload/?x-amz-credential=XXXXXXXX&x-amz-signature=XXXXXXXXXXXXX), 503 Service Unavailable (http://localhost:1234/capture-protocol/upload/?x-amz-credential=XXXXXXXX&x-amz-signature=XXXXXXXXXXXXX)', ) expect(artifactReport?.protocol?.errorStack).to.exist().and.not.to.be.empty() @@ -2569,8 +2595,8 @@ describe('capture-protocol api errors', () => { }) }) - describe('upload 500 - retries 2 times and succeeds on the last call', () => { - stubbedServerWithErrorOn('putCaptureProtocolUpload', 2) + describe('upload 503 - retries 2 times and succeeds on the last call', () => { + stubbedServerWithErrorOn('putCaptureProtocolUpload', 2, 503, 'Internal Server Error') let archiveFile = ''