Skip to content

Commit 43c8ae2

Browse files
feat: support ct/e2e specific overrides in cypress.json (#15526)
Co-authored-by: Dmitriy Kovalenko <dmtr.kovalenko@outlook.com>
1 parent 35be2ae commit 43c8ae2

File tree

47 files changed

+409
-116
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+409
-116
lines changed

cli/schema/cypress.schema.json

+10
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,16 @@
276276
"type": "boolean",
277277
"default": false,
278278
"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()"
279+
},
280+
"component": {
281+
"type": "object",
282+
"default": {},
283+
"description": "Any component runner specific overrides"
284+
},
285+
"e2e": {
286+
"type": "object",
287+
"default": {},
288+
"description": "Any e2e runner specific overrides"
279289
}
280290
}
281291
}

cli/types/cypress.d.ts

+16
Original file line numberDiff line numberDiff line change
@@ -2608,6 +2608,18 @@ declare namespace Cypress {
26082608
* @default false
26092609
*/
26102610
includeShadowDom: boolean
2611+
2612+
/**
2613+
* Override default config options for Component Testing runner.
2614+
* @default {}
2615+
*/
2616+
component: ResolvedConfigOptions
2617+
2618+
/**
2619+
* Override default config options for E2E Testing runner.
2620+
* @default {}
2621+
*/
2622+
e2e: ResolvedConfigOptions
26112623
}
26122624

26132625
/**
@@ -2732,6 +2744,10 @@ declare namespace Cypress {
27322744
* Absolute path to the root of the project
27332745
*/
27342746
projectRoot: string
2747+
/**
2748+
* Type of test and associated runner that was launched.
2749+
*/
2750+
testingType: 'e2e' | 'component'
27352751
/**
27362752
* Cypress version.
27372753
*/

npm/create-cypress-tests/__snapshots__/babel.test.ts.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ const injectDevServer = require('@cypress/react/plugins/babel');
44
const something = require("something");
55
66
module.exports = (on, config) => {
7-
injectDevServer(on, config);
8-
return config; // IMPORTANT to return the config object
7+
if (config.testingType === "component") {
8+
injectDevServer(on, config);
9+
}
10+
11+
return config; // IMPORTANT to return a config
912
};
1013
`

npm/create-cypress-tests/__snapshots__/init-component-testing.test.ts.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ exports['Injected overridden webpack template plugins/index.js'] = `
1010
const injectDevServer = require("@cypress/react/plugins/react-scripts");
1111
1212
module.exports = (on, config) => {
13-
injectDevServer(on, config);
14-
return config; // IMPORTANT to return the config object
13+
if (config.testingType === "component") {
14+
injectDevServer(on, config);
15+
}
16+
17+
return config; // IMPORTANT to return a config
1518
};
1619
1720
`
@@ -32,8 +35,11 @@ exports['injects guessed next.js template plugins/index.js'] = `
3235
const injectDevServer = require("@cypress/react/plugins/next");
3336
3437
module.exports = (on, config) => {
35-
injectDevServer(on, config);
36-
return config; // IMPORTANT to return the config object
38+
if (config.testingType === "component") {
39+
injectDevServer(on, config);
40+
}
41+
42+
return config; // IMPORTANT to return a config
3743
};
3844
3945
`

npm/create-cypress-tests/__snapshots__/next.test.ts.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ const injectDevServer = require('@cypress/react/plugins/next');
44
const something = require("something");
55
66
module.exports = (on, config) => {
7-
injectDevServer(on, config);
8-
return config; // IMPORTANT to return the config object
7+
if (config.testingType === "component") {
8+
injectDevServer(on, config);
9+
}
10+
11+
return config; // IMPORTANT to return a config
912
};
1013
`

npm/create-cypress-tests/__snapshots__/react-scripts.test.ts.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ const injectDevServer = require('@cypress/react/plugins/react-scripts');
44
const something = require("something");
55
66
module.exports = (on, config) => {
7-
injectDevServer(on, config);
8-
return config; // IMPORTANT to return the config object
7+
if (config.testingType === "component") {
8+
injectDevServer(on, config);
9+
}
10+
11+
return config; // IMPORTANT to return a config
912
};
1013
`

npm/create-cypress-tests/__snapshots__/reactWebpackFile.test.ts.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ const injectDevServer = require("@cypress/react/plugins/load-webpack");
44
const something = require("something");
55
66
module.exports = (on, config) => {
7-
// TODO replace with valid webpack config path
8-
config.env.webpackFilename = './webpack.config.js';
9-
injectDevServer(on, config);
10-
return config; // IMPORTANT to return the config object
7+
if (config.testingType === "component") {
8+
injectDevServer(on, config, {
9+
// TODO replace with valid webpack config path
10+
webpackFileName: './webpack.config.js'
11+
});
12+
}
13+
14+
return config; // IMPORTANT to return a config
1115
};
1216
`
1317

@@ -17,8 +21,12 @@ const injectDevServer = require("@cypress/react/plugins/load-webpack");
1721
const something = require("something");
1822
1923
module.exports = (on, config) => {
20-
config.env.webpackFilename = 'config/webpack.config.js';
21-
injectDevServer(on, config);
22-
return config; // IMPORTANT to return the config object
24+
if (config.testingType === "component") {
25+
injectDevServer(on, config, {
26+
webpackFileName: 'config/webpack.config.js'
27+
});
28+
}
29+
30+
return config; // IMPORTANT to return a config
2331
};
2432
`

npm/create-cypress-tests/__snapshots__/rollup.test.ts.js

+17-13
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ const {
88
const something = require("something");
99
1010
module.exports = (on, config) => {
11-
on("dev-server:start", async options => {
12-
return startDevServer({
13-
options,
14-
// TODO replace with valid rollup config path
15-
rollupConfig: path.resolve(__dirname, 'rollup.config.js')
11+
if (config.testingType === "component") {
12+
on("dev-server:start", async options => {
13+
return startDevServer({
14+
options,
15+
// TODO replace with valid rollup config path
16+
rollupConfig: path.resolve(__dirname, 'rollup.config.js')
17+
});
1618
});
17-
});
18-
return config; // IMPORTANT to return the config object
19+
return config; // IMPORTANT to return the config object
20+
}
1921
};
2022
`
2123

@@ -29,12 +31,14 @@ const {
2931
const something = require("something");
3032
3133
module.exports = (on, config) => {
32-
on("dev-server:start", async options => {
33-
return startDevServer({
34-
options,
35-
rollupConfig: path.resolve(__dirname, 'config/rollup.config.js')
34+
if (config.testingType === "component") {
35+
on("dev-server:start", async options => {
36+
return startDevServer({
37+
options,
38+
rollupConfig: path.resolve(__dirname, 'config/rollup.config.js')
39+
});
3640
});
37-
});
38-
return config; // IMPORTANT to return the config object
41+
return config; // IMPORTANT to return the config object
42+
}
3943
};
4044
`

npm/create-cypress-tests/__snapshots__/vite.test.ts.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ const {
66
const something = require("something");
77
88
module.exports = (on, config) => {
9-
on("dev-server:start", async options => startDevServer({
10-
options
11-
}));
9+
if (config.testingType === "component") {
10+
on("dev-server:start", async options => startDevServer({
11+
options
12+
}));
13+
}
1214
};
1315
`

npm/create-cypress-tests/__snapshots__/vueCli.test.ts.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ const webpackConfig = require("@vue/cli-service/webpack.config.js");
88
const something = require("something");
99
1010
module.exports = (on, config) => {
11-
on('dev-server:start', options => startDevServer({
12-
options,
13-
webpackConfig
14-
}));
11+
if (config.testingType === "component") {
12+
on('dev-server:start', options => startDevServer({
13+
options,
14+
webpackConfig
15+
}));
16+
}
1517
};
1618
`

npm/create-cypress-tests/__snapshots__/vueWebpackFile.test.ts.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ const webpackConfig = require("./webpack.config.js"); // TODO replace with valid
99
const something = require("something");
1010
1111
module.exports = (on, config) => {
12-
on('dev-server:start', options => startDevServer({
13-
options,
14-
webpackConfig
15-
}));
12+
if (config.testingType === "component") {
13+
on('dev-server:start', options => startDevServer({
14+
options,
15+
webpackConfig
16+
}));
17+
}
1618
};
1719
`
1820

@@ -26,9 +28,11 @@ const webpackConfig = require("build/webpack.config.js");
2628
const something = require("something");
2729
2830
module.exports = (on, config) => {
29-
on('dev-server:start', options => startDevServer({
30-
options,
31-
webpackConfig
32-
}));
31+
if (config.testingType === "component") {
32+
on('dev-server:start', options => startDevServer({
33+
options,
34+
webpackConfig
35+
}));
36+
}
3337
};
3438
`

npm/create-cypress-tests/__snapshots__/webpackOptions.test.ts.js

+28-26
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,33 @@ const {
88
const something = require("something");
99
1010
module.exports = (on, config) => {
11-
/** @type import("webpack").Configuration */
12-
const webpackConfig = {
13-
resolve: {
14-
extensions: ['.js', '.ts', '.jsx', '.tsx']
15-
},
16-
mode: 'development',
17-
devtool: false,
18-
output: {
19-
publicPath: '/',
20-
chunkFilename: '[name].bundle.js'
21-
},
22-
// TODO: update with valid configuration for your components
23-
module: {
24-
rules: [{
25-
test: /\\.(js|jsx|mjs|ts|tsx)$/,
26-
loader: 'babel-loader',
27-
options: {
28-
cacheDirectory: path.resolve(__dirname, '.babel-cache')
29-
}
30-
}]
31-
}
32-
};
33-
on('dev-server:start', options => startDevServer({
34-
options,
35-
webpackConfig
36-
}));
11+
if (config.testingType === "component") {
12+
/** @type import("webpack").Configuration */
13+
const webpackConfig = {
14+
resolve: {
15+
extensions: ['.js', '.ts', '.jsx', '.tsx']
16+
},
17+
mode: 'development',
18+
devtool: false,
19+
output: {
20+
publicPath: '/',
21+
chunkFilename: '[name].bundle.js'
22+
},
23+
// TODO: update with valid configuration for your components
24+
module: {
25+
rules: [{
26+
test: /\\.(js|jsx|mjs|ts|tsx)$/,
27+
loader: 'babel-loader',
28+
options: {
29+
cacheDirectory: path.resolve(__dirname, '.babel-cache')
30+
}
31+
}]
32+
}
33+
};
34+
on('dev-server:start', options => startDevServer({
35+
options,
36+
webpackConfig
37+
}));
38+
}
3739
};
3840
`

npm/create-cypress-tests/src/component-testing/babel/babelTransform.test.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ describe('babel transform utils', () => {
66
context('Plugins config babel plugin', () => {
77
it('injects code into the plugins file based on ast', () => {
88
const plugin = createTransformPluginsFileBabelPlugin({
9-
Require: babel.template.ast('require("something")'),
10-
ModuleExportsBody: babel.template.ast('yey()'),
9+
RequireAst: babel.template.ast('require("something")'),
10+
IfComponentTestingPluginsAst: babel.template.ast('yey()'),
1111
})
1212

1313
const output = babel.transformSync([
@@ -23,7 +23,10 @@ describe('babel transform utils', () => {
2323
'',
2424
'module.exports = (on, config) => {',
2525
' on("do");',
26-
' yey();',
26+
'',
27+
' if (config.testingType === "component") {',
28+
' yey();',
29+
' }',
2730
'};',
2831
].join(`\n`))
2932
})

npm/create-cypress-tests/src/component-testing/babel/babelTransform.ts

+28-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import * as fs from 'fs-extra'
33
import * as babel from '@babel/core'
44
import * as babelTypes from '@babel/types'
55

6-
export type PluginsConfigAst = Record<'Require' | 'ModuleExportsBody', ReturnType<typeof babel.template.ast>>
6+
type AST = ReturnType<typeof babel.template.ast>
7+
8+
export type PluginsConfigAst = {
9+
RequireAst: AST
10+
IfComponentTestingPluginsAst: AST
11+
requiresReturnConfig?: true
12+
}
713

814
function tryRequirePrettier () {
915
try {
@@ -48,11 +54,13 @@ async function transformFileViaPlugin (filePath: string, babelPlugin: babel.Plug
4854
}
4955
}
5056

57+
const returnConfigAst = babel.template.ast('return config; // IMPORTANT to return a config', { preserveComments: true })
58+
5159
export function createTransformPluginsFileBabelPlugin (ast: PluginsConfigAst): babel.PluginObj {
5260
return {
5361
visitor: {
5462
Program: (path) => {
55-
path.unshiftContainer('body', ast.Require)
63+
path.unshiftContainer('body', ast.RequireAst)
5664
},
5765
Function: (path) => {
5866
if (!babelTypes.isAssignmentExpression(path.parent)) {
@@ -80,7 +88,24 @@ export function createTransformPluginsFileBabelPlugin (ast: PluginsConfigAst): b
8088
path.parent.right.params.push(babelTypes.identifier('config'))
8189
}
8290

83-
path.get('body').pushContainer('body' as never, ast.ModuleExportsBody)
91+
const statementToInject = Array.isArray(ast.IfComponentTestingPluginsAst)
92+
? ast.IfComponentTestingPluginsAst
93+
: [ast.IfComponentTestingPluginsAst]
94+
95+
const ifComponentMode = babelTypes.ifStatement(
96+
babelTypes.binaryExpression(
97+
'===',
98+
babelTypes.identifier('config.testingType'),
99+
babelTypes.stringLiteral('component'),
100+
),
101+
babelTypes.blockStatement(statementToInject as babelTypes.Statement[] | babelTypes.Statement[]),
102+
)
103+
104+
path.get('body').pushContainer('body' as never, ifComponentMode as babel.Node)
105+
106+
if (ast.requiresReturnConfig) {
107+
path.get('body').pushContainer('body' as never, returnConfigAst)
108+
}
84109
}
85110
},
86111
},

0 commit comments

Comments
 (0)