Skip to content

Commit

Permalink
feat: support ct/e2e specific overrides in cypress.json (#15526)
Browse files Browse the repository at this point in the history
Co-authored-by: Dmitriy Kovalenko <dmtr.kovalenko@outlook.com>
  • Loading branch information
lmiller1990 and dmtrKovalenko committed Mar 22, 2021
1 parent 35be2ae commit 43c8ae2
Show file tree
Hide file tree
Showing 47 changed files with 409 additions and 116 deletions.
10 changes: 10 additions & 0 deletions cli/schema/cypress.schema.json
Expand Up @@ -276,6 +276,16 @@
"type": "boolean",
"default": false,
"description": "Enables including elements within the shadow DOM when using querying commands (e.g. cy.get(), cy.find()). Can be set globally in cypress.json, per-suite or per-test in the test configuration object, or programmatically with Cypress.config()"
},
"component": {
"type": "object",
"default": {},
"description": "Any component runner specific overrides"
},
"e2e": {
"type": "object",
"default": {},
"description": "Any e2e runner specific overrides"
}
}
}
16 changes: 16 additions & 0 deletions cli/types/cypress.d.ts
Expand Up @@ -2608,6 +2608,18 @@ declare namespace Cypress {
* @default false
*/
includeShadowDom: boolean

/**
* Override default config options for Component Testing runner.
* @default {}
*/
component: ResolvedConfigOptions

/**
* Override default config options for E2E Testing runner.
* @default {}
*/
e2e: ResolvedConfigOptions
}

/**
Expand Down Expand Up @@ -2732,6 +2744,10 @@ declare namespace Cypress {
* Absolute path to the root of the project
*/
projectRoot: string
/**
* Type of test and associated runner that was launched.
*/
testingType: 'e2e' | 'component'
/**
* Cypress version.
*/
Expand Down
7 changes: 5 additions & 2 deletions npm/create-cypress-tests/__snapshots__/babel.test.ts.js
Expand Up @@ -4,7 +4,10 @@ const injectDevServer = require('@cypress/react/plugins/babel');
const something = require("something");
module.exports = (on, config) => {
injectDevServer(on, config);
return config; // IMPORTANT to return the config object
if (config.testingType === "component") {
injectDevServer(on, config);
}
return config; // IMPORTANT to return a config
};
`
Expand Up @@ -10,8 +10,11 @@ exports['Injected overridden webpack template plugins/index.js'] = `
const injectDevServer = require("@cypress/react/plugins/react-scripts");
module.exports = (on, config) => {
injectDevServer(on, config);
return config; // IMPORTANT to return the config object
if (config.testingType === "component") {
injectDevServer(on, config);
}
return config; // IMPORTANT to return a config
};
`
Expand All @@ -32,8 +35,11 @@ exports['injects guessed next.js template plugins/index.js'] = `
const injectDevServer = require("@cypress/react/plugins/next");
module.exports = (on, config) => {
injectDevServer(on, config);
return config; // IMPORTANT to return the config object
if (config.testingType === "component") {
injectDevServer(on, config);
}
return config; // IMPORTANT to return a config
};
`
7 changes: 5 additions & 2 deletions npm/create-cypress-tests/__snapshots__/next.test.ts.js
Expand Up @@ -4,7 +4,10 @@ const injectDevServer = require('@cypress/react/plugins/next');
const something = require("something");
module.exports = (on, config) => {
injectDevServer(on, config);
return config; // IMPORTANT to return the config object
if (config.testingType === "component") {
injectDevServer(on, config);
}
return config; // IMPORTANT to return a config
};
`
Expand Up @@ -4,7 +4,10 @@ const injectDevServer = require('@cypress/react/plugins/react-scripts');
const something = require("something");
module.exports = (on, config) => {
injectDevServer(on, config);
return config; // IMPORTANT to return the config object
if (config.testingType === "component") {
injectDevServer(on, config);
}
return config; // IMPORTANT to return a config
};
`
22 changes: 15 additions & 7 deletions npm/create-cypress-tests/__snapshots__/reactWebpackFile.test.ts.js
Expand Up @@ -4,10 +4,14 @@ const injectDevServer = require("@cypress/react/plugins/load-webpack");
const something = require("something");
module.exports = (on, config) => {
// TODO replace with valid webpack config path
config.env.webpackFilename = './webpack.config.js';
injectDevServer(on, config);
return config; // IMPORTANT to return the config object
if (config.testingType === "component") {
injectDevServer(on, config, {
// TODO replace with valid webpack config path
webpackFileName: './webpack.config.js'
});
}
return config; // IMPORTANT to return a config
};
`

Expand All @@ -17,8 +21,12 @@ const injectDevServer = require("@cypress/react/plugins/load-webpack");
const something = require("something");
module.exports = (on, config) => {
config.env.webpackFilename = 'config/webpack.config.js';
injectDevServer(on, config);
return config; // IMPORTANT to return the config object
if (config.testingType === "component") {
injectDevServer(on, config, {
webpackFileName: 'config/webpack.config.js'
});
}
return config; // IMPORTANT to return a config
};
`
30 changes: 17 additions & 13 deletions npm/create-cypress-tests/__snapshots__/rollup.test.ts.js
Expand Up @@ -8,14 +8,16 @@ const {
const something = require("something");
module.exports = (on, config) => {
on("dev-server:start", async options => {
return startDevServer({
options,
// TODO replace with valid rollup config path
rollupConfig: path.resolve(__dirname, 'rollup.config.js')
if (config.testingType === "component") {
on("dev-server:start", async options => {
return startDevServer({
options,
// TODO replace with valid rollup config path
rollupConfig: path.resolve(__dirname, 'rollup.config.js')
});
});
});
return config; // IMPORTANT to return the config object
return config; // IMPORTANT to return the config object
}
};
`

Expand All @@ -29,12 +31,14 @@ const {
const something = require("something");
module.exports = (on, config) => {
on("dev-server:start", async options => {
return startDevServer({
options,
rollupConfig: path.resolve(__dirname, 'config/rollup.config.js')
if (config.testingType === "component") {
on("dev-server:start", async options => {
return startDevServer({
options,
rollupConfig: path.resolve(__dirname, 'config/rollup.config.js')
});
});
});
return config; // IMPORTANT to return the config object
return config; // IMPORTANT to return the config object
}
};
`
8 changes: 5 additions & 3 deletions npm/create-cypress-tests/__snapshots__/vite.test.ts.js
Expand Up @@ -6,8 +6,10 @@ const {
const something = require("something");
module.exports = (on, config) => {
on("dev-server:start", async options => startDevServer({
options
}));
if (config.testingType === "component") {
on("dev-server:start", async options => startDevServer({
options
}));
}
};
`
10 changes: 6 additions & 4 deletions npm/create-cypress-tests/__snapshots__/vueCli.test.ts.js
Expand Up @@ -8,9 +8,11 @@ const webpackConfig = require("@vue/cli-service/webpack.config.js");
const something = require("something");
module.exports = (on, config) => {
on('dev-server:start', options => startDevServer({
options,
webpackConfig
}));
if (config.testingType === "component") {
on('dev-server:start', options => startDevServer({
options,
webpackConfig
}));
}
};
`
20 changes: 12 additions & 8 deletions npm/create-cypress-tests/__snapshots__/vueWebpackFile.test.ts.js
Expand Up @@ -9,10 +9,12 @@ const webpackConfig = require("./webpack.config.js"); // TODO replace with valid
const something = require("something");
module.exports = (on, config) => {
on('dev-server:start', options => startDevServer({
options,
webpackConfig
}));
if (config.testingType === "component") {
on('dev-server:start', options => startDevServer({
options,
webpackConfig
}));
}
};
`

Expand All @@ -26,9 +28,11 @@ const webpackConfig = require("build/webpack.config.js");
const something = require("something");
module.exports = (on, config) => {
on('dev-server:start', options => startDevServer({
options,
webpackConfig
}));
if (config.testingType === "component") {
on('dev-server:start', options => startDevServer({
options,
webpackConfig
}));
}
};
`
54 changes: 28 additions & 26 deletions npm/create-cypress-tests/__snapshots__/webpackOptions.test.ts.js
Expand Up @@ -8,31 +8,33 @@ const {
const something = require("something");
module.exports = (on, config) => {
/** @type import("webpack").Configuration */
const webpackConfig = {
resolve: {
extensions: ['.js', '.ts', '.jsx', '.tsx']
},
mode: 'development',
devtool: false,
output: {
publicPath: '/',
chunkFilename: '[name].bundle.js'
},
// TODO: update with valid configuration for your components
module: {
rules: [{
test: /\\.(js|jsx|mjs|ts|tsx)$/,
loader: 'babel-loader',
options: {
cacheDirectory: path.resolve(__dirname, '.babel-cache')
}
}]
}
};
on('dev-server:start', options => startDevServer({
options,
webpackConfig
}));
if (config.testingType === "component") {
/** @type import("webpack").Configuration */
const webpackConfig = {
resolve: {
extensions: ['.js', '.ts', '.jsx', '.tsx']
},
mode: 'development',
devtool: false,
output: {
publicPath: '/',
chunkFilename: '[name].bundle.js'
},
// TODO: update with valid configuration for your components
module: {
rules: [{
test: /\\.(js|jsx|mjs|ts|tsx)$/,
loader: 'babel-loader',
options: {
cacheDirectory: path.resolve(__dirname, '.babel-cache')
}
}]
}
};
on('dev-server:start', options => startDevServer({
options,
webpackConfig
}));
}
};
`
Expand Up @@ -6,8 +6,8 @@ describe('babel transform utils', () => {
context('Plugins config babel plugin', () => {
it('injects code into the plugins file based on ast', () => {
const plugin = createTransformPluginsFileBabelPlugin({
Require: babel.template.ast('require("something")'),
ModuleExportsBody: babel.template.ast('yey()'),
RequireAst: babel.template.ast('require("something")'),
IfComponentTestingPluginsAst: babel.template.ast('yey()'),
})

const output = babel.transformSync([
Expand All @@ -23,7 +23,10 @@ describe('babel transform utils', () => {
'',
'module.exports = (on, config) => {',
' on("do");',
' yey();',
'',
' if (config.testingType === "component") {',
' yey();',
' }',
'};',
].join(`\n`))
})
Expand Down
Expand Up @@ -3,7 +3,13 @@ import * as fs from 'fs-extra'
import * as babel from '@babel/core'
import * as babelTypes from '@babel/types'

export type PluginsConfigAst = Record<'Require' | 'ModuleExportsBody', ReturnType<typeof babel.template.ast>>
type AST = ReturnType<typeof babel.template.ast>

export type PluginsConfigAst = {
RequireAst: AST
IfComponentTestingPluginsAst: AST
requiresReturnConfig?: true
}

function tryRequirePrettier () {
try {
Expand Down Expand Up @@ -48,11 +54,13 @@ async function transformFileViaPlugin (filePath: string, babelPlugin: babel.Plug
}
}

const returnConfigAst = babel.template.ast('return config; // IMPORTANT to return a config', { preserveComments: true })

export function createTransformPluginsFileBabelPlugin (ast: PluginsConfigAst): babel.PluginObj {
return {
visitor: {
Program: (path) => {
path.unshiftContainer('body', ast.Require)
path.unshiftContainer('body', ast.RequireAst)
},
Function: (path) => {
if (!babelTypes.isAssignmentExpression(path.parent)) {
Expand Down Expand Up @@ -80,7 +88,24 @@ export function createTransformPluginsFileBabelPlugin (ast: PluginsConfigAst): b
path.parent.right.params.push(babelTypes.identifier('config'))
}

path.get('body').pushContainer('body' as never, ast.ModuleExportsBody)
const statementToInject = Array.isArray(ast.IfComponentTestingPluginsAst)
? ast.IfComponentTestingPluginsAst
: [ast.IfComponentTestingPluginsAst]

const ifComponentMode = babelTypes.ifStatement(
babelTypes.binaryExpression(
'===',
babelTypes.identifier('config.testingType'),
babelTypes.stringLiteral('component'),
),
babelTypes.blockStatement(statementToInject as babelTypes.Statement[] | babelTypes.Statement[]),
)

path.get('body').pushContainer('body' as never, ifComponentMode as babel.Node)

if (ast.requiresReturnConfig) {
path.get('body').pushContainer('body' as never, returnConfigAst)
}
}
},
},
Expand Down

4 comments on commit 43c8ae2

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 43c8ae2 Mar 22, 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.9.0/circle-develop-43c8ae2a7c20ba70a0bb0b45b8f6a086e2782f29/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 43c8ae2 Mar 22, 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.9.0/appveyor-develop-43c8ae2a7c20ba70a0bb0b45b8f6a086e2782f29/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 43c8ae2 Mar 22, 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.9.0/appveyor-develop-43c8ae2a7c20ba70a0bb0b45b8f6a086e2782f29/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 43c8ae2 Mar 22, 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.9.0/circle-develop-43c8ae2a7c20ba70a0bb0b45b8f6a086e2782f29/cypress.tgz

Please sign in to comment.