diff --git a/scripts/babel/__tests__/transform-test-gate-pragma-test.js b/scripts/babel/__tests__/transform-test-gate-pragma-test.js index 1970ab4c1c2c2..e4b76dd05e859 100644 --- a/scripts/babel/__tests__/transform-test-gate-pragma-test.js +++ b/scripts/babel/__tests__/transform-test-gate-pragma-test.js @@ -203,6 +203,15 @@ describe('transform test-gate-pragma: actual runtime', () => { console.error('Stop that!'); throw Error('I told you to stop!'); }); + + // @gate false + test('a global error event is treated as a test failure', () => { + dispatchEvent( + new ErrorEvent('error', { + error: new Error('Oops!'), + }) + ); + }); }); describe('dynamic gate method', () => { diff --git a/scripts/jest/setupTests.js b/scripts/jest/setupTests.js index 0d23861568fe4..14864264c9092 100644 --- a/scripts/jest/setupTests.js +++ b/scripts/jest/setupTests.js @@ -241,13 +241,30 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) { global.Error = ErrorProxy; } - const expectTestToFail = async (callback, error) => { + const expectTestToFail = async (callback, errorToThrowIfTestSucceeds) => { if (callback.length > 0) { throw Error( 'Gated test helpers do not support the `done` callback. Return a ' + 'promise instead.' ); } + + // Install a global error event handler. We treat global error events as + // test failures, same as Jest's default behavior. + // + // Becaused we installed our own error event handler, Jest will not report a + // test failure. Conceptually it's as if we wrapped the entire test event in + // a try-catch. + let didError = false; + const errorEventHandler = () => { + didError = true; + }; + // eslint-disable-next-line no-restricted-globals + if (typeof addEventListener === 'function') { + // eslint-disable-next-line no-restricted-globals + addEventListener('error', errorEventHandler); + } + try { const maybePromise = callback(); if ( @@ -262,11 +279,20 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) { // throws, we won't have captured it. flushAllUnexpectedConsoleCalls(); } catch (testError) { - // Failed as expected - resetAllUnexpectedConsoleCalls(); - return; + didError = true; + } + resetAllUnexpectedConsoleCalls(); + // eslint-disable-next-line no-restricted-globals + if (typeof removeEventListener === 'function') { + // eslint-disable-next-line no-restricted-globals + removeEventListener('error', errorEventHandler); + } + + if (!didError) { + // The test did not error like we expected it to. Report this to Jest as + // a failure. + throw errorToThrowIfTestSucceeds; } - throw error; }; const gatedErrorMessage = 'Gated test was expected to fail, but it passed.';