From 1c5a67fa927e16620966e977f12cd8a7c3ff69fc Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Mon, 13 Mar 2023 08:53:59 -0500 Subject: [PATCH] fix: handle async before:spec event handler (#26055) Co-authored-by: Ryan Manuel --- .circleci/workflows.yml | 8 +- cli/CHANGELOG.md | 1 + packages/app/src/example.spec.ts | 5 - packages/app/src/runner/event-manager.ts | 27 ++-- packages/app/src/runner/index.ts | 2 +- packages/server/lib/modes/run.ts | 6 +- packages/server/lib/open_project.ts | 2 +- packages/server/lib/plugins/index.ts | 3 +- packages/server/lib/plugins/run_events.js | 2 +- packages/server/lib/project-base.ts | 4 +- packages/server/lib/socket-base.ts | 17 ++- .../server/test/unit/open_project_spec.js | 2 +- .../test/unit/plugins/run_events_spec.js | 8 +- packages/server/test/unit/project_spec.js | 4 +- .../plugin_run_events_spec.ts.js | 124 ++++++++++++++++-- system-tests/lib/system-tests.ts | 1 - .../e2e/after_spec_deletes_video.cy.js | 1 - .../cypress/e2e/run_event_throws.cy.js | 1 - .../cypress.config.afterSpec.deleteVideo.js} | 7 +- .../cypress.config.beforeSpec.async.js | 22 ++++ .../plugin-run-events/cypress.config.js | 1 + .../cypress.config.runEvent.throws.js} | 7 +- system-tests/test/plugin_run_events_spec.ts | 20 +-- 23 files changed, 210 insertions(+), 65 deletions(-) delete mode 100644 packages/app/src/example.spec.ts delete mode 100644 system-tests/projects/plugin-after-spec-deletes-video/cypress/e2e/after_spec_deletes_video.cy.js delete mode 100644 system-tests/projects/plugin-run-event-throws/cypress/e2e/run_event_throws.cy.js rename system-tests/projects/{plugin-after-spec-deletes-video/cypress.config.js => plugin-run-events/cypress.config.afterSpec.deleteVideo.js} (74%) create mode 100644 system-tests/projects/plugin-run-events/cypress.config.beforeSpec.async.js rename system-tests/projects/{plugin-run-event-throws/cypress.config.js => plugin-run-events/cypress.config.runEvent.throws.js} (70%) diff --git a/.circleci/workflows.yml b/.circleci/workflows.yml index 881b498eb8..dd0f2f7a23 100644 --- a/.circleci/workflows.yml +++ b/.circleci/workflows.yml @@ -30,8 +30,7 @@ mainBuildFilters: &mainBuildFilters - /^release\/\d+\.\d+\.\d+$/ # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - 'update-v8-snapshot-cache-on-develop' - - 'lmiller/issue-25947' - - 'fix/preflight' + - 'emily/before-spec-promise' # usually we don't build Mac app - it takes a long time # but sometimes we want to really confirm we are doing the right thing @@ -42,8 +41,7 @@ macWorkflowFilters: &darwin-workflow-filters - equal: [ develop, << pipeline.git.branch >> ] # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ] - - equal: [ 'fix/preflight', << pipeline.git.branch >> ] - - equal: [ 'lmiller/issue-25947', << pipeline.git.branch >> ] + - equal: [ 'emily/before-spec-promise', << pipeline.git.branch >> ] - matches: pattern: /^release\/\d+\.\d+\.\d+$/ value: << pipeline.git.branch >> @@ -141,7 +139,7 @@ commands: - run: name: Check current branch to persist artifacts command: | - if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "lmiller/issue-25947" && "$CIRCLE_BRANCH" != "update-v8-snapshot-cache-on-develop" ]]; then + if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "emily/before-spec-promise" && "$CIRCLE_BRANCH" != "update-v8-snapshot-cache-on-develop" ]]; then echo "Not uploading artifacts or posting install comment for this branch." circleci-agent step halt fi diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 081d482fd7..2cea5c4701 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -11,6 +11,7 @@ _Released 03/14/2023 (PENDING)_ **Bugfixes:** - Fixed an issue where using `Cypress.require()` would throw the error `Cannot find module 'typescript'`. Fixes [#25885](https://github.com/cypress-io/cypress/issues/25885). +- The [`before:spec`](https://docs.cypress.io/api/plugins/before-spec-api) API was updated to correctly support async event handlers in `run` mode. Fixes [#24403](https://github.com/cypress-io/cypress/issues/24403). **Misc:** diff --git a/packages/app/src/example.spec.ts b/packages/app/src/example.spec.ts deleted file mode 100644 index ea3b5c1379..0000000000 --- a/packages/app/src/example.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe('example', () => { - it('does not do much', () => { - expect(true).to.be.true - }) -}) diff --git a/packages/app/src/runner/event-manager.ts b/packages/app/src/runner/event-manager.ts index 223cf6310e..ed7e4d85df 100644 --- a/packages/app/src/runner/event-manager.ts +++ b/packages/app/src/runner/event-manager.ts @@ -8,9 +8,8 @@ import type { RunState, CachedTestState, AutomationElementId, FileDetails, Repor import { logger } from './logger' import type { Socket } from '@packages/socket/lib/browser' -import { automation, useRunnerUiStore } from '../store' +import { automation, useRunnerUiStore, useSpecStore } from '../store' import { useScreenshotStore } from '../store/screenshot-store' -import { useSpecStore } from '../store/specs-store' import { useStudioStore } from '../store/studio-store' import { getAutIframeModel } from '.' import { handlePausing } from './events/pausing' @@ -360,7 +359,23 @@ export class EventManager { } } - setup (config) { + async setup (config) { + this.ws.emit('watch:test:file', config.spec) + + if (config.isTextTerminal || config.experimentalInteractiveRunEvents) { + await new Promise((resolve, reject) => { + this.ws.emit('plugins:before:spec', config.spec, (res?: { error: Error }) => { + // FIXME: handle surfacing the error to the browser instead of hanging with + // 'Your tests are loading...' message. Fix in https://github.com/cypress-io/cypress/issues/23627 + if (res && res.error) { + reject(res.error) + } + + resolve(null) + }) + }) + } + Cypress = this.Cypress = this.$CypressDriver.create(config) // expose Cypress globally @@ -368,12 +383,6 @@ export class EventManager { window.Cypress = Cypress this._addListeners() - - this.ws.emit('watch:test:file', config.spec) - - if (config.isTextTerminal || config.experimentalInteractiveRunEvents) { - this.ws.emit('plugins:before:spec', config.spec) - } } isBrowser (browserName) { diff --git a/packages/app/src/runner/index.ts b/packages/app/src/runner/index.ts index 054fee6611..4e1dfe0053 100644 --- a/packages/app/src/runner/index.ts +++ b/packages/app/src/runner/index.ts @@ -401,7 +401,7 @@ async function executeSpec (spec: SpecFile, isRerun: boolean = false) { // creates a new instance of the Cypress driver for this spec, // initializes a bunch of listeners watches spec file for changes. - getEventManager().setup(config) + await getEventManager().setup(config) if (window.__CYPRESS_TESTING_TYPE__ === 'e2e') { return runSpecE2E(config, spec) diff --git a/packages/server/lib/modes/run.ts b/packages/server/lib/modes/run.ts index adc11abac8..8fd310472f 100644 --- a/packages/server/lib/modes/run.ts +++ b/packages/server/lib/modes/run.ts @@ -601,7 +601,7 @@ async function waitForTestsToFinishRunning (options: { project: Project, screens } } - await runEvents.execute('after:spec', config, spec, results) + await runEvents.execute('after:spec', spec, results) debug('executed after:spec') const videoName = videoRecording?.api.videoName @@ -746,7 +746,7 @@ async function runSpecs (options: { config: Cfg, browser: Browser, sys: any, hea autoCancelAfterFailures, } - await runEvents.execute('before:run', config, beforeRunDetails) + await runEvents.execute('before:run', beforeRunDetails) const runs = await iterateThroughSpecs({ specs, @@ -816,7 +816,7 @@ async function runSpecs (options: { config: Cfg, browser: Browser, sys: any, hea })), }) - await runEvents.execute('after:run', config, moduleAPIResults) + await runEvents.execute('after:run', moduleAPIResults) await writeOutput(outputPath, moduleAPIResults) return results diff --git a/packages/server/lib/open_project.ts b/packages/server/lib/open_project.ts index ad79bf2e1d..b7147b3080 100644 --- a/packages/server/lib/open_project.ts +++ b/packages/server/lib/open_project.ts @@ -136,7 +136,7 @@ export class OpenProject { return Bluebird.resolve() } - return runEvents.execute('after:spec', cfg, spec) + return runEvents.execute('after:spec', spec) } const { onBrowserClose } = options diff --git a/packages/server/lib/plugins/index.ts b/packages/server/lib/plugins/index.ts index 007ea9d793..3ea0eafbd5 100644 --- a/packages/server/lib/plugins/index.ts +++ b/packages/server/lib/plugins/index.ts @@ -1,5 +1,6 @@ import { - getCtx, registerServerPluginHandler, + getCtx, + registerServerPluginHandler, } from '@packages/data-context' export const registerEvent = (event, callback) => { diff --git a/packages/server/lib/plugins/run_events.js b/packages/server/lib/plugins/run_events.js index d197b35773..83e2ae0b50 100644 --- a/packages/server/lib/plugins/run_events.js +++ b/packages/server/lib/plugins/run_events.js @@ -4,7 +4,7 @@ const errors = require('../errors') const plugins = require('../plugins') module.exports = { - execute: Promise.method((eventName, config = {}, ...args) => { + execute: Promise.method((eventName, ...args) => { if (!plugins.has(eventName)) return return plugins.execute(eventName, ...args) diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index 85da6bfac2..50aa71cfc5 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -235,7 +235,7 @@ export class ProjectBase extends EE { this.isOpen = true - return runEvents.execute('before:run', cfg, beforeRunDetails) + return runEvents.execute('before:run', beforeRunDetails) } reset () { @@ -287,7 +287,7 @@ export class ProjectBase extends EE { if (config.isTextTerminal || !config.experimentalInteractiveRunEvents) return - return runEvents.execute('after:run', config) + return runEvents.execute('after:run') } initializeReporter ({ diff --git a/packages/server/lib/socket-base.ts b/packages/server/lib/socket-base.ts index 2cb6a0d74b..eaa212dc62 100644 --- a/packages/server/lib/socket-base.ts +++ b/packages/server/lib/socket-base.ts @@ -46,12 +46,14 @@ export class SocketBase { private _isRunnerSocketConnected private _sendFocusBrowserMessage + protected inRunMode: boolean protected supportsRunEvents: boolean protected ended: boolean protected _io?: socketIo.SocketIOServer localBus: EventEmitter constructor (config: Record) { + this.inRunMode = config.isTextTerminal this.supportsRunEvents = config.isTextTerminal || config.experimentalInteractiveRunEvents this.ended = false this.localBus = new EventEmitter() @@ -532,10 +534,17 @@ export class SocketBase { }) if (this.supportsRunEvents) { - socket.on('plugins:before:spec', (spec) => { - runEvents.execute('before:spec', {}, spec).catch((error) => { - socket.disconnect() - throw error + socket.on('plugins:before:spec', (spec, cb) => { + runEvents.execute('before:spec', spec) + .then(cb) + .catch((error) => { + if (this.inRunMode) { + socket.disconnect() + throw error + } + + // surfacing the error to the app in open mode + cb({ error }) }) }) } diff --git a/packages/server/test/unit/open_project_spec.js b/packages/server/test/unit/open_project_spec.js index 9e1e8669a3..bb76f7d732 100644 --- a/packages/server/test/unit/open_project_spec.js +++ b/packages/server/test/unit/open_project_spec.js @@ -131,7 +131,7 @@ describe('lib/open_project', () => { return browsers.open.lastCall.args[1].onBrowserClose() }) .then(() => { - expect(runEvents.execute).to.be.calledWith('after:spec', this.config, this.spec) + expect(runEvents.execute).to.be.calledWith('after:spec', this.spec) }) }) diff --git a/packages/server/test/unit/plugins/run_events_spec.js b/packages/server/test/unit/plugins/run_events_spec.js index b9d9c2b34f..ae47983807 100644 --- a/packages/server/test/unit/plugins/run_events_spec.js +++ b/packages/server/test/unit/plugins/run_events_spec.js @@ -13,7 +13,7 @@ describe('lib/plugins/run_events', () => { }) it('returns a promise noop if event is not registered', () => { - return runEvents.execute('before:spec', {}) + return runEvents.execute('before:spec') .then(() => { expect(plugins.execute).not.to.be.called }) @@ -23,7 +23,7 @@ describe('lib/plugins/run_events', () => { plugins.has.returns(true) plugins.execute.resolves('the result') - return runEvents.execute('before:spec', {}, 'arg1', 'arg2') + return runEvents.execute('before:spec', 'arg1', 'arg2') .then(() => { expect(plugins.execute).to.be.calledWith('before:spec', 'arg1', 'arg2') }) @@ -33,7 +33,7 @@ describe('lib/plugins/run_events', () => { plugins.has.returns(true) plugins.execute.resolves('the result') - return runEvents.execute('before:spec', {}, 'arg1', 'arg2') + return runEvents.execute('before:spec', 'arg1', 'arg2') .then((result) => { expect(result).to.equal('the result') }) @@ -43,7 +43,7 @@ describe('lib/plugins/run_events', () => { plugins.has.returns(true) plugins.execute.rejects({ name: 'Error', message: 'The event threw an error', stack: 'stack trace' }) - return runEvents.execute('before:spec', {}, 'arg1', 'arg2') + return runEvents.execute('before:spec', 'arg1', 'arg2') .then(() => { expect(errors.throwErr).to.be.calledWith('PLUGINS_RUN_EVENT_ERROR', 'before:spec', { name: 'Error', message: 'The event threw an error', stack: 'stack trace' }) }) diff --git a/packages/server/test/unit/project_spec.js b/packages/server/test/unit/project_spec.js index f9085c5718..62ad710638 100644 --- a/packages/server/test/unit/project_spec.js +++ b/packages/server/test/unit/project_spec.js @@ -264,7 +264,7 @@ This option will not have an effect in Some-other-name. Tests that rely on web s return this.project.open() .then(() => { - expect(runEvents.execute).to.be.calledWith('before:run', this.config, { + expect(runEvents.execute).to.be.calledWith('before:run', { config: this.config, cypressVersion: pkg.version, system: sysInfo, @@ -417,7 +417,7 @@ This option will not have an effect in Some-other-name. Tests that rely on web s return this.project.close() .then(() => { - expect(runEvents.execute).to.be.calledWith('after:run', this.config) + expect(runEvents.execute).to.be.calledWith('after:run') }) }) diff --git a/system-tests/__snapshots__/plugin_run_events_spec.ts.js b/system-tests/__snapshots__/plugin_run_events_spec.ts.js index bd0e573452..2f5554b2fd 100644 --- a/system-tests/__snapshots__/plugin_run_events_spec.ts.js +++ b/system-tests/__snapshots__/plugin_run_events_spec.ts.js @@ -8,7 +8,7 @@ exports['e2e plugin run events / sends events'] = ` │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ │ Specs: 2 found (run_events_spec_1.cy.js, run_events_spec_2.cy.js) │ - │ Searched: cypress/e2e/* │ + │ Searched: cypress/e2e/**/*.cy.{js,jsx,ts,tsx} │ │ Experiments: experimentalInteractiveRunEvents=true │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ @@ -100,14 +100,14 @@ exports['e2e plugin run events / handles video being deleted in after:spec'] = ` ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ - │ Specs: 1 found (after_spec_deletes_video.cy.js) │ - │ Searched: cypress/e2e/* │ + │ Specs: 1 found (run_events_spec_1.cy.js) │ + │ Searched: cypress/e2e/*1.cy.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: after_spec_deletes_video.cy.js (1 of 1) + Running: run_events_spec_1.cy.js (1 of 1) ✓ is true @@ -126,7 +126,7 @@ exports['e2e plugin run events / handles video being deleted in after:spec'] = ` │ Screenshots: 0 │ │ Video: false │ │ Duration: X seconds │ - │ Spec Ran: after_spec_deletes_video.cy.js │ + │ Spec Ran: run_events_spec_1.cy.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ @@ -137,7 +137,7 @@ exports['e2e plugin run events / handles video being deleted in after:spec'] = ` Spec Tests Passing Failing Pending Skipped ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ ✔ after_spec_deletes_video.cy.js XX:XX 1 1 - - - │ + │ ✔ run_events_spec_1.cy.js XX:XX 1 1 - - - │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ✔ All specs passed! XX:XX 1 1 - - - @@ -153,14 +153,14 @@ exports['e2e plugin run events / fails run if event handler throws'] = ` ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ - │ Specs: 1 found (run_event_throws.cy.js) │ - │ Searched: cypress/e2e/* │ + │ Specs: 2 found (run_events_spec_1.cy.js, run_events_spec_2.cy.js) │ + │ Searched: cypress/e2e/**/*.cy.{js,jsx,ts,tsx} │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: run_event_throws.cy.js (1 of 1) + Running: run_events_spec_1.cy.js (1 of 2) An error was thrown in your plugins file while executing the handler for the before:spec event. The error we received was: @@ -168,3 +168,109 @@ The error we received was: Error: error thrown in before:spec [stack trace lines] ` + +exports['e2e plugin run events / handles async before:spec'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 2 found (run_events_spec_1.cy.js, run_events_spec_2.cy.js) │ + │ Searched: cypress/e2e/**/*.cy.{js,jsx,ts,tsx} │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: run_events_spec_1.cy.js (1 of 2) +<---- before:spec promise start +received args { + fileExtension: '.js', + baseName: 'run_events_spec_1.cy.js', + fileName: 'run_events_spec_1', + specFileExtension: '.cy.js', + relativeToCommonRoot: 'run_events_spec_1.cy.js', + specType: 'integration', + name: 'run_events_spec_1.cy.js', + relative: 'cypress/e2e/run_events_spec_1.cy.js', + absolute: '/foo/bar/.projects/plugin-run-events/cypress/e2e/run_events_spec_1.cy.js' +} +----> before:spec: Promise resolved! + + + ✓ is true + + 1 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: false │ + │ Duration: X seconds │ + │ Spec Ran: run_events_spec_1.cy.js │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: run_events_spec_2.cy.js (2 of 2) +<---- before:spec promise start +received args { + fileExtension: '.js', + baseName: 'run_events_spec_2.cy.js', + fileName: 'run_events_spec_2', + specFileExtension: '.cy.js', + relativeToCommonRoot: 'run_events_spec_2.cy.js', + specType: 'integration', + name: 'run_events_spec_2.cy.js', + relative: 'cypress/e2e/run_events_spec_2.cy.js', + absolute: '/foo/bar/.projects/plugin-run-events/cypress/e2e/run_events_spec_2.cy.js' +} +----> before:spec: Promise resolved! + + + ✓ is true + + 1 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: false │ + │ Duration: X seconds │ + │ Spec Ran: run_events_spec_2.cy.js │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ run_events_spec_1.cy.js XX:XX 1 1 - - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✔ run_events_spec_2.cy.js XX:XX 1 1 - - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✔ All specs passed! XX:XX 2 2 - - - + + +` diff --git a/system-tests/lib/system-tests.ts b/system-tests/lib/system-tests.ts index ada6c36d09..06b919da2b 100644 --- a/system-tests/lib/system-tests.ts +++ b/system-tests/lib/system-tests.ts @@ -487,7 +487,6 @@ const localItFn = function (title: string, opts: ItOptions) { skip: false, browser: [], snapshot: false, - spec: 'no spec name supplied!', onStdout: _.noop, onRun (execFn, browser, ctx) { return execFn() diff --git a/system-tests/projects/plugin-after-spec-deletes-video/cypress/e2e/after_spec_deletes_video.cy.js b/system-tests/projects/plugin-after-spec-deletes-video/cypress/e2e/after_spec_deletes_video.cy.js deleted file mode 100644 index 582cc9815a..0000000000 --- a/system-tests/projects/plugin-after-spec-deletes-video/cypress/e2e/after_spec_deletes_video.cy.js +++ /dev/null @@ -1 +0,0 @@ -it('is true', () => {}) diff --git a/system-tests/projects/plugin-run-event-throws/cypress/e2e/run_event_throws.cy.js b/system-tests/projects/plugin-run-event-throws/cypress/e2e/run_event_throws.cy.js deleted file mode 100644 index 582cc9815a..0000000000 --- a/system-tests/projects/plugin-run-event-throws/cypress/e2e/run_event_throws.cy.js +++ /dev/null @@ -1 +0,0 @@ -it('is true', () => {}) diff --git a/system-tests/projects/plugin-after-spec-deletes-video/cypress.config.js b/system-tests/projects/plugin-run-events/cypress.config.afterSpec.deleteVideo.js similarity index 74% rename from system-tests/projects/plugin-after-spec-deletes-video/cypress.config.js rename to system-tests/projects/plugin-run-events/cypress.config.afterSpec.deleteVideo.js index 5aefb7ff45..d294845ca8 100644 --- a/system-tests/projects/plugin-after-spec-deletes-video/cypress.config.js +++ b/system-tests/projects/plugin-run-events/cypress.config.afterSpec.deleteVideo.js @@ -1,9 +1,10 @@ const fs = require('fs-extra') module.exports = { - 'fixturesFolder': false, - 'e2e': { - 'supportFile': false, + fixturesFolder: false, + e2e: { + supportFile: false, + video: true, setupNodeEvents (on, config) { on('after:spec', (spec, results) => { return fs.remove(results.video) diff --git a/system-tests/projects/plugin-run-events/cypress.config.beforeSpec.async.js b/system-tests/projects/plugin-run-events/cypress.config.beforeSpec.async.js new file mode 100644 index 0000000000..165ca932d7 --- /dev/null +++ b/system-tests/projects/plugin-run-events/cypress.config.beforeSpec.async.js @@ -0,0 +1,22 @@ +module.exports = { + fixturesFolder: false, + e2e: { + supportFile: false, + video: false, + setupNodeEvents (on, config) { + on('before:spec', (args) => { + console.log('<---- before:spec promise start') + console.log('received args', args) + + return new Promise((res) => { + return setTimeout(() => { + console.log('----> before:spec: Promise resolved!') + res() + }, 5000) + }) + }) + + return config + }, + }, +} diff --git a/system-tests/projects/plugin-run-events/cypress.config.js b/system-tests/projects/plugin-run-events/cypress.config.js index f66e513fe2..a505f47c49 100644 --- a/system-tests/projects/plugin-run-events/cypress.config.js +++ b/system-tests/projects/plugin-run-events/cypress.config.js @@ -8,6 +8,7 @@ module.exports = { experimentalInteractiveRunEvents: true, e2e: { supportFile: false, + video: false, setupNodeEvents (on, config) { on('before:run', (runDetails) => { const { specs, browser } = runDetails diff --git a/system-tests/projects/plugin-run-event-throws/cypress.config.js b/system-tests/projects/plugin-run-events/cypress.config.runEvent.throws.js similarity index 70% rename from system-tests/projects/plugin-run-event-throws/cypress.config.js rename to system-tests/projects/plugin-run-events/cypress.config.runEvent.throws.js index f6609e0864..8f7deba93e 100644 --- a/system-tests/projects/plugin-run-event-throws/cypress.config.js +++ b/system-tests/projects/plugin-run-events/cypress.config.runEvent.throws.js @@ -1,7 +1,8 @@ module.exports = { - 'fixturesFolder': false, - 'e2e': { - 'supportFile': false, + fixturesFolder: false, + e2e: { + supportFile: false, + video: false, setupNodeEvents (on, config) { on('before:spec', () => { throw new Error('error thrown in before:spec') diff --git a/system-tests/test/plugin_run_events_spec.ts b/system-tests/test/plugin_run_events_spec.ts index 9831a16051..adf9289cf8 100644 --- a/system-tests/test/plugin_run_events_spec.ts +++ b/system-tests/test/plugin_run_events_spec.ts @@ -6,29 +6,33 @@ describe('e2e plugin run events', () => { systemTests.it('sends events', { browser: 'electron', project: 'plugin-run-events', - spec: '*', snapshot: true, config: { video: false, }, }) + systemTests.it('handles async before:spec', { + browser: 'electron', + project: 'plugin-run-events', + snapshot: true, + configFile: 'cypress.config.beforeSpec.async.js', + }) + systemTests.it('handles video being deleted in after:spec', { browser: 'electron', - project: 'plugin-after-spec-deletes-video', - spec: '*', + project: 'plugin-run-events', + spec: '*1.cy.js', + configFile: 'cypress.config.afterSpec.deleteVideo.js', snapshot: true, }) systemTests.it('fails run if event handler throws', { browser: 'electron', - project: 'plugin-run-event-throws', - spec: '*', + project: 'plugin-run-events', snapshot: true, expectedExitCode: 1, - config: { - video: false, - }, + configFile: 'cypress.config.runEvent.throws.js', onStdout: (stdout) => { // TODO: Figure out how to fix the race condition on thrown exceptions in before:spec that causes additional electron exceptions to fire: https://github.com/cypress-io/cypress/issues/24102 return stdout.trimRight()