Skip to content

Commit

Permalink
fix: angular and nuxt ct tests now fail on uncaught exceptions (#24122)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZachJW34 authored Oct 11, 2022
1 parent d0f13e9 commit 53eef4f
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 14 deletions.
20 changes: 19 additions & 1 deletion npm/angular/src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ window.Mocha['__zone_patch__'] = false
import 'zone.js/testing'

import { CommonModule } from '@angular/common'
import { Component, EventEmitter, SimpleChange, SimpleChanges, Type } from '@angular/core'
import { Component, ErrorHandler, EventEmitter, Injectable, SimpleChange, SimpleChanges, Type } from '@angular/core'
import {
ComponentFixture,
getTestBed,
Expand Down Expand Up @@ -99,6 +99,13 @@ export type MountResponse<T> = {
// so we'll patch here pending a fix in that library
globalThis.it.skip = globalThis.xit

@Injectable()
class CypressAngularErrorHandler implements ErrorHandler {
handleError (error: Error): void {
throw error
}
}

/**
* Bootstraps the TestModuleMetaData passed to the TestBed
*
Expand All @@ -120,6 +127,17 @@ function bootstrapModule<T> (
testModuleMetaData.imports = []
}

if (!testModuleMetaData.providers) {
testModuleMetaData.providers = []
}

// Replace default error handler since it will swallow uncaught exceptions.
// We want these to be uncaught so Cypress catches it and fails the test
testModuleMetaData.providers.push({
provide: ErrorHandler,
useClass: CypressAngularErrorHandler,
})

// check if the component is a standalone component
if ((component as any).ɵcmp.standalone) {
testModuleMetaData.imports.push(component)
Expand Down
10 changes: 5 additions & 5 deletions npm/vue2/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,11 @@ declare global {
* @see https://github.com/cypress-io/cypress/issues/7910
*/
function failTestOnVueError (err, vm, info) {
console.error(`Vue error`)
console.error(err)
console.error('component:', vm)
console.error('info:', info)
window.top.onerror(err)
// Vue 2 try catches the error-handler so push the error to be caught outside
// of the handler.
setTimeout(() => {
throw err
})
}

function registerAutoDestroy ($destroy: () => void) {
Expand Down
58 changes: 51 additions & 7 deletions packages/app/cypress/e2e/runner/ct-framework-errors.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ function loadErrorSpec (options: Options): VerifyFunc {
cy.get('.runnable-header', { log: false }).should('be.visible')
// Extended timeout needed due to lengthy Angular bootstrap on Windows
cy.contains('Your tests are loading...', { timeout: 60000, log: false }).should('not.exist')
// Then ensure the tests have finished
cy.get('[aria-label="Rerun all tests"]', { timeout: 30000 })
cy.findByLabelText('Stats').within(() => {
cy.get('.passed .num', { timeout: 30000 }).should('have.text', `${passCount}`)
cy.get('.failed .num', { timeout: 30000 }).should('have.text', `${failCount}`)
cy.get('.passed .num').should('have.text', `${passCount}`)
cy.get('.failed .num').should('have.text', `${failCount}`)
})

// Return scoped verify function with spec options baked in
Expand Down Expand Up @@ -285,19 +287,36 @@ describe('Nuxt', {
projectName: 'nuxtjs-vue2-configured',
configFile: 'cypress.config.js',
filePath: 'components/Errors.cy.js',
failCount: 3,
failCount: 4,
})

verify('error on mount', {
fileName: 'Errors.vue',
line: 19,
uncaught: true,
uncaughtMessage: 'mount error',
message: [
'mount error',
],
stackRegex: /Errors\.vue:19/,
codeFrameText: 'Errors.vue',
})

verify('sync error', {
fileName: 'Errors.vue',
line: 24,
uncaught: true,
uncaughtMessage: 'sync error',
message: [
'The following error originated from your application code',
'sync error',
],
stackRegex: /Errors\.vue:24/,
codeFrameText: 'Errors.vue',
}).then(() => {
verifyErrorOnlyCapturedOnce('Error: sync error')
})

verify('async error', {
fileName: 'Errors.vue',
line: 28,
Expand Down Expand Up @@ -413,12 +432,37 @@ angularVersions.forEach((angularVersion) => {
projectName: `angular-${angularVersion}`,
configFile: 'cypress.config.ts',
filePath: 'src/app/errors.cy.ts',
failCount: 1,
failCount: 3,
passCount: 1,
})

verify('sync error', {
fileName: 'errors.ts',
line: 14,
column: 11,
uncaught: true,
uncaughtMessage: 'sync error',
message: [
'The following error originated from your application code',
'sync error',
],
}).then(() => {
verifyErrorOnlyCapturedOnce('Error: sync error')
})

// Angular uses ZoneJS which encapsulates errors thrown by components
// Thus, the mount, sync, and async error case errors will not propagate to Cypress
// and thus won't fail the tests
verify('async error', {
fileName: 'errors.ts',
line: 19,
column: 13,
uncaught: true,
uncaughtMessage: 'async error',
message: [
'The following error originated from your application code',
'async error',
],
}).then(() => {
verifyErrorOnlyCapturedOnce('Error: async error')
})

verify('command failure', {
line: 21,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ export class ErrorsComponent {
asyncError() {
setTimeout(() => {
throw new Error('async error')
}, 50)
})
}
}

5 comments on commit 53eef4f

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 53eef4f Oct 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.10.0/linux-x64/develop-53eef4fbd7e1caf32f0183cadbc0e4cf05524c34/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 53eef4f Oct 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.10.0/linux-arm64/develop-53eef4fbd7e1caf32f0183cadbc0e4cf05524c34/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 53eef4f Oct 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.10.0/darwin-arm64/develop-53eef4fbd7e1caf32f0183cadbc0e4cf05524c34/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 53eef4f Oct 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.10.0/darwin-x64/develop-53eef4fbd7e1caf32f0183cadbc0e4cf05524c34/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 53eef4f Oct 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.10.0/win32-x64/develop-53eef4fbd7e1caf32f0183cadbc0e4cf05524c34/cypress.tgz

Please sign in to comment.