Skip to content

Commit

Permalink
feat: support ct/e2e specific overrides in cypress.json (#15444)
Browse files Browse the repository at this point in the history
Co-authored-by: ElevateBart <ledouxb@gmail.com>
Co-authored-by: Jessica Sachs <jess@jessicasachs.io>
  • Loading branch information
3 people committed Mar 13, 2021
1 parent 2871b19 commit a94c9d5
Show file tree
Hide file tree
Showing 22 changed files with 416 additions and 296 deletions.
563 changes: 288 additions & 275 deletions cli/schema/cypress.schema.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cli/types/cypress.d.ts
Expand Up @@ -8,7 +8,7 @@ declare namespace Cypress {
type RequestBody = string | object
type ViewportOrientation = 'portrait' | 'landscape'
type PrevSubject = 'optional' | 'element' | 'document' | 'window'
type PluginConfig = (on: PluginEvents, config: PluginConfigOptions) => void | ConfigOptions | Promise<ConfigOptions>
type PluginConfig = (on: PluginEvents, config: PluginConfigOptions, mode: 'e2e' | 'component') => void | ConfigOptions | Promise<ConfigOptions>

interface CommandOptions {
prevSubject: boolean | PrevSubject | PrevSubject[]
Expand Down
6 changes: 5 additions & 1 deletion npm/react/cypress/plugins/index.js
Expand Up @@ -60,7 +60,11 @@ const webpackConfig = {
/**
* @type Cypress.PluginConfig
*/
module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'component') {
throw Error('This is an component project. mode should be `component`.')
}

on('dev-server:start', (options) => {
return startDevServer({ options, webpackConfig, disableLazyCompilation: false })
})
Expand Down
6 changes: 5 additions & 1 deletion npm/vue/cypress/plugins/index.js
Expand Up @@ -5,7 +5,11 @@ const webpackConfig = require('../../webpack.config')
/**
* @type Cypress.PluginConfig
*/
module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'component') {
throw Error('This is a component testing project. mode should be `component`.')
}

require('@cypress/code-coverage/task')(on, config)
on('dev-server:start', (options) => startDevServer({ options, webpackConfig }))

Expand Down
3 changes: 2 additions & 1 deletion packages/server-ct/src/project-ct.ts
Expand Up @@ -47,7 +47,7 @@ export class ProjectCt extends ProjectBase<ServerCt> {
this.server.socket.changeToUrl(targetUrl)
}

open (options) {
open (options: Record<string, unknown>) {
this._server = new ServerCt()

return super.open(options, {
Expand Down Expand Up @@ -85,6 +85,7 @@ export class ProjectCt extends ProjectBase<ServerCt> {
return plugins.init(allowedCfg, {
projectRoot: this.projectRoot,
configFile: settings.pathToConfigFile(this.projectRoot, options),
mode: options.mode,
})
.then((modifiedCfg) => {
debug('plugin config yielded: %o', modifiedCfg)
Expand Down
2 changes: 1 addition & 1 deletion packages/server/lib/open_project.js
Expand Up @@ -328,7 +328,7 @@ const moduleFactory = () => {
debug('opening project %s', path)
debug('and options %o', options)

return openProject.open(options)
return openProject.open({ ...options, mode: args.testingType })
.return(this)
},
}
Expand Down
14 changes: 10 additions & 4 deletions packages/server/lib/plugins/child/run_plugins.js
Expand Up @@ -37,7 +37,13 @@ const getDefaultPreprocessor = function (config) {

let plugins

const load = (ipc, config, pluginsFile) => {
/**
* @param {EventEmitter} ipc
* @param {object} config
* @param {string} pluginsFile
* @param {'component' | 'e2e'} string
*/
const load = (ipc, config, pluginsFile, mode) => {
debug('run plugins function')

let eventIdCount = 0
Expand Down Expand Up @@ -87,7 +93,7 @@ const load = (ipc, config, pluginsFile) => {
.try(() => {
debug('run plugins function')

return plugins(register, config)
return plugins(register, config, mode)
})
.tap(() => {
if (!registeredEventsByName['file:preprocessor']) {
Expand Down Expand Up @@ -192,10 +198,10 @@ const runPlugins = (ipc, pluginsFile, projectRoot) => {
return
}

ipc.on('load', (config) => {
ipc.on('load', (config, mode) => {
debug('plugins load file "%s"', pluginsFile)
debug('passing config %o', config)
load(ipc, config, pluginsFile)
load(ipc, config, pluginsFile, mode)
})

ipc.on('execute', (event, ids, args) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/lib/plugins/index.js
Expand Up @@ -113,7 +113,7 @@ const init = (config, options) => {
version: pkg.version,
})

ipc.send('load', config)
ipc.send('load', config, options.mode)

ipc.on('loaded', (newCfg, registrations) => {
_.omit(config, 'projectRoot', 'configFile')
Expand Down
3 changes: 2 additions & 1 deletion packages/server/lib/project-e2e.ts
Expand Up @@ -14,7 +14,7 @@ export class ProjectE2E extends ProjectBase<ServerE2E> {
return 'e2e'
}

open (options) {
open (options: Record<string, unknown>) {
this._server = new ServerE2E()

return super.open(options, {
Expand Down Expand Up @@ -59,6 +59,7 @@ export class ProjectE2E extends ProjectBase<ServerE2E> {
return plugins.init(cfg, {
projectRoot: this.projectRoot,
configFile: settings.pathToConfigFile(this.projectRoot, options),
mode: options.mode,
onError (err) {
debug('got plugins error', err.stack)

Expand Down
14 changes: 14 additions & 0 deletions packages/server/lib/util/settings.js
Expand Up @@ -93,6 +93,10 @@ module.exports = {
}, _.cloneDeep(obj))
},

isComponentTesting (options = {}) {
return options.experimentalComponentTesting || options.componentTesting || options.testingType === 'component'
},

configFile (options = {}) {
return options.configFile === false ? false : (options.configFile || 'cypress.json')
},
Expand Down Expand Up @@ -151,6 +155,16 @@ module.exports = {
.catch({ code: 'ENOENT' }, () => {
return this._write(file, {})
}).then((json = {}) => {
if (this.isComponentTesting(options) && 'component' in json) {
json = { ...json, ...json.component }
delete json.component
}

if (!this.isComponentTesting(options) && 'e2e' in json) {
json = { ...json, ...json.e2e }
delete json.e2e
}

const changed = this._applyRewriteRules(json)

// if our object is unchanged
Expand Down
1 change: 1 addition & 0 deletions packages/server/test/integration/plugins_spec.js
Expand Up @@ -26,6 +26,7 @@ describe('lib/plugins', () => {

const options = {
onWarning,
mode: 'e2e',
}

return plugins.init(projectConfig, options)
Expand Down
Expand Up @@ -3,7 +3,11 @@ const { expect } = require('chai')
const fse = require('fs-extra')
const path = require('path')

module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

const parentPid = process.ppid
let { PATH_TO_CHROME_PROFILE } = config.env

Expand Down
Expand Up @@ -13,7 +13,11 @@ const webpackConfig = {
/**
* @type Cypress.PluginConfig
*/
module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

require('@cypress/code-coverage/task')(on, config)
on('dev-server:start', (options) => startDevServer({ options, webpackConfig }))

Expand Down
Expand Up @@ -11,7 +11,11 @@ const { useFixedFirefoxResolution } = require('../../../utils')
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

let performance = {
track: () => Promise.resolve(),
}
Expand Down
Expand Up @@ -20,7 +20,11 @@ let timings = []
let rss = []
let intervalId

module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

on('task', {
'console' (...args) {
console.log(...args)
Expand Down
Expand Up @@ -109,7 +109,11 @@ const getHandlersByType = (type) => {
}
}

module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

const beforeBrowserLaunchHandler = config.env.BEFORE_BROWSER_LAUNCH_HANDLER

if (!beforeBrowserLaunchHandler) {
Expand Down
@@ -1,6 +1,10 @@
const semver = require('semver')

module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

if (!semver.valid(config.version)) {
throw new Error('config.version is invalid')
}
Expand Down
@@ -1,4 +1,8 @@
module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

return new Promise((resolve) => {
setTimeout(resolve, 100)
})
Expand Down
@@ -1,4 +1,8 @@
module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

if (config.env.NO_MUTATE_RETURN) {
on('before:browser:launch', (browser, options) => {
// this will emit a warning
Expand Down
@@ -1,7 +1,11 @@
const fs = require('fs')
const { expect } = require('chai')

module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

expect(process.geteuid()).to.not.eq(0)
console.log('✅ not running as root')

Expand Down
Expand Up @@ -5,7 +5,11 @@ const { useFixedFirefoxResolution } = require('../../../utils')
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
module.exports = (on, config, mode) => {
if (mode !== 'e2e') {
throw Error('This is an e2e project. mode should be `e2e`.')
}

on('before:browser:launch', (browser, options) => {
useFixedFirefoxResolution(browser, options, config)

Expand Down
36 changes: 36 additions & 0 deletions packages/server/test/unit/settings_spec.js
Expand Up @@ -111,6 +111,42 @@ describe('lib/settings', () => {
})
})

it('promises cypress.json and merges CT specific properties for via testingType: component', function () {
return this.setup({ a: 'b', component: { a: 'c' } })
.then(() => {
return settings.read(projectRoot, { testingType: 'component' })
}).then((obj) => {
expect(obj).to.deep.eq({ a: 'c' })
})
})

it('promises cypress.json and merges CT specific properties for via componentTesting: true', function () {
return this.setup({ a: 'b', component: { a: 'c' } })
.then(() => {
return settings.read(projectRoot, { componentTesting: true })
}).then((obj) => {
expect(obj).to.deep.eq({ a: 'c' })
})
})

it('promises cypress.json and merges CT specific properties for via experimentalComponentTesting: true', function () {
return this.setup({ a: 'b', component: { a: 'c' } })
.then(() => {
return settings.read(projectRoot, { experimentalComponentTesting: true })
}).then((obj) => {
expect(obj).to.deep.eq({ a: 'c' })
})
})

it('promises cypress.json and merges e2e specific properties', function () {
return this.setup({ a: 'b', e2e: { a: 'c' } })
.then(() => {
return settings.read(projectRoot)
}).then((obj) => {
expect(obj).to.deep.eq({ a: 'c' })
})
})

it('renames commandTimeout -> defaultCommandTimeout', function () {
return this.setup({ commandTimeout: 30000, foo: 'bar' })
.then(() => {
Expand Down

4 comments on commit a94c9d5

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on a94c9d5 Mar 13, 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/6.7.0/circle-develop-a94c9d5ef0da8559f20391fc14396d71fdca7a2f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on a94c9d5 Mar 13, 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/6.7.0/appveyor-develop-a94c9d5ef0da8559f20391fc14396d71fdca7a2f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on a94c9d5 Mar 13, 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/6.7.0/appveyor-develop-a94c9d5ef0da8559f20391fc14396d71fdca7a2f/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on a94c9d5 Mar 13, 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/6.7.0/circle-develop-a94c9d5ef0da8559f20391fc14396d71fdca7a2f/cypress.tgz

Please sign in to comment.