mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-15 11:40:07 -06:00
109 lines
3.6 KiB
JavaScript
109 lines
3.6 KiB
JavaScript
// @ts-check
|
|
const debug = require('debug')('@cypress/react')
|
|
const tryLoadWebpackConfig = require('../utils/tryLoadWebpackConfig')
|
|
const { getTranspileFolders } = require('../utils/get-transpile-folders')
|
|
const { addFolderToBabelLoaderTranspileInPlace } = require('../utils/babel-helpers')
|
|
|
|
/**
|
|
* Finds the ModuleScopePlugin plugin and adds given folder
|
|
* to that list. This allows react-scripts to import folders
|
|
* outside of the default "/src" folder.
|
|
* WARNING modifies the input webpack options argument.
|
|
* @see https://github.com/bahmutov/cypress-react-unit-test/issues/289
|
|
* @param {string} folderName Folder to add, should be absolute
|
|
*/
|
|
function allowModuleSourceInPlace (folderName, webpackOptions) {
|
|
if (!folderName) {
|
|
return
|
|
}
|
|
|
|
if (!webpackOptions.resolve) {
|
|
return
|
|
}
|
|
|
|
if (!Array.isArray(webpackOptions.resolve.plugins)) {
|
|
return
|
|
}
|
|
|
|
const moduleSourcePlugin = webpackOptions.resolve.plugins.find((plugin) => {
|
|
return Array.isArray(plugin.appSrcs)
|
|
})
|
|
|
|
if (!moduleSourcePlugin) {
|
|
debug('cannot find module source plugin')
|
|
|
|
return
|
|
}
|
|
|
|
debug('found module source plugin %o', moduleSourcePlugin)
|
|
if (!moduleSourcePlugin.appSrcs.includes(folderName)) {
|
|
moduleSourcePlugin.appSrcs.push(folderName)
|
|
debug('added folder %s to allowed sources', folderName)
|
|
}
|
|
}
|
|
|
|
const addCypressToWebpackEslintRulesInPlace = (webpackOptions) => {
|
|
const globalsToAdd = ['cy', 'Cypress', 'before', 'after', 'context']
|
|
|
|
if (webpackOptions.module && Array.isArray(webpackOptions.module.rules)) {
|
|
const modulePre = webpackOptions.module.rules.find(
|
|
(rule) => rule.enforce === 'pre',
|
|
)
|
|
|
|
if (modulePre && Array.isArray(modulePre.use)) {
|
|
debug('found Pre block %o', modulePre)
|
|
|
|
const useEslintLoader = modulePre.use.find(
|
|
(use) => use.loader && use.loader.includes('eslint-loader'),
|
|
)
|
|
|
|
if (useEslintLoader) {
|
|
debug('found useEslintLoader %o', useEslintLoader)
|
|
|
|
if (useEslintLoader.options) {
|
|
if (Array.isArray(useEslintLoader.options.globals)) {
|
|
debug(
|
|
'adding cy to existing globals %o',
|
|
useEslintLoader.options.globals,
|
|
)
|
|
|
|
useEslintLoader.options.globals.push(...globalsToAdd)
|
|
} else {
|
|
debug('setting new list of globals with cy and Cypress')
|
|
useEslintLoader.options.globals = globalsToAdd
|
|
}
|
|
|
|
debug('updated globals %o', useEslintLoader.options.globals)
|
|
} else {
|
|
debug('eslint loader does not have options ⚠️')
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = function findReactScriptsWebpackConfig (config) {
|
|
// this is required because
|
|
// 1) we use our own HMR and we don't need react-refresh transpiling overhead
|
|
// 2) it doesn't work with process.env=test @see https://github.com/cypress-io/cypress-realworld-app/pull/832
|
|
process.env.FAST_REFRESH = 'false'
|
|
const webpackConfig = tryLoadWebpackConfig('react-scripts/config/webpack.config')
|
|
|
|
if (!webpackConfig) {
|
|
throw new Error('⚠️ Could not find Webpack options for react-scripts. Make sure that you have react-scripts module available.')
|
|
}
|
|
|
|
// because for react-scripts user doesn't have direct access to webpack webpackConfig
|
|
// we must implicitly inject everything required to run tests
|
|
addCypressToWebpackEslintRulesInPlace(webpackConfig)
|
|
|
|
getTranspileFolders(config).forEach((cypressFolder) => {
|
|
allowModuleSourceInPlace(cypressFolder, webpackConfig)
|
|
addFolderToBabelLoaderTranspileInPlace(cypressFolder, webpackConfig)
|
|
})
|
|
|
|
debug('resolved webpack config: %o', webpackConfig)
|
|
|
|
return webpackConfig
|
|
}
|