bootstrap.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { get } from 'lodash';
  2. import {
  3. clearLocalStorage,
  4. enablePageDialogAccept,
  5. setBrowserViewport,
  6. } from '@wordpress/e2e-test-utils';
  7. /**
  8. * Environment variables
  9. */
  10. const { PUPPETEER_TIMEOUT } = process.env;
  11. /**
  12. * Set of console logging types observed to protect against unexpected yet
  13. * handled (i.e. not catastrophic) errors or warnings. Each key corresponds
  14. * to the Puppeteer ConsoleMessage type, its value the corresponding function
  15. * on the console global object.
  16. *
  17. * @type {Object<string,string>}
  18. */
  19. const OBSERVED_CONSOLE_MESSAGE_TYPES = {
  20. warning: 'warn',
  21. error: 'error',
  22. };
  23. /**
  24. * Array of page event tuples of [ eventName, handler ].
  25. *
  26. * @type {Array}
  27. */
  28. const pageEvents = [];
  29. // The Jest timeout is increased because these tests are a bit slow
  30. jest.setTimeout( PUPPETEER_TIMEOUT || 100000 );
  31. /**
  32. * Adds an event listener to the page to handle additions of page event
  33. * handlers, to assure that they are removed at test teardown.
  34. */
  35. function capturePageEventsForTearDown() {
  36. page.on( 'newListener', ( eventName, listener ) => {
  37. pageEvents.push( [ eventName, listener ] );
  38. } );
  39. }
  40. /**
  41. * Removes all bound page event handlers.
  42. */
  43. function removePageEvents() {
  44. pageEvents.forEach( ( [ eventName, handler ] ) => {
  45. page.removeListener( eventName, handler );
  46. } );
  47. }
  48. /**
  49. * Adds a page event handler to emit uncaught exception to process if one of
  50. * the observed console logging types is encountered.
  51. */
  52. function observeConsoleLogging() {
  53. page.on( 'console', ( message ) => {
  54. const type = message.type();
  55. if ( ! OBSERVED_CONSOLE_MESSAGE_TYPES.hasOwnProperty( type ) ) {
  56. return;
  57. }
  58. let text = message.text();
  59. // An exception is made for _blanket_ deprecation warnings: Those
  60. // which log regardless of whether a deprecated feature is in use.
  61. if ( text.includes( 'This is a global warning' ) ) {
  62. return;
  63. }
  64. // Viewing posts on the front end can result in this error, which
  65. // has nothing to do with Gutenberg.
  66. if ( text.includes( 'net::ERR_UNKNOWN_URL_SCHEME' ) ) {
  67. return;
  68. }
  69. // A bug present in WordPress 5.2 will produce console warnings when
  70. // loading the Dashicons font. These can be safely ignored, as they do
  71. // not otherwise regress on application behavior. This logic should be
  72. // removed once the associated ticket has been closed.
  73. //
  74. // See: https://core.trac.wordpress.org/ticket/47183
  75. if (
  76. text.startsWith( 'Failed to decode downloaded font:' ) ||
  77. text.startsWith( 'OTS parsing error:' )
  78. ) {
  79. return;
  80. }
  81. const logFunction = OBSERVED_CONSOLE_MESSAGE_TYPES[ type ];
  82. // As of Puppeteer 1.6.1, `message.text()` wrongly returns an object of
  83. // type JSHandle for error logging, instead of the expected string.
  84. //
  85. // See: https://github.com/GoogleChrome/puppeteer/issues/3397
  86. //
  87. // The recommendation there to asynchronously resolve the error value
  88. // upon a console event may be prone to a race condition with the test
  89. // completion, leaving a possibility of an error not being surfaced
  90. // correctly. Instead, the logic here synchronously inspects the
  91. // internal object shape of the JSHandle to find the error text. If it
  92. // cannot be found, the default text value is used instead.
  93. text = get( message.args(), [ 0, '_remoteObject', 'description' ], text );
  94. // Disable reason: We intentionally bubble up the console message
  95. // which, unless the test explicitly anticipates the logging via
  96. // @wordpress/jest-console matchers, will cause the intended test
  97. // failure.
  98. // eslint-disable-next-line no-console
  99. console[ logFunction ]( text );
  100. } );
  101. }
  102. // Before every test suite run, delete all content created by the test. This ensures
  103. // other posts/comments/etc. aren't dirtying tests and tests don't depend on
  104. // each other's side-effects.
  105. beforeAll( async () => {
  106. capturePageEventsForTearDown();
  107. enablePageDialogAccept();
  108. observeConsoleLogging();
  109. await setBrowserViewport( 'large' );
  110. } );
  111. afterEach( async () => {
  112. await clearLocalStorage();
  113. await setBrowserViewport( 'large' );
  114. } );
  115. afterAll( () => {
  116. removePageEvents();
  117. } );