chore: additional metadata for protocol capture errors (#27507)

* split protocol errors into fatal/nonfatal

* change test stubs to implement capture protocol iface

* attach spec and project metadata to nonfatal error reports

* starting to test error reporting

* properly report fatal errors to artifact endpoint

* more meaningful error reporting

* better error reporting for protocol download + initialization errors

* refactgor protocol stubs for easier instantiation and use

* tests for beforeSpec error state

* fixes api spec tests

* code review comments

* revert import style for routes to appease tscheck

* update snapshots

* fix typedef for ArtifactLike, set error message on beforeSpec stub
This commit is contained in:
Cacie Prins
2023-08-15 10:37:59 -04:00
committed by GitHub
parent 9bfa454ad3
commit 47b18d2268
14 changed files with 742 additions and 341 deletions
+329 -165
View File
@@ -2902,169 +2902,6 @@ exports['e2e record capture-protocol enabled passing retrieves the capture proto
Recorded Run: https://dashboard.cypress.io/projects/cjvoj7/runs/12
`
exports['e2e record capture-protocol enabled protocol errors db size too large displays error and does not upload if db size is too large 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 - 1 kB
(Uploaded Cloud Artifacts)
- Screenshot - Done Uploading 1 kB 1/2 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png
- Test Replay - Failed Uploading 2/2 - Spec recording too large: db is 1047 bytes, limit is 200 bytes
====================================================================================================
(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
`
exports['e2e record capture-protocol enabled protocol errors error initializing protocol displays the error and reports to cloud 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 - Failed Capturing
(Uploaded Cloud Artifacts)
- Screenshot - Done Uploading 1 kB 1/1 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png
====================================================================================================
(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
`
exports['capture-protocol api errors upload 500 continues 1'] = `
@@ -3128,7 +2965,7 @@ exports['capture-protocol api errors upload 500 continues 1'] = `
(Uploaded Cloud Artifacts)
- Screenshot - Done Uploading 1 kB 1/2 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png
- Test Replay - Failed Uploading 2/2
- Test Replay - Failed Uploading 2/2 - 500 - Internal Server Error
====================================================================================================
@@ -3152,7 +2989,7 @@ exports['capture-protocol api errors upload 500 continues 1'] = `
exports['capture-protocol api errors fetch script 500 continues 1'] = `
We encountered an unexpected error communicating with our servers.
StatusCodeError: 500 - ""
StatusCodeError: 500 - "500 - Internal Server Error"
We will retry 1 more time in X second(s)...
@@ -3211,6 +3048,7 @@ We will retry 1 more time in X second(s)...
- Video - Nothing to upload
- Screenshot - 1 kB /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png
- Test Replay - Failed Capturing - Error downloading capture code: 500 - "500 - Internal Server Error"
(Uploaded Cloud Artifacts)
@@ -3316,3 +3154,329 @@ exports['capture-protocol api errors error report 500 continues 1'] = `
`
exports['e2e record capture-protocol enabled protocol runtime errors db size too large displays error and does not upload if db size is too large 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 - 1 kB
(Uploaded Cloud Artifacts)
- Screenshot - Done Uploading 1 kB 1/2 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png
- Test Replay - Failed Uploading 2/2 - Spec recording too large: db is 1047 bytes, limit is 200 bytes
====================================================================================================
(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
`
exports['e2e record capture-protocol enabled protocol runtime errors error initializing protocol displays the error and reports the fatal error to cloud via artifacts 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 - Failed Capturing - Error instantiating Protocol Capture
(Uploaded Cloud Artifacts)
- Screenshot - Done Uploading 1 kB 1/1 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png
====================================================================================================
(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
`
exports['e2e record capture-protocol enabled protocol runtime errors non-fatal error encountered during protocol capture reports the error to the protocol error endpoint 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 - 1 kB
(Uploaded Cloud Artifacts)
- Screenshot - Done Uploading 1 kB 1/2 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png
- Test Replay - Done Uploading 1 kB 2/2
====================================================================================================
(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
`
exports['e2e record capture-protocol enabled protocol runtime errors error in protocol beforeSpec displays the error and reports the fatal error to the cloud via artifacts 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 - Failed Capturing - Error constructing AppCaptureProtocol
(Uploaded Cloud Artifacts)
- Screenshot - Done Uploading 1 kB 1/1 /XXX/XXX/XXX/cypress/screenshots/record_pass.cy.js/yay it passes.png
====================================================================================================
(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
`
@@ -8,7 +8,7 @@ export const SYSTEM_TESTS_PRIVATE = 'LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV
export const TEST_PRIVATE = crypto.createPrivateKey(Buffer.from(SYSTEM_TESTS_PRIVATE, 'base64').toString('utf8'))
const buildStub = (filename: string): string => {
const build = (filename: string): string => {
const { outputFiles: [{ contents }] } = esbuild.buildSync({
entryPoints: [path.join(__dirname, filename)],
bundle: true,
@@ -28,18 +28,21 @@ const sign = (stub: string): string => {
return base64Url.fromBase64(crypto.createSign('SHA256').update(stub).sign(TEST_PRIVATE, 'base64'))
}
export const CYPRESS_LOCAL_PROTOCOL_STUB = buildStub('protocolStub.ts')
const stub = (filename: string) => {
const value = build(filename)
export const CYPRESS_LOCAL_PROTOCOL_STUB_COMPRESSED = gzipSync(CYPRESS_LOCAL_PROTOCOL_STUB)
return {
value,
compressed: gzipSync(value),
hash: hash(value),
sign: sign(value),
}
}
export const CYPRESS_LOCAL_PROTOCOL_STUB_HASH = hash(CYPRESS_LOCAL_PROTOCOL_STUB)
export const PROTOCOL_STUB_VALID = stub('protocolStub.ts')
export const CYPRESS_LOCAL_PROTOCOL_STUB_SIGN = sign(CYPRESS_LOCAL_PROTOCOL_STUB)
export const PROTOCOL_STUB_CONSTRUCTOR_ERROR = stub('protocolStubWithRuntimeError.ts')
export const CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB = buildStub('protocolStubWithRuntimeErrors.ts')
export const PROTOCOL_STUB_BEFORESPEC_ERROR = stub('protocolStubWithBeforeSpecError.ts')
export const CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_COMPRESSED = gzipSync(CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB)
export const CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_HASH = hash(CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB)
export const CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_SIGN = sign(CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB)
export const PROTOCOL_STUB_NONFATAL_ERROR = stub('protocolStubWithNonFatalError.ts')
@@ -3,7 +3,7 @@ import type { Database } from 'better-sqlite3'
export class AppCaptureProtocol implements AppCaptureProtocolInterface {
constructor () {
throw new Error()
throw new Error('Error constructing AppCaptureProtocol')
}
beforeSpec (db: Database): void {}
addRunnables (runnables: any): void {}
@@ -0,0 +1,30 @@
import type { AppCaptureProtocolInterface, CDPClient } from '@packages/types'
import type { Database } from 'better-sqlite3'
export class AppCaptureProtocol implements AppCaptureProtocolInterface {
beforeSpec (db: Database): void {}
addRunnables (runnables: any): void {}
commandLogAdded = (log) => {
throw new Error('Error reacting to commandLogAdded')
}
commandLogChanged (log: any): void {}
viewportChanged (input: any): void {}
urlChanged (input: any): void {}
beforeTest (test: Record<string, any>): Promise<void> {
return Promise.resolve()
}
preAfterTest (test: Record<string, any>, options: Record<string, any>): Promise<void> {
return Promise.resolve()
}
afterTest (test: Record<string, any>): Promise<void> {
return Promise.resolve()
}
afterSpec (): Promise<void> {
return Promise.resolve()
}
connectToBrowser (cdpClient: CDPClient): Promise<void> {
return Promise.resolve()
}
pageLoading (input: any): void {}
resetTest (testId: string): void {}
}
@@ -0,0 +1,28 @@
import type { AppCaptureProtocolInterface } from '@packages/types'
export class AppCaptureProtocol implements AppCaptureProtocolInterface {
constructor () {
throw new Error('Error instantiating Protocol Capture')
}
connectToBrowser = (cdpClient) => {
return Promise.resolve()
}
addRunnables = (runnables) => {}
beforeSpec = (spec) => {}
afterSpec = () => {
return Promise.resolve()
}
beforeTest = (test) => {
return Promise.resolve()
}
commandLogAdded = (log) => {}
commandLogChanged = (log) => {}
viewportChanged = (input) => {}
urlChanged = (input) => {}
pageLoading = (input) => {}
resetTest (testId) {}
afterTest = (test) => {
return Promise.resolve()
}
}
+27 -38
View File
@@ -14,17 +14,11 @@ import systemTests from './system-tests'
let CAPTURE_PROTOCOL_ENABLED = false
let CAPTURE_PROTOCOL_MESSAGE: string | undefined
let FAULTY_CAPTURE_PROTOCOL_ENABLED = false
import {
TEST_PRIVATE,
CYPRESS_LOCAL_PROTOCOL_STUB_COMPRESSED,
CYPRESS_LOCAL_PROTOCOL_STUB_HASH,
CYPRESS_LOCAL_PROTOCOL_STUB_SIGN,
CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_SIGN,
CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_COMPRESSED,
CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_HASH,
} from './protocolStubResponse'
PROTOCOL_STUB_VALID,
} from './protocol-stubs/protocolStubResponse'
const debug = Debug('cypress:system-tests:server-stub')
@@ -40,31 +34,36 @@ export const postRunResponse = _.assign({}, postRunResponseWithWarnings, { warni
// mocked here rather than attempting to intercept and mock an s3 req
export const CAPTURE_PROTOCOL_UPLOAD_URL = '/capture-protocol/upload/'
export const postRunResponseWithProtocolEnabled = () => {
const hash = FAULTY_CAPTURE_PROTOCOL_ENABLED ? CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_HASH : CYPRESS_LOCAL_PROTOCOL_STUB_HASH
let protocolStub: {
value: string
compressed: Buffer
hash: string
sign: string
} | undefined = undefined
debug('building postRunResponse', {
hash,
FAULTY_CAPTURE_PROTOCOL_ENABLED,
})
export const postRunResponseWithProtocolEnabled = () => {
debug('protocol enabled post run response with hash: ', protocolStub?.hash)
return {
...postRunResponse,
captureProtocolUrl: `http://localhost:1234/capture-protocol/script/${hash}.js`,
captureProtocolUrl: protocolStub?.hash ? `http://localhost:1234/capture-protocol/script/${protocolStub?.hash}.js` : '',
capture: {
url: `http://localhost:1234/capture-protocol/script/${hash}.js`,
url: protocolStub?.hash ? `http://localhost:1234/capture-protocol/script/${protocolStub?.hash}.js` : '',
},
}
}
export const postRunResponseWithProtocolDisabled = () => {
export const postRunResponseWithProtocolDisabled = (response = postRunResponse) => {
debug('protocol disabled post run response with message')
const disabledMessage = CAPTURE_PROTOCOL_MESSAGE || postRunResponse.capture?.disabledMessage
return {
...postRunResponse,
...response,
captureProtocolUrl: '',
capture: {
url: '',
disabledMessage: CAPTURE_PROTOCOL_MESSAGE || postRunResponse.capture?.disabledMessage,
disabledMessage,
},
}
}
@@ -230,13 +229,12 @@ export const routeHandlers: Record<string, RouteHandler> = {
method: 'get',
url: '/capture-protocol/script/*',
res: async (req, res) => {
res.header('Content-Encoding', 'gzip')
if (FAULTY_CAPTURE_PROTOCOL_ENABLED) {
res.header('x-cypress-signature', CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_SIGN)
res.status(200).send(CYPRESS_LOCAL_FAULTY_PROTOCOL_STUB_COMPRESSED)
if (protocolStub) {
res.header('Content-Encoding', 'gzip')
res.header('x-cypress-signature', protocolStub.sign)
res.status(200).send(protocolStub.compressed)
} else {
res.header('x-cypress-signature', CYPRESS_LOCAL_PROTOCOL_STUB_SIGN)
res.status(200).send(CYPRESS_LOCAL_PROTOCOL_STUB_COMPRESSED)
res.status(404).send('')
}
},
},
@@ -343,6 +341,7 @@ const ensureSchema = function (onRequestBody, expectedRequestSchema, responseBod
} catch (err) {
// eslint-disable-next-line no-console
console.log('Schema Error:', err.message)
debug(err)
return res.status(412).json(err)
}
@@ -431,30 +430,20 @@ const onServer = (routes) => {
})
}
export const enableCaptureProtocol = () => {
export const enableCaptureProtocol = (stub = PROTOCOL_STUB_VALID) => {
beforeEach(() => {
protocolStub = stub
CAPTURE_PROTOCOL_ENABLED = true
CAPTURE_PROTOCOL_MESSAGE = undefined
})
afterEach(() => {
protocolStub = undefined
CAPTURE_PROTOCOL_ENABLED = false
CAPTURE_PROTOCOL_MESSAGE = undefined
})
}
export const useFaultyCaptureProtocol = () => {
debug('setting tests to use faulty protocol stub')
beforeEach(() => {
debug('using faulty capture protocol')
FAULTY_CAPTURE_PROTOCOL_ENABLED = true
})
afterEach(() => {
FAULTY_CAPTURE_PROTOCOL_ENABLED = false
})
}
export const disableCaptureProtocolWithMessage = (message: string) => {
beforeEach(() => {
CAPTURE_PROTOCOL_ENABLED = false
+78 -8
View File
@@ -23,12 +23,12 @@ const {
postInstanceTestsResponse,
encryptBody,
disableCaptureProtocolWithMessage,
useFaultyCaptureProtocol,
CAPTURE_PROTOCOL_UPLOAD_URL,
postRunResponseWithProtocolDisabled,
} = require('../lib/serverStub')
const { expectRunsToHaveCorrectTimings } = require('../lib/resultsUtils')
const { randomBytes } = require('crypto')
const { PROTOCOL_STUB_CONSTRUCTOR_ERROR, PROTOCOL_STUB_NONFATAL_ERROR, PROTOCOL_STUB_BEFORESPEC_ERROR } = require('../lib/protocol-stubs/protocolStubResponse')
const debug = require('debug')('cypress:system-tests:record_spec')
const e2ePath = Fixtures.projectPath('e2e')
const outputPath = path.join(e2ePath, 'output.json')
@@ -2232,7 +2232,7 @@ describe('e2e record', () => {
postRun: {
res: (req, res) => {
mockServer.setSpecs(req)
res.json(postRunResponseWithWarnings)
res.json(postRunResponseWithProtocolDisabled(postRunResponseWithWarnings))
},
},
}))
@@ -2244,6 +2244,14 @@ describe('e2e record', () => {
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
debug(artifactReport)
})
})
})
@@ -2299,7 +2307,7 @@ describe('e2e record', () => {
})
})
describe('protocol errors', () => {
describe('protocol runtime errors', () => {
enableCaptureProtocol()
describe('db size too large', () => {
beforeEach(() => {
@@ -2329,9 +2337,9 @@ describe('e2e record', () => {
})
describe('error initializing protocol', () => {
useFaultyCaptureProtocol()
enableCaptureProtocol(PROTOCOL_STUB_CONSTRUCTOR_ERROR)
it('displays the error and reports to cloud', function () {
it('displays the error and reports the fatal error to cloud via artifacts', function () {
return systemTests.exec(this, {
key: 'f858a2bc-b469-4e48-be67-0876339ee7e1',
configFile: 'cypress-with-project-id.config.js',
@@ -2341,9 +2349,71 @@ describe('e2e record', () => {
}).then(() => {
const urls = getRequestUrls()
debug(urls)
expect(urls).to.include.members(['POST /capture-protocol/errors'])
expect(urls).to.include.members([`PUT /instances/${instanceId}/artifacts`])
expect(urls).not.to.include.members([`PUT ${CAPTURE_PROTOCOL_UPLOAD_URL}`])
const artifactReport = getRequests().find(({ url }) => url === `PUT /instances/${instanceId}/artifacts`)?.body
expect(artifactReport?.protocol).to.exist()
expect(artifactReport?.protocol?.error).to.exist().and.not.to.be.empty()
})
})
})
describe('error in protocol beforeSpec', () => {
enableCaptureProtocol(PROTOCOL_STUB_BEFORESPEC_ERROR)
it('displays the error and reports the fatal error to the cloud via artifacts', function () {
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`])
expect(urls).not.to.include.members([`PUT ${CAPTURE_PROTOCOL_UPLOAD_URL}`])
const artifactReport = getRequests().find(({ url }) => url === `PUT /instances/${instanceId}/artifacts`)?.body
expect(artifactReport?.protocol).to.exist()
expect(artifactReport?.protocol?.error).to.exist().and.not.to.be.empty()
})
})
})
describe('non-fatal error encountered during protocol capture', () => {
enableCaptureProtocol(PROTOCOL_STUB_NONFATAL_ERROR)
it('reports the error to the protocol error endpoint', function () {
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 reportErrorUrl = 'POST /capture-protocol/errors'
const urls = getRequestUrls()
debug(urls)
expect(urls).to.include.members([reportErrorUrl])
const errorReport = getRequests().find(({ url }) => url === reportErrorUrl).body
debug(errorReport)
expect(errorReport.errors).to.be.length(4)
errorReport.errors.forEach((e) => {
expect(e.captureMethod).to.eq('commandLogAdded')
expect(e.runnableId).to.eq('r3')
})
expect(errorReport.context.specName).to.eq('cypress/e2e/record_pass.cy.js')
expect(errorReport.context.projectSlug).to.eq('pid123')
expect(errorReport.context.osName).to.eq(os.platform())
})
})
})
@@ -2359,7 +2429,7 @@ describe('capture-protocol api errors', () => {
return setupStubbedServer(createRoutes({
[endpoint]: {
res: (req, res) => {
res.status(500).send()
res.status(500).send('500 - Internal Server Error')
},
},
}))