@woocommerce/e2e-environment
Version:
WooCommerce End to End Testing Environment Configuration.
172 lines (143 loc) • 5.41 kB
JavaScript
/**
* 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