diff --git a/e2e/react/src/cypress-component-tests.test.ts b/e2e/react/src/cypress-component-tests.test.ts index 8692b785fb080..050179003fd7c 100644 --- a/e2e/react/src/cypress-component-tests.test.ts +++ b/e2e/react/src/cypress-component-tests.test.ts @@ -215,4 +215,33 @@ ${content}`; 'All specs passed!' ); }, 300_000); + + it('should work with async webpack config', () => { + // TODO: (caleb) for whatever reason the MF webpack config + CT is running, but cypress is not starting up? + // are they overriding some option on top of each other causing cypress to not see it's running? + createFile( + `apps/${appName}/webpack.config.js`, + `module.exports = async function (configuration) { + await new Promise((res) => { + setTimeout(() => { + console.log('I am from the custom async Webpack config') + res() + }, 1000) + }) + const defaultConfig = require("@nrwl/react/plugins/webpack") + return defaultConfig(configuration); +};` + ); + updateProjectConfig(appName, (config) => { + config.targets[ + 'build' + ].options.webpackConfig = `apps/${appName}/webpack.config.js`; + + return config; + }); + + const results = runCLI(`component-test ${appName}`); + expect(results).toContain('I am from the custom async Webpack config'); + expect(results).toContain('All specs passed!'); + }); }); diff --git a/packages/react/plugins/component-testing/index.ts b/packages/react/plugins/component-testing/index.ts index c595aa9c36d54..b05005ab66c5f 100644 --- a/packages/react/plugins/component-testing/index.ts +++ b/packages/react/plugins/component-testing/index.ts @@ -19,6 +19,18 @@ import { getProjectConfigByPath, } from '@nrwl/cypress/src/utils/ct-helpers'; +import type { Configuration } from 'webpack'; +type ViteDevServer = { + framework: 'react'; + bundler: 'vite'; + viteConfig?: any; +}; + +type WebpackDevServer = { + framework: 'react'; + bundler: 'webpack'; + webpackConfig?: any; +}; /** * React nx preset for Cypress Component Testing * @@ -42,18 +54,13 @@ export function nxComponentTestingPreset( options?: NxComponentTestingOptions ): { specPattern: string; - devServer: { - framework?: 'react'; - bundler?: 'vite' | 'webpack'; - viteConfig?: any; - webpackConfig?: any; - }; + devServer: ViteDevServer | WebpackDevServer; videosFolder: string; screenshotsFolder: string; video: boolean; chromeWebSecurity: boolean; } { - if (options.bundler === 'vite') { + if (options?.bundler === 'vite') { return { ...nxBaseCypressPreset(pathToConfig), specPattern: 'src/**/*.cy.{js,jsx,ts,tsx}', @@ -63,7 +70,7 @@ export function nxComponentTestingPreset( }; } - let webpackConfig; + let webpackConfig: any; try { const graph = readCachedProjectGraph(); const { targets: ctTargets, name: ctProjectName } = getProjectConfigByPath( @@ -119,10 +126,11 @@ export function nxComponentTestingPreset( devServer: { // cypress uses string union type, // need to use const to prevent typing to string - framework: 'react', - bundler: 'webpack', + // but don't want to use as const on webpackConfig + // so it is still user modifiable + ...({ framework: 'react', bundler: 'webpack' } as const), webpackConfig, - } as const, + }, }; } @@ -194,47 +202,43 @@ function buildTargetWebpack( buildableProjectConfig.sourceRoot! ); - const isScriptOptimizeOn = - typeof options.optimization === 'boolean' - ? options.optimization - : options.optimization && options.optimization.scripts - ? options.optimization.scripts - : false; - - let customWebpack; if (options.webpackConfig) { + let customWebpack: any; + + const isScriptOptimizeOn = + typeof options.optimization === 'boolean' + ? options.optimization + : options.optimization && options.optimization.scripts + ? options.optimization.scripts + : false; + customWebpack = resolveCustomWebpackConfig( options.webpackConfig, options.tsConfig ); - if (typeof customWebpack.then === 'function') { - // cypress configs have to be sync. - // TODO(caleb): there might be a workaround with setUpNodeEvents preprocessor? - logger.warn(stripIndents`Nx React Component Testing Preset currently doesn't support custom async webpack configs. - Skipping the custom webpack config option '${options.webpackConfig}'`); - customWebpack = null; - } - } - - const defaultWebpack = getWebpackConfig( - context, - options, - true, - isScriptOptimizeOn, - { - root: ctProjectConfig.root, - sourceRoot: ctProjectConfig.sourceRoot, - configuration: parsed.configuration, - } - ); + return async () => { + customWebpack = await customWebpack; + const defaultWebpack = getWebpackConfig( + context, + options, + true, + isScriptOptimizeOn, + { + root: ctProjectConfig.root, + sourceRoot: ctProjectConfig.sourceRoot, + configuration: parsed.configuration, + } + ); - if (customWebpack) { - return customWebpack(defaultWebpack, { - options, - context, - configuration: parsed.configuration, - }); + if (customWebpack) { + return await customWebpack(defaultWebpack, { + options, + context, + configuration: parsed.configuration, + }); + } + return defaultWebpack; + }; } - return defaultWebpack; } diff --git a/packages/react/src/generators/cypress-component-configuration/__snapshots__/cypress-component-configuration.spec.ts.snap b/packages/react/src/generators/cypress-component-configuration/__snapshots__/cypress-component-configuration.spec.ts.snap index 6eaccf7587c4b..a3e3b0d3c27d8 100644 --- a/packages/react/src/generators/cypress-component-configuration/__snapshots__/cypress-component-configuration.spec.ts.snap +++ b/packages/react/src/generators/cypress-component-configuration/__snapshots__/cypress-component-configuration.spec.ts.snap @@ -7,8 +7,9 @@ import { nxComponentTestingPreset } from '@nrwl/react/plugins/component-testing' export default defineConfig({ component: nxComponentTestingPreset(__filename, { bundler: 'vite' - }) as any, -});" + }), +}); +" `; exports[`React:CypressComponentTestConfiguration should generate cypress component test config with project graph 1`] = ` @@ -18,8 +19,9 @@ import { nxComponentTestingPreset } from '@nrwl/react/plugins/component-testing' export default defineConfig({ component: nxComponentTestingPreset(__filename, { bundler: 'vite' - }) as any, -});" + }), +}); +" `; exports[`React:CypressComponentTestConfiguration should generate cypress component test config with webpack 1`] = ` @@ -29,8 +31,9 @@ import { nxComponentTestingPreset } from '@nrwl/react/plugins/component-testing' export default defineConfig({ component: nxComponentTestingPreset(__filename, { bundler: 'webpack' - }) as any, -});" + }), +}); +" `; exports[`React:CypressComponentTestConfiguration should generate cypress config with vite 1`] = ` @@ -40,8 +43,9 @@ import { nxComponentTestingPreset } from '@nrwl/react/plugins/component-testing' export default defineConfig({ component: nxComponentTestingPreset(__filename, { bundler: 'vite' - }) as any, -});" + }), +}); +" `; exports[`React:CypressComponentTestConfiguration should generate tests for existing js components 1`] = ` diff --git a/packages/react/src/generators/cypress-component-configuration/files/cypress.config.ts__tpl__ b/packages/react/src/generators/cypress-component-configuration/files/cypress.config.ts__tpl__ index 22b4b44221a71..fae43e41d7b39 100644 --- a/packages/react/src/generators/cypress-component-configuration/files/cypress.config.ts__tpl__ +++ b/packages/react/src/generators/cypress-component-configuration/files/cypress.config.ts__tpl__ @@ -4,5 +4,5 @@ import { nxComponentTestingPreset } from '@nrwl/react/plugins/component-testing' export default defineConfig({ component: nxComponentTestingPreset(__filename, { bundler: '<%= bundler %>' - }) as any, -}); \ No newline at end of file + }), +});