throw-on-react-error.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. /* global fail */
  2. // eslint-disable-next-line no-console
  3. const originalConsoleError = console.error;
  4. // List of `console.error` messages to ignore
  5. // (i.e. don't fail tests when we get these messages)
  6. const IGNORED_ERRORS = [
  7. (message, ...args) =>
  8. typeof message === 'string' &&
  9. message.includes('Warning: ') &&
  10. args[0] === 'CreatableSelect',
  11. message =>
  12. typeof message === 'string' &&
  13. message.includes(
  14. 'The pseudo class ":first-child" is potentially unsafe when doing server-side rendering.'
  15. ),
  16. message =>
  17. typeof message === 'string' && message.includes('HTMLMediaElement.prototype.play'),
  18. ];
  19. // This is needed because when we throw the captured error message, it will
  20. // also `console.error` it
  21. const REPEATED_ERROR = 'Error: Uncaught [Error: ';
  22. jest.spyOn(console, 'error').mockImplementation((message, ...args) => {
  23. const isIgnored = IGNORED_ERRORS.some(checkFn => checkFn(message, ...args));
  24. if (
  25. typeof message === 'string' &&
  26. message.indexOf(REPEATED_ERROR) !== 0 &&
  27. !isIgnored
  28. ) {
  29. originalConsoleError(message, ...args);
  30. const err = new Error('Warnings received from console.error()');
  31. const lines = err.stack?.split('\n');
  32. const startIndex = lines?.findIndex(line => line.includes('tests/js/spec'));
  33. err.stack = ['\n', lines?.[0], ...lines?.slice(startIndex)].join('\n');
  34. // `fail` is a global from jest/jasmine
  35. // eslint-disable-next-line jest/no-jasmine-globals
  36. fail(err);
  37. }
  38. });