Skip to content

Commit

Permalink
feat: Fire run events in interactive mode (#15787)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbreiding authored Apr 12, 2021
1 parent dde2f22 commit b53f04e
Show file tree
Hide file tree
Showing 12 changed files with 318 additions and 46 deletions.
5 changes: 5 additions & 0 deletions cli/schema/cypress.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@
"default": "bundled",
"description": "If set to 'system', Cypress will try to find a Node.js executable on your path to use when executing your plugins. Otherwise, Cypress will use the Node version bundled with Cypress."
},
"experimentalInteractiveRunEvents": {
"type": "boolean",
"default": false,
"description": "Allows listening to the `before:run`, `after:run`, `before:spec`, and `after:spec` events in the plugins file during interactive mode."
},
"experimentalSourceRewriting": {
"type": "boolean",
"default": false,
Expand Down
20 changes: 12 additions & 8 deletions cli/types/cypress.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2615,8 +2615,12 @@ declare namespace Cypress {
*/
firefoxGcInterval: Nullable<number | { runMode: Nullable<number>, openMode: Nullable<number> }>
/**
* Enables AST-based JS/HTML rewriting. This may fix issues caused by the existing regex-based JS/HTML replacement
* algorithm.
* Allows listening to the `before:run`, `after:run`, `before:spec`, and `after:spec` events in the plugins file during interactive mode.
* @default false
*/
experimentalInteractiveRunEvents: boolean
/**
* Generate and save commands directly to your test suite by interacting with your app as an end user would.
* @default false
*/
experimentalSourceRewriting: boolean
Expand Down Expand Up @@ -5159,22 +5163,22 @@ declare namespace Cypress {
}

interface BeforeRunDetails {
browser: Browser
browser?: Browser
config: ConfigOptions
cypressVersion: string
group?: string
parallel: boolean
parallel?: boolean
runUrl?: string
specs: Spec[]
specPattern: string[]
specs?: Spec[]
specPattern?: string[]
system: SystemDetails
tag?: string
}

interface DevServerOptions {
specs: Spec[]
config: ResolvedConfigOptions & RuntimeConfigOptions,
devServerEvents: NodeJS.EventEmitter,
config: ResolvedConfigOptions & RuntimeConfigOptions
devServerEvents: NodeJS.EventEmitter
}

interface ResolvedDevServerConfig {
Expand Down
12 changes: 8 additions & 4 deletions packages/desktop-gui/src/projects/projects-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const runSpec = (project, spec, browser, specFilter) => {
.then(launchBrowser)
}

const closeBrowser = (project, spec) => {
const onBrowserClose = (project, spec) => {
if (!spec) {
specsStore.setChosenSpec(null)
}
Expand All @@ -112,6 +112,10 @@ const closeBrowser = (project, spec) => {
}

ipc.offLaunchBrowser()
}

const closeBrowser = (project, spec) => {
onBrowserClose(project, spec)

return ipc.closeBrowser()
}
Expand All @@ -127,10 +131,10 @@ const closeProject = (project) => {
ipc.offOnProjectWarning()
ipc.offOnConfigChanged()

return Promise.join(
closeBrowser(project),
return Promise.all([
onBrowserClose(project),
ipc.closeProject(),
)
])
}

const openProject = (project) => {
Expand Down
1 change: 0 additions & 1 deletion packages/server/lib/browsers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,5 +233,4 @@ module.exports = {
})
})
},

}
5 changes: 5 additions & 0 deletions packages/server/lib/config_options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export const options = [
defaultValue: false,
validation: v.isBoolean,
isExperimental: true,
}, {
name: 'experimentalInteractiveRunEvents',
defaultValue: false,
validation: v.isBoolean,
isExperimental: true,
}, {
name: 'experimentalSourceRewriting',
defaultValue: false,
Expand Down
2 changes: 2 additions & 0 deletions packages/server/lib/experiments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ interface StringValues {
*/
const _summaries: StringValues = {
experimentalFetchPolyfill: 'Polyfills `window.fetch` to enable Network spying and stubbing.',
experimentalInteractiveRunEvents: 'Allows listening to the `before:run`, `after:run`, `before:spec`, and `after:spec` events in the plugins file during interactive mode.',
experimentalSourceRewriting: 'Enables AST-based JS/HTML rewriting. This may fix issues caused by the existing regex-based JS/HTML replacement algorithm.',
experimentalStudio: 'Generate and save commands directly to your test suite by interacting with your app as an end user would.',
}
Expand All @@ -68,6 +69,7 @@ const _summaries: StringValues = {
*/
const _names: StringValues = {
experimentalFetchPolyfill: 'Fetch polyfill',
experimentalInteractiveRunEvents: 'Interactive Mode Run Events',
experimentalSourceRewriting: 'Improved source rewriting',
experimentalStudio: 'Studio',
}
Expand Down
35 changes: 28 additions & 7 deletions packages/server/lib/open_project.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { ProjectE2E } = require('./project-e2e')
const browsers = require('./browsers')
const specsUtil = require('./util/specs')
const preprocessor = require('./plugins/preprocessor')
const runEvents = require('./plugins/run_events')

const moduleFactory = () => {
let openProject = null
Expand Down Expand Up @@ -123,13 +124,24 @@ const moduleFactory = () => {
})
}

const afterSpec = () => {
if (!openProject || cfg.isTextTerminal || !cfg.experimentalInteractiveRunEvents) return Promise.resolve()

return runEvents.execute('after:spec', cfg, spec)
}

const { onBrowserClose } = options

options.onBrowserClose = () => {
if (spec && spec.absolute) {
preprocessor.removeFile(spec.absolute, cfg)
}

afterSpec(cfg, spec)
.catch((err) => {
openProject.options.onError(err)
})

if (onBrowserClose) {
return onBrowserClose()
}
Expand All @@ -144,7 +156,14 @@ const moduleFactory = () => {
spec.relative,
)

return browsers.open(browser, options, automation)
return Promise.try(() => {
if (!cfg.isTextTerminal && cfg.experimentalInteractiveRunEvents) {
return runEvents.execute('before:spec', cfg, spec)
}
})
.then(() => {
return browsers.open(browser, options, automation)
})
}

return relaunchBrowser()
Expand Down Expand Up @@ -216,8 +235,7 @@ const moduleFactory = () => {
return get()
.then(sendIfChanged)
.catch(options.onError)
},
250, { leading: true })
}, 250, { leading: true })

const createSpecsWatcher = (cfg) => {
// TODO I keep repeating this to get the resolved value
Expand Down Expand Up @@ -287,10 +305,10 @@ const moduleFactory = () => {
},

closeOpenProjectAndBrowsers () {
return Promise.all([
this.closeBrowser(),
openProject ? openProject.close() : undefined,
])
return this.closeBrowser()
.then(() => {
return openProject && openProject.close()
})
.then(() => {
reset()

Expand Down Expand Up @@ -335,6 +353,9 @@ const moduleFactory = () => {
return openProject.open({ ...options, testingType: args.testingType })
.return(this)
},

// for testing purposes
__reset: reset,
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/server/lib/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ const init = (config, options) => {

// no argument is passed for cy.task()
// This is necessary because undefined becomes null when it is sent through ipc.
if (args[1] === undefined) {
if (registration.event === 'task' && args[1] === undefined) {
args[1] = {
__cypress_task_no_argument__: true,
}
Expand Down
27 changes: 25 additions & 2 deletions packages/server/lib/project-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import la from 'lazy-ass'
import _ from 'lodash'
import path from 'path'
import R from 'ramda'

import commitInfo from '@cypress/commit-info'
import pkg from '@packages/root'
import { RunnablesStore } from '@packages/reporter'
import { ServerCt } from '@packages/server-ct'
import api from './api'
Expand All @@ -19,9 +21,11 @@ import cwd from './cwd'
import errors from './errors'
import logger from './logger'
import Reporter from './reporter'
import runEvents from './plugins/run_events'
import savedState from './saved_state'
import scaffold from './scaffold'
import { ServerE2E } from './server-e2e'
import system from './util/system'
import user from './user'
import { ensureProp } from './util/class-helpers'
import { escapeFilenameInUrl } from './util/escape_filename'
Expand All @@ -40,8 +44,6 @@ interface OpenOptions {
onAfterOpen: (cfg: any) => Bluebird<any>
}

// type ProjectOptions = Record<string, any>

export type Cfg = Record<string, any>

const localCwd = cwd()
Expand Down Expand Up @@ -183,6 +185,20 @@ export class ProjectBase<TServer extends ServerE2E | ServerCt> extends EE {
this.watchPluginsFile(cfg, options),
)
})
.then(() => {
if (cfg.isTextTerminal || !cfg.experimentalInteractiveRunEvents) return

return system.info()
.then((sys) => {
const beforeRunDetails = {
config: cfg,
cypressVersion: pkg.version,
system: _.pick(sys, 'osName', 'osVersion'),
}

return runEvents.execute('before:run', cfg, beforeRunDetails)
})
})
})
.return(this)
}
Expand Down Expand Up @@ -227,6 +243,13 @@ export class ProjectBase<TServer extends ServerE2E | ServerCt> extends EE {
)
.then(() => {
process.chdir(localCwd)

return this.getConfig()
})
.then((config) => {
if (config.isTextTerminal || !config.experimentalInteractiveRunEvents) return

return runEvents.execute('after:run', config)
})
}

Expand Down
2 changes: 2 additions & 0 deletions packages/server/test/unit/config_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,7 @@ describe('lib/config', () => {
env: {},
execTimeout: { value: 60000, from: 'default' },
experimentalFetchPolyfill: { value: false, from: 'default' },
experimentalInteractiveRunEvents: { value: false, from: 'default' },
experimentalSourceRewriting: { value: false, from: 'default' },
experimentalStudio: { value: false, from: 'default' },
fileServerFolder: { value: '', from: 'default' },
Expand Down Expand Up @@ -1411,6 +1412,7 @@ describe('lib/config', () => {
e2e: { from: 'default', value: {} },
execTimeout: { value: 60000, from: 'default' },
experimentalFetchPolyfill: { value: false, from: 'default' },
experimentalInteractiveRunEvents: { value: false, from: 'default' },
experimentalSourceRewriting: { value: false, from: 'default' },
experimentalStudio: { value: false, from: 'default' },
env: {
Expand Down
Loading

4 comments on commit b53f04e

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on b53f04e Apr 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/7.1.0/circle-develop-b53f04e4f734b25078ec926eac88a93ff58ce205/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on b53f04e Apr 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppVeyor has built the win32 ia32 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/7.1.0/appveyor-develop-b53f04e4f734b25078ec926eac88a93ff58ce205/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on b53f04e Apr 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppVeyor has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/7.1.0/appveyor-develop-b53f04e4f734b25078ec926eac88a93ff58ce205/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on b53f04e Apr 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/7.1.0/circle-develop-b53f04e4f734b25078ec926eac88a93ff58ce205/cypress.tgz

Please sign in to comment.