UNPKG

@woocommerce/e2e-environment

Version:
172 lines (143 loc) 5.41 kB
/** * External dependencies */ import { get } from 'lodash'; import { clearLocalStorage, enablePageDialogAccept, isOfflineMode, setBrowserViewport } from '@wordpress/e2e-test-utils'; import { consoleShouldSuppress, addConsoleSuppression } from '../../utils'; import { setupJestRetries } from '../../config/jest-object.config'; /** * Array of page event tuples of [ eventName, handler ]. * * @type {Array} */ const pageEvents = []; /** * Set of logged messages that will only be logged once. */ addConsoleSuppression('Failed to load resource: net::ERR_PROXY_CONNECTION_FAILED'); addConsoleSuppression('the server responded with a status of 404'); /** * Set of console logging types observed to protect against unexpected yet * handled (i.e. not catastrophic) errors or warnings. Each key corresponds * to the Puppeteer ConsoleMessage type, its value the corresponding function * on the console global object. * * @type {Object<string,string>} */ const OBSERVED_CONSOLE_MESSAGE_TYPES = { warning: 'warn', error: 'error' }; async function setupBrowser() { await clearLocalStorage(); await setBrowserViewport({ width: 1280, height: 800 }); } /** * Adds an event listener to the page to handle additions of page event * handlers, to assure that they are removed at test teardown. */ function capturePageEventsForTearDown() { page.on('newListener', (eventName, listener) => { pageEvents.push([eventName, listener]); }); } /** * Removes all bound page event handlers. */ function removePageEvents() { pageEvents.forEach(_ref => { let [eventName, handler] = _ref; page.removeListener(eventName, handler); }); } /** * Add an expect range matcher. * @see https://jestjs.io/docs/expect#expectextendmatchers */ expect.extend({ toBeInRange: function (received, floor, ceiling) { const pass = received >= floor && received <= ceiling; const condition = pass ? 'not to be' : 'to be'; return { message: () => `expected ${received} ${condition} within range ${floor} - ${ceiling}`, pass }; } }); /** * Adds a page event handler to emit uncaught exception to process if one of * the observed console logging types is encountered. */ function observeConsoleLogging() { page.on('console', message => { const type = message.type(); if (!OBSERVED_CONSOLE_MESSAGE_TYPES.hasOwnProperty(type)) { return; } let text = message.text(); // An exception is made for _blanket_ deprecation warnings: Those // which log regardless of whether a deprecated feature is in use. if (text.includes('This is a global warning')) { return; } // A chrome advisory warning about SameSite cookies is informational // about future changes, tracked separately for improvement in core. // // See: https://core.trac.wordpress.org/ticket/37000 // See: https://www.chromestatus.com/feature/5088147346030592 // See: https://www.chromestatus.com/feature/5633521622188032 if (text.includes('A cookie associated with a cross-site resource')) { return; } // Viewing posts on the front end can result in this error, which // has nothing to do with Gutenberg. if (text.includes('net::ERR_UNKNOWN_URL_SCHEME')) { return; } // Network errors are ignored only if we are intentionally testing // offline mode. if (text.includes('net::ERR_INTERNET_DISCONNECTED') && isOfflineMode()) { return; } // As of WordPress 5.3.2 in Chrome 79, navigating to the block editor // (Posts > Add New) will display a console warning about // non - unique IDs. // See: https://core.trac.wordpress.org/ticket/23165 if (text.includes('elements with non-unique id #_wpnonce')) { return; } const logFunction = OBSERVED_CONSOLE_MESSAGE_TYPES[type]; // Limit repeated warnings. if (consoleShouldSuppress(text)) { return; } // As of Puppeteer 1.6.1, `message.text()` wrongly returns an object of // type JSHandle for error logging, instead of the expected string. // // See: https://github.com/GoogleChrome/puppeteer/issues/3397 // // The recommendation there to asynchronously resolve the error value // upon a console event may be prone to a race condition with the test // completion, leaving a possibility of an error not being surfaced // correctly. Instead, the logic here synchronously inspects the // internal object shape of the JSHandle to find the error text. If it // cannot be found, the default text value is used instead. text = get(message.args(), [0, '_remoteObject', 'description'], text); // Disable reason: We intentionally bubble up the console message // which, unless the test explicitly anticipates the logging via // @wordpress/jest-console matchers, will cause the intended test // failure. // eslint-disable-next-line no-console console[logFunction](text); }); } // Before every test suite run, delete all content created by the test. This ensures // other posts/comments/etc. aren't dirtying tests and tests don't depend on // each other's side-effects. beforeAll(async () => { capturePageEventsForTearDown(); enablePageDialogAccept(); observeConsoleLogging(); setupJestRetries(); }); afterEach(async () => { await setupBrowser(); }); afterAll(() => { removePageEvents(); }); //# sourceMappingURL=jest.setup.js.map