upkeep/e2e-utils-playwright: Exposing Playwright utils (#51982)
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
parent
03ec423519
commit
30121f5be6
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "@woocommerce/e2e-utils-playwright",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "End-To-End (E2E) test Playwright utils for WooCommerce",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/woocommerce/woocommerce.git"
|
||||||
|
},
|
||||||
|
"license": "GPL-3.0+",
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.11.1",
|
||||||
|
"pnpm": "9.1.3"
|
||||||
|
},
|
||||||
|
"main": "src/index.js",
|
||||||
|
"module": "build-module/index.js"
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
* Adds a specified quantity of a product by ID to the WooCommerce cart.
|
||||||
|
*
|
||||||
|
* @param page
|
||||||
|
* @param productId
|
||||||
|
* @param quantity
|
||||||
|
*/
|
||||||
|
export const addAProductToCart = async ( page, productId, quantity = 1 ) => {
|
||||||
|
for ( let i = 0; i < quantity; i++ ) {
|
||||||
|
const responsePromise = page.waitForResponse(
|
||||||
|
'**/wp-json/wc/store/v1/cart?**'
|
||||||
|
);
|
||||||
|
await page.goto( `/shop/?add-to-cart=${ productId }` );
|
||||||
|
await responsePromise;
|
||||||
|
await page.getByRole( 'alert' ).waitFor( { state: 'visible' } );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Util helper made for adding multiple same products to cart
|
||||||
|
*
|
||||||
|
* @param page
|
||||||
|
* @param productName
|
||||||
|
* @param quantityCount
|
||||||
|
*/
|
||||||
|
export async function addOneOrMoreProductToCart( page, productName, quantityCount ) {
|
||||||
|
await page.goto(
|
||||||
|
`product/${ productName.replace( / /gi, '-' ).toLowerCase() }`
|
||||||
|
);
|
||||||
|
await page.getByLabel( 'Product quantity' ).fill( quantityCount );
|
||||||
|
await page.locator( 'button[name="add-to-cart"]' ).click();
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* Util helper made for filling shipping details in the block-based checkout
|
||||||
|
*
|
||||||
|
* @param {Object} page
|
||||||
|
* @param {string} firstName
|
||||||
|
* @param {string} lastName
|
||||||
|
* @param {string} address
|
||||||
|
* @param {string} city
|
||||||
|
* @param {string} zip
|
||||||
|
*/
|
||||||
|
export async function fillShippingCheckoutBlocks(
|
||||||
|
page,
|
||||||
|
firstName = 'Homer',
|
||||||
|
lastName = 'Simpson',
|
||||||
|
address = '123 Evergreen Terrace',
|
||||||
|
city = 'Springfield',
|
||||||
|
zip = '97403'
|
||||||
|
) {
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Shipping address' } )
|
||||||
|
.getByLabel( 'First name' )
|
||||||
|
.fill( firstName );
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Shipping address' } )
|
||||||
|
.getByLabel( 'Last name' )
|
||||||
|
.fill( lastName );
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Shipping address' } )
|
||||||
|
.getByLabel( 'Address', { exact: true } )
|
||||||
|
.fill( address );
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Shipping address' } )
|
||||||
|
.getByLabel( 'City' )
|
||||||
|
.fill( city );
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Shipping address' } )
|
||||||
|
.getByLabel( 'ZIP Code' )
|
||||||
|
.fill( zip );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Util helper made for filling billing details in the block-based checkout
|
||||||
|
*
|
||||||
|
* @param {Object} page
|
||||||
|
* @param {string} firstName
|
||||||
|
* @param {string} lastName
|
||||||
|
* @param {string} address
|
||||||
|
* @param {string} city
|
||||||
|
* @param {string} zip
|
||||||
|
*/
|
||||||
|
export async function fillBillingCheckoutBlocks(
|
||||||
|
page,
|
||||||
|
firstName = 'Mister',
|
||||||
|
lastName = 'Burns',
|
||||||
|
address = '156th Street',
|
||||||
|
city = 'Springfield',
|
||||||
|
zip = '98500'
|
||||||
|
) {
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Billing address' } )
|
||||||
|
.getByLabel( 'First name' )
|
||||||
|
.fill( firstName );
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Billing address' } )
|
||||||
|
.getByLabel( 'Last name' )
|
||||||
|
.fill( lastName );
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Billing address' } )
|
||||||
|
.getByLabel( 'Address', { exact: true } )
|
||||||
|
.fill( address );
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Billing address' } )
|
||||||
|
.getByLabel( 'City' )
|
||||||
|
.fill( city );
|
||||||
|
await page
|
||||||
|
.getByRole( 'group', { name: 'Billing address' } )
|
||||||
|
.getByLabel( 'ZIP Code' )
|
||||||
|
.fill( zip );
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
export const closeChoosePatternModal = async ( { page } ) => {
|
||||||
|
const closeModal = page
|
||||||
|
.getByLabel( 'Scrollable section' )
|
||||||
|
.filter()
|
||||||
|
.getByRole( 'button', {
|
||||||
|
name: 'Close',
|
||||||
|
exact: true,
|
||||||
|
} );
|
||||||
|
await page.addLocatorHandler( closeModal, async () => {
|
||||||
|
await closeModal.click();
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
export const disableWelcomeModal = async ( { page } ) => {
|
||||||
|
// Further info: https://github.com/woocommerce/woocommerce/pull/45856/
|
||||||
|
await page.waitForLoadState( 'domcontentloaded' );
|
||||||
|
|
||||||
|
const isWelcomeGuideActive = await page.evaluate( () =>
|
||||||
|
window.wp.data.select( 'core/edit-post' ).isFeatureActive( 'welcomeGuide' )
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( isWelcomeGuideActive ) {
|
||||||
|
await page.evaluate( () =>
|
||||||
|
window.wp.data.dispatch( 'core/edit-post' ).toggleFeature( 'welcomeGuide' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const openEditorSettings = async ( { page } ) => {
|
||||||
|
// Open Settings sidebar if closed
|
||||||
|
if ( await page.getByLabel( 'Editor Settings' ).isVisible() ) {
|
||||||
|
console.log( 'Editor Settings is open, skipping action.' );
|
||||||
|
} else {
|
||||||
|
await page.getByLabel( 'Settings', { exact: true } ).click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getCanvas = async ( page ) => {
|
||||||
|
return page.frame( 'editor-canvas' ) || page;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const goToPageEditor = async ( { page } ) => {
|
||||||
|
await page.goto( 'wp-admin/post-new.php?post_type=page' );
|
||||||
|
await disableWelcomeModal( { page } );
|
||||||
|
await closeChoosePatternModal( { page } );
|
||||||
|
};
|
||||||
|
|
||||||
|
export const goToPostEditor = async ( { page } ) => {
|
||||||
|
await page.goto( 'wp-admin/post-new.php' );
|
||||||
|
await disableWelcomeModal( { page } );
|
||||||
|
};
|
||||||
|
|
||||||
|
export const insertBlock = async ( page, blockName ) => {
|
||||||
|
await page
|
||||||
|
.getByRole( 'button', {
|
||||||
|
name: 'Toggle block inserter',
|
||||||
|
expanded: false,
|
||||||
|
} )
|
||||||
|
.click();
|
||||||
|
await page.getByPlaceholder( 'Search', { exact: true } ).fill( blockName );
|
||||||
|
await page.getByRole( 'option', { name: blockName, exact: true } ).click();
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByRole( 'button', {
|
||||||
|
name: 'Close block inserter',
|
||||||
|
} )
|
||||||
|
.click();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const insertBlockByShortcut = async ( page, blockName ) => {
|
||||||
|
const canvas = await getCanvas( page );
|
||||||
|
await canvas.getByRole( 'button', { name: 'Add default block' } ).click();
|
||||||
|
await canvas
|
||||||
|
.getByRole( 'document', {
|
||||||
|
name: 'Empty block; start writing or type forward slash to choose a block',
|
||||||
|
} )
|
||||||
|
.pressSequentially( `/${ blockName }` );
|
||||||
|
await page.getByRole( 'option', { name: blockName, exact: true } ).click();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const transformIntoBlocks = async ( page ) => {
|
||||||
|
const canvas = await getCanvas( page );
|
||||||
|
|
||||||
|
await canvas
|
||||||
|
.getByRole( 'button' )
|
||||||
|
.filter( { hasText: 'Transform into blocks' } )
|
||||||
|
.click();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const publishPage = async ( page, pageTitle, isPost = false ) => {
|
||||||
|
await page
|
||||||
|
.getByRole( 'button', { name: 'Publish', exact: true } )
|
||||||
|
.dispatchEvent( 'click' );
|
||||||
|
|
||||||
|
const createPageResponse = page.waitForResponse( ( response ) => {
|
||||||
|
return (
|
||||||
|
response.url().includes( isPost ? '/posts/' : '/pages/' ) &&
|
||||||
|
response.ok() &&
|
||||||
|
response.request().method() === 'POST' &&
|
||||||
|
response
|
||||||
|
.json()
|
||||||
|
.then(
|
||||||
|
( json ) =>
|
||||||
|
json.title.rendered === pageTitle &&
|
||||||
|
json.status === 'publish'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByRole( 'region', { name: 'Editor publish' } )
|
||||||
|
.getByRole( 'button', { name: 'Publish', exact: true } )
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// Validating that page was published via UI elements is not reliable,
|
||||||
|
// installed plugins (e.g. WooCommerce PayPal Payments) can interfere and add flakiness to the flow.
|
||||||
|
// In WC context, checking the API response is possibly the most reliable way to ensure the page was published.
|
||||||
|
await createPageResponse;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
export * from './cart';
|
||||||
|
export * from './checkout';
|
||||||
|
export * from './editor';
|
||||||
|
export * from './order';
|
|
@ -0,0 +1,4 @@
|
||||||
|
export function getOrderIdFromUrl( page ) {
|
||||||
|
const regex = /order-received\/(\d+)/;
|
||||||
|
return page.url().match( regex )[ 1 ];
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: dev
|
||||||
|
Comment: Expose Playwright E2E tests utils.
|
||||||
|
|
|
@ -673,6 +673,7 @@
|
||||||
"@woocommerce/e2e-utils": "workspace:*",
|
"@woocommerce/e2e-utils": "workspace:*",
|
||||||
"@woocommerce/eslint-plugin": "workspace:*",
|
"@woocommerce/eslint-plugin": "workspace:*",
|
||||||
"@woocommerce/woocommerce-rest-api": "^1.0.1",
|
"@woocommerce/woocommerce-rest-api": "^1.0.1",
|
||||||
|
"@woocommerce/e2e-utils-playwright": "workspace:*",
|
||||||
"@wordpress/babel-plugin-import-jsx-pragma": "1.1.3",
|
"@wordpress/babel-plugin-import-jsx-pragma": "1.1.3",
|
||||||
"@wordpress/babel-preset-default": "3.0.2",
|
"@wordpress/babel-preset-default": "3.0.2",
|
||||||
"@wordpress/e2e-test-utils-playwright": "wp-6.6",
|
"@wordpress/e2e-test-utils-playwright": "wp-6.6",
|
||||||
|
|
|
@ -1667,6 +1667,8 @@ importers:
|
||||||
specifier: 0.14.3
|
specifier: 0.14.3
|
||||||
version: 0.14.3
|
version: 0.14.3
|
||||||
|
|
||||||
|
packages/js/e2e-utils-playwright: {}
|
||||||
|
|
||||||
packages/js/eslint-plugin:
|
packages/js/eslint-plugin:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
|
@ -3375,6 +3377,9 @@ importers:
|
||||||
'@woocommerce/e2e-utils':
|
'@woocommerce/e2e-utils':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/js/e2e-utils
|
version: link:../../packages/js/e2e-utils
|
||||||
|
'@woocommerce/e2e-utils-playwright':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../packages/js/e2e-utils-playwright
|
||||||
'@woocommerce/eslint-plugin':
|
'@woocommerce/eslint-plugin':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/js/eslint-plugin
|
version: link:../../packages/js/eslint-plugin
|
||||||
|
@ -65336,11 +65341,11 @@ snapshots:
|
||||||
'@webassemblyjs/ast': 1.11.6
|
'@webassemblyjs/ast': 1.11.6
|
||||||
'@webassemblyjs/wasm-edit': 1.11.6
|
'@webassemblyjs/wasm-edit': 1.11.6
|
||||||
'@webassemblyjs/wasm-parser': 1.11.6
|
'@webassemblyjs/wasm-parser': 1.11.6
|
||||||
acorn: 8.11.2
|
acorn: 8.12.1
|
||||||
acorn-import-assertions: 1.9.0(acorn@8.11.2)
|
acorn-import-assertions: 1.9.0(acorn@8.12.1)
|
||||||
browserslist: 4.19.3
|
browserslist: 4.19.3
|
||||||
chrome-trace-event: 1.0.3
|
chrome-trace-event: 1.0.3
|
||||||
enhanced-resolve: 5.15.0
|
enhanced-resolve: 5.16.0
|
||||||
es-module-lexer: 1.4.1
|
es-module-lexer: 1.4.1
|
||||||
eslint-scope: 5.1.1
|
eslint-scope: 5.1.1
|
||||||
events: 3.3.0
|
events: 3.3.0
|
||||||
|
|
Loading…
Reference in New Issue