Skip to content

Commit 68a02fc

Browse files
committed
Merge branch 'develop' into feature/IATR-M0
2 parents 3fd6a54 + 0e14b9e commit 68a02fc

File tree

12 files changed

+200
-104
lines changed

12 files changed

+200
-104
lines changed

npm/mount-utils/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"@rollup/plugin-commonjs": "^17.1.0",
1717
"@rollup/plugin-node-resolve": "^11.1.1",
1818
"rollup": "3.7.3",
19-
"rollup-plugin-dts": "^4.2.3",
19+
"rollup-plugin-dts": "5.0.0",
2020
"rollup-plugin-typescript2": "^0.29.0",
2121
"typescript": "^4.7.4"
2222
},

npm/react/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"react-router-dom": "6.0.0-alpha.1",
2929
"semver": "^7.3.2",
3030
"typescript": "^4.7.4",
31-
"vite": "3.1.0",
31+
"vite": "4.0.1",
3232
"vite-plugin-require-transform": "1.0.3"
3333
},
3434
"peerDependencies": {

npm/vite-dev-server/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"mocha": "^9.2.2",
2727
"sinon": "^13.0.1",
2828
"ts-node": "^10.9.1",
29-
"vite": "3.1.0",
29+
"vite": "4.0.1",
3030
"vite-plugin-inspect": "0.4.3"
3131
},
3232
"files": [

npm/vue/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"globby": "^11.0.1",
2828
"tailwindcss": "1.1.4",
2929
"typescript": "^4.7.4",
30-
"vite": "3.1.0",
30+
"vite": "4.0.1",
3131
"vue": "3.2.31",
3232
"vue-i18n": "9.0.0-rc.6",
3333
"vue-router": "^4.0.0",

packages/app/cypress/e2e/runner/reporter.errors.cy.ts

+12
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,18 @@ describe('errors ui', {
180180
],
181181
})
182182

183+
verify('spec unhandled rejection with string content', {
184+
uncaught: true,
185+
column: 20,
186+
originalMessage: 'Unhandled promise rejection with string content from the spec',
187+
message: [
188+
'The following error originated from your test code',
189+
'It was caused by an unhandled promise rejection',
190+
],
191+
stackRegex: /.*/,
192+
hasCodeFrame: false,
193+
})
194+
183195
verify('spec unhandled rejection with done', {
184196
uncaught: true,
185197
column: 20,

packages/driver/cypress/component/spec.cy.js

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const { sinon } = Cypress
2+
13
describe('component testing', () => {
24
/** @type {Cypress.Agent<sinon.SinonSpy>} */
35
let uncaughtExceptionStub
@@ -12,17 +14,40 @@ describe('component testing', () => {
1214
})
1315
})
1416

17+
beforeEach(() => {
18+
uncaughtExceptionStub.resetHistory()
19+
document.querySelector('[data-cy-root]').innerHTML = ''
20+
})
21+
1522
it('fails and shows an error', () => {
23+
cy.spy(Cypress, 'log').log(false)
1624
const $el = document.createElement('button')
1725

1826
$el.innerText = `Don't click it!`
1927
$el.addEventListener('click', () => {
20-
throw Error('An error!')
28+
throw new Error('An error!')
2129
})
2230

2331
document.querySelector('[data-cy-root]').appendChild($el)
2432
cy.get('button').click().then(() => {
2533
expect(uncaughtExceptionStub).to.have.been.calledOnceWithExactly(null)
34+
expect(Cypress.log).to.be.calledWithMatch(sinon.match({ 'message': `Error: An error!`, name: 'uncaught exception' }))
35+
})
36+
})
37+
38+
it('fails and shows when a promise rejects with a string', () => {
39+
cy.spy(Cypress, 'log').log(false)
40+
const $el = document.createElement('button')
41+
42+
$el.innerText = `Don't click it!`
43+
$el.addEventListener('click', new Promise((_, reject) => {
44+
reject('Promise rejected with a string!')
45+
}))
46+
47+
document.querySelector('[data-cy-root]').appendChild($el)
48+
cy.get('button').click().then(() => {
49+
expect(uncaughtExceptionStub).to.have.been.calledOnceWithExactly(null)
50+
expect(Cypress.log).to.be.calledWithMatch(sinon.match({ 'message': `Error: "Promise rejected with a string!"`, name: 'uncaught exception' }))
2651
})
2752
})
2853
})

packages/driver/cypress/e2e/cypress/error_utils.cy.ts

+34-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import $stackUtils from '@packages/driver/src/cypress/stack_utils'
66
import $errUtils, { CypressError } from '@packages/driver/src/cypress/error_utils'
77
import $errorMessages from '@packages/driver/src/cypress/error_messages'
88

9+
const { sinon } = Cypress
10+
911
describe('driver/src/cypress/error_utils', () => {
1012
context('.modifyErrMsg', () => {
1113
let originalErr
@@ -90,7 +92,7 @@ describe('driver/src/cypress/error_utils', () => {
9092
})
9193

9294
it('attaches onFail to the error when it is a function', () => {
93-
const onFail = function () {}
95+
const onFail = function () { }
9496
const fn = () => $errUtils.throwErr(new Error('foo'), { onFail })
9597

9698
expect(fn).throw().and.satisfy((err) => {
@@ -561,7 +563,7 @@ describe('driver/src/cypress/error_utils', () => {
561563

562564
it('does not error if no last log', () => {
563565
state.returns({
564-
getLastLog: () => {},
566+
getLastLog: () => { },
565567
})
566568

567569
const result = $errUtils.createUncaughtException({
@@ -660,4 +662,34 @@ describe('driver/src/cypress/error_utils', () => {
660662
expect(unsupportedPlugin).to.eq(null)
661663
})
662664
})
665+
666+
context('.logError', () => {
667+
let cypressMock
668+
669+
beforeEach(() => {
670+
cypressMock = {
671+
log: cy.stub(),
672+
}
673+
})
674+
675+
it('calls Cypress.log with error name and message when error is instance of Error', () => {
676+
$errUtils.logError(cypressMock, 'error', new Error('Some error'))
677+
expect(cypressMock.log).to.have.been.calledWithMatch(sinon.match.has('message', `Error: Some error`))
678+
})
679+
680+
it('calls Cypress.log with error name and message when error a string', () => {
681+
$errUtils.logError(cypressMock, 'error', 'Some string error')
682+
expect(cypressMock.log).to.have.been.calledWithMatch(sinon.match.has('message', `Error: \"Some string error\"`))
683+
})
684+
685+
it('calls Cypress.log with default error name and provided message message when error is an object with a message', () => {
686+
$errUtils.logError(cypressMock, 'error', { message: 'Some object error with message' })
687+
expect(cypressMock.log).to.have.been.calledWithMatch(sinon.match.has('message', `Error: Some object error with message`))
688+
})
689+
690+
it('calls Cypress.log with error name and message when error is an object', () => {
691+
$errUtils.logError(cypressMock, 'error', { err: 'Error details' })
692+
expect(cypressMock.log).to.have.been.calledWithMatch(sinon.match.has('message', `Error: {"err":"Error details"}`))
693+
})
694+
})
663695
})

packages/driver/src/cypress/cy.ts

+13-12
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ const setTopOnError = function (Cypress, cy: $Cy) {
109109

110110
// prevent Mocha from setting top.onerror
111111
Object.defineProperty(top, 'onerror', {
112-
set () {},
113-
get () {},
112+
set () { },
113+
get () { },
114114
configurable: false,
115115
enumerable: true,
116116
})
@@ -131,12 +131,12 @@ const ensureRunnable = (cy, cmd) => {
131131
interface ICyFocused extends Omit<
132132
IFocused,
133133
'documentHasFocus' | 'interceptFocus' | 'interceptBlur'
134-
> {}
134+
> { }
135135

136136
interface ICySnapshots extends Omit<
137137
ISnapshots,
138138
'onCssModified' | 'onBeforeWindowLoad'
139-
> {}
139+
> { }
140140

141141
export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssertions, IRetries, IJQuery, ILocation, ITimer, IChai, IXhr, IAliases, ICySnapshots, ICyFocused {
142142
id: string
@@ -505,16 +505,16 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
505505
// If the runner can communicate, we should setup all events, otherwise just setup the window and fire the load event.
506506
if (isRunnerAbleToCommunicateWithAUT) {
507507
if (this.Cypress.isBrowser('webkit')) {
508-
// WebKit's unhandledrejection event will sometimes not fire within the AUT
509-
// due to a documented bug: https://bugs.webkit.org/show_bug.cgi?id=187822
510-
// To ensure that the event will always fire (and always report these
511-
// unhandled rejections to the user), we patch the AUT's Error constructor
512-
// to enqueue a no-op microtask when executed, which ensures that the unhandledrejection
513-
// event handler will be executed if this Error is uncaught.
508+
// WebKit's unhandledrejection event will sometimes not fire within the AUT
509+
// due to a documented bug: https://bugs.webkit.org/show_bug.cgi?id=187822
510+
// To ensure that the event will always fire (and always report these
511+
// unhandled rejections to the user), we patch the AUT's Error constructor
512+
// to enqueue a no-op microtask when executed, which ensures that the unhandledrejection
513+
// event handler will be executed if this Error is uncaught.
514514
const originalError = autWindow.Error
515515

516516
autWindow.Error = function __CyWebKitError (...args) {
517-
autWindow.queueMicrotask(() => {})
517+
autWindow.queueMicrotask(() => { })
518518

519519
return originalError.apply(this, args)
520520
}
@@ -1059,6 +1059,7 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
10591059
// eslint-disable-next-line @cypress/dev/arrow-body-multiline-braces
10601060
onError: (handlerType) => (event) => {
10611061
const { originalErr, err, promise } = $errUtils.errorFromUncaughtEvent(handlerType, event) as ErrorFromProjectRejectionEvent
1062+
10621063
const handled = cy.onUncaughtException({
10631064
err,
10641065
promise,
@@ -1080,7 +1081,7 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
10801081
onSubmit (e) {
10811082
return cy.Cypress.action('app:form:submitted', e)
10821083
},
1083-
onLoad () {},
1084+
onLoad () { },
10841085
onBeforeUnload (e) {
10851086
cy.isStable(false, 'beforeunload')
10861087

packages/driver/src/cypress/error_utils.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ const appendErrMsg = (err, errMsg) => {
189189
}
190190

191191
const makeErrFromObj = (obj) => {
192+
if (_.isString(obj)) {
193+
return new Error(obj)
194+
}
195+
192196
const err2 = new Error(obj.message)
193197

194198
err2.name = obj.name
@@ -549,9 +553,11 @@ const errorFromUncaughtEvent = (handlerType: HandlerType, event) => {
549553
errorFromProjectRejectionEvent(event)
550554
}
551555

552-
const logError = (Cypress, handlerType: HandlerType, err, handled = false) => {
556+
const logError = (Cypress, handlerType: HandlerType, err: unknown, handled = false) => {
557+
const error = toLoggableError(err)
558+
553559
Cypress.log({
554-
message: `${err.name}: ${err.message}`,
560+
message: `${error.name || 'Error'}: ${error.message}`,
555561
name: 'uncaught exception',
556562
type: 'parent',
557563
// specifying the error causes the log to be red/failed
@@ -572,6 +578,25 @@ const logError = (Cypress, handlerType: HandlerType, err, handled = false) => {
572578
})
573579
}
574580

581+
interface LoggableError { name?: string, message: string }
582+
583+
const isLoggableError = (error: unknown): error is LoggableError => {
584+
return (
585+
typeof error === 'object' &&
586+
error !== null &&
587+
'message' in error)
588+
}
589+
590+
const toLoggableError = (maybeError: unknown): LoggableError => {
591+
if (isLoggableError(maybeError)) return maybeError
592+
593+
try {
594+
return { message: JSON.stringify(maybeError) }
595+
} catch {
596+
return { message: String(maybeError) }
597+
}
598+
}
599+
575600
const getUnsupportedPlugin = (runnable) => {
576601
if (!(runnable.invocationDetails && runnable.invocationDetails.originalFile && runnable.err && runnable.err.message)) {
577602
return null

packages/frontend-shared/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
"@urql/exchange-execute": "1.1.0",
3636
"@urql/exchange-graphcache": "4.3.6",
3737
"@urql/vue": "0.6.2",
38-
"@vitejs/plugin-vue": "2.2.4",
39-
"@vitejs/plugin-vue-jsx": "1.3.8",
38+
"@vitejs/plugin-vue": "4.0.0",
39+
"@vitejs/plugin-vue-jsx": "3.0.0",
4040
"@vue/compiler-core": "3.2.31",
4141
"@vue/compiler-dom": "3.2.31",
4242
"@vue/compiler-sfc": "3.2.31",

system-tests/project-fixtures/runner-specs/cypress/e2e/errors/uncaught.cy.js

+6
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ describe('uncaught errors', { defaultCommandTimeout: 0 }, () => {
6161
cy.wait(10000)
6262
})
6363

64+
it('spec unhandled rejection with string content', () => {
65+
Promise.reject('Unhandled promise rejection with string content from the spec')
66+
67+
cy.wait(10000)
68+
})
69+
6470
// eslint-disable-next-line mocha/handle-done-callback
6571
it('spec unhandled rejection with done', (done) => {
6672
Promise.reject(new Error('Unhandled promise rejection from the spec'))

0 commit comments

Comments
 (0)