mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-21 14:41:00 -06:00
feat: Use plugins on config files (#18798)
Co-authored-by: Tim Griesser <tgriesser10@gmail.com>
This commit is contained in:
committed by
GitHub
parent
8a2acdcdfa
commit
bb8251b752
18
circle.yml
18
circle.yml
@@ -1032,6 +1032,8 @@ jobs:
|
||||
runner-integration-tests-chrome,
|
||||
runner-ct-integration-tests-chrome,
|
||||
reporter-integration-tests,
|
||||
run-app-integration-tests-chrome,
|
||||
run-launchpad-integration-tests-chrome
|
||||
- run: yarn percy build:finalize
|
||||
|
||||
cli-visual-tests:
|
||||
@@ -1914,7 +1916,21 @@ jobs:
|
||||
CYPRESS_INTERNAL_FORCE_SCAFFOLD: "1"
|
||||
command: |
|
||||
rm -rf cypress.json
|
||||
echo 'export default {}' > cypress.config.ts
|
||||
echo "export default {
|
||||
e2e: {
|
||||
setupNodeEvents (on, config) {
|
||||
on('task', {
|
||||
log (x) {
|
||||
console.log(x)
|
||||
|
||||
return null
|
||||
},
|
||||
})
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}" > cypress.config.ts
|
||||
- run:
|
||||
name: Run project tests 🗳
|
||||
working_directory: <<parameters.wd>>
|
||||
|
||||
@@ -6,6 +6,7 @@ const mockfs = require('mock-fs')
|
||||
const Promise = require('bluebird')
|
||||
const util = require('../lib/util')
|
||||
const { MockChildProcess } = require('spawn-mock')
|
||||
|
||||
const _kill = MockChildProcess.prototype.kill
|
||||
|
||||
const patchMockSpawn = () => {
|
||||
|
||||
5
cli/types/cypress.d.ts
vendored
5
cli/types/cypress.d.ts
vendored
@@ -2813,6 +2813,11 @@ declare namespace Cypress {
|
||||
* An array of objects defining the certificates
|
||||
*/
|
||||
clientCertificates: ClientCertificate[]
|
||||
|
||||
/**
|
||||
* Handle Cypress plugins
|
||||
*/
|
||||
setupNodeEvents: (on: PluginEvents, config: PluginConfigOptions) => Promise<PluginConfigOptions> | PluginConfigOptions
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,5 +9,6 @@ export default defineConfig({
|
||||
'component': {
|
||||
'componentFolder': 'src/app',
|
||||
'testFiles': '**/*cy-spec.ts',
|
||||
'setupNodeEvents': require('./cypress/plugins'),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -13,4 +13,13 @@ module.exports = {
|
||||
],
|
||||
componentFolder: 'src',
|
||||
fixturesFolder: false,
|
||||
component: {
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/vite-dev-server')
|
||||
|
||||
on('dev-server:start', (options) => startDevServer({ options }))
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// @ts-check
|
||||
const { startDevServer } = require('@cypress/vite-dev-server')
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
on('dev-server:start', (options) => startDevServer({ options }))
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// @ts-check
|
||||
|
||||
module.exports = {
|
||||
'viewportWidth': 400,
|
||||
'viewportHeight': 400,
|
||||
@@ -12,4 +14,70 @@ module.exports = {
|
||||
'**/__image_snapshots__/*',
|
||||
],
|
||||
'experimentalFetchPolyfill': true,
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const path = require('path')
|
||||
const babelConfig = require('./babel.config.js')
|
||||
|
||||
const webpackConfig = {
|
||||
resolve: {
|
||||
extensions: ['.js', '.ts', '.jsx', '.tsx'],
|
||||
},
|
||||
mode: 'development',
|
||||
devtool: false,
|
||||
output: {
|
||||
publicPath: '/',
|
||||
chunkFilename: '[name].bundle.js',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx|mjs|ts|tsx)$/,
|
||||
loader: 'babel-loader',
|
||||
options: { ...babelConfig, cacheDirectory: path.resolve(__dirname, '..', '..', '.babel-cache') },
|
||||
},
|
||||
{
|
||||
test: /\.modules\.css$/i,
|
||||
exclude: [/node_modules/],
|
||||
use: [
|
||||
'style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
modules: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: [/node_modules/, /\.modules\.css$/i],
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
{
|
||||
// some of our examples import SVG
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-url-loader',
|
||||
},
|
||||
{
|
||||
// some of our examples import SVG
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-url-loader',
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg)$/,
|
||||
use: ['file-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
on('dev-server:start', (options) => {
|
||||
return startDevServer({ options, webpackConfig, disableLazyCompilation: false })
|
||||
})
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
// @ts-check
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const path = require('path')
|
||||
const babelConfig = require('../../babel.config.js')
|
||||
|
||||
/** @type import("webpack").Configuration */
|
||||
const webpackConfig = {
|
||||
resolve: {
|
||||
extensions: ['.js', '.ts', '.jsx', '.tsx'],
|
||||
},
|
||||
mode: 'development',
|
||||
devtool: false,
|
||||
output: {
|
||||
publicPath: '/',
|
||||
chunkFilename: '[name].bundle.js',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx|mjs|ts|tsx)$/,
|
||||
loader: 'babel-loader',
|
||||
options: { ...babelConfig, cacheDirectory: path.resolve(__dirname, '..', '..', '.babel-cache') },
|
||||
},
|
||||
{
|
||||
test: /\.modules\.css$/i,
|
||||
exclude: [/node_modules/],
|
||||
use: [
|
||||
'style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
modules: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: [/node_modules/, /\.modules\.css$/i],
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
{
|
||||
// some of our examples import SVG
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-url-loader',
|
||||
},
|
||||
{
|
||||
// some of our examples import SVG
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-url-loader',
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg)$/,
|
||||
use: ['file-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
if (config.testingType !== 'component') {
|
||||
throw Error(`This is a component testing project. testingType should be 'component'. Received ${config.testingType}`)
|
||||
}
|
||||
|
||||
on('dev-server:start', (options) => {
|
||||
return startDevServer({ options, webpackConfig, disableLazyCompilation: false })
|
||||
})
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -4,4 +4,17 @@ module.exports = {
|
||||
'testFiles': '**/*spec.js',
|
||||
'viewportWidth': 500,
|
||||
'viewportHeight': 500,
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -2,5 +2,13 @@ module.exports = {
|
||||
'component': {
|
||||
'testFiles': '**/*.test.{js,ts,jsx,tsx}',
|
||||
'componentFolder': 'src',
|
||||
setupNodeEvents (on, config) {
|
||||
const cracoConfig = require('./craco.config.js')
|
||||
const devServer = require('@cypress/react/plugins/craco')
|
||||
|
||||
devServer(on, config, cracoConfig)
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
const cracoConfig = require('../../craco.config.js')
|
||||
const devServer = require('@cypress/react/plugins/craco')
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config, cracoConfig)
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -6,6 +6,30 @@ export default defineConfig({
|
||||
'component': {
|
||||
'testFiles': '**/*.spec.{js,ts,jsx,tsx}',
|
||||
'componentFolder': 'src',
|
||||
setupNodeEvents (on, config) {
|
||||
const findReactScriptsWebpackConfig = require('@cypress/react/plugins/react-scripts/findReactScriptsWebpackConfig')
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const _ = require('lodash')
|
||||
|
||||
const map = _.map([4, 8], (n) => n * 2)
|
||||
|
||||
console.log(map)
|
||||
require('@cypress/code-coverage/task')(on, config)
|
||||
const webpackConfig = findReactScriptsWebpackConfig(config)
|
||||
|
||||
const rules = webpackConfig.module.rules.find((rule) => !!rule.oneOf).oneOf
|
||||
const babelRule = rules.find((rule) => typeof rule.loader === 'string' && /babel-loader/.test(rule.loader))
|
||||
|
||||
typeof babelRule.options !== 'string' && babelRule.options.plugins.push(require.resolve('babel-plugin-istanbul'))
|
||||
|
||||
on('dev-server:start', (options) => {
|
||||
return startDevServer({ options, webpackConfig })
|
||||
})
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
'env': {
|
||||
'cypress-react-selector': {
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
const findReactScriptsWebpackConfig = require('@cypress/react/plugins/react-scripts/findReactScriptsWebpackConfig')
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const _ = require('lodash')
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
const map = _.map([4, 8], (n) => n * 2)
|
||||
|
||||
console.log(map)
|
||||
require('@cypress/code-coverage/task')(on, config)
|
||||
const webpackConfig = findReactScriptsWebpackConfig(config)
|
||||
|
||||
const rules = webpackConfig.module.rules.find((rule) => !!rule.oneOf).oneOf
|
||||
const babelRule = rules.find((rule) => typeof rule.loader === 'string' && /babel-loader/.test(rule.loader))
|
||||
|
||||
typeof babelRule.options !== 'string' && babelRule.options.plugins.push(require.resolve('babel-plugin-istanbul'))
|
||||
|
||||
on('dev-server:start', (options) => {
|
||||
return startDevServer({ options, webpackConfig })
|
||||
})
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -5,4 +5,13 @@ module.exports = {
|
||||
'viewportHeight': 800,
|
||||
'componentFolder': 'cypress/components',
|
||||
'pluginsFile': 'cypress/plugins.js',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const devServer = require('@cypress/react/plugins/next')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
const devServer = require('@cypress/react/plugins/next')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -8,4 +8,13 @@ module.exports = {
|
||||
'env': {
|
||||
'coverage': true,
|
||||
},
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const devServer = require('@cypress/react/plugins/next')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
const devServer = require('@cypress/react/plugins/next')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -5,4 +5,17 @@ module.exports = {
|
||||
'viewportWidth': 500,
|
||||
'viewportHeight': 800,
|
||||
'componentFolder': 'cypress/component',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -4,4 +4,13 @@ module.exports = {
|
||||
'viewportWidth': 500,
|
||||
'viewportHeight': 800,
|
||||
'componentFolder': 'src',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -5,4 +5,17 @@ module.exports = {
|
||||
'viewportHeight': 800,
|
||||
'experimentalFetchPolyfill': true,
|
||||
'componentFolder': 'src',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -9,4 +9,19 @@ module.exports = {
|
||||
'env': {
|
||||
'coverage': true,
|
||||
},
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// load Webpack file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/load-webpack')
|
||||
|
||||
devServer(on, config, {
|
||||
webpackFilename: 'webpack.config.js',
|
||||
})
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load Webpack file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/load-webpack')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config, {
|
||||
webpackFilename: 'webpack.config.js',
|
||||
})
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -13,4 +13,21 @@ module.exports = {
|
||||
'prettier': true,
|
||||
},
|
||||
},
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
const { initPlugin: initSnapshots } = require('cypress-plugin-snapshots/plugin')
|
||||
|
||||
devServer(on, config)
|
||||
// initialize the snapshots plugin following
|
||||
// https://github.com/meinaart/cypress-plugin-snapshots
|
||||
initSnapshots(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
const { initPlugin: initSnapshots } = require('cypress-plugin-snapshots/plugin')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
// initialize the snapshots plugin following
|
||||
// https://github.com/meinaart/cypress-plugin-snapshots
|
||||
initSnapshots(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -8,4 +8,17 @@ module.exports = {
|
||||
'env': {
|
||||
'coverage': true,
|
||||
},
|
||||
config: {
|
||||
setupNodeEvents (on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -5,4 +5,18 @@ module.exports = {
|
||||
'viewportWidth': 500,
|
||||
'viewportHeight': 500,
|
||||
'componentFolder': 'src',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// let's bundle spec files and the components they include using
|
||||
// the same bundling settings as the project by loading .babelrc
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/babel')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// let's bundle spec files and the components they include using
|
||||
// the same bundling settings as the project by loading .babelrc
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/babel')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -5,4 +5,18 @@ module.exports = {
|
||||
'viewportWidth': 500,
|
||||
'viewportHeight': 500,
|
||||
'componentFolder': 'src',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// let's bundle spec files and the components they include using
|
||||
// the same bundling settings as the project by loading .babelrc
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/babel')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// let's bundle spec files and the components they include using
|
||||
// the same bundling settings as the project by loading .babelrc
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/babel')
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -4,5 +4,19 @@ module.exports = {
|
||||
"testFiles": "**/*cy-spec.js",
|
||||
"viewportWidth": 1000,
|
||||
"viewportHeight": 1000,
|
||||
"componentFolder": "src"
|
||||
}
|
||||
"componentFolder": "src",
|
||||
'component': {
|
||||
setupNodeEvents(on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin')
|
||||
|
||||
addMatchImageSnapshotPlugin(on, config)
|
||||
devServer(on, config)
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
addMatchImageSnapshotPlugin(on, config)
|
||||
devServer(on, config)
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -8,4 +8,19 @@ module.exports = {
|
||||
'env': {
|
||||
'coverage': false,
|
||||
},
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require('@applitools/eyes-cypress')(module)
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
require('@applitools/eyes-cypress')(module)
|
||||
@@ -4,4 +4,19 @@ module.exports = {
|
||||
'viewportWidth': 400,
|
||||
'viewportHeight': 700,
|
||||
'componentFolder': 'src',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
const happoTask = require('happo-cypress/task')
|
||||
|
||||
on('task', happoTask)
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/cypress-react-unit-test#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
// @ts-ignore
|
||||
const happoTask = require('happo-cypress/task')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
on('task', happoTask)
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -5,4 +5,17 @@ module.exports = {
|
||||
'viewportWidth': 500,
|
||||
'viewportHeight': 500,
|
||||
'componentFolder': 'src',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/@cypress/react#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
// load file devServer that comes with this plugin
|
||||
// https://github.com/bahmutov/@cypress/react#install
|
||||
const devServer = require('@cypress/react/plugins/react-scripts')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
devServer(on, config)
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -4,4 +4,16 @@ module.exports = {
|
||||
'testFiles': '**/*cy-spec.js',
|
||||
'viewportWidth': 500,
|
||||
'viewportHeight': 500,
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
require('@cypress/react/plugins/load-webpack')(on, config, {
|
||||
// from the root of the project (folder with cypress.config.{ts|js} file)
|
||||
webpackFilename: 'webpack.config.js',
|
||||
})
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
require('@cypress/react/plugins/load-webpack')(on, config, {
|
||||
// from the root of the project (folder with cypress.config.{ts|js} file)
|
||||
webpackFilename: 'webpack.config.js',
|
||||
})
|
||||
|
||||
// IMPORTANT to return the config object
|
||||
// with the any changed environment variables
|
||||
return config
|
||||
}
|
||||
@@ -4,4 +4,40 @@ module.exports = {
|
||||
'testFiles': '**/*cy-spec.js',
|
||||
'viewportWidth': 500,
|
||||
'viewportHeight': 500,
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const path = require('path')
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const babelConfig = require('./babel.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: { ...babelConfig, cacheDirectory: path.resolve(__dirname, '.babel-cache') },
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
process.env.BABEL_ENV = 'test' // this is required to load commonjs babel plugin
|
||||
on('dev-server:start', (options) => startDevServer({ options, webpackConfig }))
|
||||
|
||||
// if adding code coverage, important to return updated config
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
// @ts-check
|
||||
const path = require('path')
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const babelConfig = require('../../babel.config')
|
||||
|
||||
/**
|
||||
* Cypress Webpack devServer includes Babel env preset,
|
||||
* but to transpile JSX code we need to add Babel React preset
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
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: { ...babelConfig, cacheDirectory: path.resolve(__dirname, '.babel-cache') },
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
process.env.BABEL_ENV = 'test' // this is required to load commonjs babel plugin
|
||||
on('dev-server:start', (options) => startDevServer({ options, webpackConfig }))
|
||||
|
||||
// if adding code coverage, important to return updated config
|
||||
return config
|
||||
}
|
||||
@@ -6,4 +6,21 @@ export default defineConfig({
|
||||
'fixturesFolder': false,
|
||||
'testFiles': '**/*.spec.*',
|
||||
'componentFolder': 'cypress/components',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const path = require('path')
|
||||
const { startDevServer } = require('./dist')
|
||||
|
||||
on('dev-server:start', async (options) => {
|
||||
return startDevServer({
|
||||
options,
|
||||
viteConfig: {
|
||||
configFile: path.resolve(__dirname, 'vite.config.ts'),
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
const path = require('path')
|
||||
const { startDevServer } = require('../dist')
|
||||
|
||||
module.exports = (on, config) => {
|
||||
on('dev-server:start', async (options) => {
|
||||
return startDevServer({
|
||||
options,
|
||||
viteConfig: {
|
||||
configFile: path.resolve(__dirname, '..', 'vite.config.ts'),
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -8,4 +8,24 @@ export default defineConfig({
|
||||
'projectId': '134ej7',
|
||||
'testFiles': '**/*spec.{js,ts,tsx}',
|
||||
'experimentalFetchPolyfill': true,
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const webpackConfig = require('./webpack.config')
|
||||
|
||||
if (!webpackConfig.resolve) {
|
||||
webpackConfig.resolve = {}
|
||||
}
|
||||
|
||||
webpackConfig.resolve.alias = {
|
||||
...webpackConfig.resolve.alias,
|
||||
'@vue/compiler-core$': '@vue/compiler-core/dist/compiler-core.cjs.js',
|
||||
}
|
||||
|
||||
require('@cypress/code-coverage/task')(on, config)
|
||||
on('dev-server:start', (options) => startDevServer({ options, webpackConfig }))
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const webpackConfig = require('../../webpack.config')
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
if (config.testingType !== 'component') {
|
||||
return config
|
||||
}
|
||||
|
||||
if (!webpackConfig.resolve) {
|
||||
webpackConfig.resolve = {}
|
||||
}
|
||||
|
||||
webpackConfig.resolve.alias = {
|
||||
...webpackConfig.resolve.alias,
|
||||
'@vue/compiler-core$': '@vue/compiler-core/dist/compiler-core.cjs.js',
|
||||
}
|
||||
|
||||
require('@cypress/code-coverage/task')(on, config)
|
||||
on('dev-server:start', (options) => startDevServer({ options, webpackConfig }))
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -3,4 +3,21 @@ module.exports = {
|
||||
'fixturesFolder': false,
|
||||
'testFiles': '**/*.spec.js',
|
||||
'video': false,
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const webpackConfig = require('./webpack.config')
|
||||
|
||||
on('dev-server:start', (options) => {
|
||||
return startDevServer({
|
||||
options,
|
||||
webpackConfig,
|
||||
})
|
||||
})
|
||||
|
||||
require('@cypress/code-coverage/task')(on, config)
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const webpackConfig = require('../../webpack.config')
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
on('dev-server:start', (options) => {
|
||||
return startDevServer({
|
||||
options,
|
||||
webpackConfig,
|
||||
})
|
||||
})
|
||||
|
||||
require('@cypress/code-coverage/task')(on, config)
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -3,4 +3,33 @@ module.exports = {
|
||||
'fixturesFolder': false,
|
||||
'testFiles': '**/*spec.js',
|
||||
'componentFolder': 'src',
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const webpackConfig = require('@vue/cli-service/webpack.config')
|
||||
|
||||
on('dev-server:start', (options) => {
|
||||
// HtmlPwaPlugin is coupled to a hook in HtmlWebpackPlugin
|
||||
// that was deprecated after 3.x. We currently only support
|
||||
// HtmlWebpackPlugin 4.x and 5.x.
|
||||
// TODO: Figure out how to deal with 2 major versions old HtmlWebpackPlugin
|
||||
// which is still in widespread usage.
|
||||
const modifiedWebpackConfig = {
|
||||
...webpackConfig,
|
||||
plugins: (webpackConfig.plugins || []).filter((x) => {
|
||||
return x.constructor.name !== 'HtmlPwaPlugin'
|
||||
}),
|
||||
}
|
||||
|
||||
return startDevServer({
|
||||
options,
|
||||
webpackConfig: modifiedWebpackConfig,
|
||||
})
|
||||
})
|
||||
|
||||
require('@cypress/code-coverage/task')(on, config)
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const webpackConfig = require('@vue/cli-service/webpack.config')
|
||||
|
||||
/**
|
||||
* @type Cypress.PluginConfig
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
on('dev-server:start', (options) => {
|
||||
// HtmlPwaPlugin is coupled to a hook in HtmlWebpackPlugin
|
||||
// that was deprecated after 3.x. We currently only support
|
||||
// HtmlWebpackPlugin 4.x and 5.x.
|
||||
// TODO: Figure out how to deal with 2 major versions old HtmlWebpackPlugin
|
||||
// which is still in widespread usage.
|
||||
const modifiedWebpackConfig = {
|
||||
...webpackConfig,
|
||||
plugins: (webpackConfig.plugins || []).filter((x) => {
|
||||
return x.constructor.name !== 'HtmlPwaPlugin'
|
||||
}),
|
||||
}
|
||||
|
||||
return startDevServer({
|
||||
options,
|
||||
webpackConfig: modifiedWebpackConfig,
|
||||
})
|
||||
})
|
||||
|
||||
require('@cypress/code-coverage/task')(on, config)
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -1,3 +1,12 @@
|
||||
module.exports = {
|
||||
'integrationFolder': 'cypress/tests',
|
||||
'e2e': {
|
||||
setupNodeEvents (on, config) {
|
||||
const webpackPreprocessor = require('./index')
|
||||
|
||||
on('file:preprocessor', webpackPreprocessor())
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
const webpackPreprocessor = require('../../')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on) => {
|
||||
on('file:preprocessor', webpackPreprocessor())
|
||||
}
|
||||
@@ -1,4 +1,15 @@
|
||||
module.exports = {
|
||||
'fixturesFolder': false,
|
||||
'supportFile': false,
|
||||
'e2e': {
|
||||
setupNodeEvents (on, config) {
|
||||
const webpackPreprocessor = require('../..')
|
||||
const defaults = webpackPreprocessor.defaultOptions
|
||||
|
||||
delete defaults.webpackOptions.module.rules[0].use[0].options.presets
|
||||
on('file:preprocessor', webpackPreprocessor(defaults))
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
const webpackPreprocessor = require('../../../..')
|
||||
const defaults = webpackPreprocessor.defaultOptions
|
||||
|
||||
module.exports = (on) => {
|
||||
delete defaults.webpackOptions.module.rules[0].use[0].options.presets
|
||||
on('file:preprocessor', webpackPreprocessor(defaults))
|
||||
}
|
||||
@@ -3,4 +3,15 @@ import { defineConfig } from 'cypress'
|
||||
export default defineConfig({
|
||||
'fixturesFolder': false,
|
||||
'supportFile': false,
|
||||
'e2e': {
|
||||
async setupNodeEvents (on, config) {
|
||||
const webpackPreprocessor = await import('../..')
|
||||
|
||||
const webpack = await import('./webpack.config')
|
||||
|
||||
on('file:preprocessor', webpackPreprocessor({ webpack }))
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
const webpackPreprocessor = require('../../../..')
|
||||
|
||||
module.exports = (on) => {
|
||||
const webpack = require('../../webpack.config.js')
|
||||
|
||||
on('file:preprocessor', webpackPreprocessor({ webpack }))
|
||||
}
|
||||
@@ -20,10 +20,38 @@ export default defineConfig({
|
||||
'component': {
|
||||
'testFiles': '**/*.{spec,cy}.{js,ts,tsx,jsx}',
|
||||
'supportFile': 'cypress/component/support/index.ts',
|
||||
'pluginsFile': 'cypress/component/plugins/index.js',
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/vite-dev-server')
|
||||
|
||||
on('dev-server:start', async (options) => {
|
||||
return startDevServer({
|
||||
options,
|
||||
viteConfig: {
|
||||
// TODO(tim): Figure out why this isn't being picked up
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
'@headlessui/vue',
|
||||
'vue3-file-selector',
|
||||
'just-my-luck',
|
||||
'combine-properties',
|
||||
'faker',
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
'e2e': {
|
||||
'pluginsFile': 'cypress/e2e/plugins/index.ts',
|
||||
'supportFile': 'cypress/e2e/support/e2eSupport.ts',
|
||||
async setupNodeEvents (on, config) {
|
||||
const { monorepoPaths } = require('../../scripts/gulp/monorepoPaths')
|
||||
const { e2ePluginSetup } = require('@packages/frontend-shared/cypress/e2e/e2ePluginSetup')
|
||||
|
||||
return await e2ePluginSetup(monorepoPaths.pkgApp, on, config)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
module.exports = require('@packages/frontend-shared/cypress/plugins/index')
|
||||
@@ -58,7 +58,12 @@ describe('App', () => {
|
||||
cy.loginUser()
|
||||
cy.visitApp()
|
||||
cy.withCtx(async (ctx) => {
|
||||
ctx.config.cleanupCachedConfigForActiveProject()
|
||||
// TODO: (Alejandro) This should be removed when we add a file listener to update the config file
|
||||
if (ctx.currentProject) {
|
||||
ctx.currentProject.config = null
|
||||
ctx.currentProject.configChildProcess = null
|
||||
}
|
||||
|
||||
await ctx.actions.file.writeFileInProject('cypress.config.js', 'module.exports = {}')
|
||||
})
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
const { monorepoPaths } = require('../../../../../scripts/gulp/monorepoPaths')
|
||||
import { e2ePluginSetup } from '@packages/frontend-shared/cypress/e2e/e2ePluginSetup'
|
||||
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = async (on, config) => {
|
||||
return await e2ePluginSetup(monorepoPaths.pkgApp, on, config)
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { DataContext } from '.'
|
||||
import { AppActions, ElectronActions, FileActions, ProjectActions, WizardActions } from './actions'
|
||||
import { AppActions, ProjectConfigDataActions, ElectronActions, FileActions, ProjectActions, WizardActions } from './actions'
|
||||
import { AuthActions } from './actions/AuthActions'
|
||||
import { DevActions } from './actions/DevActions'
|
||||
import { cached } from './util'
|
||||
@@ -41,4 +41,9 @@ export class DataActions {
|
||||
get electron () {
|
||||
return new ElectronActions(this.ctx)
|
||||
}
|
||||
|
||||
@cached
|
||||
get projectConfig () {
|
||||
return new ProjectConfigDataActions(this.ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
BrowserDataSource,
|
||||
StorybookDataSource,
|
||||
CloudDataSource,
|
||||
ConfigDataSource,
|
||||
ProjectConfigDataSource,
|
||||
EnvDataSource,
|
||||
GraphQLDataSource,
|
||||
HtmlDataSource,
|
||||
@@ -42,7 +42,7 @@ export interface DataContextConfig {
|
||||
os: PlatformName
|
||||
launchArgs: LaunchArgs
|
||||
launchOptions: OpenProjectLaunchOptions
|
||||
electronApp: ElectronApp
|
||||
electronApp?: ElectronApp
|
||||
/**
|
||||
* Default is to
|
||||
*/
|
||||
@@ -91,6 +91,8 @@ export class DataContext {
|
||||
this.actions.app.refreshBrowsers(),
|
||||
// load the cached user & validate the token on start
|
||||
this.actions.auth.getUser(),
|
||||
|
||||
this.actions.app.refreshNodePathAndVersion(),
|
||||
]
|
||||
|
||||
if (this._config._internalOptions.loadCachedProjects) {
|
||||
@@ -153,6 +155,10 @@ export class DataContext {
|
||||
return this.coreData.app.browsers
|
||||
}
|
||||
|
||||
get nodePathAndVersion () {
|
||||
return this.coreData.app.nodePathAndVersion
|
||||
}
|
||||
|
||||
get baseError () {
|
||||
return this.coreData.baseError
|
||||
}
|
||||
@@ -196,7 +202,7 @@ export class DataContext {
|
||||
|
||||
@cached
|
||||
get config () {
|
||||
return new ConfigDataSource(this)
|
||||
return new ProjectConfigDataSource(this)
|
||||
}
|
||||
|
||||
@cached
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type Bluebird from 'bluebird'
|
||||
import type { FoundBrowser } from '@packages/types'
|
||||
import type { FoundBrowser, NodePathAndVersion } from '@packages/types'
|
||||
import pDefer from 'p-defer'
|
||||
|
||||
import type { DataContext } from '..'
|
||||
@@ -7,6 +7,7 @@ import type { DataContext } from '..'
|
||||
export interface AppApiShape {
|
||||
getBrowsers(): Promise<FoundBrowser[]>
|
||||
ensureAndGetByNameOrPath(nameOrPath: string, returnAll?: boolean, browsers?: FoundBrowser[]): Bluebird<FoundBrowser | FoundBrowser[] | undefined>
|
||||
findNodePathAndVersion(): Promise<{ path: string, version: string}>
|
||||
}
|
||||
|
||||
export class AppActions {
|
||||
@@ -85,4 +86,20 @@ export class AppActions {
|
||||
|
||||
return browsers.some((b) => this.idForBrowser(b) === this.idForBrowser(chosenBrowser))
|
||||
}
|
||||
|
||||
async refreshNodePathAndVersion () {
|
||||
if (this.ctx.coreData.app.refreshingNodePathAndVersion) {
|
||||
return
|
||||
}
|
||||
|
||||
const dfd = pDefer<NodePathAndVersion>()
|
||||
|
||||
this.ctx.coreData.app.refreshingNodePathAndVersion = dfd.promise
|
||||
|
||||
const nodePathAndVersion = await this.ctx._apis.appApi.findNodePathAndVersion()
|
||||
|
||||
this.ctx.coreData.app.nodePathAndVersion = nodePathAndVersion
|
||||
|
||||
dfd.resolve(nodePathAndVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export class ElectronActions {
|
||||
this.electron.browserWindow?.hide()
|
||||
|
||||
if (this.isMac) {
|
||||
this.ctx.electronApp.dock.hide()
|
||||
this.ctx.electronApp?.dock.hide()
|
||||
} else {
|
||||
this.electron.browserWindow?.setSkipTaskbar(true)
|
||||
}
|
||||
@@ -35,7 +35,7 @@ export class ElectronActions {
|
||||
this.electron.browserWindow?.show()
|
||||
|
||||
if (this.isMac) {
|
||||
this.ctx.electronApp.dock.show()
|
||||
this.ctx.electronApp?.dock.show()
|
||||
} else {
|
||||
this.electron.browserWindow?.setSkipTaskbar(false)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ export interface ProjectApiShape {
|
||||
clearProjectPreferences(projectTitle: string): Promise<unknown>
|
||||
clearAllProjectPreferences(): Promise<unknown>
|
||||
closeActiveProject(): Promise<unknown>
|
||||
error(type: string, ...args: any): Error
|
||||
error: {
|
||||
throw: (type: string, ...args: any) => Error
|
||||
get(type: string, ...args: any): Error & { code: string, isCypressErr: boolean}
|
||||
}
|
||||
}
|
||||
|
||||
export class ProjectActions {
|
||||
@@ -37,7 +40,7 @@ export class ProjectActions {
|
||||
}
|
||||
|
||||
async clearActiveProject () {
|
||||
this.ctx.coreData.currentProject = null
|
||||
this.ctx.actions.projectConfig.killConfigProcess()
|
||||
await this.api.closeActiveProject()
|
||||
|
||||
// TODO(tim): Improve general state management w/ immutability (immer) & updater fn
|
||||
@@ -77,7 +80,24 @@ export class ProjectActions {
|
||||
return this
|
||||
}
|
||||
|
||||
private setCurrentProjectProperties (currentProjectProperties: Partial<ActiveProjectShape>) {
|
||||
// Temporary: remove after other refactor lands
|
||||
setActiveProjectForTestSetup (projectRoot: string) {
|
||||
this.ctx.actions.projectConfig.killConfigProcess()
|
||||
|
||||
const title = this.ctx.project.projectTitle(projectRoot)
|
||||
|
||||
// Set initial properties, so we can set the config object on the active project
|
||||
this.setCurrentProjectProperties({
|
||||
projectRoot,
|
||||
title,
|
||||
ctPluginsInitialized: false,
|
||||
e2ePluginsInitialized: false,
|
||||
config: null,
|
||||
configChildProcess: null,
|
||||
})
|
||||
}
|
||||
|
||||
setCurrentProjectProperties (currentProjectProperties: Partial<ActiveProjectShape>) {
|
||||
this.ctx.coreData.currentProject = {
|
||||
browsers: this.ctx.coreData.app.browsers,
|
||||
...this.ctx.coreData.currentProject,
|
||||
|
||||
142
packages/data-context/src/actions/ProjectConfigDataActions.ts
Normal file
142
packages/data-context/src/actions/ProjectConfigDataActions.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import childProcess, { ChildProcess, ForkOptions } from 'child_process'
|
||||
import _ from 'lodash'
|
||||
import path from 'path'
|
||||
import { EventEmitter } from 'events'
|
||||
import pDefer from 'p-defer'
|
||||
|
||||
import type { DataContext } from '..'
|
||||
import inspector from 'inspector'
|
||||
|
||||
interface ForkConfigProcessOptions {
|
||||
projectRoot: string
|
||||
configFilePath: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the lifecycle of the Config sourcing & Plugin execution
|
||||
*/
|
||||
export class ProjectConfigDataActions {
|
||||
constructor (private ctx: DataContext) {}
|
||||
|
||||
static CHILD_PROCESS_FILE_PATH = path.join(__dirname, '../../../server/lib/util', 'require_async_child.js')
|
||||
|
||||
killConfigProcess () {
|
||||
if (this.ctx.currentProject?.configChildProcess) {
|
||||
this.ctx.currentProject.configChildProcess.process.kill()
|
||||
this.ctx.currentProject.configChildProcess = null
|
||||
}
|
||||
}
|
||||
|
||||
refreshProjectConfig (configFilePath: string) {
|
||||
if (!this.ctx.currentProject) {
|
||||
throw new Error('Can\'t refresh project config without current project')
|
||||
}
|
||||
|
||||
this.killConfigProcess()
|
||||
|
||||
const process = this.forkConfigProcess({
|
||||
projectRoot: this.ctx.currentProject.projectRoot,
|
||||
configFilePath,
|
||||
})
|
||||
const dfd = pDefer<Cypress.ConfigOptions>()
|
||||
|
||||
this.ctx.currentProject.configChildProcess = {
|
||||
process,
|
||||
executedPlugins: null,
|
||||
resolvedBaseConfig: dfd.promise,
|
||||
}
|
||||
|
||||
this.wrapConfigProcess(process, dfd)
|
||||
|
||||
return dfd.promise as Cypress.ConfigOptions
|
||||
}
|
||||
|
||||
private forkConfigProcess (opts: ForkConfigProcessOptions) {
|
||||
const configProcessArgs = ['--projectRoot', opts.projectRoot, '--file', opts.configFilePath]
|
||||
|
||||
const childOptions: ForkOptions = {
|
||||
stdio: 'pipe',
|
||||
cwd: path.dirname(opts.configFilePath),
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_OPTIONS: process.env.ORIGINAL_NODE_OPTIONS || '',
|
||||
},
|
||||
execPath: this.ctx.nodePathAndVersion?.path,
|
||||
}
|
||||
|
||||
if (inspector.url()) {
|
||||
childOptions.execArgv = _.chain(process.execArgv.slice(0))
|
||||
.remove('--inspect-brk')
|
||||
.push(`--inspect=${process.debugPort + 1}`)
|
||||
.value()
|
||||
}
|
||||
|
||||
this.ctx.debug('fork child process', ProjectConfigDataActions.CHILD_PROCESS_FILE_PATH, configProcessArgs, childOptions)
|
||||
|
||||
return childProcess.fork(ProjectConfigDataActions.CHILD_PROCESS_FILE_PATH, configProcessArgs, childOptions)
|
||||
}
|
||||
|
||||
private wrapConfigProcess (child: ChildProcess, dfd: pDefer.DeferredPromise<Cypress.ConfigOptions>) {
|
||||
const ipc = this.wrapIpc(child)
|
||||
|
||||
if (child.stdout && child.stderr) {
|
||||
// manually pipe plugin stdout and stderr for dashboard capture
|
||||
// @see https://github.com/cypress-io/cypress/issues/7434
|
||||
child.stdout.on('data', (data) => process.stdout.write(data))
|
||||
child.stderr.on('data', (data) => process.stderr.write(data))
|
||||
}
|
||||
|
||||
ipc.on('loaded', (result) => {
|
||||
this.ctx.debug('resolving with result %o', result)
|
||||
dfd.resolve(result)
|
||||
})
|
||||
|
||||
ipc.on('load:error', (type, ...args) => {
|
||||
this.ctx.debug('load:error %s, rejecting', type)
|
||||
this.killConfigProcess()
|
||||
|
||||
const err = this.ctx._apis.projectApi.error.get(type, ...args)
|
||||
|
||||
// if it's a non-cypress error, restore the initial error
|
||||
if (!(err.message?.length)) {
|
||||
err.isCypressErr = false
|
||||
err.message = args[1]
|
||||
err.code = type
|
||||
err.name = type
|
||||
}
|
||||
|
||||
dfd.reject(err)
|
||||
})
|
||||
|
||||
this.ctx.debug('trigger the load of the file')
|
||||
ipc.send('load')
|
||||
}
|
||||
|
||||
protected wrapIpc (aProcess: ChildProcess) {
|
||||
const emitter = new EventEmitter()
|
||||
|
||||
aProcess.on('message', (message: { event: string, args: any}) => {
|
||||
return emitter.emit(message.event, ...message.args)
|
||||
})
|
||||
|
||||
// prevent max listeners warning on ipc
|
||||
// @see https://github.com/cypress-io/cypress/issues/1305#issuecomment-780895569
|
||||
emitter.setMaxListeners(Infinity)
|
||||
|
||||
return {
|
||||
send (event: string, ...args: any) {
|
||||
if (aProcess.killed) {
|
||||
return
|
||||
}
|
||||
|
||||
return aProcess.send({
|
||||
event,
|
||||
args,
|
||||
})
|
||||
},
|
||||
|
||||
on: emitter.on.bind(emitter),
|
||||
removeListener: emitter.removeListener.bind(emitter),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,5 @@ export * from './DevActions'
|
||||
export * from './ElectronActions'
|
||||
export * from './FileActions'
|
||||
export * from './ProjectActions'
|
||||
export * from './ProjectConfigDataActions'
|
||||
export * from './WizardActions'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BUNDLERS, FoundBrowser, FoundSpec, FullConfig, Preferences } from '@packages/types'
|
||||
import { BUNDLERS, FoundBrowser, FoundSpec, FullConfig, Preferences, NodePathAndVersion } from '@packages/types'
|
||||
import type { NexusGenEnums, TestingTypeEnum } from '@packages/graphql/src/gen/nxs.gen'
|
||||
import type { BrowserWindow } from 'electron'
|
||||
import type { ChildProcess } from 'child_process'
|
||||
@@ -20,8 +20,18 @@ export interface DevStateShape {
|
||||
}
|
||||
|
||||
export interface ConfigChildProcessShape {
|
||||
/**
|
||||
* Child process executing the config & sourcing plugin events
|
||||
*/
|
||||
process: ChildProcess
|
||||
/**
|
||||
* Keeps track of which plugins we have executed in the current config process
|
||||
*/
|
||||
executedPlugins: null | 'e2e' | 'ct'
|
||||
/**
|
||||
* Config from the initial module.exports
|
||||
*/
|
||||
resolvedBaseConfig: Promise<Cypress.ConfigOptions>
|
||||
}
|
||||
|
||||
export interface ActiveProjectShape extends ProjectShape {
|
||||
@@ -32,7 +42,7 @@ export interface ActiveProjectShape extends ProjectShape {
|
||||
isE2EConfigured: Maybe<boolean>
|
||||
specs?: FoundSpec[]
|
||||
config: Promise<FullConfig> | null
|
||||
configChildProcess: ConfigChildProcessShape | null
|
||||
configChildProcess?: ConfigChildProcessShape | null
|
||||
preferences?: Preferences| null
|
||||
browsers: FoundBrowser[] | null
|
||||
}
|
||||
@@ -42,6 +52,8 @@ export interface AppDataShape {
|
||||
projects: ProjectShape[]
|
||||
currentTestingType: Maybe<TestingTypeEnum>
|
||||
refreshingBrowsers: Promise<FoundBrowser[]> | null
|
||||
refreshingNodePathAndVersion: Promise<NodePathAndVersion> | null
|
||||
nodePathAndVersion: NodePathAndVersion | null
|
||||
}
|
||||
|
||||
export interface WizardDataShape {
|
||||
@@ -92,6 +104,8 @@ export function makeCoreData (): CoreDataShape {
|
||||
refreshingBrowsers: null,
|
||||
browsers: null,
|
||||
projects: [],
|
||||
refreshingNodePathAndVersion: null,
|
||||
nodePathAndVersion: null,
|
||||
},
|
||||
isAuthBrowserOpened: false,
|
||||
currentProject: null,
|
||||
|
||||
@@ -1,9 +1,28 @@
|
||||
import type { FullConfig } from '@packages/types'
|
||||
import path from 'path'
|
||||
import type { DataContext } from '..'
|
||||
|
||||
export class ConfigDataSource {
|
||||
export class ProjectConfigDataSource {
|
||||
constructor (private ctx: DataContext) {}
|
||||
|
||||
async getOrCreateBaseConfig (configFilePath?: string) {
|
||||
const configChildProcess = this.ctx.currentProject?.configChildProcess
|
||||
|
||||
if (!configChildProcess) {
|
||||
if (!configFilePath) {
|
||||
configFilePath = await this.getConfigFilePath()
|
||||
}
|
||||
|
||||
if (!this.ctx.nodePathAndVersion) {
|
||||
await this.ctx.actions.app.refreshNodePathAndVersion()
|
||||
}
|
||||
|
||||
return this.ctx.deref.actions.projectConfig.refreshProjectConfig(configFilePath)
|
||||
}
|
||||
|
||||
return configChildProcess.resolvedBaseConfig
|
||||
}
|
||||
|
||||
async getConfigForProject (projectRoot: string): Promise<FullConfig> {
|
||||
if (!this.ctx.coreData.currentProject) {
|
||||
throw new Error(`Cannot access config without currentProject`)
|
||||
@@ -31,8 +50,12 @@ export class ConfigDataSource {
|
||||
if (foundConfigFiles.length === 1) {
|
||||
const configFile = foundConfigFiles[0]
|
||||
|
||||
if (!configFile) {
|
||||
throw this.ctx._apis.projectApi.error.throw('NO_DEFAULT_CONFIG_FILE_FOUND', projectRoot)
|
||||
}
|
||||
|
||||
if (configFile === legacyConfigFile) {
|
||||
throw this.ctx._apis.projectApi.error('CONFIG_FILE_MIGRATION_NEEDED', projectRoot, configFile)
|
||||
throw this.ctx._apis.projectApi.error.throw('CONFIG_FILE_MIGRATION_NEEDED', projectRoot, configFile)
|
||||
}
|
||||
|
||||
return configFile
|
||||
@@ -43,20 +66,24 @@ export class ConfigDataSource {
|
||||
if (foundConfigFiles.includes(legacyConfigFile)) {
|
||||
const foundFiles = foundConfigFiles.filter((f) => f !== legacyConfigFile)
|
||||
|
||||
throw this.ctx._apis.projectApi.error('LEGACY_CONFIG_FILE', projectRoot, ...foundFiles)
|
||||
throw this.ctx._apis.projectApi.error.throw('LEGACY_CONFIG_FILE', projectRoot, ...foundFiles)
|
||||
}
|
||||
|
||||
throw this.ctx._apis.projectApi.error('CONFIG_FILES_LANGUAGE_CONFLICT', projectRoot, ...foundConfigFiles)
|
||||
throw this.ctx._apis.projectApi.error.throw('CONFIG_FILES_LANGUAGE_CONFLICT', projectRoot, ...foundConfigFiles)
|
||||
}
|
||||
|
||||
throw this.ctx._apis.projectApi.error('NO_DEFAULT_CONFIG_FILE_FOUND', projectRoot)
|
||||
throw this.ctx._apis.projectApi.error.throw('NO_DEFAULT_CONFIG_FILE_FOUND', projectRoot)
|
||||
}
|
||||
|
||||
async cleanupCachedConfigForActiveProject () {
|
||||
if (!this.ctx.coreData.currentProject?.config) {
|
||||
return
|
||||
protected async getConfigFilePath () {
|
||||
const projectRoot = this.ctx.currentProject?.projectRoot
|
||||
|
||||
if (!projectRoot) {
|
||||
throw new Error('Can\'t het the config file path without current project root')
|
||||
}
|
||||
|
||||
this.ctx.coreData.currentProject.config = null
|
||||
const defaultConfigBasename = await this.getDefaultConfigBasename(projectRoot)
|
||||
|
||||
return path.join(projectRoot, defaultConfigBasename)
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
export * from './BrowserDataSource'
|
||||
export * from './CloudDataSource'
|
||||
export * from './ConfigDataSource'
|
||||
export * from './EnvDataSource'
|
||||
export * from './FileDataSource'
|
||||
export * from './GitDataSource'
|
||||
export * from './GraphQLDataSource'
|
||||
export * from './HtmlDataSource'
|
||||
export * from './ProjectConfigDataSource'
|
||||
export * from './ProjectDataSource'
|
||||
export * from './SettingsDataSource'
|
||||
export * from './StorybookDataSource'
|
||||
|
||||
@@ -18,4 +18,30 @@ module.exports = {
|
||||
'reporterOptions': {
|
||||
'configFile': '../../mocha-reporter-config.json',
|
||||
},
|
||||
'e2e': {
|
||||
setupNodeEvents (on, config) {
|
||||
const express = require('express')
|
||||
|
||||
express().use(express.static('dist')).listen(5005)
|
||||
|
||||
const webpackPreprocessor = require('@cypress/webpack-preprocessor')
|
||||
|
||||
on('file:preprocessor', webpackPreprocessor())
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
'component': {
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
|
||||
const webpackConfig = require('./webpack.config').default
|
||||
|
||||
on('dev-server:start', (options) => {
|
||||
return startDevServer({ options, webpackConfig })
|
||||
})
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
const express = require('express')
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
const webpackPreprocessor = require('@cypress/webpack-preprocessor')
|
||||
const webpackConfig = require('../../webpack.config').default
|
||||
|
||||
express().use(express.static('dist')).listen(5005)
|
||||
|
||||
module.exports = (on, config) => {
|
||||
if (config.testingType === 'component') {
|
||||
on('dev-server:start', (options) => {
|
||||
return startDevServer({ options, webpackConfig })
|
||||
})
|
||||
} else {
|
||||
on('file:preprocessor', webpackPreprocessor())
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -2,9 +2,6 @@ import { defineConfig } from 'cypress'
|
||||
|
||||
export default defineConfig({
|
||||
'projectId': 'ypt4pf',
|
||||
'e2e': {
|
||||
'baseUrl': 'http://localhost:3500',
|
||||
},
|
||||
'testFiles': '**/*',
|
||||
'hosts': {
|
||||
'*.foobar.com': '127.0.0.1',
|
||||
@@ -13,4 +10,8 @@ export default defineConfig({
|
||||
'reporterOptions': {
|
||||
'configFile': '../../mocha-reporter-config.json',
|
||||
},
|
||||
'e2e': {
|
||||
'setupNodeEvents': require('./cypress/plugins'),
|
||||
'baseUrl': 'http://localhost:3500',
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const { _, Promise } = Cypress
|
||||
const path = require('path')
|
||||
|
||||
describe('src/cy/commands/task', () => {
|
||||
context('#task', {
|
||||
@@ -209,7 +210,7 @@ describe('src/cy/commands/task', () => {
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
|
||||
expect(err.message).to.eq(`\`cy.task('bar')\` failed with the following error:\n\nThe task 'bar' was not handled in the plugins file. The following tasks are registered: return:arg, arg:is:undefined, wait, create:long:file\n\nFix this in your plugins file here:\n${Cypress.config('pluginsFile')}`)
|
||||
expect(err.message).to.eq(`\`cy.task('bar')\` failed with the following error:\n\nThe task 'bar' was not handled in the setupNodeEvents method. The following tasks are registered: return:arg, arg:is:undefined, wait, create:long:file\n\nFix this in your setupNodeEvents method here:\n${path.join(Cypress.config('projectRoot'), Cypress.config('configFile'))}`)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
@@ -31,7 +31,7 @@ babelLoader.use.options.plugins = _.reject(babelLoader.use.options.plugins, (plu
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on) => {
|
||||
module.exports = (on, config) => {
|
||||
on('file:preprocessor', wp({ webpackOptions }))
|
||||
|
||||
on('task', {
|
||||
@@ -59,4 +59,6 @@ module.exports = (on) => {
|
||||
return null
|
||||
},
|
||||
})
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
@@ -18,6 +18,34 @@ export default defineConfig({
|
||||
'componentFolder': 'src',
|
||||
'component': {
|
||||
'testFiles': '**/*.spec.{js,ts,tsx,jsx}',
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/vite-dev-server')
|
||||
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
|
||||
if (config.testingType === 'component') {
|
||||
on('dev-server:start', async (options) => {
|
||||
return startDevServer({
|
||||
options,
|
||||
viteConfig: {
|
||||
// TODO(tim): Figure out why this isn't being picked up
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
'@headlessui/vue',
|
||||
'vue3-file-selector',
|
||||
'just-my-luck',
|
||||
'combine-properties',
|
||||
'faker',
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return config // IMPORTANT to return a config
|
||||
},
|
||||
},
|
||||
'e2e': {
|
||||
'supportFile': 'cypress/e2e/support/e2eSupport.ts',
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* @type {import('@cypress/vite-dev-server')}
|
||||
*/
|
||||
const { startDevServer } = require('@cypress/vite-dev-server')
|
||||
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
|
||||
if (config.testingType === 'component') {
|
||||
on('dev-server:start', async (options) => {
|
||||
return startDevServer({
|
||||
options,
|
||||
viteConfig: {
|
||||
// TODO(tim): Figure out why this isn't being picked up
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
'@headlessui/vue',
|
||||
'vue3-file-selector',
|
||||
'just-my-luck',
|
||||
'combine-properties',
|
||||
'faker',
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return config // IMPORTANT to return a config
|
||||
}
|
||||
@@ -29,8 +29,8 @@ export const mutation = mutationType({
|
||||
|
||||
t.field('internal_clearLatestProjectCache', {
|
||||
type: 'Boolean',
|
||||
resolve: (_, args, ctx) => {
|
||||
ctx.actions.project.clearLatestProjectCache()
|
||||
resolve: async (_, args, ctx) => {
|
||||
await ctx.actions.project.clearLatestProjectCache()
|
||||
|
||||
return true
|
||||
},
|
||||
@@ -53,8 +53,8 @@ export const mutation = mutationType({
|
||||
args: {
|
||||
projectTitle: nonNull(stringArg()),
|
||||
},
|
||||
resolve: (_, args, ctx) => {
|
||||
ctx.actions.project.clearProjectPreferencesCache(args.projectTitle)
|
||||
resolve: async (_, args, ctx) => {
|
||||
await ctx.actions.project.clearProjectPreferencesCache(args.projectTitle)
|
||||
|
||||
return true
|
||||
},
|
||||
@@ -62,8 +62,8 @@ export const mutation = mutationType({
|
||||
|
||||
t.field('internal_clearAllProjectPreferencesCache', {
|
||||
type: 'Boolean',
|
||||
resolve: (_, args, ctx) => {
|
||||
ctx.actions.project.clearAllProjectPreferencesCache()
|
||||
resolve: async (_, args, ctx) => {
|
||||
await ctx.actions.project.clearAllProjectPreferencesCache()
|
||||
|
||||
return true
|
||||
},
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
export default {
|
||||
import { defineConfig } from 'cypress'
|
||||
import { e2ePluginSetup } from '@packages/frontend-shared/cypress/e2e/e2ePluginSetup'
|
||||
|
||||
export default defineConfig({
|
||||
'projectId': 'sehy69',
|
||||
'viewportWidth': 800,
|
||||
'viewportHeight': 850,
|
||||
@@ -17,10 +20,43 @@ export default {
|
||||
'testFiles': '**/*.spec.{js,ts,tsx,jsx}',
|
||||
'supportFile': 'cypress/component/support/index.ts',
|
||||
'pluginsFile': 'cypress/component/plugins/index.js',
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/vite-dev-server')
|
||||
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
|
||||
if (config.testingType === 'component') {
|
||||
on('dev-server:start', async (options) => {
|
||||
return startDevServer({
|
||||
options,
|
||||
viteConfig: {
|
||||
// TODO(tim): Figure out why this isn't being picked up
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
'@headlessui/vue',
|
||||
'vue3-file-selector',
|
||||
'just-my-luck',
|
||||
'combine-properties',
|
||||
'faker',
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return config // IMPORTANT to return a config
|
||||
},
|
||||
},
|
||||
'e2e': {
|
||||
'supportFile': 'cypress/e2e/support/e2eSupport.ts',
|
||||
'integrationFolder': 'cypress/e2e/integration',
|
||||
'pluginsFile': 'cypress/e2e/plugins/index.ts',
|
||||
async setupNodeEvents (on, config) {
|
||||
const { monorepoPaths } = require('../../scripts/gulp/monorepoPaths')
|
||||
|
||||
return await e2ePluginSetup(monorepoPaths.pkgLaunchpad, on, config)
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
module.exports = require('@packages/frontend-shared/cypress/plugins/index')
|
||||
@@ -12,7 +12,7 @@ describe('Plugin error handling', () => {
|
||||
.and('contain.text', 'The function exported by the plugins file threw an error')
|
||||
|
||||
cy.withCtx(async (ctx) => {
|
||||
await ctx.actions.file.writeFileInProject('cypress/plugins/index.js', `module.exports = (on, config) => {}`)
|
||||
await ctx.actions.file.writeFileInProject('cypress.config.js', `module.exports = { e2e: { baseUrl: 'https://cypress.com' } }`)
|
||||
})
|
||||
|
||||
cy.get('[data-testid=error-retry-button]').click()
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
const { monorepoPaths } = require('../../../../../scripts/gulp/monorepoPaths')
|
||||
import { e2ePluginSetup } from '@packages/frontend-shared/cypress/e2e/e2ePluginSetup'
|
||||
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
export default async (on, config) => {
|
||||
return await e2ePluginSetup(monorepoPaths.pkgLaunchpad, on, config)
|
||||
}
|
||||
@@ -13,4 +13,13 @@ export default defineConfig({
|
||||
'runMode': 2,
|
||||
'openMode': 0,
|
||||
},
|
||||
'e2e': {
|
||||
setupNodeEvents (on, config) {
|
||||
const express = require('express')
|
||||
|
||||
express().use(express.static('dist')).listen(5006)
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// const cp = require('child_process')
|
||||
|
||||
// cp.exec('http-server -p 5006 dist')
|
||||
|
||||
const express = require('express')
|
||||
|
||||
express().use(express.static('dist')).listen(5006)
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on: Function) => {
|
||||
}
|
||||
@@ -12,5 +12,36 @@ export default defineConfig({
|
||||
},
|
||||
component: {
|
||||
testFiles: '**/*spec.{ts,tsx}',
|
||||
setupNodeEvents (on, config) {
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
|
||||
function injectStylesInlineForPercyInPlace (webpackConfig) {
|
||||
webpackConfig.module.rules = webpackConfig.module.rules.map((rule) => {
|
||||
if (rule?.use[0]?.loader.includes('mini-css-extract-plugin')) {
|
||||
return {
|
||||
...rule,
|
||||
use: [{
|
||||
loader: 'style-loader',
|
||||
}],
|
||||
}
|
||||
}
|
||||
|
||||
return rule
|
||||
})
|
||||
}
|
||||
|
||||
on('dev-server:start', (options) => {
|
||||
const { default: webpackConfig } = require('./webpack.config.ts')
|
||||
|
||||
injectStylesInlineForPercyInPlace(webpackConfig)
|
||||
|
||||
return startDevServer({
|
||||
webpackConfig,
|
||||
options,
|
||||
})
|
||||
})
|
||||
|
||||
return config
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
const path = require('path')
|
||||
const { startDevServer } = require('@cypress/webpack-dev-server')
|
||||
|
||||
function injectStylesInlineForPercyInPlace (webpackConfig) {
|
||||
webpackConfig.module.rules = webpackConfig.module.rules.map((rule) => {
|
||||
if (rule?.use[0]?.loader.includes('mini-css-extract-plugin')) {
|
||||
return {
|
||||
...rule,
|
||||
use: [{
|
||||
loader: 'style-loader',
|
||||
}],
|
||||
}
|
||||
}
|
||||
|
||||
return rule
|
||||
})
|
||||
}
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
on('dev-server:start', (options) => {
|
||||
/** @type {import('webpack').Configuration} */
|
||||
const { default: webpackConfig } = require(path.resolve(__dirname, '..', '..', 'webpack.config.ts'))
|
||||
|
||||
injectStylesInlineForPercyInPlace(webpackConfig)
|
||||
|
||||
return startDevServer({
|
||||
webpackConfig,
|
||||
options,
|
||||
})
|
||||
})
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -12,4 +12,7 @@ module.exports = {
|
||||
'reporterOptions': {
|
||||
'configFile': '../../mocha-reporter-config.json',
|
||||
},
|
||||
'e2e': {
|
||||
'setupNodeEvents': require('./cypress/plugins'),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile is missing 1'] = `
|
||||
Error: Cannot find module '/does/not/exist.coffee'
|
||||
`
|
||||
|
||||
exports['lib/plugins/child/run_plugins sends error message if requiring pluginsFile errors 1'] = `
|
||||
Error: error thrown by pluginsFile
|
||||
`
|
||||
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile has syntax error 1'] = `
|
||||
<path>syntax_error.js)
|
||||
|
||||
|
||||
|
||||
SyntaxError: Unexpected end of input
|
||||
[stack trace]
|
||||
`
|
||||
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile does not export a function 1'] = `
|
||||
null
|
||||
exports['lib/plugins/child/run_plugins sends error message if setupNodeEvents is not a function 1'] = `
|
||||
plugins-file
|
||||
`
|
||||
|
||||
@@ -93,19 +93,6 @@ exports['lib/scaffold .fileTree returns tree-like structure of scaffolded 1'] =
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cypress",
|
||||
"children": [
|
||||
{
|
||||
"name": "plugins",
|
||||
"children": [
|
||||
{
|
||||
"name": "index.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
exports['lib/scaffold .fileTree leaves out integration tests if using component testing 1'] = [
|
||||
@@ -203,19 +190,6 @@ exports['lib/scaffold .fileTree leaves out integration tests if using component
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cypress",
|
||||
"children": [
|
||||
{
|
||||
"name": "plugins",
|
||||
"children": [
|
||||
{
|
||||
"name": "index.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
exports['lib/scaffold .fileTree leaves out fixtures if configured to false 1'] = [
|
||||
@@ -305,19 +279,6 @@ exports['lib/scaffold .fileTree leaves out fixtures if configured to false 1'] =
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cypress",
|
||||
"children": [
|
||||
{
|
||||
"name": "plugins",
|
||||
"children": [
|
||||
{
|
||||
"name": "index.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
exports['lib/scaffold .fileTree leaves out support if configured to false 1'] = [
|
||||
@@ -404,19 +365,6 @@ exports['lib/scaffold .fileTree leaves out support if configured to false 1'] =
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cypress",
|
||||
"children": [
|
||||
{
|
||||
"name": "plugins",
|
||||
"children": [
|
||||
{
|
||||
"name": "index.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 1'] = `
|
||||
|
||||
@@ -18,6 +18,7 @@ const debug = Debug('cypress:server:config')
|
||||
|
||||
import { options, breakingOptions } from './config_options'
|
||||
import { getProcessEnvVars, CYPRESS_SPECIAL_ENV_VARS } from './util/config'
|
||||
import type { DataContext } from '@packages/data-context'
|
||||
|
||||
const dashesOrUnderscoresRe = /^(_-)+/
|
||||
|
||||
@@ -185,9 +186,13 @@ export type FullConfig =
|
||||
resolved: ResolvedConfigurationOptions
|
||||
}
|
||||
|
||||
export function get (projectRoot, options: {configFile?: string | false } = { configFile: undefined }): Promise<FullConfig> {
|
||||
export function get (
|
||||
projectRoot,
|
||||
options: { configFile?: string | false } = { configFile: undefined },
|
||||
ctx: DataContext,
|
||||
): Promise<FullConfig> {
|
||||
return Promise.all([
|
||||
settings.read(projectRoot, options).then(validateFile(options.configFile ?? 'cypress.config.{ts|js}')),
|
||||
settings.read(projectRoot, options, ctx).then(validateFile(options.configFile ?? 'cypress.config.{ts|js}')),
|
||||
settings.readEnv(projectRoot).then(validateFile('cypress.env.json')),
|
||||
])
|
||||
.spread((settings, envFile) => {
|
||||
@@ -298,7 +303,6 @@ export function mergeDefaults (config: Record<string, any> = {}, options: Record
|
||||
validateNoBreakingConfig(config)
|
||||
|
||||
return setSupportFileAndFolder(config)
|
||||
.then(setPluginsFile)
|
||||
.then(setScaffoldPaths)
|
||||
.then(_.partialRight(setNodeBinary, options.onWarning))
|
||||
}
|
||||
@@ -342,10 +346,10 @@ export function updateWithPluginValues (cfg, overrides) {
|
||||
// make sure every option returned from the plugins file
|
||||
// passes our validation functions
|
||||
validate(overrides, (errMsg) => {
|
||||
if (cfg.pluginsFile && cfg.projectRoot) {
|
||||
const relativePluginsPath = path.relative(cfg.projectRoot, cfg.pluginsFile)
|
||||
if (cfg.configFile && cfg.projectRoot) {
|
||||
const relativeConfigPath = path.relative(cfg.projectRoot, cfg.configFile)
|
||||
|
||||
return errors.throw('PLUGINS_CONFIG_VALIDATION_ERROR', relativePluginsPath, errMsg)
|
||||
return errors.throw('PLUGINS_CONFIG_VALIDATION_ERROR', relativeConfigPath, errMsg)
|
||||
}
|
||||
|
||||
return errors.throw('CONFIG_VALIDATION_ERROR', errMsg)
|
||||
@@ -553,63 +557,6 @@ export function setSupportFileAndFolder (obj) {
|
||||
})
|
||||
}
|
||||
|
||||
// set pluginsFile to an absolute path with the following rules:
|
||||
// - do nothing if pluginsFile is falsey
|
||||
// - look up the absolute path via node, so 'cypress/plugins' can resolve
|
||||
// to 'cypress/plugins/index.js' or 'cypress/plugins/index.coffee'
|
||||
// - if not found
|
||||
// * and the pluginsFile is set to the default
|
||||
// - and the path to the pluginsFile directory exists
|
||||
// * assume the user doesn't need a pluginsFile, set it to false
|
||||
// so it's ignored down the pipeline
|
||||
// - and the path to the pluginsFile directory does not exist
|
||||
// * set it to cypress/plugins/index.js, it will get scaffolded
|
||||
// * and the pluginsFile is NOT set to the default
|
||||
// - throw an error, because it should be there if the user
|
||||
// explicitly set it
|
||||
export const setPluginsFile = Promise.method((obj) => {
|
||||
if (!obj.pluginsFile) {
|
||||
return obj
|
||||
}
|
||||
|
||||
obj = _.clone(obj)
|
||||
|
||||
const {
|
||||
pluginsFile,
|
||||
} = obj
|
||||
|
||||
debug(`setting plugins file ${pluginsFile}`)
|
||||
debug(`for project root ${obj.projectRoot}`)
|
||||
|
||||
return Promise
|
||||
.try(() => {
|
||||
// resolve full path with extension
|
||||
obj.pluginsFile = utils.resolveModule(pluginsFile)
|
||||
|
||||
return debug(`set pluginsFile to ${obj.pluginsFile}`)
|
||||
}).catch({ code: 'MODULE_NOT_FOUND' }, () => {
|
||||
debug('plugins module does not exist %o', { pluginsFile })
|
||||
|
||||
const isLoadingDefaultPluginsFile = pluginsFile === path.resolve(obj.projectRoot, defaultValues.pluginsFile)
|
||||
|
||||
return utils.discoverModuleFile({
|
||||
filename: pluginsFile,
|
||||
isDefault: isLoadingDefaultPluginsFile,
|
||||
projectRoot: obj.projectRoot,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result === null) {
|
||||
return errors.throw('PLUGINS_FILE_ERROR', path.resolve(obj.projectRoot, pluginsFile))
|
||||
}
|
||||
|
||||
debug('setting plugins file to %o', { result })
|
||||
obj.pluginsFile = result
|
||||
|
||||
return obj
|
||||
})
|
||||
}).return(obj)
|
||||
})
|
||||
|
||||
export function setParentTestsPaths (obj) {
|
||||
// projectRoot: "/path/to/project"
|
||||
// integrationFolder: "/path/to/project/cypress/integration"
|
||||
|
||||
@@ -559,34 +559,19 @@ const getMsgByType = function (type, arg1 = {}, arg2, arg3) {
|
||||
Or you might have renamed the extension of your \`supportFile\` to \`.ts\`. If that's the case, restart the test runner.
|
||||
|
||||
Learn more at https://on.cypress.io/support-file-missing-or-invalid`
|
||||
case 'PLUGINS_FILE_ERROR':
|
||||
case 'SETUP_NODE_EVENTS_IS_NOT_FUNCTION':
|
||||
msg = stripIndent`\
|
||||
The plugins file is missing or invalid.
|
||||
|
||||
Your \`pluginsFile\` is set to \`${arg1}\`, but either the file is missing, it contains a syntax error, or threw an error when required. The \`pluginsFile\` must be a \`.js\`, \`.ts\`, or \`.coffee\` file.
|
||||
|
||||
Or you might have renamed the extension of your \`pluginsFile\`. If that's the case, restart the test runner.
|
||||
|
||||
Please fix this, or set \`pluginsFile\` to \`false\` if a plugins file is not necessary for your project.`.trim()
|
||||
|
||||
if (arg2) {
|
||||
return { msg, details: arg2 }
|
||||
}
|
||||
|
||||
return msg
|
||||
case 'PLUGINS_DIDNT_EXPORT_FUNCTION':
|
||||
msg = stripIndent`\
|
||||
The \`pluginsFile\` must export a function with the following signature:
|
||||
The \`setupNodeEvents\` method must BE a function with the following signature:
|
||||
|
||||
\`\`\`
|
||||
module.exports = function (on, config) {
|
||||
setupNodeEvents (on, config) {
|
||||
// configure plugins here
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
Learn more: https://on.cypress.io/plugins-api
|
||||
|
||||
We loaded the \`pluginsFile\` from: \`${arg1}\`
|
||||
We loaded the \`setupNodeEvents\` from: \`${arg1}\`
|
||||
|
||||
It exported:`
|
||||
|
||||
@@ -598,10 +583,10 @@ const getMsgByType = function (type, arg1 = {}, arg2, arg3) {
|
||||
We invoked the function exported by \`${arg1}\`, but it threw an error.`
|
||||
|
||||
return { msg, details: arg2 }
|
||||
case 'PLUGINS_UNEXPECTED_ERROR':
|
||||
msg = `The following error was thrown by a plugin. We stopped running your tests because a plugin crashed. Please check your plugins file (\`${arg1}\`)`
|
||||
case 'SETUP_NODE_EVENTS_UNEXPECTED_ERROR':
|
||||
msg = `The following error was thrown by a plugin. We stopped running your tests because a plugin crashed. Please check your setupNodeEvents method for (\`${arg1}\`) on file (\`${arg2}\`)`
|
||||
|
||||
return { msg, details: arg2 }
|
||||
return { msg, details: arg3 }
|
||||
case 'PLUGINS_VALIDATION_ERROR':
|
||||
msg = `The following validation error was thrown by your plugins file (\`${arg1}\`).`
|
||||
|
||||
@@ -639,7 +624,7 @@ const getMsgByType = function (type, arg1 = {}, arg2, arg3) {
|
||||
filePath = `\`${arg1}\``
|
||||
|
||||
return stripIndent`\
|
||||
An invalid configuration value returned from the plugins file: ${chalk.blue(filePath)}
|
||||
An invalid configuration value returned from the setupNodeEvents on config file: ${chalk.blue(filePath)}
|
||||
|
||||
${chalk.yellow(arg2)}`
|
||||
// general configuration error not-specific to configuration or plugins files
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DataContext } from '@packages/data-context'
|
||||
import os from 'os'
|
||||
import { app } from 'electron'
|
||||
import type { App } from 'electron'
|
||||
|
||||
import specsUtil from './util/specs'
|
||||
import type { FindSpecs, FoundBrowser, LaunchArgs, LaunchOpts, OpenProjectLaunchOptions, PlatformName, Preferences, SettingsOptions } from '@packages/types'
|
||||
@@ -12,6 +12,7 @@ import { EventEmitter } from 'events'
|
||||
import { openProject } from './open_project'
|
||||
import cache from './cache'
|
||||
import errors from './errors'
|
||||
import findSystemNode from './util/find_system_node'
|
||||
import { graphqlSchema } from '@packages/graphql/src/schema'
|
||||
import type { InternalDataContextOptions } from '@packages/data-context/src/DataContext'
|
||||
import { openExternal } from '@packages/server/lib/gui/links'
|
||||
@@ -19,6 +20,7 @@ import { openExternal } from '@packages/server/lib/gui/links'
|
||||
const { getBrowsers, ensureAndGetByNameOrPath } = browserUtils
|
||||
|
||||
interface MakeDataContextOptions {
|
||||
electronApp?: App
|
||||
os: PlatformName
|
||||
rootBus: EventEmitter
|
||||
launchArgs: LaunchArgs
|
||||
@@ -28,7 +30,8 @@ interface MakeDataContextOptions {
|
||||
let legacyDataContext: DataContext | undefined
|
||||
|
||||
// For testing
|
||||
export function clearLegacyDataContext () {
|
||||
export async function clearLegacyDataContext () {
|
||||
await legacyDataContext?.destroy()
|
||||
legacyDataContext = undefined
|
||||
}
|
||||
|
||||
@@ -49,15 +52,17 @@ export function makeLegacyDataContext (launchArgs: LaunchArgs = {} as LaunchArgs
|
||||
return legacyDataContext
|
||||
}
|
||||
|
||||
export function makeDataContext (options: MakeDataContextOptions) {
|
||||
return new DataContext({
|
||||
export function makeDataContext (options: MakeDataContextOptions): DataContext {
|
||||
const ctx = new DataContext({
|
||||
schema: graphqlSchema,
|
||||
...options,
|
||||
launchOptions: {},
|
||||
electronApp: app,
|
||||
appApi: {
|
||||
getBrowsers,
|
||||
ensureAndGetByNameOrPath,
|
||||
findNodePathAndVersion () {
|
||||
return findSystemNode.findNodePathAndVersion()
|
||||
},
|
||||
},
|
||||
authApi: {
|
||||
getUser () {
|
||||
@@ -72,7 +77,7 @@ export function makeDataContext (options: MakeDataContextOptions) {
|
||||
},
|
||||
projectApi: {
|
||||
getConfig (projectRoot: string, options?: SettingsOptions) {
|
||||
return config.get(projectRoot, options)
|
||||
return config.get(projectRoot, options, ctx)
|
||||
},
|
||||
launchProject (browser: FoundBrowser, spec: Cypress.Spec, options?: LaunchOpts) {
|
||||
return openProject.launch({ ...browser }, spec, options)
|
||||
@@ -110,8 +115,8 @@ export function makeDataContext (options: MakeDataContextOptions) {
|
||||
closeActiveProject () {
|
||||
return openProject.closeActiveProject()
|
||||
},
|
||||
error (type: string, ...args: any) {
|
||||
throw errors.throw(type, ...args)
|
||||
get error () {
|
||||
return errors
|
||||
},
|
||||
},
|
||||
electronApi: {
|
||||
@@ -120,4 +125,6 @@ export function makeDataContext (options: MakeDataContextOptions) {
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ export = {
|
||||
ready (options: {projectRoot?: string} = {}) {
|
||||
const { projectRoot } = options
|
||||
const { serverPortPromise, bus, ctx } = process.env.LAUNCHPAD
|
||||
? runInternalServer(options)
|
||||
? runInternalServer(options, undefined, app)
|
||||
: { bus: new EventEmitter, serverPortPromise: Promise.resolve(undefined), ctx: null }
|
||||
|
||||
// TODO: potentially just pass an event emitter
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import os from 'os'
|
||||
import { EventEmitter } from 'events'
|
||||
import type { App } from 'electron'
|
||||
|
||||
import { makeDataContext } from '../makeDataContext'
|
||||
import { makeGraphQLServer } from '../gui/makeGraphQLServer'
|
||||
import { assertValidPlatform } from '@packages/types/src/platform'
|
||||
|
||||
export function runInternalServer (launchArgs, _internalOptions = { loadCachedProjects: true }) {
|
||||
export function runInternalServer (launchArgs, _internalOptions = { loadCachedProjects: true }, electronApp?: App) {
|
||||
const bus = new EventEmitter()
|
||||
const platform = os.platform()
|
||||
|
||||
assertValidPlatform(platform)
|
||||
|
||||
const ctx = makeDataContext({
|
||||
electronApp,
|
||||
os: platform,
|
||||
rootBus: bus,
|
||||
launchArgs,
|
||||
|
||||
@@ -453,13 +453,15 @@ export class OpenProject {
|
||||
debug('opening project %s', path)
|
||||
debug('and options %o', options)
|
||||
|
||||
const testingType = args.testingType === 'component' ? 'component' : 'e2e'
|
||||
|
||||
// store the currently open project
|
||||
this.openProject = new ProjectBase({
|
||||
testingType: args.testingType === 'component' ? 'component' : 'e2e',
|
||||
testingType,
|
||||
projectRoot: path,
|
||||
options: {
|
||||
...options,
|
||||
testingType: args.testingType,
|
||||
testingType,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user