diff --git a/npm/vite-dev-server/cypress/e2e/react.cy.ts b/npm/vite-dev-server/cypress/e2e/react.cy.ts index 1916389a70fb..0f0e0ea5c33f 100644 --- a/npm/vite-dev-server/cypress/e2e/react.cy.ts +++ b/npm/vite-dev-server/cypress/e2e/react.cy.ts @@ -1,6 +1,7 @@ /// /// import type { fixtureDirs } from '@tooling/system-tests' +import dedent from 'dedent' type ProjectDirs = typeof fixtureDirs @@ -24,17 +25,19 @@ for (const project of VITE_REACT) { it('should mount a passing test', () => { cy.visitApp() cy.contains('App.cy.jsx').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) it('MissingReact: should fail, rerun, succeed', () => { - cy.once('uncaught:exception', () => { + cy.on('uncaught:exception', () => { // Ignore the uncaught exception in the AUT return false }) cy.visitApp() cy.contains('MissingReact.cy.jsx').click() + cy.waitForSpecToFinish() cy.get('.failed > .num').should('contain', 1) cy.withCtx(async (ctx) => { await ctx.actions.file.writeFileInProject(`src/MissingReact.jsx`, @@ -46,8 +49,14 @@ for (const project of VITE_REACT) { }) it('MissingReactInSpec: should fail, rerun, succeed', () => { + cy.on('uncaught:exception', () => { + // Ignore the uncaught exception in the AUT + return false + }) + cy.visitApp() cy.contains('MissingReactInSpec.cy.jsx').click() + cy.waitForSpecToFinish() cy.get('.failed > .num').should('contain', 1) cy.withCtx(async (ctx) => { await ctx.actions.file.writeFileInProject(`src/MissingReactInSpec.cy.jsx`, @@ -56,5 +65,55 @@ for (const project of VITE_REACT) { cy.get('.passed > .num').should('contain', 1) }) + + it('AppCompilationError: should fail with uncaught exception error', () => { + cy.on('uncaught:exception', () => { + // Ignore the uncaught exception in the AUT + return false + }) + + cy.visitApp() + cy.contains('AppCompilationError.cy.jsx').click() + cy.waitForSpecToFinish() + cy.get('.failed > .num').should('contain', 1) + cy.contains('An uncaught error was detected outside of a test') + cy.contains('The following error originated from your test code, not from Cypress.') + + // Correct the problem + cy.withCtx(async (ctx) => { + await ctx.actions.file.writeFileInProject( + `src/AppCompilationError.cy.jsx`, + await ctx.file.readFileInProject('src/App.cy.jsx'), + ) + }) + + cy.waitForSpecToFinish() + cy.get('.passed > .num').should('contain', 1) + + const appCompilationErrorSpec = dedent` + import React from 'react' + import { mount } from 'cypress/react' + import { App } from './App' + + it('renders hello world', () => { + mount() + cy.get('h1').contains('Hello World') + } + }) + ` + + // Cause the problem again + cy.withCtx(async (ctx, o) => { + await ctx.actions.file.writeFileInProject( + `src/AppCompilationError.cy.jsx`, + o.appCompilationErrorSpec, + ) + }, { appCompilationErrorSpec }) + + cy.waitForSpecToFinish() + cy.get('.failed > .num').should('contain', 1) + cy.contains('An uncaught error was detected outside of a test') + cy.contains('The following error originated from your test code, not from Cypress.') + }) }) } diff --git a/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts b/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts index 7f70de2ffe4d..12d59f6da467 100644 --- a/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts +++ b/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts @@ -9,6 +9,7 @@ describe('Config options', () => { cy.visitApp() cy.contains('App.cy.jsx').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) diff --git a/npm/vite-dev-server/cypress/support/commands.ts b/npm/vite-dev-server/cypress/support/commands.ts index 95857aea4cdf..c4dc7e61db6d 100644 --- a/npm/vite-dev-server/cypress/support/commands.ts +++ b/npm/vite-dev-server/cypress/support/commands.ts @@ -1,37 +1,34 @@ /// -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -// -// declare global { -// namespace Cypress { -// interface Chainable { -// login(email: string, password: string): Chainable -// drag(subject: string, options?: Partial): Chainable -// dismiss(subject: string, options?: Partial): Chainable -// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable -// } -// } -// } + +declare global { + namespace Cypress { + interface Chainable { + /** + * Adapter to wait for a spec to finish in a standard way. It + * + * 1. Waits for the stats to reset which signifies that the test page has loaded + * 2. Waits for 'Your tests are loading...' to not be present so that we know the tests themselves have loaded + * 3. Waits (with a timeout of 30s) for the Rerun all tests button to be present. This ensures all tests have completed + * + */ + waitForSpecToFinish() + } + } +} + +// Here we export the function with no intention to import it +// This only tells the typescript type checker that this definitely is a module +// This way, we are allowed to use the global namespace declaration +export const waitForSpecToFinish = () => { + // First ensure the test is loaded + cy.get('.passed > .num').should('contain', '--') + cy.get('.failed > .num').should('contain', '--') + + // Then ensure the tests are running + cy.contains('Your tests are loading...').should('not.exist') + + // Then ensure the tests have finished + cy.get('[aria-label="Rerun all tests"]', { timeout: 30000 }) +} + +Cypress.Commands.add('waitForSpecToFinish', waitForSpecToFinish) diff --git a/npm/vite-dev-server/cypress/support/e2e.ts b/npm/vite-dev-server/cypress/support/e2e.ts index 0abc77d09a4c..c279241b560e 100644 --- a/npm/vite-dev-server/cypress/support/e2e.ts +++ b/npm/vite-dev-server/cypress/support/e2e.ts @@ -15,6 +15,4 @@ // Import commands.js using ES2015 syntax: import '@packages/frontend-shared/cypress/e2e/support/e2eSupport' - -// Alternatively you can use CommonJS syntax: -// require('./commands') +import './commands' diff --git a/npm/vite-dev-server/package.json b/npm/vite-dev-server/package.json index 332b3230c83a..17b87e6af365 100644 --- a/npm/vite-dev-server/package.json +++ b/npm/vite-dev-server/package.json @@ -21,6 +21,7 @@ "pathe": "0.2.0" }, "devDependencies": { + "dedent": "^0.7.0", "vite": "2.9.0-beta.3", "vite-plugin-inspect": "0.4.3" }, diff --git a/npm/vite-dev-server/src/resolveConfig.ts b/npm/vite-dev-server/src/resolveConfig.ts index 83cc0b01a0bc..288eae51b945 100644 --- a/npm/vite-dev-server/src/resolveConfig.ts +++ b/npm/vite-dev-server/src/resolveConfig.ts @@ -46,6 +46,24 @@ export const createViteDevServerConfig = async (config: ViteDevServerConfig, vit base: `${cypressConfig.devServerPublicPathRoute}/`, configFile, optimizeDeps: { + esbuildOptions: { + incremental: true, + plugins: [ + { + name: 'cypress-esbuild-plugin', + setup (build) { + build.onEnd(function (result) { + // We don't want to completely fail the build here on errors so we treat the errors as warnings + // which will handle things more gracefully. Vite will 500 on files that have errors when they + // are requested later and Cypress will display an error message. + // See: https://github.com/cypress-io/cypress/pull/21599 + result.warnings = [...result.warnings, ...result.errors] + result.errors = [] + }) + }, + }, + ], + }, entries: [ ...specs.map((s) => relative(root, s.relative)), ...(cypressConfig.supportFile ? [resolve(root, cypressConfig.supportFile)] : []), diff --git a/npm/webpack-dev-server/__snapshots__/makeWebpackConfig.spec.ts.js b/npm/webpack-dev-server/__snapshots__/makeWebpackConfig.spec.ts.js index ad29c798514f..f2dc52ed214a 100644 --- a/npm/webpack-dev-server/__snapshots__/makeWebpackConfig.spec.ts.js +++ b/npm/webpack-dev-server/__snapshots__/makeWebpackConfig.spec.ts.js @@ -1,8 +1,36 @@ -exports['makeWebpackConfig ignores userland webpack `output.publicPath` 1'] = { +exports['makeWebpackConfig ignores userland webpack `output.publicPath` and `devServer.overlay` with webpack-dev-server v4 1'] = { "output": { "publicPath": "/test-public-path/", "filename": "[name].js" }, + "devServer": { + "magicHtml": true, + "client": { + "progress": false, + "overlay": false + } + }, + "mode": "development", + "optimization": { + "splitChunks": { + "chunks": "all" + } + }, + "plugins": [ + "HtmlWebpackPlugin", + "CypressCTWebpackPlugin" + ] +} + +exports['makeWebpackConfig ignores userland webpack `output.publicPath` and `devServer.overlay` with webpack-dev-server v3 1'] = { + "output": { + "publicPath": "/test-public-path/", + "filename": "[name].js" + }, + "devServer": { + "progress": true, + "overlay": false + }, "mode": "development", "optimization": { "splitChunks": { diff --git a/npm/webpack-dev-server/cypress/e2e/create-react-app.cy.ts b/npm/webpack-dev-server/cypress/e2e/create-react-app.cy.ts index d859951054c8..b20c2ec4cf04 100644 --- a/npm/webpack-dev-server/cypress/e2e/create-react-app.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/create-react-app.cy.ts @@ -22,6 +22,7 @@ for (const project of WEBPACK_REACT) { it('should mount a passing test', () => { cy.visitApp() cy.contains('App.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) @@ -29,6 +30,7 @@ for (const project of WEBPACK_REACT) { cy.visitApp() cy.contains('App.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) cy.withCtx(async (ctx) => { @@ -61,6 +63,7 @@ for (const project of WEBPACK_REACT) { }) cy.contains('New.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) }) diff --git a/npm/webpack-dev-server/cypress/e2e/next.cy.ts b/npm/webpack-dev-server/cypress/e2e/next.cy.ts index 0a7cf2693e8c..46f0712747d9 100644 --- a/npm/webpack-dev-server/cypress/e2e/next.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/next.cy.ts @@ -22,6 +22,7 @@ for (const project of WEBPACK_REACT) { it('should mount a passing test', () => { cy.visitApp() cy.contains('index.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) @@ -29,6 +30,7 @@ for (const project of WEBPACK_REACT) { cy.visitApp() cy.contains('index.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) cy.withCtx(async (ctx) => { @@ -68,6 +70,7 @@ for (const project of WEBPACK_REACT) { }) cy.contains('New.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) }) diff --git a/npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts b/npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts index a8356d87aadd..379e70bc2795 100644 --- a/npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts @@ -24,6 +24,7 @@ for (const project of PROJECTS) { it('should mount a passing test and live-reload', () => { cy.visitApp() cy.contains('Tutorial.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) cy.withCtx(async (ctx) => { @@ -63,6 +64,7 @@ for (const project of PROJECTS) { }) cy.contains('New.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) }) diff --git a/npm/webpack-dev-server/cypress/e2e/react.cy.ts b/npm/webpack-dev-server/cypress/e2e/react.cy.ts index eafb0046b5e5..4eca06947717 100644 --- a/npm/webpack-dev-server/cypress/e2e/react.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/react.cy.ts @@ -1,6 +1,7 @@ /// /// import type { fixtureDirs } from '@tooling/system-tests' +import dedent from 'dedent' type ProjectDirs = typeof fixtureDirs @@ -24,17 +25,19 @@ for (const project of WEBPACK_REACT) { it('should mount a passing test', () => { cy.visitApp() cy.contains('App.cy.jsx').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) it('MissingReact: should fail, rerun, succeed', () => { - cy.once('uncaught:exception', () => { + cy.on('uncaught:exception', () => { // Ignore the uncaught exception in the AUT return false }) cy.visitApp() cy.contains('MissingReact.cy.jsx').click() + cy.waitForSpecToFinish() cy.get('.failed > .num').should('contain', 1) cy.withCtx(async (ctx) => { await ctx.actions.file.writeFileInProject(`src/MissingReact.jsx`, @@ -46,8 +49,14 @@ for (const project of WEBPACK_REACT) { }) it('MissingReactInSpec: should fail, rerun, succeed', () => { + cy.on('uncaught:exception', () => { + // Ignore the uncaught exception in the AUT + return false + }) + cy.visitApp() cy.contains('MissingReactInSpec.cy.jsx').click() + cy.waitForSpecToFinish() cy.get('.failed > .num').should('contain', 1) cy.withCtx(async (ctx) => { await ctx.actions.file.writeFileInProject(`src/MissingReactInSpec.cy.jsx`, @@ -57,6 +66,56 @@ for (const project of WEBPACK_REACT) { cy.get('.passed > .num').should('contain', 1) }) + it('AppCompilationError: should fail with uncaught exception error', () => { + cy.on('uncaught:exception', () => { + // Ignore the uncaught exception in the AUT + return false + }) + + cy.visitApp() + cy.contains('AppCompilationError.cy.jsx').click() + cy.waitForSpecToFinish() + cy.get('.failed > .num').should('contain', 1) + cy.contains('An uncaught error was detected outside of a test') + cy.contains('The following error originated from your test code, not from Cypress.') + + // Correct the problem + cy.withCtx(async (ctx) => { + await ctx.actions.file.writeFileInProject( + `src/AppCompilationError.cy.jsx`, + await ctx.file.readFileInProject('src/App.cy.jsx'), + ) + }) + + cy.waitForSpecToFinish() + cy.get('.passed > .num').should('contain', 1) + + const appCompilationErrorSpec = dedent` + import React from 'react' + import { mount } from 'cypress/react' + import { App } from './App' + + it('renders hello world', () => { + mount() + cy.get('h1').contains('Hello World') + } + }) + ` + + // Cause the problem again + cy.withCtx(async (ctx, o) => { + await ctx.actions.file.writeFileInProject( + `src/AppCompilationError.cy.jsx`, + o.appCompilationErrorSpec, + ) + }, { appCompilationErrorSpec }) + + cy.waitForSpecToFinish() + cy.get('.failed > .num').should('contain', 1) + cy.contains('An uncaught error was detected outside of a test') + cy.contains('The following error originated from your test code, not from Cypress.') + }) + // https://cypress-io.atlassian.net/browse/UNIFY-1697 it('filters missing spec files from loader during pre-compilation', () => { cy.visitApp() diff --git a/npm/webpack-dev-server/cypress/e2e/vue-cli.cy.ts b/npm/webpack-dev-server/cypress/e2e/vue-cli.cy.ts index cbe6ac788bd8..57ada2da8fd0 100644 --- a/npm/webpack-dev-server/cypress/e2e/vue-cli.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/vue-cli.cy.ts @@ -22,6 +22,7 @@ for (const project of PROJECTS) { it('should mount a passing test', () => { cy.visitApp() cy.contains('HelloWorld.cy.js').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) cy.get('.commands-container').within(() => { cy.contains('mount') diff --git a/npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts b/npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts index d888a08608fd..3906f21c761d 100644 --- a/npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/webpack-dev-server.cy.ts @@ -6,6 +6,7 @@ describe('Config options', () => { cy.visitApp() cy.contains('App.cy.jsx').click() + cy.waitForSpecToFinish() cy.get('.passed > .num').should('contain', 1) }) }) diff --git a/npm/webpack-dev-server/cypress/support/commands.ts b/npm/webpack-dev-server/cypress/support/commands.ts index 95857aea4cdf..c4dc7e61db6d 100644 --- a/npm/webpack-dev-server/cypress/support/commands.ts +++ b/npm/webpack-dev-server/cypress/support/commands.ts @@ -1,37 +1,34 @@ /// -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -// -// declare global { -// namespace Cypress { -// interface Chainable { -// login(email: string, password: string): Chainable -// drag(subject: string, options?: Partial): Chainable -// dismiss(subject: string, options?: Partial): Chainable -// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable -// } -// } -// } + +declare global { + namespace Cypress { + interface Chainable { + /** + * Adapter to wait for a spec to finish in a standard way. It + * + * 1. Waits for the stats to reset which signifies that the test page has loaded + * 2. Waits for 'Your tests are loading...' to not be present so that we know the tests themselves have loaded + * 3. Waits (with a timeout of 30s) for the Rerun all tests button to be present. This ensures all tests have completed + * + */ + waitForSpecToFinish() + } + } +} + +// Here we export the function with no intention to import it +// This only tells the typescript type checker that this definitely is a module +// This way, we are allowed to use the global namespace declaration +export const waitForSpecToFinish = () => { + // First ensure the test is loaded + cy.get('.passed > .num').should('contain', '--') + cy.get('.failed > .num').should('contain', '--') + + // Then ensure the tests are running + cy.contains('Your tests are loading...').should('not.exist') + + // Then ensure the tests have finished + cy.get('[aria-label="Rerun all tests"]', { timeout: 30000 }) +} + +Cypress.Commands.add('waitForSpecToFinish', waitForSpecToFinish) diff --git a/npm/webpack-dev-server/cypress/support/e2e.ts b/npm/webpack-dev-server/cypress/support/e2e.ts index 0abc77d09a4c..c279241b560e 100644 --- a/npm/webpack-dev-server/cypress/support/e2e.ts +++ b/npm/webpack-dev-server/cypress/support/e2e.ts @@ -15,6 +15,4 @@ // Import commands.js using ES2015 syntax: import '@packages/frontend-shared/cypress/e2e/support/e2eSupport' - -// Alternatively you can use CommonJS syntax: -// require('./commands') +import './commands' diff --git a/npm/webpack-dev-server/package.json b/npm/webpack-dev-server/package.json index 9be881ec1343..caf9f67e0e9b 100644 --- a/npm/webpack-dev-server/package.json +++ b/npm/webpack-dev-server/package.json @@ -31,6 +31,7 @@ "@types/speed-measure-webpack-plugin": "^1.3.4", "@types/webpack-dev-server-3": "npm:@types/webpack-dev-server@^3", "chai": "^4.3.6", + "dedent": "^0.7.0", "mocha": "^9.2.2", "proxyquire": "2.1.3", "sinon": "^13.0.1", diff --git a/npm/webpack-dev-server/src/CypressCTWebpackPlugin.ts b/npm/webpack-dev-server/src/CypressCTWebpackPlugin.ts index 70bcf3fc78f9..f625d6d2c98a 100644 --- a/npm/webpack-dev-server/src/CypressCTWebpackPlugin.ts +++ b/npm/webpack-dev-server/src/CypressCTWebpackPlugin.ts @@ -45,7 +45,6 @@ export const normalizeError = (error: Error | string) => { export class CypressCTWebpackPlugin { private files: Cypress.Cypress['spec'][] = [] private supportFile: string | false - private errorEmitted = false private compilation: Webpack45Compilation | null = null private webpack: Function @@ -93,42 +92,6 @@ export class CypressCTWebpackPlugin { callback() } - /* - * After compiling, we check for errors and inform the server of them. - */ - private afterCompile = () => { - if (!this.compilation) { - return - } - - const stats = this.compilation.getStats() - - if (stats.hasErrors()) { - this.errorEmitted = true - - // webpack 4: string[] - // webpack 5: Error[] - const errors = stats.toJson().errors as Array | undefined - - if (!errors || !errors.length) { - return - } - - this.devServerEvents.emit('dev-server:compile:error', normalizeError(errors[0])) - } else if (this.errorEmitted) { - // compilation succeed but assets haven't emitted to the output yet - this.devServerEvents.emit('dev-server:compile:error', null) - } - } - - // After emitting assets, we tell the server compilation was successful - // so it can trigger a reload the AUT iframe. - private afterEmit = () => { - if (!this.compilation?.getStats().hasErrors()) { - this.devServerEvents.emit('dev-server:compile:success') - } - } - /* * `webpack --watch` watches the existing specs and their dependencies for changes, * but we also need to add additional dependencies to our dynamic "browser.js" (generated @@ -178,8 +141,9 @@ export class CypressCTWebpackPlugin { this.devServerEvents.on('dev-server:specs:changed', this.onSpecsChange) _compiler.hooks.beforeCompile.tapAsync('CypressCTPlugin', this.beforeCompile) - _compiler.hooks.afterCompile.tap('CypressCTPlugin', this.afterCompile) - _compiler.hooks.afterEmit.tap('CypressCTPlugin', this.afterEmit) _compiler.hooks.compilation.tap('CypressCTPlugin', (compilation) => this.addCompilationHooks(compilation as Webpack45Compilation)) + _compiler.hooks.done.tap('CypressCTPlugin', () => { + this.devServerEvents.emit('dev-server:compile:success') + }) } } diff --git a/npm/webpack-dev-server/src/devServer.ts b/npm/webpack-dev-server/src/devServer.ts index 077c0401b99b..3548b761f957 100644 --- a/npm/webpack-dev-server/src/devServer.ts +++ b/npm/webpack-dev-server/src/devServer.ts @@ -39,10 +39,6 @@ type DevServerCreateResult = { compiler: Compiler } -const normalizeError = (error: Error | string) => { - return typeof error === 'string' ? error : error.message -} - /** * import { devServer } from '@cypress/webpack-dev-server' * @@ -55,21 +51,6 @@ export function devServer (devServerConfig: WebpackDevServerConfig): Promise { const result = await devServer.create(devServerConfig) as DevServerCreateResult - // When compiling in run mode - // Stop the clock early, no need to run all the tests on a failed build - result.compiler.hooks.done.tap('cyCustomErrorBuild', function (stats) { - if (stats.hasErrors()) { - const errors = stats.compilation.errors - - devServerConfig.devServerEvents.emit('dev-server:compile:error', normalizeError(errors[0])) - if (devServerConfig.cypressConfig.isTextTerminal) { - process.exit(1) - } - } - - devServerConfig.devServerEvents.emit('dev-server:compile:done') - }) - if (result.version === 3) { const srv = result.server.listen(0, '127.0.0.1', () => { const port = (srv.address() as AddressInfo).port diff --git a/npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts b/npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts index bb42a4603609..16ff6a8d60b0 100644 --- a/npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts +++ b/npm/webpack-dev-server/src/makeDefaultWebpackConfig.ts @@ -24,7 +24,7 @@ export function makeDefaultWebpackConfig ( debug(`Using HtmlWebpackPlugin version ${version} from ${importPath}`) - return { + const finalConfig = { mode: 'development', optimization: { splitChunks: { @@ -41,5 +41,24 @@ export function makeDefaultWebpackConfig ( template: indexHtmlFile, }) as any, ], + } as any + + if (config.sourceWebpackModulesResult.webpackDevServer.majorVersion === 4) { + return { + ...finalConfig, + devServer: { + client: { + overlay: false, + }, + }, + } + } + + // @ts-ignore + return { + ...finalConfig, + devServer: { + overlay: false, + }, } } diff --git a/npm/webpack-dev-server/src/makeWebpackConfig.ts b/npm/webpack-dev-server/src/makeWebpackConfig.ts index 31aeb90cbf08..e1e251464780 100644 --- a/npm/webpack-dev-server/src/makeWebpackConfig.ts +++ b/npm/webpack-dev-server/src/makeWebpackConfig.ts @@ -14,14 +14,14 @@ const removeList = [ // https://github.com/cypress-io/cypress/issues/15865 'HtmlWebpackPlugin', - // This plugin is an opitimization for HtmlWebpackPlugin for use in - // production environments, not relevent for testing. + // This plugin is an optimization for HtmlWebpackPlugin for use in + // production environments, not relevant for testing. 'PreloadPlugin', - // Another optimization not relevent in a testing environment. + // Another optimization not relevant in a testing environment. 'HtmlPwaPlugin', - // We already reload when webpack recomplies (via listeners on + // We already reload when webpack recompiles (via listeners on // devServerEvents). Removing this plugin can prevent double-refreshes // in some setups. 'HotModuleReplacementPlugin', diff --git a/npm/webpack-dev-server/test/devServer-e2e.spec.ts b/npm/webpack-dev-server/test/devServer-e2e.spec.ts index a7f66f7267d0..0fa39d3a32dd 100644 --- a/npm/webpack-dev-server/test/devServer-e2e.spec.ts +++ b/npm/webpack-dev-server/test/devServer-e2e.spec.ts @@ -1,5 +1,4 @@ import path from 'path' -import sinon from 'sinon' import { expect } from 'chai' import { once, EventEmitter } from 'events' import http from 'http' @@ -179,74 +178,6 @@ describe('#devServer', () => { }) }) - it('emits dev-server:compile:error event on error compilation', async () => { - const devServerEvents = new EventEmitter() - const exitSpy = sinon.stub(process, 'exit') - - const badSpec = `${root}/test/fixtures/compilation-fails.spec.js` - const { close } = await devServer({ - webpackConfig, - cypressConfig, - specs: [ - { - name: badSpec, - relative: badSpec, - absolute: badSpec, - }, - ], - devServerEvents, - }) - - const [err] = await once(devServerEvents, 'dev-server:compile:error') - - expect(err).to.contain('Module parse failed: Unexpected token (1:5)') - expect(err).to.contain('You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders') - expect(err).to.contain('> this is an invalid spec file') - expect(exitSpy.calledOnce).to.be.true - - await new Promise((resolve, reject) => { - close((err) => { - if (err) { - return reject(err) - } - - resolve() - }) - }) - }) - - it('does not inject files into loader that do not exist at compile time', async () => { - const devServerEvents = new EventEmitter() - const { close } = await devServer({ - webpackConfig, - cypressConfig, - specs: [...createSpecs('foo.spec.js'), ...createSpecs('does_not_exist.spec.js')], - devServerEvents, - }) - - let compileErrorOccurred - - devServerEvents.on('dev-server:compile:error', () => { - compileErrorOccurred = true - }) - - await once(devServerEvents, 'dev-server:compile:done') - - // An error event should not have been emitted, as we should have - // filtered any missing specs out of the set provided to the loader. - expect(compileErrorOccurred).to.not.be.true - - await new Promise((resolve, reject) => { - close((err) => { - if (err) { - return reject(err) - } - - resolve() - }) - }) - }) - it('touches browser.js when a spec file is added and recompile', async function () { const devServerEvents = new EventEmitter() const { close } = await devServer({ diff --git a/npm/webpack-dev-server/test/makeWebpackConfig.spec.ts b/npm/webpack-dev-server/test/makeWebpackConfig.spec.ts index ad8fe5c43b8f..bb00e29ee0a0 100644 --- a/npm/webpack-dev-server/test/makeWebpackConfig.spec.ts +++ b/npm/webpack-dev-server/test/makeWebpackConfig.spec.ts @@ -4,9 +4,10 @@ import snapshot from 'snap-shot-it' import { WebpackDevServerConfig } from '../src/devServer' import { sourceDefaultWebpackDependencies } from '../src/helpers/sourceRelativeWebpackModules' import { makeWebpackConfig } from '../src/makeWebpackConfig' +import { createModuleMatrixResult } from './test-helpers/createModuleMatrixResult' describe('makeWebpackConfig', () => { - it('ignores userland webpack `output.publicPath`', async () => { + it('ignores userland webpack `output.publicPath` and `devServer.overlay` with webpack-dev-server v3', async () => { const devServerConfig: WebpackDevServerConfig = { specs: [], cypressConfig: { @@ -17,7 +18,11 @@ describe('makeWebpackConfig', () => { } as Cypress.PluginConfigOptions, webpackConfig: { output: { - publicPath: '/this-will-be-ignored', + publicPath: '/this-will-be-ignored', // This will be overridden by makeWebpackConfig.ts + }, + devServer: { + progress: true, + overlay: true, // This will be overridden by makeWebpackConfig.ts }, }, devServerEvents: new EventEmitter(), @@ -38,4 +43,47 @@ describe('makeWebpackConfig', () => { expect(actual.output.publicPath).to.eq('/test-public-path/') snapshot(actual) }) + + it('ignores userland webpack `output.publicPath` and `devServer.overlay` with webpack-dev-server v4', async () => { + const devServerConfig: WebpackDevServerConfig = { + specs: [], + cypressConfig: { + isTextTerminal: false, + projectRoot: '.', + supportFile: '/support.js', + devServerPublicPathRoute: '/test-public-path', // This will be overridden by makeWebpackConfig.ts + } as Cypress.PluginConfigOptions, + webpackConfig: { + output: { + publicPath: '/this-will-be-ignored', + }, + devServer: { + magicHtml: true, + client: { + progress: false, + overlay: true, // This will be overridden by makeWebpackConfig.ts + }, + }, + }, + devServerEvents: new EventEmitter(), + } + const actual = await makeWebpackConfig({ + devServerConfig, + sourceWebpackModulesResult: createModuleMatrixResult({ + webpack: 4, + webpackDevServer: 4, + }), + }) + + // plugins contain circular deps which cannot be serialized in a snapshot. + // instead just compare the name and order of the plugins. + actual.plugins = actual.plugins.map((p) => p.constructor.name) + + // these will include paths from the user's local file system, so we should not include them the snapshot + delete actual.output.path + delete actual.entry + + expect(actual.output.publicPath).to.eq('/test-public-path/') + snapshot(actual) + }) }) diff --git a/packages/app/src/runner/event-manager.ts b/packages/app/src/runner/event-manager.ts index 86eb017a5038..2fca17444111 100644 --- a/packages/app/src/runner/event-manager.ts +++ b/packages/app/src/runner/event-manager.ts @@ -142,11 +142,6 @@ export class EventManager { rerun() }) - this.ws.on('dev-server:hmr:error', (error) => { - Cypress.stop() - this.localBus.emit('script:error', error) - }) - this.ws.on('dev-server:compile:success', ({ specFile }) => { if (!specFile || specFile === state?.spec?.absolute) { rerun() diff --git a/packages/driver/src/cypress/error_utils.ts b/packages/driver/src/cypress/error_utils.ts index 94eee97065fd..a4905c4eefa7 100644 --- a/packages/driver/src/cypress/error_utils.ts +++ b/packages/driver/src/cypress/error_utils.ts @@ -3,6 +3,7 @@ import chai from 'chai' import _ from 'lodash' import $dom from '../dom' +import { stripAnsi } from '@packages/errors' import $errorMessages from './error_messages' import $stackUtils, { StackAndCodeFrameIndex } from './stack_utils' import $utils from './utils' @@ -386,7 +387,7 @@ const errByPath = (msgPath, args?) => { const createUncaughtException = ({ frameType, handlerType, state, err }) => { const errPath = frameType === 'spec' ? 'uncaught.fromSpec' : 'uncaught.fromApp' let uncaughtErr = errByPath(errPath, { - errMsg: err.message, + errMsg: stripAnsi(err.message), promiseAddendum: handlerType === 'unhandledrejection' ? ' It was caused by an unhandled promise rejection.' : '', }) as CypressError diff --git a/packages/launchpad/cypress/e2e/config-files-error-handling.cy.ts b/packages/launchpad/cypress/e2e/config-files-error-handling.cy.ts index 671b796995a1..b7ee7543e613 100644 --- a/packages/launchpad/cypress/e2e/config-files-error-handling.cy.ts +++ b/packages/launchpad/cypress/e2e/config-files-error-handling.cy.ts @@ -101,6 +101,14 @@ describe('Launchpad: Error System Tests', () => { expectStackToBe('open') }) + it('Handles a syntax error in the config file', () => { + cy.scaffoldProject('plugins-root-syntax-error') + cy.openProject('plugins-root-syntax-error', ['--e2e']) + cy.visitLaunchpad() + cy.contains('h1', cy.i18n.launchpadErrors.generic.configErrorTitle) + expectStackToBe('open') + }) + it('Handles an error thrown asynchronously in the root of the config', () => { cy.scaffoldProject('plugins-root-async-error') cy.openProject('plugins-root-async-error', ['--e2e']) diff --git a/packages/server/lib/modes/run-ct.ts b/packages/server/lib/modes/run-ct.ts index 3a23504bf2c2..d2d3fff071fe 100644 --- a/packages/server/lib/modes/run-ct.ts +++ b/packages/server/lib/modes/run-ct.ts @@ -1,25 +1,9 @@ import type { LaunchArgs } from '@packages/types' -import { openProject } from '../open_project' - export const run = (options: LaunchArgs, loadingPromise: Promise) => { // TODO: make sure if we need to run this in electron by default to match e2e behavior? options.browser = options.browser || 'electron' options.runAllSpecsInSameBrowserSession = true - require('../plugins/dev-server').emitter.on('dev-server:compile:error', (error: Error) => { - options.onError?.( - new Error(`Dev-server compilation failed. We can not run tests if dev-server can not compile and emit assets, please make sure that all syntax errors resolved before running cypress. \n\n ${error}`), - ) - - // because in run mode we decided to build all the bundle and avoid lazy compilation - // if we get compilation error (e.g. from webpack) it means that no assets were emitted - // and we can not run any tests, even if the error belongs to the different module - // that's why the only way to avoid this is to close the process - openProject.closeBrowser().then(() => { - process.exit(1) - }) - }) - return require('./run').run(options, loadingPromise) } diff --git a/packages/server/lib/plugins/child/dev-server.js b/packages/server/lib/plugins/child/dev-server.js index e8312064cb0f..c82b06050e86 100644 --- a/packages/server/lib/plugins/child/dev-server.js +++ b/packages/server/lib/plugins/child/dev-server.js @@ -9,10 +9,6 @@ const wrap = (ipc, invoke, ids, args) => { devServerEvents.emit('dev-server:specs:changed', specs) }) - devServerEvents.on('dev-server:compile:error', (error) => { - ipc.send('dev-server:compile:error', error) - }) - devServerEvents.on('dev-server:compile:success', ({ specFile } = {}) => { ipc.send('dev-server:compile:success', { specFile }) }) diff --git a/packages/server/lib/plugins/dev-server.js b/packages/server/lib/plugins/dev-server.js index 35a1d08ac3c9..d304766381a7 100644 --- a/packages/server/lib/plugins/dev-server.js +++ b/packages/server/lib/plugins/dev-server.js @@ -12,10 +12,6 @@ plugins.registerHandler((ipc) => { ipc.send('dev-server:specs:changed', specs) }) - ipc.on('dev-server:compile:error', (error) => { - baseEmitter.emit('dev-server:compile:error', error) - }) - ipc.on('dev-server:compile:success', ({ specFile } = {}) => { baseEmitter.emit('dev-server:compile:success', { specFile }) }) diff --git a/packages/server/lib/socket-ct.ts b/packages/server/lib/socket-ct.ts index 93dedadb854d..0d8a0d3584e8 100644 --- a/packages/server/lib/socket-ct.ts +++ b/packages/server/lib/socket-ct.ts @@ -10,10 +10,6 @@ export class SocketCt extends SocketBase { constructor (config: Record) { super(config) - devServer.emitter.on('dev-server:compile:error', (error: string | undefined) => { - this.toRunner('dev-server:hmr:error', error) - }) - // should we use this option at all for component testing 😕? if (config.watchForFileChanges) { devServer.emitter.on('dev-server:compile:success', ({ specFile }) => { diff --git a/system-tests/__snapshots__/plugins_spec.js b/system-tests/__snapshots__/plugins_spec.js index 4d73bf4795a6..0ccc17235203 100644 --- a/system-tests/__snapshots__/plugins_spec.js +++ b/system-tests/__snapshots__/plugins_spec.js @@ -524,3 +524,16 @@ https://on.cypress.io/plugins-api ` + +exports['e2e plugins fails when require has a syntax error 1'] = ` +Your configFile is invalid: /foo/bar/.projects/plugins-root-syntax-error/cypress.config.js + +It threw an error when required, check the stack trace below: + +/foo/bar/.projects/plugins-root-syntax-error/cypress.config.js:3 +} +^ + +SyntaxError: Unexpected token '}' + [stack trace lines] +` diff --git a/system-tests/__snapshots__/vite_dev_server_fresh_spec.ts.js b/system-tests/__snapshots__/vite_dev_server_fresh_spec.ts.js index a4d3c3d8e20d..7488c16e1e56 100644 --- a/system-tests/__snapshots__/vite_dev_server_fresh_spec.ts.js +++ b/system-tests/__snapshots__/vite_dev_server_fresh_spec.ts.js @@ -1,4 +1,4 @@ -exports['@cypress/vite-dev-server / react / runs specs in vite 2.8.6'] = ` +exports['@cypress/vite-dev-server react executes all of the tests for vite2.8.6-react 1'] = ` ==================================================================================================== @@ -7,14 +7,15 @@ exports['@cypress/vite-dev-server / react / runs specs in vite 2.8.6'] = ` ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ - │ Specs: 3 found (App.cy.jsx, MissingReact.cy.jsx, MissingReactInSpec.cy.jsx) │ + │ Specs: 4 found (App.cy.jsx, AppCompilationError.cy.jsx, MissingReact.cy.jsx, MissingReact │ + │ InSpec.cy.jsx) │ │ Searched: **/*.cy.{js,jsx,ts,tsx} │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: App.cy.jsx (1 of 3) + Running: App.cy.jsx (1 of 4) ✓ renders hello world @@ -45,7 +46,59 @@ exports['@cypress/vite-dev-server / react / runs specs in vite 2.8.6'] = ` ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: MissingReact.cy.jsx (2 of 3) + Running: AppCompilationError.cy.jsx (2 of 4) + + + 1) An uncaught error was detected outside of a test + + 0 passing + 1 failing + + 1) An uncaught error was detected outside of a test: + TypeError: The following error originated from your test code, not from Cypress. + + > Failed to fetch dynamically imported module: http://localhost:3000/__cypress/src/src/AppCompilationError.cy.jsx + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + +Cypress could not associate this error to any specific test. + +We dynamically generated a new test to display this failure. + + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: AppCompilationError.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/AppCompilationError.cy.jsx/An uncaught error wa (1280x720) + s detected outside of a test (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/AppCompilationError.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReact.cy.jsx (3 of 4) 1) is missing React @@ -93,7 +146,7 @@ When Cypress detects uncaught errors originating from your test code it will aut ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: MissingReactInSpec.cy.jsx (3 of 3) + Running: MissingReactInSpec.cy.jsx (4 of 4) 1) is missing React in this file @@ -144,16 +197,18 @@ When Cypress detects uncaught errors originating from your test code it will aut ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ ✔ App.cy.jsx XX:XX 1 1 - - - │ ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ AppCompilationError.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✖ MissingReact.cy.jsx XX:XX 1 - 1 - - │ ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✖ MissingReactInSpec.cy.jsx XX:XX 1 - 1 - - │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✖ 2 of 3 failed (67%) XX:XX 3 1 2 - - + ✖ 3 of 4 failed (75%) XX:XX 4 1 3 - - ` -exports['@cypress/vite-dev-server / react / runs specs in vite 2.9.1'] = ` +exports['@cypress/vite-dev-server react executes all of the tests for vite2.9.1-react 1'] = ` ==================================================================================================== @@ -162,14 +217,15 @@ exports['@cypress/vite-dev-server / react / runs specs in vite 2.9.1'] = ` ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ - │ Specs: 3 found (App.cy.jsx, MissingReact.cy.jsx, MissingReactInSpec.cy.jsx) │ + │ Specs: 4 found (App.cy.jsx, AppCompilationError.cy.jsx, MissingReact.cy.jsx, MissingReact │ + │ InSpec.cy.jsx) │ │ Searched: **/*.cy.{js,jsx,ts,tsx} │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: App.cy.jsx (1 of 3) + Running: App.cy.jsx (1 of 4) ✓ renders hello world @@ -200,7 +256,59 @@ exports['@cypress/vite-dev-server / react / runs specs in vite 2.9.1'] = ` ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: MissingReact.cy.jsx (2 of 3) + Running: AppCompilationError.cy.jsx (2 of 4) + + + 1) An uncaught error was detected outside of a test + + 0 passing + 1 failing + + 1) An uncaught error was detected outside of a test: + TypeError: The following error originated from your test code, not from Cypress. + + > Failed to fetch dynamically imported module: http://localhost:3000/__cypress/src/src/AppCompilationError.cy.jsx + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + +Cypress could not associate this error to any specific test. + +We dynamically generated a new test to display this failure. + + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: AppCompilationError.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/AppCompilationError.cy.jsx/An uncaught error wa (1280x720) + s detected outside of a test (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/AppCompilationError.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReact.cy.jsx (3 of 4) 1) is missing React @@ -248,7 +356,7 @@ When Cypress detects uncaught errors originating from your test code it will aut ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: MissingReactInSpec.cy.jsx (3 of 3) + Running: MissingReactInSpec.cy.jsx (4 of 4) 1) is missing React in this file @@ -299,11 +407,13 @@ When Cypress detects uncaught errors originating from your test code it will aut ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ ✔ App.cy.jsx XX:XX 1 1 - - - │ ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ AppCompilationError.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✖ MissingReact.cy.jsx XX:XX 1 - 1 - - │ ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✖ MissingReactInSpec.cy.jsx XX:XX 1 - 1 - - │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✖ 2 of 3 failed (67%) XX:XX 3 1 2 - - + ✖ 3 of 4 failed (75%) XX:XX 4 1 3 - - ` diff --git a/system-tests/__snapshots__/webpack_dev_server_fresh_spec.ts.js b/system-tests/__snapshots__/webpack_dev_server_fresh_spec.ts.js new file mode 100644 index 000000000000..5421d9e40748 --- /dev/null +++ b/system-tests/__snapshots__/webpack_dev_server_fresh_spec.ts.js @@ -0,0 +1,919 @@ +exports['@cypress/webpack-dev-server react executes all of the tests for webpack4_wds3-react 1'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 4 found (App.cy.jsx, AppCompilationError.cy.jsx, MissingReact.cy.jsx, MissingReact │ + │ InSpec.cy.jsx) │ + │ Searched: **/*.cy.{js,jsx,ts,tsx} │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: App.cy.jsx (1 of 4) + 48 modules + +ERROR in ./src/AppCompilationError.cy.jsx +Module build failed (from [..]): +SyntaxError: /foo/bar/.projects/webpack4_wds3-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0) + + 7 | cy.get('h1').contains('Hello World') + 8 | } +> 9 | }) + | ^ + 10 | + [stack trace lines] + + + ✓ renders hello world + + 1 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: App.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/App.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: AppCompilationError.cy.jsx (2 of 4) + + + 1) An uncaught error was detected outside of a test + + 0 passing + 1 failing + + 1) An uncaught error was detected outside of a test: + Error: The following error originated from your test code, not from Cypress. + + > Module build failed (from [..]): +SyntaxError: /foo/bar/.projects/webpack4_wds3-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0) + + 7 | cy.get('h1').contains('Hello World') + 8 | } +> 9 | }) + | ^ + 10 | + [stack trace lines] + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + +Cypress could not associate this error to any specific test. + +We dynamically generated a new test to display this failure. + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: AppCompilationError.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/AppCompilationError.cy.jsx/An uncaught error wa (1280x720) + s detected outside of a test (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/AppCompilationError.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReact.cy.jsx (3 of 4) + + + 1) is missing React + + 0 passing + 1 failing + + 1) is missing React: + ReferenceError: The following error originated from your test code, not from Cypress. + + > React is not defined + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: MissingReact.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/MissingReact.cy.jsx/is missing React (failed).p (1280x720) + ng + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/MissingReact.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReactInSpec.cy.jsx (4 of 4) + + + 1) is missing React in this file + + 0 passing + 1 failing + + 1) is missing React in this file: + ReferenceError: React is not defined + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: MissingReactInSpec.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/MissingReactInSpec.cy.jsx/is missing React in t (1280x720) + his file (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/MissingReactInSpec.cy.jsx.mp4 (X second) + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ App.cy.jsx XX:XX 1 1 - - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ AppCompilationError.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ MissingReact.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ MissingReactInSpec.cy.jsx XX:XX 1 - 1 - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✖ 3 of 4 failed (75%) XX:XX 4 1 3 - - + + +` + +exports['@cypress/webpack-dev-server react executes all of the tests for webpack4_wds4-react 1'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 4 found (App.cy.jsx, AppCompilationError.cy.jsx, MissingReact.cy.jsx, MissingReact │ + │ InSpec.cy.jsx) │ + │ Searched: **/*.cy.{js,jsx,ts,tsx} │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: App.cy.jsx (1 of 4) + 48 modules + +ERROR in ./src/AppCompilationError.cy.jsx +Module build failed (from [..]): +SyntaxError: /foo/bar/.projects/webpack4_wds4-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0) + + 7 | cy.get('h1').contains('Hello World') + 8 | } +> 9 | }) + | ^ + 10 | + [stack trace lines] + + + ✓ renders hello world + + 1 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: App.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/App.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: AppCompilationError.cy.jsx (2 of 4) + + + 1) An uncaught error was detected outside of a test + + 0 passing + 1 failing + + 1) An uncaught error was detected outside of a test: + Error: The following error originated from your test code, not from Cypress. + + > Module build failed (from [..]): +SyntaxError: /foo/bar/.projects/webpack4_wds4-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0) + + 7 | cy.get('h1').contains('Hello World') + 8 | } +> 9 | }) + | ^ + 10 | + [stack trace lines] + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + +Cypress could not associate this error to any specific test. + +We dynamically generated a new test to display this failure. + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: AppCompilationError.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/AppCompilationError.cy.jsx/An uncaught error wa (1280x720) + s detected outside of a test (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/AppCompilationError.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReact.cy.jsx (3 of 4) + + + 1) is missing React + + 0 passing + 1 failing + + 1) is missing React: + ReferenceError: The following error originated from your test code, not from Cypress. + + > React is not defined + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: MissingReact.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/MissingReact.cy.jsx/is missing React (failed).p (1280x720) + ng + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/MissingReact.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReactInSpec.cy.jsx (4 of 4) + + + 1) is missing React in this file + + 0 passing + 1 failing + + 1) is missing React in this file: + ReferenceError: React is not defined + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: MissingReactInSpec.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/MissingReactInSpec.cy.jsx/is missing React in t (1280x720) + his file (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/MissingReactInSpec.cy.jsx.mp4 (X second) + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ App.cy.jsx XX:XX 1 1 - - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ AppCompilationError.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ MissingReact.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ MissingReactInSpec.cy.jsx XX:XX 1 - 1 - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✖ 3 of 4 failed (75%) XX:XX 4 1 3 - - + + +` + +exports['@cypress/webpack-dev-server react executes all of the tests for webpack5_wds3-react 1'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 4 found (App.cy.jsx, AppCompilationError.cy.jsx, MissingReact.cy.jsx, MissingReact │ + │ InSpec.cy.jsx) │ + │ Searched: **/*.cy.{js,jsx,ts,tsx} │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: App.cy.jsx (1 of 4) + 48 modules + +ERROR in ./src/AppCompilationError.cy.jsx +Module build failed (from [..]): +SyntaxError: /foo/bar/.projects/webpack5_wds3-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0) + + 7 | cy.get('h1').contains('Hello World') + 8 | } +> 9 | }) + | ^ + 10 | + [stack trace lines] + + + ✓ renders hello world + + 1 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: App.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/App.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: AppCompilationError.cy.jsx (2 of 4) + + + 1) An uncaught error was detected outside of a test + + 0 passing + 1 failing + + 1) An uncaught error was detected outside of a test: + Error: The following error originated from your test code, not from Cypress. + + > Module build failed (from [..]): +SyntaxError: /foo/bar/.projects/webpack5_wds3-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0) + + 7 | cy.get('h1').contains('Hello World') + 8 | } +> 9 | }) + | ^ + 10 | + [stack trace lines] + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + +Cypress could not associate this error to any specific test. + +We dynamically generated a new test to display this failure. + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: AppCompilationError.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/AppCompilationError.cy.jsx/An uncaught error wa (1280x720) + s detected outside of a test (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/AppCompilationError.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReact.cy.jsx (3 of 4) + + + 1) is missing React + + 0 passing + 1 failing + + 1) is missing React: + ReferenceError: The following error originated from your test code, not from Cypress. + + > React is not defined + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: MissingReact.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/MissingReact.cy.jsx/is missing React (failed).p (1280x720) + ng + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/MissingReact.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReactInSpec.cy.jsx (4 of 4) + + + 1) is missing React in this file + + 0 passing + 1 failing + + 1) is missing React in this file: + ReferenceError: React is not defined + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: MissingReactInSpec.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/MissingReactInSpec.cy.jsx/is missing React in t (1280x720) + his file (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/MissingReactInSpec.cy.jsx.mp4 (X second) + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ App.cy.jsx XX:XX 1 1 - - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ AppCompilationError.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ MissingReact.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ MissingReactInSpec.cy.jsx XX:XX 1 - 1 - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✖ 3 of 4 failed (75%) XX:XX 4 1 3 - - + + +` + +exports['@cypress/webpack-dev-server react executes all of the tests for webpack5_wds4-react 1'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 4 found (App.cy.jsx, AppCompilationError.cy.jsx, MissingReact.cy.jsx, MissingReact │ + │ InSpec.cy.jsx) │ + │ Searched: **/*.cy.{js,jsx,ts,tsx} │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: App.cy.jsx (1 of 4) + 48 modules + +ERROR in ./src/AppCompilationError.cy.jsx +Module build failed (from [..]): +SyntaxError: /foo/bar/.projects/webpack5_wds4-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0) + + 7 | cy.get('h1').contains('Hello World') + 8 | } +> 9 | }) + | ^ + 10 | + [stack trace lines] + + + ✓ renders hello world + + 1 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: App.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/App.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: AppCompilationError.cy.jsx (2 of 4) + + + 1) An uncaught error was detected outside of a test + + 0 passing + 1 failing + + 1) An uncaught error was detected outside of a test: + Error: The following error originated from your test code, not from Cypress. + + > Module build failed (from [..]): +SyntaxError: /foo/bar/.projects/webpack5_wds4-react/src/AppCompilationError.cy.jsx: Unexpected token, expected "," (9:0) + + 7 | cy.get('h1').contains('Hello World') + 8 | } +> 9 | }) + | ^ + 10 | + [stack trace lines] + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + +Cypress could not associate this error to any specific test. + +We dynamically generated a new test to display this failure. + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: AppCompilationError.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/AppCompilationError.cy.jsx/An uncaught error wa (1280x720) + s detected outside of a test (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/AppCompilationError.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReact.cy.jsx (3 of 4) + + + 1) is missing React + + 0 passing + 1 failing + + 1) is missing React: + ReferenceError: The following error originated from your test code, not from Cypress. + + > React is not defined + +When Cypress detects uncaught errors originating from your test code it will automatically fail the current test. + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: MissingReact.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/MissingReact.cy.jsx/is missing React (failed).p (1280x720) + ng + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/MissingReact.cy.jsx.mp4 (X second) + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: MissingReactInSpec.cy.jsx (4 of 4) + + + 1) is missing React in this file + + 0 passing + 1 failing + + 1) is missing React in this file: + ReferenceError: React is not defined + [stack trace lines] + + + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 0 │ + │ Failing: 1 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 1 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: MissingReactInSpec.cy.jsx │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Screenshots) + + - /XXX/XXX/XXX/cypress/screenshots/MissingReactInSpec.cy.jsx/is missing React in t (1280x720) + his file (failed).png + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/MissingReactInSpec.cy.jsx.mp4 (X second) + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ App.cy.jsx XX:XX 1 1 - - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ AppCompilationError.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ MissingReact.cy.jsx XX:XX 1 - 1 - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✖ MissingReactInSpec.cy.jsx XX:XX 1 - 1 - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✖ 3 of 4 failed (75%) XX:XX 4 1 3 - - + + +` diff --git a/system-tests/lib/system-tests.ts b/system-tests/lib/system-tests.ts index 8fcea1edf6bf..076865f792b1 100644 --- a/system-tests/lib/system-tests.ts +++ b/system-tests/lib/system-tests.ts @@ -301,7 +301,7 @@ const pathUpToProjectName = Fixtures.projectPath('') const DEFAULT_BROWSERS = ['electron', 'chrome', 'firefox'] -const stackTraceLinesRe = /(\n?[^\S\n\r]*).*?(@|\bat\b)(?:.*node:.*|.*\.(js|coffee|ts|html|jsx|tsx))(-\d+)?:\d+:\d+[\n\S\s]*?(\n\s*?\n|$)/g +const stackTraceLinesRe = /(\n?[^\S\n\r]*).*?(@|\bat\b)(?:.*node:.*|.*\.(js|coffee|ts|html|jsx|tsx))\??(-\d+)?:\d+:\d+[\n\S\s]*?(\n\s*?\n|$)/g const browserNameVersionRe = /(Browser\:\s+)(Custom |)(Electron|Chrome|Canary|Chromium|Firefox)(\s\d+)(\s\(\w+\))?(\s+)/ const availableBrowsersRe = /(Available browsers found on your system are:)([\s\S]+)/g const crossOriginErrorRe = /(Blocked a frame .* from accessing a cross-origin frame.*|Permission denied.*cross-origin object.*)/gm diff --git a/system-tests/project-fixtures/react/src/App.cy.jsx b/system-tests/project-fixtures/react/src/App.cy.jsx index da2585ff6d2e..cf2926f2a558 100644 --- a/system-tests/project-fixtures/react/src/App.cy.jsx +++ b/system-tests/project-fixtures/react/src/App.cy.jsx @@ -4,5 +4,6 @@ import { App } from './App' it('renders hello world', () => { mount() - cy.get('h1').contains('Hello World') + // Click on the header here to ensure that the AUT is interactable. This ensures that the dev server overlay is not displaying + cy.get('h1').contains('Hello World').click() }) diff --git a/system-tests/project-fixtures/react/src/AppCompilationError.cy.jsx b/system-tests/project-fixtures/react/src/AppCompilationError.cy.jsx new file mode 100644 index 000000000000..36d70ef24c75 --- /dev/null +++ b/system-tests/project-fixtures/react/src/AppCompilationError.cy.jsx @@ -0,0 +1,9 @@ +import React from 'react' +import { mount } from 'cypress/react' +import { App } from './App' + +it('renders hello world', () => { + mount() + cy.get('h1').contains('Hello World') +} +}) diff --git a/system-tests/projects/.eslintrc.json b/system-tests/projects/.eslintrc.json index 3dc864e6a7b2..c6eb74761352 100644 --- a/system-tests/projects/.eslintrc.json +++ b/system-tests/projects/.eslintrc.json @@ -9,6 +9,7 @@ "mocha/no-global-tests": "off" }, "ignorePatterns": [ - "failures/cypress/e2e/syntax_error.js" + "failures/cypress/e2e/syntax_error.js", + "plugins-root-syntax-error/cypress.config.js" ] } diff --git a/system-tests/projects/plugins-root-syntax-error/cypress.config.js b/system-tests/projects/plugins-root-syntax-error/cypress.config.js new file mode 100644 index 000000000000..acead75536ce --- /dev/null +++ b/system-tests/projects/plugins-root-syntax-error/cypress.config.js @@ -0,0 +1,3 @@ +module.exports = { +} +} diff --git a/system-tests/projects/plugins-root-syntax-error/cypress/integration/app.cy.js b/system-tests/projects/plugins-root-syntax-error/cypress/integration/app.cy.js new file mode 100644 index 000000000000..b3fc22ae77ba --- /dev/null +++ b/system-tests/projects/plugins-root-syntax-error/cypress/integration/app.cy.js @@ -0,0 +1 @@ +it('passes', () => { }) diff --git a/system-tests/test/plugins_spec.js b/system-tests/test/plugins_spec.js index 5fd712cf3999..1c4128eae59d 100644 --- a/system-tests/test/plugins_spec.js +++ b/system-tests/test/plugins_spec.js @@ -177,6 +177,16 @@ describe('e2e plugins', function () { }) }) + it('fails when require has a syntax error', function () { + return systemTests.exec(this, { + spec: 'app_spec.js', + project: 'plugins-root-syntax-error', + sanitizeScreenshotDimensions: true, + snapshot: true, + expectedExitCode: 1, + }) + }) + it('fails when function throws synchronously', function () { return systemTests.exec(this, { spec: 'app_spec.js', diff --git a/system-tests/test/vite_dev_server_fresh_spec.ts b/system-tests/test/vite_dev_server_fresh_spec.ts index b3d17eb47a24..c7d193640c15 100644 --- a/system-tests/test/vite_dev_server_fresh_spec.ts +++ b/system-tests/test/vite_dev_server_fresh_spec.ts @@ -1,27 +1,25 @@ import systemTests from '../lib/system-tests' +import type { fixtureDirs } from '@tooling/system-tests' + +type ProjectDirs = typeof fixtureDirs + +const VITE_REACT: ProjectDirs[number][] = ['vite2.8.6-react', 'vite2.9.1-react'] describe('@cypress/vite-dev-server', function () { systemTests.setup() describe('react', () => { - systemTests.it('runs specs in vite 2.8.6', { - project: 'vite2.8.6-react', - testingType: 'component', - browser: 'chrome', - spec: null, - configFile: 'cypress-vite.config.ts', - expectedExitCode: 2, - snapshot: true, - }) - - systemTests.it('runs specs in vite 2.9.1', { - project: 'vite2.8.6-react', - testingType: 'component', - browser: 'chrome', - spec: null, - configFile: 'cypress-vite.config.ts', - expectedExitCode: 2, - snapshot: true, - }) + for (const project of VITE_REACT) { + it(`executes all of the tests for ${project}`, function () { + return systemTests.exec(this, { + project, + configFile: 'cypress-vite.config.ts', + testingType: 'component', + browser: 'chrome', + snapshot: true, + expectedExitCode: 3, + }) + }) + } }) }) diff --git a/system-tests/test/webpack_dev_server_fresh_spec.ts b/system-tests/test/webpack_dev_server_fresh_spec.ts index ae305da28ecf..d9d8628b85d6 100644 --- a/system-tests/test/webpack_dev_server_fresh_spec.ts +++ b/system-tests/test/webpack_dev_server_fresh_spec.ts @@ -1,43 +1,29 @@ import systemTests from '../lib/system-tests' +import type { fixtureDirs } from '@tooling/system-tests' +import { stripAnsi } from '@packages/server/lib/errors' + +type ProjectDirs = typeof fixtureDirs + +const WEBPACK_REACT: ProjectDirs[number][] = ['webpack4_wds3-react', 'webpack4_wds4-react', 'webpack5_wds3-react', 'webpack5_wds4-react'] describe('@cypress/webpack-dev-server', function () { systemTests.setup() describe('react', () => { - systemTests.it('runs specs in webpack4, webpack_dev_server 3', { - project: 'webpack4_wds3-react', - testingType: 'component', - browser: 'chrome', - spec: null, - configFile: 'cypress-webpack.config.ts', - expectedExitCode: 2, - }) - - systemTests.it('runs specs in webpack4, webpack_dev_server 4', { - project: 'webpack4_wds4-react', - testingType: 'component', - browser: 'chrome', - spec: null, - configFile: 'cypress-webpack.config.ts', - expectedExitCode: 2, - }) - - systemTests.it('runs specs in webpack5, webpack_dev_server 3', { - project: 'webpack5_wds3-react', - testingType: 'component', - browser: 'chrome', - spec: null, - configFile: 'cypress-webpack.config.ts', - expectedExitCode: 2, - }) - - systemTests.it('runs specs in webpack5, webpack_dev_server 4', { - project: 'webpack5_wds4-react', - testingType: 'component', - browser: 'chrome', - spec: null, - configFile: 'cypress-webpack.config.ts', - expectedExitCode: 2, - }) + for (const project of WEBPACK_REACT) { + it(`executes all of the tests for ${project}`, function () { + return systemTests.exec(this, { + project, + configFile: 'cypress-webpack.config.ts', + testingType: 'component', + browser: 'chrome', + snapshot: true, + expectedExitCode: 3, + onStdout: (stdout) => { + return stripAnsi(systemTests.normalizeWebpackErrors(stdout)) + }, + }) + }) + } }) })