woocommerce/plugins/woocommerce-blocks/tests/e2e/playwright-utils/test.ts

224 lines
6.0 KiB
TypeScript

/* eslint-disable rulesdir/no-raw-playwright-test-import */
/**
* External dependencies
*/
import { test as base, expect, request as baseRequest } from '@playwright/test';
import type { ConsoleMessage } from '@playwright/test';
import {
Admin,
Editor,
PageUtils,
RequestUtils,
} from '@wordpress/e2e-test-utils-playwright';
import {
TemplateApiUtils,
STORAGE_STATE_PATH,
EditorUtils,
FrontendUtils,
StoreApiUtils,
PerformanceUtils,
ShippingUtils,
LocalPickupUtils,
MiniCartUtils,
WPCLIUtils,
} from '@woocommerce/e2e-utils';
import { Post } from '@wordpress/e2e-test-utils-playwright/build-types/request-utils/posts';
/**
* Internal dependencies
*/
import {
PostPayload,
createPostFromTemplate,
deletePost,
} from '../utils/create-dynamic-content';
/**
* Set of console logging types observed to protect against unexpected yet
* handled (i.e. not catastrophic) errors or warnings. Each key corresponds
* to the Playwright ConsoleMessage type, its value the corresponding function
* on the console global object.
*/
const OBSERVED_CONSOLE_MESSAGE_TYPES = [ 'warn', 'error' ] as const;
/**
* Adds a page event handler to emit uncaught exception to process if one of
* the observed console logging types is encountered.
*
* @param message The console message.
*/
function observeConsoleLogging( message: ConsoleMessage ) {
const type = message.type();
if (
! OBSERVED_CONSOLE_MESSAGE_TYPES.includes(
type as ( typeof OBSERVED_CONSOLE_MESSAGE_TYPES )[ number ]
)
) {
return;
}
const 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;
}
// Not implemented yet.
// 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;
}
// Ignore all JQMIGRATE (jQuery migrate) deprecation warnings.
if ( text.includes( 'JQMIGRATE' ) ) {
return;
}
const logFunction =
type as ( typeof OBSERVED_CONSOLE_MESSAGE_TYPES )[ number ];
// 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 );
}
const test = base.extend<
{
admin: Admin;
editor: Editor;
pageUtils: PageUtils;
templateApiUtils: TemplateApiUtils;
editorUtils: EditorUtils;
frontendUtils: FrontendUtils;
storeApiUtils: StoreApiUtils;
performanceUtils: PerformanceUtils;
snapshotConfig: void;
shippingUtils: ShippingUtils;
localPickupUtils: LocalPickupUtils;
miniCartUtils: MiniCartUtils;
wpCliUtils: WPCLIUtils;
},
{
requestUtils: RequestUtils & {
createPostFromTemplate: (
post: PostPayload,
templatePath: string,
data: unknown
) => Promise< Post >;
deletePost: ( id: number ) => Promise< void >;
};
}
>( {
admin: async ( { page, pageUtils, editor }, use ) => {
await use( new Admin( { page, pageUtils, editor } ) );
},
editor: async ( { page }, use ) => {
await use( new Editor( { page } ) );
},
page: async ( { page }, use ) => {
page.on( 'console', observeConsoleLogging );
await use( page );
// Clear local storage after each test.
await page.evaluate( () => {
window.localStorage.clear();
} );
},
pageUtils: async ( { page }, use ) => {
await use( new PageUtils( { page } ) );
},
templateApiUtils: async ( {}, use ) =>
await use( new TemplateApiUtils( baseRequest ) ),
editorUtils: async ( { editor, page }, use ) => {
await use( new EditorUtils( editor, page ) );
},
frontendUtils: async ( { page, requestUtils }, use ) => {
await use( new FrontendUtils( page, requestUtils ) );
},
performanceUtils: async ( { page }, use ) => {
await use( new PerformanceUtils( page ) );
},
storeApiUtils: async ( { requestUtils }, use ) => {
await use( new StoreApiUtils( requestUtils ) );
},
shippingUtils: async ( { page, admin }, use ) => {
await use( new ShippingUtils( page, admin ) );
},
localPickupUtils: async ( { page, admin }, use ) => {
await use( new LocalPickupUtils( page, admin ) );
},
miniCartUtils: async ( { page, frontendUtils }, use ) => {
await use( new MiniCartUtils( page, frontendUtils ) );
},
wpCliUtils: async ( {}, use ) => {
await use( new WPCLIUtils() );
},
requestUtils: [
async ( {}, use, workerInfo ) => {
const requestUtils = await RequestUtils.setup( {
baseURL: workerInfo.project.use.baseURL,
storageStatePath: STORAGE_STATE_PATH,
} );
const utilCreatePostFromTemplate = (
post: Partial< PostPayload >,
templatePath: string,
data: unknown
) =>
createPostFromTemplate(
requestUtils,
post,
templatePath,
data
);
const utilDeletePost = ( id: number ) =>
deletePost( requestUtils, id );
await use( {
...requestUtils,
createPostFromTemplate: utilCreatePostFromTemplate,
deletePost: utilDeletePost,
} );
},
{ scope: 'worker', auto: true },
],
} );
export { test, expect };