Block E2E: Eliminate side effects through improved test isolation (#46125)

This commit is contained in:
Bart Kalisz 2024-04-26 11:39:11 +02:00 committed by GitHub
parent 6d914ff573
commit 5f7cc39330
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
76 changed files with 422 additions and 857 deletions

View File

@ -10,8 +10,8 @@
"mappings": {
"wp-content/mu-plugins": "./node_modules/@wordpress/e2e-tests/mu-plugins",
"wp-content/plugins/gutenberg-test-plugins": "./node_modules/@wordpress/e2e-tests/plugins",
"wp-content/plugins/woocommerce-blocks-test-plugins": "./tests/e2e/plugins",
"wp-cli.yml": "./wp-cli.yml",
"custom-plugins": "./tests/e2e/mocks/custom-plugins",
"wp-content/plugins/woocommerce/blocks-bin": "./bin",
"wp-content/plugins/woocommerce/blocks-bin/playwright": "./tests/e2e/bin"
}

View File

@ -221,7 +221,7 @@
"eslint-import-resolver-typescript": "3.6.1",
"eslint-import-resolver-webpack": "0.13.2",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-playwright": "0.15.3",
"eslint-plugin-playwright": "1.6.0",
"eslint-plugin-rulesdir": "^0.2.2",
"eslint-plugin-storybook": "^0.6.15",
"eslint-plugin-woocommerce": "file:bin/eslint-plugin-woocommerce",

View File

@ -23,6 +23,7 @@ const config = {
'playwright/prefer-web-first-assertions': 'error',
'playwright/valid-expect': 'error',
'rulesdir/no-raw-playwright-test-import': 'error',
'playwright/no-hooks': [ 'error', { allow: [ 'beforeEach' ] } ],
},
};

View File

@ -0,0 +1,4 @@
#!/usr/bin/env bash
wp language core install nl_NL
wp language plugin install woocommerce nl_NL

View File

@ -37,4 +37,3 @@ done
# Run the main script in the container for better performance.
wp-env run tests-cli -- bash wp-content/plugins/woocommerce/blocks-bin/playwright/scripts/index.sh
wp-env run tests-cli wp option update woocommerce_coming_soon 'no'

View File

@ -1,9 +1,19 @@
/**
* External dependencies
*/
import { BLOCK_THEME_WITH_TEMPLATES_SLUG } from '@woocommerce/e2e-utils';
import { test as setup } from '@woocommerce/e2e-playwright-utils';
import {
BLOCK_THEME_WITH_TEMPLATES_SLUG,
DB_EXPORT_FILE,
cli,
} from '@woocommerce/e2e-utils';
import { test as setup, expect } from '@woocommerce/e2e-playwright-utils';
setup( 'Sets up the block theme with templates', async ( { requestUtils } ) => {
await requestUtils.activateTheme( BLOCK_THEME_WITH_TEMPLATES_SLUG );
const cliOutput = await cli(
`npm run wp-env run tests-cli wp db export ${ DB_EXPORT_FILE }`
);
// eslint-disable-next-line playwright/no-standalone-expect
expect( cliOutput.stdout ).toContain( 'Success: Exported' );
} );

View File

@ -1,7 +1,8 @@
/* eslint-disable playwright/no-standalone-expect */
/**
* External dependencies
*/
import { BLOCK_THEME_SLUG, cli } from '@woocommerce/e2e-utils';
import { BLOCK_THEME_SLUG, DB_EXPORT_FILE, cli } from '@woocommerce/e2e-utils';
import { test as setup, expect } from '@woocommerce/e2e-playwright-utils';
setup( 'Sets up the block theme', async () => {
@ -21,4 +22,9 @@ setup( 'Sets up the block theme', async () => {
expect( cliOutput.stdout ).toContain( 'Success: Rewrite structure set' );
expect( cliOutput.stdout ).toContain( 'Success: Rewrite rules flushed' );
cliOutput = await cli(
`npm run wp-env run tests-cli wp db export ${ DB_EXPORT_FILE }`
);
expect( cliOutput.stdout ).toContain( 'Success: Exported' );
} );

View File

@ -1,9 +1,11 @@
/* eslint-disable playwright/no-standalone-expect */
/**
* External dependencies
*/
import {
CLASSIC_THEME_NAME,
CLASSIC_THEME_SLUG,
DB_EXPORT_FILE,
cli,
} from '@woocommerce/e2e-utils';
import { test as setup, expect } from '@woocommerce/e2e-playwright-utils';
@ -16,4 +18,9 @@ setup( 'Sets up the classic theme', async ( { admin } ) => {
await expect(
admin.page.getByText( `Active: ${ CLASSIC_THEME_NAME }` )
).toBeVisible();
const cliOutput = await cli(
`npm run wp-env run tests-cli wp db export ${ DB_EXPORT_FILE }`
);
expect( cliOutput.stdout ).toContain( 'Success: Exported' );
} );

View File

@ -41,45 +41,6 @@ const prepareAttributes = async () => {
.getByRole( 'button' )
.click();
await page.goto( BASE_URL + '/wp-admin/post-new.php' );
await page.waitForFunction( () => {
return window.wp.data !== undefined;
} );
// Disable the welcome guide for the site editor.
await page.evaluate( () => {
return Promise.all( [
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-site', 'welcomeGuide', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-site', 'welcomeGuideStyles', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-site', 'welcomeGuidePage', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-site', 'welcomeGuideTemplate', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-post', 'welcomeGuide', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-post', 'welcomeGuideStyles', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-post', 'welcomeGuidePage', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-post', 'welcomeGuideTemplate', false ),
] );
} );
await page.context().storageState( { path: adminFile } );
await context.close();
await browser.close();

View File

@ -1 +0,0 @@
export * from './utils';

View File

@ -1,70 +0,0 @@
# Testing WordPress actions and filters
This documentation covers testing WordPress actions and filters when writing Playwright tests.
## Table of Contents
- [Description](#description)
- [Usage](#usage)
## Description
You can test an action or filter (change) by creating a custom WordPress plugin, installing it and when you are done, removing it.
The 3 functions responsible are located inside of `tests/e2e-pw/mocks/custom-plugins/utils.ts`:
- `createPluginFromPHPFile()`
- `installPluginFromPHPFile()`
- `uninstallPluginFromPHPFile()`
## Usage
### Example: Testing a custom Add to Cart text
1. Create the custom plugin file.
`update-product-button-text.php`.
```php
<?php
/**
* Plugin Name: Custom Add to Cart Text
* Description: Modifies the "Add to Cart" button text for WooCommerce products.
*/
function woocommerce_add_to_cart_button_text_archives() {
return 'Buy Now';
}
add_filter( 'woocommerce_product_add_to_cart_text', 'woocommerce_add_to_cart_button_text_archives' );
```
2. Install the plugin when running the test.
```javascript
test( 'the filter `woocommerce_product_add_to_cart_text` is applied', async ( { frontendUtils } ) => {
await installPluginFromPHPFile(
`${ __dirname }/update-product-button-text.php`
);
await frontendUtils.goToShop();
const blocks = await frontendUtils.getBlockByName( blockData.name );
const buttonWithNewText = await blocks.getByText( 'Buy Now' ).count();
const productsDisplayed = 16;
expect( buttonWithNewText ).toEqual( productsDisplayed );
} );
```
3. Remove the plugin when done testing.
```javascript
test.afterAll( async () => {
await uninstallPluginFromPHPFile(
`${ __dirname }/update-product-button-text.php`
);
} );
```
In the above example, the test checks whether the filter `woocommerce_product_add_to_cart_text` is applied correctly. It installs the "Custom Add to Cart Text" plugin, navigates to the shop page using `frontendUtils`, and verifies if the "Buy Now" button text appears as expected. Finally, it cleans the cart and uninstalls the plugin.
You can adapt this example to test other filters and actions by modifying the code accordingly.

View File

@ -1,31 +0,0 @@
/**
* External dependencies
*/
import { cli } from '@woocommerce/e2e-utils';
import path from 'path';
const createPluginFromPHPFile = async ( phpFilePath: string ) => {
const absolutePath = path.resolve( phpFilePath );
const directory = path.dirname( absolutePath );
const fileName = path.basename( phpFilePath );
const fileNameZip = fileName.replace( '.php', '' );
await cli(
`cd ${ directory } && zip ${ fileNameZip }.zip ${ fileName } && mv ${ fileNameZip }.zip ${ __dirname }`
);
};
export const installPluginFromPHPFile = async ( phpFilePath: string ) => {
await createPluginFromPHPFile( phpFilePath );
const fileName = path.basename( phpFilePath ).replace( '.php', '' );
await cli(
`npm run wp-env run tests-cli -- wp plugin install /var/www/html/custom-plugins/${ fileName }.zip --activate`
);
};
export const uninstallPluginFromPHPFile = async ( phpFilePath: string ) => {
const fileName = path.basename( phpFilePath ).replace( '.php', '' );
await cli(
`npm run wp-env run tests-cli -- wp plugin delete ${ fileName }`
);
await cli( `rm ${ __dirname }/${ fileName }.zip` );
};

View File

@ -13,6 +13,7 @@ import {
import {
TemplateApiUtils,
STORAGE_STATE_PATH,
DB_EXPORT_FILE,
EditorUtils,
FrontendUtils,
StoreApiUtils,
@ -21,6 +22,7 @@ import {
LocalPickupUtils,
MiniCartUtils,
WPCLIUtils,
cli,
} from '@woocommerce/e2e-utils';
import { Post } from '@wordpress/e2e-test-utils-playwright/build-types/request-utils/posts';
@ -158,14 +160,21 @@ const test = base.extend<
await page.evaluate( () => {
window.localStorage.clear();
} );
const cliOutput = await cli(
`npm run wp-env run tests-cli wp db import ${ DB_EXPORT_FILE }`
);
if ( ! cliOutput.stdout.includes( 'Success: Imported ' ) ) {
throw new Error( `Failed to import ${ DB_EXPORT_FILE }` );
}
},
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 ) );
editorUtils: async ( { editor, page, admin }, use ) => {
await use( new EditorUtils( editor, page, admin ) );
},
frontendUtils: async ( { page, requestUtils }, use ) => {
await use( new FrontendUtils( page, requestUtils ) );

View File

@ -1,8 +1,11 @@
<?php
/**
* Plugin Name: Additional checkout fields plugin
* Description: Add additional checkout fields
* @package WordPress
* Plugin Name: WooCommerce Blocks Test Additional Checkout Fields
* Description: Adds custom checkout fields to the checkout form.
* Plugin URI: https://github.com/woocommerce/woocommerce
* Author: WooCommerce
*
* @package woocommerce-blocks-test-additional-checkout-fields
*/
class Additional_Checkout_Fields_Test_Helper {

View File

@ -1,16 +1,13 @@
<?php
/**
* Plugin Name: Custom Add to Cart Text
* Plugin Name: WooCommerce Blocks Test Custom Add to Cart Button Text
* Description: Modifies the "Add to Cart" button text for WooCommerce products.
* @package WordPress
* Plugin URI: https://github.com/woocommerce/woocommerce
* Author: WooCommerce
*
* @package woocommerce-blocks-test-custom-add-to-cart-button-text
*/
/**
* Modifies the "Add to Cart" button text
*
*
* @return string The new text.
*/
function woocommerce_add_to_cart_button_text_archives() {
return 'Buy Now';
}

View File

@ -1,8 +1,11 @@
<?php
/**
* Plugin Name: Compatibility Layer Plugin
* Plugin Name: WooCommerce Blocks Test Product Collection Compatibility Layer
* Description: Adds custom content to the Shop page with Product Collection included
* @package WordPress
* Plugin URI: https://github.com/woocommerce/woocommerce
* Author: WooCommerce
*
* @package woocommerce-blocks-test-product-collection-compatibility-layer
*/
add_action(

View File

@ -1,8 +1,11 @@
<?php
/**
* Plugin Name: Compatibility Layer Plugin
* Plugin Name: WooCommerce Blocks Test Single Product Template Compatibility Layer
* Description: Adds custom content to the Shop page with Product Collection included
* @package WordPress
* Plugin URI: https://github.com/woocommerce/woocommerce
* Author: WooCommerce
*
* @package woocommerce-blocks-test-single-product-template-compatibility-layer
*/
add_action(

View File

@ -0,0 +1,17 @@
<?php
/**
* Plugin Name: WooCommerce Blocks Test Update Price
* Description: Update price of products.
* Plugin URI: https://github.com/woocommerce/woocommerce
* Author: WooCommerce
*
* @package woocommerce-blocks-test-update-price
*/
function calc_price( $cart_object ) {
foreach ( $cart_object->get_cart() as $hash => $value ) {
$value['data']->set_price( 50 );
}
}
add_action( 'woocommerce_before_calculate_totals', 'calc_price' );

View File

@ -4,7 +4,7 @@
import { test, expect } from '@woocommerce/e2e-playwright-utils';
import { customerFile, guestFile } from '@woocommerce/e2e-utils';
test.describe( 'Basic role-based functionality tests', async () => {
test.describe( 'Basic role-based functionality tests', () => {
test.describe( 'As admin', () => {
// Admin is the default user, so no need to set storage state.
test( 'Load Dashboard page', async ( { page } ) => {

View File

@ -21,7 +21,6 @@ const test = base.extend< { pageObject: CartPage } >( {
test.describe( 'Cart performance', () => {
test.beforeEach( async ( { frontendUtils } ) => {
await frontendUtils.goToShop();
await frontendUtils.emptyCart();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
} );

View File

@ -2,10 +2,6 @@
* External dependencies
*/
import { test as base, expect } from '@woocommerce/e2e-playwright-utils';
import {
installPluginFromPHPFile,
uninstallPluginFromPHPFile,
} from '@woocommerce/e2e-mocks/custom-plugins';
/**
* Internal dependencies
@ -33,7 +29,6 @@ test.describe( 'Shopper → Cart block', () => {
frontendUtils,
} ) => {
await frontendUtils.goToShop();
await frontendUtils.emptyCart();
await frontendUtils.addToCart( DISCOUNTED_PRODUCT_NAME );
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCart();
@ -68,13 +63,14 @@ test.describe( 'Shopper → Cart block', () => {
test( 'Products with updated prices should not display a discount label', async ( {
pageObject,
requestUtils,
frontendUtils,
} ) => {
await installPluginFromPHPFile(
`${ __dirname }/update-price-plugin.php`
await requestUtils.activatePlugin(
'woocommerce-blocks-test-update-price'
);
await frontendUtils.goToShop();
await frontendUtils.emptyCart();
await frontendUtils.addToCart( DISCOUNTED_PRODUCT_NAME );
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCart();
@ -125,17 +121,12 @@ test.describe( 'Shopper → Cart block', () => {
// Get the text content of the price element and check the price
const hoodiePriceText = await hoodiePriceElement.textContent();
expect( hoodiePriceText ).toBe( '$50.00' );
await uninstallPluginFromPHPFile(
`${ __dirname }/update-price-plugin.php`
);
} );
test( 'User can view empty cart message', async ( {
frontendUtils,
page,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToCart();
// Verify cart is empty
@ -257,7 +248,6 @@ test.describe( 'Shopper → Cart block', () => {
frontendUtils,
page,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCart();

View File

@ -26,21 +26,11 @@ test.describe( 'Shopper → Coupon', () => {
);
} );
test.afterEach( async ( { wpCliUtils } ) => {
const couponId = await wpCliUtils.getCouponIDByCode(
'single-use-coupon'
);
await cli(
`npm run wp-env run tests-cli -- wp wc shop_coupon delete ${ couponId } --force=1 --user=1`
);
} );
test( 'Logged in user can apply single-use coupon and place order', async ( {
checkoutPageObject,
frontendUtils,
page,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCart();
@ -89,7 +79,6 @@ test.describe( 'Shopper → Coupon', () => {
frontendUtils,
page,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCheckout();

View File

@ -33,20 +33,10 @@ test.describe( 'Shopper → Notice Templates', () => {
`npm run wp-env run tests-cli -- wp option update woocommerce_cart_page_id ${ cartShortcodeID }`
);
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
} );
test.afterEach( async ( { wpCliUtils, frontendUtils } ) => {
const cartID = await wpCliUtils.getPostIDByTitle( 'Cart Shortcode' );
await cli(
`npm run wp-env run tests-cli -- wp option update woocommerce_cart_page_id ${ cartID }`
);
await frontendUtils.emptyCart();
} );
test( 'default block notice templates are visible', async ( {
frontendUtils,
page,

View File

@ -34,20 +34,10 @@ test.describe( 'Shopper → Notice Templates', () => {
`npm run wp-env run tests-cli -- wp option update woocommerce_cart_page_id ${ cartShortcodeID }`
);
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
} );
test.afterEach( async ( { wpCliUtils, frontendUtils } ) => {
const cartID = await wpCliUtils.getPostIDByTitle( 'Cart Shortcode' );
await cli(
`npm run wp-env run tests-cli -- wp option update woocommerce_cart_page_id ${ cartID }`
);
await frontendUtils.emptyCart();
} );
test( 'default classic notice templates are visible', async ( {
frontendUtils,
page,

View File

@ -2,7 +2,7 @@
* External dependencies
*/
import { expect, test as base } from '@woocommerce/e2e-playwright-utils';
import { guestFile } from '@woocommerce/e2e-utils';
import { FrontendUtils } from '@woocommerce/e2e-utils';
/**
* Internal dependencies
@ -41,42 +41,52 @@ test.describe( 'Merchant → Shipping', () => {
} );
test.describe( 'Shopper → Shipping', () => {
test.use( { storageState: guestFile } );
test.beforeEach( async ( { shippingUtils } ) => {
await shippingUtils.enableShippingCostsRequireAddress();
} );
test( 'Guest user can see shipping calculator on cart page', async ( {
frontendUtils,
page,
requestUtils,
browser,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCart();
const guestContext = await browser.newContext();
const userPage = await guestContext.newPage();
const userFrontendUtils = new FrontendUtils( userPage, requestUtils );
await userFrontendUtils.goToShop();
await userFrontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await userFrontendUtils.goToCart();
await expect(
page.getByLabel( 'Add an address for shipping options' )
userPage.getByLabel( 'Add an address for shipping options' )
).toBeVisible();
} );
test( 'Guest user does not see shipping rates until full address is entered', async ( {
checkoutPageObject,
frontendUtils,
page,
requestUtils,
browser,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCheckout();
const guestContext = await browser.newContext();
const userPage = await guestContext.newPage();
const userFrontendUtils = new FrontendUtils( userPage, requestUtils );
const userCheckoutPageObject = new CheckoutPage( { page: userPage } );
await userFrontendUtils.goToShop();
await userFrontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await userFrontendUtils.goToCheckout();
await expect(
page.getByText(
userPage.getByText(
'Shipping options will be displayed here after entering your full shipping addres'
)
).toBeVisible();
await checkoutPageObject.fillInCheckoutWithTestData();
await userCheckoutPageObject.fillInCheckoutWithTestData();
await expect(
page.getByText(
userPage.getByText(
'Shipping options will be displayed here after entering your full shipping addres'
)
).toBeHidden();

View File

@ -19,22 +19,10 @@ const test = base.extend< { checkoutPageObject: CheckoutPage } >( {
} );
test.describe( 'Shopper → Translations', () => {
test.beforeAll( async () => {
await cli(
`npm run wp-env run tests-cli -- wp language core install nl_NL`
);
test.beforeEach( async () => {
await cli(
`npm run wp-env run tests-cli -- wp site switch-language nl_NL`
);
await cli(
`npm run wp-env run tests-cli -- wp language plugin install woocommerce nl_NL`
);
} );
test.afterAll( async () => {
await cli(
`npm run wp-env run tests-cli -- wp site switch-language en_US`
);
} );
test( 'User can view translated Cart block', async ( {

View File

@ -1,19 +0,0 @@
<?php
/**
* Plugin Name: Update Price
* Description: Update price of products
* @package WordPress
*/
/**
* Update price of products
*
* @param object $cart_object Cart object.
*/
function calc_price( $cart_object ) {
foreach ( $cart_object->get_cart() as $hash => $value ) {
$value['data']->set_price( 50 );
}
}
add_action( 'woocommerce_before_calculate_totals', 'calc_price' );

View File

@ -3,10 +3,6 @@
*/
import { expect, test as base } from '@woocommerce/e2e-playwright-utils';
import { guestFile } from '@woocommerce/e2e-utils';
import {
installPluginFromPHPFile,
uninstallPluginFromPHPFile,
} from '@woocommerce/e2e-mocks/custom-plugins';
/**
* Internal dependencies
@ -26,19 +22,12 @@ const test = base.extend< { checkoutPageObject: CheckoutPage } >( {
test.describe( 'Shopper → Additional Checkout Fields', () => {
test.describe( 'Guest shopper', () => {
test.use( { storageState: guestFile } );
test.beforeAll( async () => {
await installPluginFromPHPFile(
`${ __dirname }/additional-checkout-fields-plugin.php`
);
} );
test.afterAll( async () => {
await uninstallPluginFromPHPFile(
`${ __dirname }/additional-checkout-fields-plugin.php`
);
} );
test.beforeEach( async ( { frontendUtils } ) => {
await frontendUtils.emptyCart();
test.beforeEach( async ( { frontendUtils, requestUtils } ) => {
await requestUtils.activatePlugin(
'woocommerce-blocks-test-additional-checkout-fields'
);
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCheckout();

View File

@ -2,10 +2,6 @@
* External dependencies
*/
import { expect, test as base } from '@woocommerce/e2e-playwright-utils';
import {
installPluginFromPHPFile,
uninstallPluginFromPHPFile,
} from '@woocommerce/e2e-mocks/custom-plugins';
/**
* Internal dependencies
@ -23,19 +19,11 @@ const test = base.extend< { checkoutPageObject: CheckoutPage } >( {
} );
test.describe( 'Merchant → Additional Checkout Fields', () => {
test.beforeAll( async () => {
await installPluginFromPHPFile(
`${ __dirname }/additional-checkout-fields-plugin.php`
test.beforeEach( async ( { requestUtils, frontendUtils } ) => {
await requestUtils.activatePlugin(
'woocommerce-blocks-test-additional-checkout-fields'
);
} );
test.afterAll( async () => {
await uninstallPluginFromPHPFile(
`${ __dirname }/additional-checkout-fields-plugin.php`
);
} );
test.beforeEach( async ( { frontendUtils } ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCheckout();

View File

@ -3,10 +3,6 @@
*/
import { expect, test as base } from '@woocommerce/e2e-playwright-utils';
import { customerFile } from '@woocommerce/e2e-utils';
import {
installPluginFromPHPFile,
uninstallPluginFromPHPFile,
} from '@woocommerce/e2e-mocks/custom-plugins';
/**
* Internal dependencies
@ -26,19 +22,12 @@ const test = base.extend< { checkoutPageObject: CheckoutPage } >( {
test.describe( 'Shopper → Additional Checkout Fields', () => {
test.describe( 'Logged in shopper', () => {
test.use( { storageState: customerFile } );
test.beforeAll( async () => {
await installPluginFromPHPFile(
`${ __dirname }/additional-checkout-fields-plugin.php`
);
} );
test.afterAll( async () => {
await uninstallPluginFromPHPFile(
`${ __dirname }/additional-checkout-fields-plugin.php`
);
} );
test.beforeEach( async ( { frontendUtils } ) => {
await frontendUtils.emptyCart();
test.beforeEach( async ( { requestUtils, frontendUtils } ) => {
await requestUtils.activatePlugin(
'woocommerce-blocks-test-additional-checkout-fields'
);
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCheckout();

View File

@ -78,7 +78,7 @@ test.describe( 'Merchant → Checkout', () => {
} );
test.describe( 'Can adjust T&S and Privacy Policy options', () => {
test.beforeAll( async ( { browser } ) => {
test.beforeEach( async ( { browser } ) => {
const page = await browser.newPage();
await page.goto(
`${ process.env.WORDPRESS_BASE_URL }/?setup_terms_and_privacy`
@ -89,17 +89,6 @@ test.describe( 'Merchant → Checkout', () => {
await page.close();
} );
test.afterAll( async ( { browser } ) => {
const page = await browser.newPage();
await page.goto(
`${ process.env.WORDPRESS_BASE_URL }/?teardown_terms_and_privacy`
);
await expect(
page.getByText( 'Terms & Privacy pages teared down.' )
).toBeVisible();
await page.close();
} );
test( 'Merchant can see T&S and Privacy Policy links without checkbox', async ( {
frontendUtils,
checkoutPageObject,

View File

@ -43,7 +43,7 @@ const blockData: BlockData = {
test.describe( 'Shopper → Account (guest user)', () => {
test.use( { storageState: guestFile } );
test.beforeAll( async ( { requestUtils } ) => {
test.beforeEach( async ( { requestUtils, frontendUtils } ) => {
await requestUtils.rest( {
method: 'PUT',
path: 'wc/v3/settings/account/woocommerce_enable_guest_checkout',
@ -54,9 +54,7 @@ test.describe( 'Shopper → Account (guest user)', () => {
path: 'wc/v3/settings/account/woocommerce_enable_checkout_login_reminder',
data: { value: 'yes' },
} );
} );
test.beforeEach( async ( { frontendUtils } ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToCheckout();
@ -129,27 +127,11 @@ test.describe( 'Shopper → Local pickup', () => {
.click();
} );
test.afterEach( async ( { admin } ) => {
// Enable local pickup.
await admin.visitAdminPage(
'admin.php',
'page=wc-settings&tab=shipping&section=pickup_location'
);
await admin.page.getByRole( 'button', { name: 'Edit' } ).last().click();
await admin.page
.getByRole( 'button', { name: 'Delete location' } )
.click();
await admin.page
.getByRole( 'button', { name: 'Save changes' } )
.click();
} );
test( 'The shopper can choose a local pickup option', async ( {
page,
frontendUtils,
checkoutPageObject,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCheckout();
@ -172,7 +154,6 @@ test.describe( 'Shopper → Local pickup', () => {
frontendUtils,
checkoutPageObject,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCheckout();
@ -209,7 +190,6 @@ test.describe( 'Shopper → Payment Methods', () => {
frontendUtils,
page,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCheckout();
@ -257,62 +237,31 @@ test.describe( 'Shopper → Shipping and Billing Addresses', () => {
// `as string` is safe here because we know the variable is a string, it is defined above.
const blockSelectorInEditor = blockData.selectors.editor.block as string;
test.beforeEach(
async ( { editor, frontendUtils, admin, editorUtils, page } ) => {
await admin.visitSiteEditor( {
postId: 'woocommerce/woocommerce//page-checkout',
postType: 'wp_template',
} );
await editorUtils.enterEditMode();
await editor.openDocumentSettingsSidebar();
await editor.selectBlocks(
blockSelectorInEditor +
' [data-type="woocommerce/checkout-shipping-address-block"]'
);
test.beforeEach( async ( { editor, admin, editorUtils, page } ) => {
await admin.visitSiteEditor( {
postId: 'woocommerce/woocommerce//page-checkout',
postType: 'wp_template',
} );
await editorUtils.enterEditMode();
await editor.openDocumentSettingsSidebar();
await editor.selectBlocks(
blockSelectorInEditor +
' [data-type="woocommerce/checkout-shipping-address-block"]'
);
const checkbox = page.getByRole( 'checkbox', {
name: 'Company',
exact: true,
} );
await checkbox.check();
await expect( checkbox ).toBeChecked();
await expect(
editor.canvas.locator(
'div.wc-block-components-address-form__company'
)
).toBeVisible();
await editorUtils.saveSiteEditorEntities();
await frontendUtils.emptyCart();
}
);
test.afterEach(
async ( { frontendUtils, admin, editorUtils, editor, page } ) => {
await frontendUtils.emptyCart();
await admin.visitSiteEditor( {
postId: 'woocommerce/woocommerce//page-checkout',
postType: 'wp_template',
} );
await editorUtils.enterEditMode();
await editor.openDocumentSettingsSidebar();
await editor.selectBlocks(
blockSelectorInEditor +
' [data-type="woocommerce/checkout-shipping-address-block"]'
);
const checkbox = page.getByRole( 'checkbox', {
name: 'Company',
exact: true,
} );
await checkbox.uncheck();
await expect( checkbox ).not.toBeChecked();
await expect(
editor.canvas.locator(
'.wc-block-checkout__shipping-fields .wc-block-components-address-form__company'
)
).toBeHidden();
await editorUtils.saveSiteEditorEntities();
}
);
const checkbox = page.getByRole( 'checkbox', {
name: 'Company',
exact: true,
} );
await checkbox.check();
await expect( checkbox ).toBeChecked();
await expect(
editor.canvas.locator(
'div.wc-block-components-address-form__company'
)
).toBeVisible();
await editorUtils.saveSiteEditorEntities();
} );
test( 'User can add postcodes for different countries', async ( {
frontendUtils,
@ -342,7 +291,6 @@ test.describe( 'Shopper → Shipping (customer user)', () => {
page,
} ) => {
await frontendUtils.goToShop();
await frontendUtils.emptyCart();
await frontendUtils.addToCart( 'Beanie' );
await frontendUtils.goToCheckout();
await expect(
@ -414,7 +362,6 @@ test.describe( 'Shopper → Place Guest Order', () => {
frontendUtils,
page,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCheckout();
@ -433,7 +380,7 @@ test.describe( 'Shopper → Place Guest Order', () => {
} );
test.describe( 'Shopper → Place Virtual Order', () => {
test.beforeAll( async ( { requestUtils } ) => {
test.beforeEach( async ( { requestUtils } ) => {
await requestUtils.rest( {
method: 'PUT',
path: 'wc/v3/settings/general/woocommerce_ship_to_countries',
@ -441,14 +388,6 @@ test.describe( 'Shopper → Place Virtual Order', () => {
} );
} );
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.rest( {
method: 'PUT',
path: 'wc/v3/settings/general/woocommerce_ship_to_countries',
data: { value: 'all' },
} );
} );
test( 'can place a digital order when shipping is disabled', async ( {
checkoutPageObject,
frontendUtils,
@ -457,7 +396,6 @@ test.describe( 'Shopper → Place Virtual Order', () => {
} ) => {
await localPickupUtils.disableLocalPickup();
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCart();
@ -490,7 +428,6 @@ test.describe( 'Shopper → Place Virtual Order', () => {
} ) => {
await localPickupUtils.enableLocalPickup();
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCart();
@ -521,7 +458,6 @@ test.describe( 'Shopper → Checkout Form Errors (guest user)', () => {
frontendUtils,
page,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCheckout();
@ -554,36 +490,40 @@ test.describe( 'Shopper → Checkout Form Errors (guest user)', () => {
test.describe( 'Billing Address Form', () => {
const blockSelectorInEditor = blockData.selectors.editor.block as string;
test( 'Enable company field', async ( { editor, admin, editorUtils } ) => {
test( 'Enable company field', async ( {
page,
editor,
admin,
editorUtils,
} ) => {
await admin.visitSiteEditor( {
postId: 'woocommerce/woocommerce//page-checkout',
postType: 'wp_template',
canvas: 'edit',
} );
await editorUtils.enterEditMode();
await editor.openDocumentSettingsSidebar();
await editor.selectBlocks(
blockSelectorInEditor +
' [data-type="woocommerce/checkout-shipping-address-block"]'
);
const checkbox = editor.page.getByRole( 'checkbox', {
name: 'Company',
const companyCheckbox = page.getByLabel( 'Company', {
exact: true,
} );
await checkbox.check();
await expect( checkbox ).toBeChecked();
await expect(
editor.canvas.locator(
'div.wc-block-components-address-form__company'
)
).toBeVisible();
await companyCheckbox.check();
await expect( companyCheckbox ).toBeChecked();
const companyInput = editor.canvas.getByLabel( 'Company (optional)' );
await expect( companyInput ).toBeVisible();
await editorUtils.saveSiteEditorEntities();
} );
const shippingTestData = {
firstname: 'John',
lastname: 'Doe',
company: 'Automattic',
addressfirstline: '123 Easy Street',
addresssecondline: 'Testville',
country: 'United States (US)',
@ -595,7 +535,6 @@ test.describe( 'Billing Address Form', () => {
const billingTestData = {
first_name: '',
last_name: '',
company: '',
address_1: '',
address_2: '',
country: 'United States (US)',
@ -613,10 +552,10 @@ test.describe( 'Billing Address Form', () => {
page,
checkoutPageObject,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCheckout();
await checkoutPageObject.fillShippingDetails( shippingTestData );
await page.getByLabel( 'Use same address for billing' ).uncheck();
@ -675,10 +614,6 @@ test.describe( 'Billing Address Form', () => {
page.locator( '#billing-state input' )
).toHaveValue( value );
break;
default:
await expect(
page.locator( `#billing-${ key }` )
).toHaveValue( value );
}
}
} );

View File

@ -49,12 +49,7 @@ test.describe( 'Shopper → Order Confirmation (logged in user)', () => {
await editorUtils.transformIntoBlocks();
} );
test.afterEach( async ( { localPickupUtils } ) => {
await localPickupUtils.enableLocalPickup();
} );
test( 'Place order', async ( { frontendUtils, pageObject, page } ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.addToCart( SIMPLE_VIRTUAL_PRODUCT_NAME );
@ -131,7 +126,6 @@ test.describe( 'Shopper → Order Confirmation (guest user)', () => {
'User is not logged out'
).toBeVisible();
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_PHYSICAL_PRODUCT_NAME );
await frontendUtils.goToCheckout();
@ -203,7 +197,6 @@ test.describe( 'Shopper → Order Confirmation → Downloadable Products', () =>
let confirmationPageUrl: string;
test.beforeEach( async ( { frontendUtils, pageObject } ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( SIMPLE_VIRTUAL_PRODUCT_NAME );
await frontendUtils.goToCheckout();

View File

@ -4,7 +4,6 @@
import { BlockData } from '@woocommerce/e2e-types';
import { test, expect } from '@woocommerce/e2e-playwright-utils';
import { cli } from '@woocommerce/e2e-utils';
import { deleteAllTemplates } from '@wordpress/e2e-test-utils';
/**
* Internal dependencies
@ -14,94 +13,94 @@ const blockData: Partial< BlockData > = {
name: 'woocommerce/legacy-template',
};
const templates = {
'single-product': {
templateTitle: 'Single Product',
const templates = [
{
title: 'Single Product',
slug: 'single-product',
frontendPage: '/product/single/',
path: '/product/single/',
},
// This test is disabled because archives are disabled for attributes by default. This can be uncommented when this is toggled on.
//'taxonomy-product_attribute': {
// templateTitle: 'Product Attribute',
// This test is disabled because archives are disabled for attributes by
// default. This can be uncommented when this is toggled on.
//{
// title: 'Product Attribute',
// slug: 'taxonomy-product_attribute',
// frontendPage: '/product-attribute/color/',
// path: '/product-attribute/color/',
//},
'taxonomy-product_cat': {
templateTitle: 'Product Category',
{
title: 'Product Category',
slug: 'taxonomy-product_cat',
frontendPage: '/product-category/music/',
path: '/product-category/music/',
},
'taxonomy-product_tag': {
templateTitle: 'Product Tag',
{
title: 'Product Tag',
slug: 'taxonomy-product_tag',
frontendPage: '/product-tag/recommended/',
path: '/product-tag/recommended/',
},
'archive-product': {
templateTitle: 'Product Catalog',
{
title: 'Product Catalog',
slug: 'archive-product',
frontendPage: '/shop/',
path: '/shop/',
},
'product-search-results': {
templateTitle: 'Product Search Results',
{
title: 'Product Search Results',
slug: 'product-search-results',
frontendPage: '/?s=s&post_type=product',
path: '/?s=s&post_type=product',
},
};
];
test.beforeAll( async () => {
await cli(
'npm run wp-env run tests-cli -- wp option update wc_blocks_use_blockified_product_grid_block_as_template false'
);
await deleteAllTemplates( 'wp_template' );
} );
test.describe( `${ blockData.name } Block `, () => {
test.beforeEach( async () => {
await cli(
'npm run wp-env run tests-cli -- wp option update wc_blocks_use_blockified_product_grid_block_as_template false'
);
} );
test.afterAll( async () => {
await cli(
'npm run wp-env run tests-cli -- wp option delete wc_blocks_use_blockified_product_grid_block_as_template'
);
await deleteAllTemplates( 'wp_template' );
} );
for ( const { templateTitle, slug } of Object.values( templates ) ) {
test.describe( `${ blockData.name } Block `, () => {
test( `is rendered on ${ templateTitle } template`, async ( {
for ( const template of templates ) {
test( `is rendered on ${ template.title } template`, async ( {
admin,
editorUtils,
editor,
} ) => {
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ slug }`,
postId: `woocommerce/woocommerce//${ template.slug }`,
postType: 'wp_template',
canvas: 'edit',
} );
await editorUtils.enterEditMode();
const block = await editorUtils.getBlockByName( blockData.name );
const block = editor.canvas.locator(
`[data-type="${ blockData.name }"]`
);
await expect( block ).toBeVisible();
} );
// These tests consistently fail due to the default content of the page--potentially the classic block is not being
// used after another test runs. Reenable this when we have a solution for this.
// These tests consistently fail due to the default content of the
// page--potentially the classic block is not being used after
// another test runs. Reenable this when we have a solution for
// this.
// eslint-disable-next-line playwright/no-skipped-test
test.skip( `is rendered on ${ templateTitle } template - frontend side`, async ( {
test.skip( `is rendered on ${ template.title } template - frontend side`, async ( {
admin,
editor,
editorUtils,
page,
} ) => {
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ slug }`,
postId: `woocommerce/woocommerce//${ template.slug }`,
postType: 'wp_template',
canvas: 'edit',
} );
await editorUtils.enterEditMode();
await editor.insertBlock( {
name: 'core/paragraph',
attributes: { content: 'Hello World' },
} );
await editor.saveSiteEditorEntities();
await page.goto( frontendPage );
await page.goto( template.path );
await expect(
page.getByText( 'Hello World' ).first()
).toBeVisible();
} );
} );
}
}
} );

View File

@ -22,7 +22,7 @@ const test = base.extend< {
},
} );
test.describe( 'Product Filter: Active Filters Block', async () => {
test.describe( 'Product Filter: Active Filters Block', () => {
test.describe( 'frontend', () => {
test( 'Without any filters selected, only a wrapper block is rendered', async ( {
page,

View File

@ -70,7 +70,7 @@ const test = base.extend< {
},
} );
test.describe( 'Product Filter: Attribute Block', async () => {
test.describe( 'Product Filter: Attribute Block', () => {
test.describe( 'With default display style', () => {
test.describe( 'With show counts enabled', () => {
test( 'Renders checkboxes with associated product counts', async ( {

View File

@ -31,7 +31,7 @@ const filterBlocks = [
},
];
test.describe( 'Filter blocks registration', async () => {
test.describe( 'Filter blocks registration', () => {
test.beforeEach( async ( { admin } ) => {
await admin.createNewPost();
} );

View File

@ -22,7 +22,7 @@ const test = base.extend< {
},
} );
test.describe( 'Product Filter: Price Filter Block', async () => {
test.describe( 'Product Filter: Price Filter Block', () => {
test.describe( 'frontend', () => {
test( 'With price filters applied it shows the correct price', async ( {
page,

View File

@ -22,7 +22,7 @@ const test = base.extend< {
},
} );
test.describe( 'Product Filter: Rating Filter Block', async () => {
test.describe( 'Product Filter: Rating Filter Block', () => {
test.describe( 'frontend', () => {
test( 'Renders a checkbox list with the available ratings', async ( {
page,

View File

@ -38,7 +38,7 @@ const test = base.extend< {
},
} );
test.describe( 'Product Filter: Stock Status Block', async () => {
test.describe( 'Product Filter: Stock Status Block', () => {
test.describe( 'With default display style', () => {
test( 'renders a checkbox list with the available stock statuses', async ( {
page,

View File

@ -25,11 +25,6 @@ test.describe( 'Merchant → Local Pickup Settings', () => {
await localPickupUtils.enableLocalPickup();
} );
test.afterEach( async ( { localPickupUtils } ) => {
await localPickupUtils.deleteLocations();
await localPickupUtils.setLocalPickupTitle( 'Local Pickup' );
} );
test( 'Updating the title in WC Settings updates the local pickup text in the block and vice/versa', async ( {
page,
localPickupUtils,

View File

@ -19,12 +19,6 @@ const blockData: BlockData = {
test.describe( 'Merchant → Mini Cart', () => {
test.describe( 'in FSE editor', () => {
test.afterAll( async ( { templateApiUtils } ) => {
await templateApiUtils.revertTemplate(
'woocommerce/woocommerce//single-product'
);
} );
test( 'can be inserted in FSE area', async ( {
editorUtils,
editor,

View File

@ -10,22 +10,10 @@ import { cli } from '@woocommerce/e2e-utils';
import { REGULAR_PRICED_PRODUCT_NAME } from '../checkout/constants';
test.describe( 'Shopper → Translations', () => {
test.beforeAll( async () => {
await cli(
`npm run wp-env run tests-cli -- wp language core install nl_NL`
);
test.beforeEach( async () => {
await cli(
`npm run wp-env run tests-cli -- wp site switch-language nl_NL`
);
await cli(
`npm run wp-env run tests-cli -- wp language plugin install woocommerce nl_NL`
);
} );
test.afterAll( async () => {
await cli(
`npm run wp-env run tests-cli -- wp site switch-language en_US`
);
} );
test( 'User can see translation in empty Mini-Cart', async ( {
@ -33,7 +21,6 @@ test.describe( 'Shopper → Translations', () => {
frontendUtils,
miniCartUtils,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await miniCartUtils.openMiniCart();
@ -70,7 +57,7 @@ test.describe( 'Shopper → Translations', () => {
} );
test.describe( 'Shopper → Tax', () => {
test.beforeAll( async () => {
test.beforeEach( async () => {
await cli(
`npm run wp-env run tests-cli -- wp option set woocommerce_prices_include_tax no`
);
@ -79,20 +66,10 @@ test.describe( 'Shopper → Tax', () => {
);
} );
test.afterAll( async () => {
await cli(
`npm run wp-env run tests-cli -- wp option set woocommerce_prices_include_tax yes`
);
await cli(
`npm run wp-env run tests-cli -- wp option set woocommerce_tax_display_cart excl`
);
} );
test( 'User can see tax label and price including tax', async ( {
frontendUtils,
page,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await frontendUtils.goToMiniCart();

View File

@ -112,7 +112,6 @@ test.describe( `${ blockData.name } Block`, () => {
frontendUtils,
miniCartUtils,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await miniCartUtils.openMiniCart();
@ -135,7 +134,6 @@ test.describe( `${ blockData.name } Block`, () => {
frontendUtils,
miniCartUtils,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await miniCartUtils.openMiniCart();
@ -150,7 +148,6 @@ test.describe( `${ blockData.name } Block`, () => {
frontendUtils,
miniCartUtils,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await miniCartUtils.openMiniCart();
@ -171,7 +168,6 @@ test.describe( `${ blockData.name } Block`, () => {
frontendUtils,
miniCartUtils,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await miniCartUtils.openMiniCart();
@ -206,7 +202,6 @@ test.describe( `${ blockData.name } Block`, () => {
frontendUtils,
miniCartUtils,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await miniCartUtils.openMiniCart();
@ -229,7 +224,6 @@ test.describe( `${ blockData.name } Block`, () => {
frontendUtils,
miniCartUtils,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await miniCartUtils.openMiniCart();
@ -242,7 +236,6 @@ test.describe( `${ blockData.name } Block`, () => {
frontendUtils,
miniCartUtils,
} ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
await miniCartUtils.openMiniCart();

View File

@ -72,22 +72,13 @@ const getBoundingClientRect = async ( {
};
test.describe( `${ blockData.name }`, () => {
test.describe( `On the Single Product Template`, () => {
test.beforeEach(
async ( { requestUtils, admin, editorUtils, editor } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ blockData.slug }`,
postType: 'wp_template',
} );
await editorUtils.enterEditMode();
await editor.setContent( '' );
}
);
test.afterEach( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
test.beforeEach( async ( { admin, editorUtils, editor } ) => {
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ blockData.slug }`,
postType: 'wp_template',
} );
await editorUtils.enterEditMode();
await editor.setContent( '' );
} );
test( 'should be rendered on the editor side', async ( {

View File

@ -9,6 +9,7 @@ import type { FrontendUtils } from '@woocommerce/e2e-utils';
const templates = [
{
title: 'Cart',
slug: 'cart',
blockClassName: '.wc-block-cart',
visitPage: async ( {
frontendUtils,
@ -20,6 +21,7 @@ const templates = [
},
{
title: 'Checkout',
slug: 'checkout',
blockClassName: '.wc-block-checkout',
visitPage: async ( {
frontendUtils,
@ -35,21 +37,26 @@ const templates = [
const userText = 'Hello World in the page';
templates.forEach( async ( template ) => {
test.describe( 'Page Content Wrapper', async () => {
test.beforeAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
} );
test.describe( 'Page Content Wrapper', () => {
test( `the content of the ${ template.title } page is correctly rendered in the ${ template.title } template`, async ( {
admin,
page,
admin,
editorUtils,
frontendUtils,
requestUtils,
} ) => {
await admin.visitAdminPage( 'edit.php?post_type=page' );
await page.getByLabel( `${ template.title }” (Edit)` ).click();
const pageData = await requestUtils.rest( {
path: 'wp/v2/pages?slug=' + template.slug,
} );
const pageId = pageData[ 0 ].id;
// Prevent trying to insert the paragraph block before the editor is ready.
await page.locator( template.blockClassName ).waitFor();
await admin.editPost( pageId );
// Prevent trying to insert the paragraph block before the editor is
// ready.
await expect(
page.locator( template.blockClassName )
).toBeVisible();
await editorUtils.editor.insertBlock( {
name: 'core/paragraph',
@ -61,18 +68,6 @@ templates.forEach( async ( template ) => {
// Verify edits are in the template when viewed from the frontend.
await template.visitPage( { frontendUtils } );
await expect( page.getByText( userText ).first() ).toBeVisible();
// Clean up the paragraph block added before.
await admin.visitAdminPage( 'edit.php?post_type=page' );
await page.getByLabel( `${ template.title }” (Edit)` ).click();
// Prevent trying to insert the paragraph block before the editor is ready.
await page.locator( template.blockClassName ).waitFor();
await editorUtils.removeBlocks( {
name: 'core/paragraph',
} );
await editorUtils.updatePost();
} );
} );
} );

View File

@ -131,12 +131,11 @@ test.describe( `${ blockData.name } Block - with All products Block`, () => {
} );
// These tests are disabled because there is an issue with the default contents of this page, possible caused by other tests.
test.describe( `${ blockData.name } Block - with PHP classic template`, () => {
test.beforeAll( async () => {
test.beforeEach( async ( { admin, page, editor } ) => {
await cli(
'npm run wp-env run tests-cli -- wp option update wc_blocks_use_blockified_product_grid_block_as_template false'
);
} );
test.beforeEach( async ( { admin, page, editor } ) => {
await admin.visitSiteEditor( {
postId: 'woocommerce/woocommerce//archive-product',
postType: 'wp_template',
@ -155,12 +154,6 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => {
await page.goto( `/shop` );
} );
test.afterEach( async ( { templateApiUtils } ) => {
await templateApiUtils.revertTemplate(
'woocommerce/woocommerce//archive-product'
);
} );
test( 'should show all products', async ( { frontendUtils } ) => {
const legacyTemplate = await frontendUtils.getBlockByName(
'woocommerce/legacy-template'
@ -201,10 +194,4 @@ test.describe( `${ blockData.name } Block - with PHP classic template`, () => {
await expect( products ).toHaveCount( 1 );
} );
test.afterAll( async () => {
await cli(
'npm run wp-env run tests-cli -- wp option delete wc_blocks_use_blockified_product_grid_block_as_template'
);
} );
} );

View File

@ -2,10 +2,6 @@
* External dependencies
*/
import { expect, test } from '@woocommerce/e2e-playwright-utils';
import {
installPluginFromPHPFile,
uninstallPluginFromPHPFile,
} from '@woocommerce/e2e-mocks/custom-plugins';
/**
* Internal dependencies
@ -13,11 +9,7 @@ import {
import { blockData, handleAddToCartAjaxSetting } from './utils';
test.describe( `${ blockData.name } Block`, () => {
test.beforeAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
} );
test.beforeEach( async ( { frontendUtils, storeApiUtils } ) => {
await storeApiUtils.cleanCart();
test.beforeEach( async ( { frontendUtils } ) => {
await frontendUtils.goToShop();
} );
@ -120,10 +112,11 @@ test.describe( `${ blockData.name } Block`, () => {
} );
test( 'the filter `woocommerce_product_add_to_cart_text` should be applied', async ( {
requestUtils,
frontendUtils,
} ) => {
await installPluginFromPHPFile(
`${ __dirname }/update-product-button-text.php`
await requestUtils.activatePlugin(
'woocommerce-blocks-test-custom-add-to-cart-button-text'
);
await frontendUtils.goToShop();
const blocks = await frontendUtils.getBlockByName( blockData.slug );
@ -132,11 +125,4 @@ test.describe( `${ blockData.name } Block`, () => {
blockData.selectors.frontend.productsToDisplay
);
} );
test.afterAll( async ( { storeApiUtils } ) => {
await storeApiUtils.cleanCart();
await uninstallPluginFromPHPFile(
`${ __dirname }/update-product-button-text.php`
);
} );
} );

View File

@ -2,10 +2,6 @@
* External dependencies
*/
import { test as base, expect } from '@woocommerce/e2e-playwright-utils';
import {
installPluginFromPHPFile,
uninstallPluginFromPHPFile,
} from '@woocommerce/e2e-mocks/custom-plugins';
/**
* Internal dependencies
@ -79,7 +75,6 @@ const multipleOccurrenceScenarios: Scenario[] = [
},
];
const compatibilityPluginFileName = 'compatibility-plugin.php';
const test = base.extend< { pageObject: ProductCollectionPage } >( {
pageObject: async (
{ page, admin, editor, templateApiUtils, editorUtils },
@ -97,14 +92,12 @@ const test = base.extend< { pageObject: ProductCollectionPage } >( {
} );
test.describe( 'Compatibility Layer with Product Collection block', () => {
test.beforeAll( async () => {
await installPluginFromPHPFile(
`${ __dirname }/${ compatibilityPluginFileName }`
);
} );
test.describe( 'Product Archive with Product Collection block', () => {
test.beforeEach( async ( { pageObject, requestUtils } ) => {
await requestUtils.activatePlugin(
'woocommerce-blocks-test-product-collection-compatibility-layer'
);
test.describe( 'Product Archive with Product Collection block', async () => {
test.beforeEach( async ( { pageObject } ) => {
await pageObject.replaceProductsWithProductCollectionInTemplate(
'woocommerce/woocommerce//archive-product'
);
@ -133,11 +126,4 @@ test.describe( 'Compatibility Layer with Product Collection block', () => {
} );
}
} );
test.afterAll( async ( { requestUtils } ) => {
await uninstallPluginFromPHPFile(
`${ __dirname }/${ compatibilityPluginFileName }`
);
await requestUtils.deleteAllTemplates( 'wp_template' );
} );
} );

View File

@ -47,7 +47,7 @@ test.describe( 'Product Collection', () => {
await expect( pageObject.addToCartButtons ).toHaveCount( 9 );
} );
test.describe( 'Renders correctly with all Product Elements', async () => {
test.describe( 'Renders correctly with all Product Elements', () => {
const insertProductElements = async (
pageObject: ProductCollectionPage
) => {
@ -177,21 +177,23 @@ test.describe( 'Product Collection', () => {
test( 'Order By - sort products by title in descending order correctly', async ( {
pageObject,
} ) => {
await pageObject.setOrderBy( 'title/desc' );
const allTitles = await pageObject.productTitles.allInnerTexts();
const expectedTitles = [ ...allTitles ].sort().reverse();
const sortedTitles = [
'WordPress Pennant',
'V-Neck T-Shirt',
'T-Shirt with Logo',
'T-Shirt',
/Sunglasses/, // In the frontend it's "Protected: Sunglasses"
'Single',
'Polo',
'Long Sleeve Tee',
'Logo Collection',
];
expect( allTitles ).toStrictEqual( expectedTitles );
await pageObject.setOrderBy( 'title/desc' );
await expect( pageObject.productTitles ).toHaveText( sortedTitles );
await pageObject.publishAndGoToFrontend();
const frontendTitles =
await pageObject.productTitles.allInnerTexts();
expect(
frontendTitles.map( ( title ) =>
title.replace( 'Protected: ', '' )
)
).toStrictEqual( expectedTitles );
await expect( pageObject.productTitles ).toHaveText( sortedTitles );
} );
// Products can be filtered based on 'on sale' status.

View File

@ -87,9 +87,7 @@ const test = base.extend< { pageObject: ProductGalleryPage } >( {
} );
test.describe( `${ blockData.name }`, () => {
test.beforeEach( async ( { requestUtils, admin, editorUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
test.beforeEach( async ( { admin, editorUtils } ) => {
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ blockData.slug }`,
postType: 'wp_template',
@ -97,11 +95,6 @@ test.describe( `${ blockData.name }`, () => {
await editorUtils.enterEditMode();
} );
test.afterEach( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
// eslint-disable-next-line playwright/no-skipped-test
test.skip( 'Renders Next/Previous Button block on the editor side', async ( {
editor,
@ -160,28 +153,26 @@ test.describe( `${ blockData.name }`, () => {
.locator( blockData.selectors.editor.noArrowsOption )
.click();
const isVisible = await page
.locator(
'.wc-block-product-gallery-large-image-next-previous-container'
)
.isVisible();
const container = page.locator(
'.wc-block-product-gallery-large-image-next-previous-container'
);
expect( isVisible ).toBe( false );
await expect( container ).toBeHidden();
await editor.saveSiteEditorEntities();
await page.goto( blockData.productPage );
const leftArrow = await page
.locator( blockData.selectors.editor.leftArrow.off )
.isVisible();
const leftArrow = page.locator(
blockData.selectors.editor.leftArrow.off
);
const rightArrow = await page
.locator( blockData.selectors.editor.rightArrow.off )
.isVisible();
const rightArrow = page.locator(
blockData.selectors.editor.rightArrow.off
);
expect( leftArrow ).toBe( false );
expect( rightArrow ).toBe( false );
await expect( leftArrow ).toBeHidden();
await expect( rightArrow ).toBeHidden();
} );
// eslint-disable-next-line playwright/no-skipped-test

View File

@ -31,9 +31,7 @@ const test = base.extend< { pageObject: ProductGalleryPage } >( {
} );
test.describe( `${ blockData.name }`, () => {
test.beforeEach( async ( { requestUtils, admin, editorUtils, editor } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
test.beforeEach( async ( { admin, editorUtils, editor } ) => {
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ blockData.slug }`,
postType: 'wp_template',
@ -42,11 +40,6 @@ test.describe( `${ blockData.name }`, () => {
await editor.openDocumentSettingsSidebar();
} );
test.afterEach( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
test( 'Renders Product Gallery Large Image block on the editor and frontend side', async ( {
page,
editor,

View File

@ -44,11 +44,6 @@ const test = base.extend< { pageObject: ProductGalleryPage } >( {
} );
test.describe( `${ blockData.name }`, () => {
test.beforeAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
test.beforeEach( async ( { admin, editorUtils, editor } ) => {
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ blockData.slug }`,
@ -58,11 +53,6 @@ test.describe( `${ blockData.name }`, () => {
await editor.openDocumentSettingsSidebar();
} );
test.afterEach( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
test( 'Renders Product Gallery Pager block on the editor and frontend side', async ( {
page,
editor,

View File

@ -48,9 +48,7 @@ const test = base.extend< { pageObject: ProductGalleryPage } >( {
},
} );
test.describe( `${ blockData.name }`, () => {
test.beforeEach( async ( { requestUtils, admin, editorUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
test.beforeEach( async ( { admin, editorUtils } ) => {
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ blockData.slug }`,
postType: 'wp_template',
@ -143,11 +141,11 @@ test.describe( `${ blockData.name }`, () => {
.locator( blockData.selectors.editor.noThumbnailsOption )
.click();
const isVisible = await page
.locator( blockData.selectors.editor.thumbnails )
.isVisible();
const element = page.locator(
blockData.selectors.editor.thumbnails
);
expect( isVisible ).toBe( false );
await expect( element ).toBeHidden();
await editor.saveSiteEditorEntities();

View File

@ -83,9 +83,7 @@ const getThumbnailImageIdByNth = async (
};
test.describe( `${ blockData.name }`, () => {
test.beforeEach( async ( { requestUtils, admin, editorUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
test.beforeEach( async ( { admin, editorUtils } ) => {
await admin.visitSiteEditor( {
postId: `woocommerce/woocommerce//${ blockData.slug }`,
postType: 'wp_template',
@ -93,11 +91,6 @@ test.describe( `${ blockData.name }`, () => {
await editorUtils.enterEditMode();
} );
test.afterEach( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
test.describe( 'with thumbnails', () => {
test( 'should have as first thumbnail, the same image that it is visible in the Large Image block', async ( {
page,
@ -570,6 +563,7 @@ test.describe( `${ blockData.name }`, () => {
editor,
pageObject,
} ) => {
await editor.openDocumentSettingsSidebar();
await pageObject.addProductGalleryBlock( { cleanContent: true } );
await page

View File

@ -123,10 +123,6 @@ for ( const {
legacyBlockName,
} of Object.values( templates ) ) {
test.describe( `${ templateTitle } template`, () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
test( 'Products block matches with classic template block', async ( {
admin,
editor,

View File

@ -2,10 +2,6 @@
* External dependencies
*/
import { test, expect } from '@woocommerce/e2e-playwright-utils';
import {
installPluginFromPHPFile,
uninstallPluginFromPHPFile,
} from '@woocommerce/e2e-mocks/custom-plugins';
/**
* Internal dependencies
@ -87,24 +83,20 @@ const singleOccurranceScenarios: Scenario[] = [
},
];
const compatiblityPluginFileName = 'compatibility-plugin.php';
test.describe( 'Compatibility Layer with Product Collection block', () => {
test.beforeAll( async () => {
await installPluginFromPHPFile(
`${ __dirname }/${ compatiblityPluginFileName }`
test.beforeEach( async ( { requestUtils } ) => {
await requestUtils.activatePlugin(
'woocommerce-blocks-test-single-product-template-compatibility-layer'
);
} );
// eslint-disable-next-line playwright/valid-describe-callback
test.describe( 'Product Archive with Product Collection block', async () => {
test.beforeAll( async ( { page } ) => {
await page.goto( '/product/hoodie/' );
} );
for ( const scenario of singleOccurranceScenarios ) {
test( `${ scenario.title } is attached to the page`, async ( {
page,
} ) => {
await page.goto( '/product/hoodie/' );
const hooks = page.getByTestId( scenario.dataTestId );
await expect( hooks ).toHaveCount( scenario.amount );
@ -113,10 +105,3 @@ test.describe( 'Compatibility Layer with Product Collection block', () => {
}
} );
} );
test.afterAll( async ( { requestUtils } ) => {
await uninstallPluginFromPHPFile(
`${ __dirname }/${ compatiblityPluginFileName }`
);
await requestUtils.deleteAllTemplates( 'wp_template' );
} );

View File

@ -41,7 +41,7 @@ const products = [
];
for ( const { classes, product, frontendPage } of products ) {
test.describe( `The Single Product page of the ${ product }`, () =>
test.describe( `The Single Product page of the ${ product }`, () => {
test( 'add product specific classes to the body', async ( {
page,
} ) => {
@ -52,7 +52,8 @@ for ( const { classes, product, frontendPage } of products ) {
classes.forEach( ( className ) => {
expect( bodyClasses?.split( ' ' ) ).toContain( className );
} );
} ) );
} );
} );
}
test( 'shows password form in products protected with password', async ( {

View File

@ -7,7 +7,7 @@ const permalink = '/cart';
const templatePath = 'woocommerce/woocommerce//page-cart';
const templateType = 'wp_template';
test.describe( 'Test the cart template', async () => {
test.describe( 'Test the cart template', () => {
test( 'Template can be opened in the site editor', async ( {
admin,
page,
@ -32,7 +32,7 @@ test.describe( 'Test the cart template', async () => {
page,
editorUtils,
} ) => {
await admin.visitAdminPage( 'site-editor.php', 'path=%2Fpage' );
await admin.visitSiteEditor( { path: '/page' } );
await editor.page
.getByRole( 'button', { name: 'Cart', exact: true } )
.click();
@ -63,12 +63,7 @@ test.describe( 'Test the cart template', async () => {
} );
} );
test.describe( 'Test editing the cart template', async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
test.describe( 'Test editing the cart template', () => {
test( 'Merchant can transform shortcode block into blocks', async ( {
admin,
editorUtils,

View File

@ -7,7 +7,7 @@ const permalink = '/checkout';
const templatePath = 'woocommerce/woocommerce//page-checkout';
const templateType = 'wp_template';
test.describe( 'Test the checkout template', async () => {
test.describe( 'Test the checkout template', () => {
test( 'Template can be opened in the site editor', async ( {
admin,
page,
@ -36,7 +36,7 @@ test.describe( 'Test the checkout template', async () => {
postId: templatePath,
postType: templateType,
} );
await admin.visitAdminPage( 'site-editor.php', 'path=%2Fpage' );
await admin.visitSiteEditor( { path: '/page' } );
await editor.page
.getByRole( 'button', { name: 'Checkout', exact: true } )
.click();
@ -72,12 +72,7 @@ test.describe( 'Test the checkout template', async () => {
} );
} );
test.describe( 'Test editing the checkout template', async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
await requestUtils.deleteAllTemplates( 'wp_template_part' );
} );
test.describe( 'Test editing the checkout template', () => {
test( 'Merchant can transform shortcode block into blocks', async ( {
admin,
editorUtils,

View File

@ -87,7 +87,6 @@ export const CUSTOMIZABLE_WC_TEMPLATES: TemplateCustomizationTest[] = [
},
{
visitPage: async ( { frontendUtils } ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart();
const block = await frontendUtils.getBlockByName(
@ -110,7 +109,6 @@ export const CUSTOMIZABLE_WC_TEMPLATES: TemplateCustomizationTest[] = [
},
{
visitPage: async ( { frontendUtils } ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart();
await frontendUtils.goToCheckout();
@ -122,7 +120,6 @@ export const CUSTOMIZABLE_WC_TEMPLATES: TemplateCustomizationTest[] = [
},
{
visitPage: async ( { frontendUtils } ) => {
await frontendUtils.emptyCart();
await frontendUtils.goToShop();
await frontendUtils.addToCart();
await frontendUtils.goToCheckout();

View File

@ -4,12 +4,8 @@
import { test, expect } from '@woocommerce/e2e-playwright-utils';
import { cli } from '@woocommerce/e2e-utils';
test.describe( 'Legacy templates', async () => {
test.beforeAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
} );
test.afterEach( async ( { requestUtils } ) => {
test.describe( 'Legacy templates', () => {
test.beforeEach( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
} );

View File

@ -3,7 +3,7 @@
*/
import { test, expect } from '@woocommerce/e2e-playwright-utils';
test.describe( 'Test the order confirmation template', async () => {
test.describe( 'Test the order confirmation template', () => {
test( 'Template can be opened in the site editor', async ( {
page,
editorUtils,

View File

@ -4,7 +4,7 @@
import { test, expect } from '@woocommerce/e2e-playwright-utils';
import { cli } from '@woocommerce/e2e-utils';
test.describe( 'Shop page', async () => {
test.describe( 'Shop page', () => {
test( 'template selector is not visible in the Page editor', async ( {
admin,
page,
@ -14,7 +14,10 @@ test.describe( 'Shop page', async () => {
`npm run wp-env run tests-cli -- wp option get woocommerce_shop_page_id`
);
const numberMatch = cliOutput.stdout.match( /\d+/ );
expect( numberMatch ).not.toBeNull();
// eslint-disable-next-line playwright/no-conditional-in-test
if ( numberMatch === null ) {
throw new Error( 'Shop page ID not found' );
}
await admin.editPost( numberMatch[ 0 ] );

View File

@ -3,11 +3,7 @@
*/
import { test, expect } from '@woocommerce/e2e-playwright-utils';
test.describe( 'Single Product template', async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
} );
test.describe( 'Single Product template', () => {
test( 'loads the Single Product template for a specific product', async ( {
admin,
editor,
@ -24,10 +20,7 @@ test.describe( 'Single Product template', async () => {
const userText = 'Hello World in the Belt template';
// Create the specific product template.
await admin.visitAdminPage(
'site-editor.php',
`path=/${ testData.templateType }`
);
await admin.visitSiteEditor( { path: `/${ testData.templateType }` } );
await page.getByLabel( 'Add New Template' ).click();
await page
.getByRole( 'button', { name: 'Single item: Product' } )
@ -52,10 +45,9 @@ test.describe( 'Single Product template', async () => {
await expect( page.getByText( userText ).first() ).toBeVisible();
// Revert edition.
await admin.visitAdminPage(
'site-editor.php',
`path=/${ testData.templateType }/all`
);
await admin.visitSiteEditor( {
path: `/${ testData.templateType }/all`,
} );
await editorUtils.revertTemplateCreation( testData.templateName );
await page.goto( testData.permalink );

View File

@ -18,11 +18,7 @@ const testData = {
const userText = 'Hello World in the Belt template';
const themeTemplateText = 'Single Product Belt template loaded from theme';
test.describe( 'Single Product Template', async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( 'wp_template' );
} );
test.describe( 'Single Product Template', () => {
test( 'loads the theme template for a specific product using the product slug and it can be customized', async ( {
admin,
editor,
@ -48,10 +44,9 @@ test.describe( 'Single Product Template', async () => {
await expect( page.getByText( userText ).first() ).toBeVisible();
// Revert edition and verify the template from the theme is used.
await admin.visitAdminPage(
'site-editor.php',
`path=/${ testData.templateType }/all`
);
await admin.visitSiteEditor( {
path: `/${ testData.templateType }/all`,
} );
await editorUtils.revertTemplateCustomizations( testData.templateName );
await page.goto( testData.permalink );

View File

@ -20,11 +20,7 @@ for ( const testData of testToRun ) {
const userText = `Hello World in the ${ testData.templateName } template`;
const woocommerceTemplateUserText = `Hello World in the WooCommerce ${ testData.templateName } template`;
test.describe( `${ testData.templateName } template`, async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( testData.templateType );
} );
test.describe( `${ testData.templateName } template`, () => {
test( `user-modified ${ testData.templateName } template based on the theme template has priority over the user-modified template based on the default WooCommerce template`, async ( {
page,
admin,
@ -73,10 +69,9 @@ for ( const testData of testToRun ) {
// `deleteAllTemplates()`). This way, we verify there are no
// duplicate templates with the same name.
// See: https://github.com/woocommerce/woocommerce/issues/42220
await admin.visitAdminPage(
'site-editor.php',
`path=/${ testData.templateType }/all`
);
await admin.visitSiteEditor( {
path: `/${ testData.templateType }/all`,
} );
await editorUtils.revertTemplateCustomizations(
testData.templateName
);

View File

@ -14,11 +14,7 @@ CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => {
const templateTypeName =
testData.templateType === 'wp_template' ? 'template' : 'template part';
test.describe( `${ testData.templateName } template`, async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( testData.templateType );
} );
test.describe( `${ testData.templateName } template`, () => {
test( 'can be modified and reverted', async ( {
admin,
frontendUtils,
@ -48,10 +44,9 @@ CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => {
await expect( page.getByText( userText ).first() ).toBeVisible();
// Verify the edition can be reverted.
await admin.visitAdminPage(
'site-editor.php',
`path=/${ testData.templateType }/all`
);
await admin.visitSiteEditor( {
path: `/${ testData.templateType }/all`,
} );
await editorUtils.revertTemplateCustomizations(
testData.templateName
);
@ -85,10 +80,9 @@ CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => {
).toBeVisible();
// Verify the edition can be reverted.
await admin.visitAdminPage(
'site-editor.php',
`path=/${ testData.templateType }/all`
);
await admin.visitSiteEditor( {
path: `/${ testData.templateType }/all`,
} );
await editorUtils.revertTemplateCustomizations(
testData.fallbackTemplate?.templateName || ''
);

View File

@ -17,11 +17,7 @@ CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => {
const templateTypeName =
testData.templateType === 'wp_template' ? 'template' : 'template part';
test.describe( `${ testData.templateName } template`, async () => {
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.deleteAllTemplates( testData.templateType );
} );
test.describe( `${ testData.templateName } template`, () => {
test( "theme template has priority over WooCommerce's and can be modified", async ( {
admin,
editor,
@ -52,10 +48,9 @@ CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => {
await expect( page.getByText( userText ).first() ).toBeVisible();
// Revert edition and verify the template from the theme is used.
await admin.visitAdminPage(
'site-editor.php',
`path=/${ testData.templateType }/all`
);
await admin.visitSiteEditor( {
path: `/${ testData.templateType }/all`,
} );
await editorUtils.revertTemplateCustomizations(
testData.templateName
);
@ -97,10 +92,9 @@ CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => {
).toHaveCount( 0 );
// Revert the edit.
await admin.visitAdminPage(
'site-editor.php',
`path=/${ testData.templateType }/all`
);
await admin.visitSiteEditor( {
path: `/${ testData.templateType }/all`,
} );
await editorUtils.revertTemplateCustomizations(
testData.fallbackTemplate?.templateName || ''
);

View File

@ -32,3 +32,5 @@ export const customerFile = path.join(
'customer.json'
);
export const guestFile = { cookies: [], origins: [] };
export const DB_EXPORT_FILE = 'blocks_e2e.sql';

View File

@ -2,7 +2,7 @@
* External dependencies
*/
import { Page } from '@playwright/test';
import { Editor, expect } from '@wordpress/e2e-test-utils-playwright';
import { Editor, expect, Admin } from '@wordpress/e2e-test-utils-playwright';
import { BlockRepresentation } from '@wordpress/e2e-test-utils-playwright/build-types/editor/insert-block';
/**
@ -13,9 +13,11 @@ import type { TemplateType } from '../../utils/types';
export class EditorUtils {
editor: Editor;
page: Page;
constructor( editor: Editor, page: Page ) {
admin: Admin;
constructor( editor: Editor, page: Page, admin: Admin ) {
this.editor = editor;
this.page = page;
this.admin = admin;
}
/**
@ -297,22 +299,44 @@ export class EditorUtils {
}
async closeWelcomeGuideModal() {
const isModalOpen = await this.page
.getByRole( 'dialog', { name: 'Welcome to the site editor' } )
.locator( 'div' )
.filter( {
hasText:
'Edit your siteDesign everything on your site — from the header right down to the',
} )
.nth( 2 )
.isVisible();
await this.page.waitForFunction( () => {
return (
window.wp &&
window.wp.data &&
window.wp.data.dispatch( 'core/preferences' )
);
} );
// eslint-disable-next-line playwright/no-conditional-in-test
if ( isModalOpen ) {
await this.page
.getByRole( 'button', { name: 'Get started' } )
.click();
}
// Disable the welcome guide for the site editor.
await this.page.evaluate( () => {
return Promise.all( [
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-site', 'welcomeGuide', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-site', 'welcomeGuideStyles', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-site', 'welcomeGuidePage', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-site', 'welcomeGuideTemplate', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-post', 'welcomeGuide', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-post', 'welcomeGuideStyles', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-post', 'welcomeGuidePage', false ),
window.wp.data
.dispatch( 'core/preferences' )
.set( 'core/edit-post', 'welcomeGuideTemplate', false ),
] );
} );
}
async transformIntoBlocks() {
@ -372,6 +396,9 @@ export class EditorUtils {
templateType: TemplateType
) {
if ( templateType === 'wp_template_part' ) {
await this.admin.visitSiteEditor( {
path: `/${ templateType }/all`,
} );
await this.page.goto(
`/wp-admin/site-editor.php?path=/${ templateType }/all`
);
@ -381,9 +408,9 @@ export class EditorUtils {
} );
await templateLink.click();
} else {
await this.page.goto(
`/wp-admin/site-editor.php?path=/${ templateType }`
);
await this.admin.visitSiteEditor( {
path: '/' + templateType,
} );
const templateButton = this.page.getByRole( 'button', {
name: templateName,
exact: true,
@ -392,7 +419,6 @@ export class EditorUtils {
}
await this.enterEditMode();
await this.closeWelcomeGuideModal();
await this.waitForSiteEditorFinishLoading();
// Verify we are editing the correct template and it has the correct title.
@ -495,7 +521,7 @@ export class EditorUtils {
productSlug: string,
createIfDoesntExist = true
) {
await this.page.goto( '/wp-admin/site-editor.php' );
await this.admin.visitSiteEditor();
await this.page.getByRole( 'button', { name: 'Templates' } ).click();
const templateButton = this.page.getByRole( 'button', {

View File

@ -8,5 +8,4 @@ export * from './mini-cart';
export * from './performance';
export * from './shipping';
export * from './storeApi';
export * from './use-block-theme';
export * from './wpCli';

View File

@ -1,15 +0,0 @@
/**
* External dependencies
*/
import { test as Test } from '@wordpress/e2e-test-utils-playwright';
/**
* Internal dependencies
*/
import { BLOCK_THEME_SLUG } from './constants';
export const useBlockTheme = ( test: typeof Test ) => {
test.beforeAll( async ( { requestUtils } ) => {
await requestUtils.activateTheme( BLOCK_THEME_SLUG );
} );
};

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Block E2E: Eliminate side effects through improved test isolation

View File

@ -4313,8 +4313,8 @@ importers:
specifier: 2.28.1
version: 2.28.1(@typescript-eslint/parser@5.56.0)(eslint-import-resolver-typescript@3.6.1)(eslint-import-resolver-webpack@0.13.2)(eslint@8.55.0)
eslint-plugin-playwright:
specifier: 0.15.3
version: 0.15.3(eslint@8.55.0)
specifier: 1.6.0
version: 1.6.0(eslint@8.55.0)
eslint-plugin-rulesdir:
specifier: ^0.2.2
version: 0.2.2
@ -31910,18 +31910,6 @@ packages:
- supports-color
dev: true
/eslint-plugin-playwright@0.15.3(eslint@8.55.0):
resolution: {integrity: sha512-LQMW5y0DLK5Fnpya7JR1oAYL2/7Y9wDiYw6VZqlKqcRGSgjbVKNqxraphk7ra1U3Bb5EK444xMgUlQPbMg2M1g==}
peerDependencies:
eslint: '>=7'
eslint-plugin-jest: '>=25'
peerDependenciesMeta:
eslint-plugin-jest:
optional: true
dependencies:
eslint: 8.55.0
dev: true
/eslint-plugin-playwright@0.22.1(eslint-plugin-jest@23.20.0)(eslint@8.55.0):
resolution: {integrity: sha512-xUQ9mJH+CjifLG6vMowl3r49G/8JvW4G10IqHjc1WO44fffdhLZF/i4Def+U3y6LqUEBp0JAMnWUhEck7ksqrw==}
peerDependencies:
@ -31936,6 +31924,20 @@ packages:
globals: 13.24.0
dev: true
/eslint-plugin-playwright@1.6.0(eslint@8.55.0):
resolution: {integrity: sha512-tI1E/EDbHT4Fx5KvukUG3RTIT0gk44gvTP8bNwxLCFsUXVM98ZJG5zWU6Om5JOzH9FrmN4AhMu/UKyEsu0ZoDA==}
engines: {node: '>=16.6.0'}
peerDependencies:
eslint: '>=8.40.0'
eslint-plugin-jest: '>=25'
peerDependenciesMeta:
eslint-plugin-jest:
optional: true
dependencies:
eslint: 8.55.0
globals: 13.24.0
dev: true
/eslint-plugin-prettier@3.4.1(eslint-config-prettier@6.15.0)(eslint@7.32.0)(wp-prettier@2.2.1-beta-1):
resolution: {integrity: sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==}
engines: {node: '>=6.0.0'}