Commit 5fb2602b13b for woocommerce
commit 5fb2602b13b3688b808e19860d5987992cc64e45
Author: Luigi Teschio <gigitux@gmail.com>
Date: Wed Sep 2 16:53:04 2026 +0200
Speed up block template customization end-to-end tests (#67561)
* Speed up template customization end-to-end tests
* Add changelog entry for template test optimization
* add comment
* improve e2e test
* remove .only
diff --git a/plugins/woocommerce/changelog/optimize-template-customization-e2e-rest b/plugins/woocommerce/changelog/optimize-template-customization-e2e-rest
new file mode 100644
index 00000000000..6f8b916efa2
--- /dev/null
+++ b/plugins/woocommerce/changelog/optimize-template-customization-e2e-rest
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Speed up block template customization end-to-end tests using REST API setup and cleanup.
diff --git a/plugins/woocommerce/tests/e2e/tests/blocks/templates/template-customization.block_theme.spec.ts b/plugins/woocommerce/tests/e2e/tests/blocks/templates/template-customization.block_theme.spec.ts
index 24e1a414585..f7fa4b4771a 100644
--- a/plugins/woocommerce/tests/e2e/tests/blocks/templates/template-customization.block_theme.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/blocks/templates/template-customization.block_theme.spec.ts
@@ -21,6 +21,11 @@ test.describe( 'Template customization', () => {
testData.templateType === 'wp_template'
? 'template'
: 'template part';
+ const templateOrigin =
+ testData.templateType === 'wp_template'
+ ? BLOCK_THEME_SLUG
+ : 'woocommerce/woocommerce';
+ const templateId = `${ templateOrigin }//${ testData.templatePath }`;
test( `"${ testData.templateName }" template can be modified and reverted`, async ( {
admin,
@@ -41,12 +46,8 @@ test.describe( 'Template customization', () => {
templateName: testData.templateName,
} );
} else {
- const templateSlug =
- testData.templateType === 'wp_template'
- ? BLOCK_THEME_SLUG
- : 'woocommerce/woocommerce';
await admin.visitSiteEditor( {
- postId: `${ templateSlug }//${ testData.templatePath }`,
+ postId: templateId,
postType: testData.templateType,
canvas: 'edit',
} );
@@ -80,12 +81,10 @@ test.describe( 'Template customization', () => {
await expect( page.getByText( userText ).first() ).toBeVisible();
// Verify the edition can be reverted.
- await admin.visitSiteEditor( {
- postType: testData.templateType,
- } );
- await editor.revertTemplate( {
- templateName: testData.templateName,
- } );
+ await requestUtils.revertTemplate(
+ testData.templateType,
+ templateId
+ );
await testData.visitPage( {
admin,
editor,
@@ -97,37 +96,22 @@ test.describe( 'Template customization', () => {
} );
if ( testData.fallbackTemplate ) {
- test( `"${ testData.templateName }" template defaults to the "${ testData.fallbackTemplate.templateName }" template`, async ( {
+ const fallbackTemplate = testData.fallbackTemplate;
+
+ test( `"${ testData.templateName }" template defaults to the "${ fallbackTemplate.templateName }" template`, async ( {
admin,
frontendUtils,
requestUtils,
editor,
page,
} ) => {
- const templateSlug =
- testData.templateType === 'wp_template'
- ? BLOCK_THEME_SLUG
- : 'woocommerce/woocommerce';
- // Edit fallback template and verify changes are visible.
- await admin.visitSiteEditor( {
- postId: `${ templateSlug }//${ testData.fallbackTemplate?.templatePath }`,
- postType: testData.templateType,
- canvas: 'edit',
- } );
-
- await editor.canvas
- .locator( 'body' )
- .waitFor( { timeout: 20000 } );
-
- await editor.insertBlock( {
- name: 'core/paragraph',
- attributes: {
- content: fallbackTemplateUserText,
- },
- } );
- await editor.saveSiteEditorEntities( {
- isOnlyCurrentEntityDirty: true,
- } );
+ // Customize the fallback template and verify changes are visible.
+ const fallbackTemplateId = `${ templateOrigin }//${ fallbackTemplate.templatePath }`;
+ await requestUtils.updateTemplateContent(
+ testData.templateType,
+ fallbackTemplateId,
+ `<!-- wp:paragraph --><p>${ fallbackTemplateUserText }</p><!-- /wp:paragraph -->`
+ );
await testData.visitPage( {
admin,
editor,
@@ -140,13 +124,10 @@ test.describe( 'Template customization', () => {
).toBeVisible();
// Verify the edition can be reverted.
- await admin.visitSiteEditor( {
- postType: testData.templateType,
- } );
-
- await editor.revertTemplate( {
- templateName: testData.fallbackTemplate?.templateName || '',
- } );
+ await requestUtils.revertTemplate(
+ testData.templateType,
+ fallbackTemplateId
+ );
await testData.visitPage( {
admin,
@@ -206,7 +187,6 @@ test.describe( 'Template customization', () => {
postType: testData.templateType,
canvas: 'edit',
} );
-
await editor.canvas.locator( 'body' ).waitFor( { timeout: 20000 } );
await editor.insertBlock( {
@@ -217,6 +197,17 @@ test.describe( 'Template customization', () => {
isOnlyCurrentEntityDirty: true,
} );
+ // Verify only the customized theme template is returned for this slug.
+ // See: https://github.com/woocommerce/woocommerce/issues/42220
+ const templates = await requestUtils.getTemplates(
+ testData.templateType
+ );
+ expect(
+ templates.filter(
+ ( template ) => template.slug === testData.templatePath
+ )
+ ).toHaveLength( 1 );
+
// Verify the template is the one modified by the user based on the theme.
await testData.visitPage( {
admin,
@@ -231,17 +222,13 @@ test.describe( 'Template customization', () => {
).toBeHidden();
// Revert edition and verify the user-modified WC template is used.
- // Note: we need to revert it from the admin (instead of calling
- // `deleteAllTemplates()`). This way, we verify there are no
- // duplicate templates with the same name.
+ // Revert the exact template rather than selecting it by its display
+ // name, which can be shared by templates from different origins.
// See: https://github.com/woocommerce/woocommerce/issues/42220
- await admin.visitSiteEditor( {
- postType: testData.templateType,
- } );
-
- await editor.revertTemplate( {
- templateName: testData.templateName,
- } );
+ await requestUtils.revertTemplate(
+ testData.templateType,
+ `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.templatePath }`
+ );
await testData.visitPage( {
admin,
diff --git a/plugins/woocommerce/tests/e2e/tests/blocks/templates/template-customization.block_theme_with_templates.spec.ts b/plugins/woocommerce/tests/e2e/tests/blocks/templates/template-customization.block_theme_with_templates.spec.ts
index 5b0aeb2f147..cb679a9ee2f 100644
--- a/plugins/woocommerce/tests/e2e/tests/blocks/templates/template-customization.block_theme_with_templates.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/blocks/templates/template-customization.block_theme_with_templates.spec.ts
@@ -27,6 +27,7 @@ test.describe( 'Template customization', () => {
testData.templateType === 'wp_template'
? 'template'
: 'template part';
+ const templateId = `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.templatePath }`;
test.describe( `${ testData.templateName } template`, () => {
test( "theme template has priority over WooCommerce's and can be modified", async ( {
@@ -38,7 +39,7 @@ test.describe( 'Template customization', () => {
} ) => {
// Edit the theme template.
await admin.visitSiteEditor( {
- postId: `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.templatePath }`,
+ postId: templateId,
postType: testData.templateType,
canvas: 'edit',
} );
@@ -76,12 +77,10 @@ test.describe( 'Template customization', () => {
).toBeVisible();
// Revert edition and verify the template from the theme is used.
- await admin.visitSiteEditor( {
- postType: testData.templateType,
- } );
- await editor.revertTemplate( {
- templateName: testData.templateName,
- } );
+ await requestUtils.revertTemplate(
+ testData.templateType,
+ templateId
+ );
await testData.visitPage( {
admin,
@@ -102,34 +101,22 @@ test.describe( 'Template customization', () => {
} );
if ( testData.fallbackTemplate ) {
- test( `theme template has priority over user-modified ${ testData.fallbackTemplate.templateName } template`, async ( {
+ const fallbackTemplate = testData.fallbackTemplate;
+
+ test( `theme template has priority over user-modified ${ fallbackTemplate.templateName } template`, async ( {
admin,
frontendUtils,
requestUtils,
editor,
page,
} ) => {
- // Edit default template and verify changes are not visible,
- // as the theme template has priority.
- await admin.visitSiteEditor( {
- postId: `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.fallbackTemplate?.templatePath }`,
- postType: testData.templateType,
- canvas: 'edit',
- } );
-
- await editor.canvas
- .locator( 'body' )
- .waitFor( { timeout: 20000 } );
-
- await editor.insertBlock( {
- name: 'core/paragraph',
- attributes: {
- content: fallbackTemplateUserText,
- },
- } );
- await editor.saveSiteEditorEntities( {
- isOnlyCurrentEntityDirty: true,
- } );
+ // Customize the fallback template and verify changes are not
+ // visible, as the theme template has priority.
+ await requestUtils.updateTemplateContent(
+ testData.templateType,
+ `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ fallbackTemplate.templatePath }`,
+ `<!-- wp:paragraph --><p>${ fallbackTemplateUserText }</p><!-- /wp:paragraph -->`
+ );
await testData.visitPage( {
admin,
editor,
diff --git a/plugins/woocommerce/tests/e2e/utils/blocks/request-utils/index.ts b/plugins/woocommerce/tests/e2e/utils/blocks/request-utils/index.ts
index b3b473eeb56..c8ba4a883aa 100644
--- a/plugins/woocommerce/tests/e2e/utils/blocks/request-utils/index.ts
+++ b/plugins/woocommerce/tests/e2e/utils/blocks/request-utils/index.ts
@@ -8,7 +8,9 @@ import { RequestUtils as CoreRequestUtils } from '@wordpress/e2e-test-utils-play
*/
import { createPostFromFile, PostCompiler } from './posts';
import {
+ updateTemplateContent,
getTemplates,
+ getTemplate,
revertTemplate,
createTemplateFromFile,
TemplateCompiler,
@@ -16,8 +18,13 @@ import {
import { resetFeatureFlag, setFeatureFlag } from './feature-flag';
export class RequestUtils extends CoreRequestUtils {
+ /** @borrows updateTemplateContent as this.updateTemplateContent */
+ updateTemplateContent: typeof updateTemplateContent =
+ updateTemplateContent.bind( this );
/** @borrows getTemplates as this.getTemplates */
getTemplates: typeof getTemplates = getTemplates.bind( this );
+ /** @borrows getTemplate as this.getTemplate */
+ getTemplate: typeof getTemplate = getTemplate.bind( this );
/** @borrows revertTemplate as this.revertTemplate */
revertTemplate: typeof revertTemplate = revertTemplate.bind( this );
/** @borrows createPostFromFile as this.createPostFromFile */
diff --git a/plugins/woocommerce/tests/e2e/utils/blocks/request-utils/templates.ts b/plugins/woocommerce/tests/e2e/utils/blocks/request-utils/templates.ts
index 691926a43d2..e7d61ba3df2 100644
--- a/plugins/woocommerce/tests/e2e/utils/blocks/request-utils/templates.ts
+++ b/plugins/woocommerce/tests/e2e/utils/blocks/request-utils/templates.ts
@@ -19,41 +19,103 @@ export type WPTemplateType = 'wp_template' | 'wp_template_part';
export interface WPTemplate {
wp_id: number;
id: string;
+ slug: string;
type: WPTemplateType;
+ origin: 'plugin' | 'theme' | null;
+ content: {
+ raw: string;
+ };
}
export interface TemplateCompiler {
compile: ( data?: unknown ) => Promise< WPTemplate >;
}
+function getTemplateRestPath(
+ templateType: WPTemplateType,
+ templateId?: string
+) {
+ const endpoint =
+ templateType === 'wp_template' ? 'templates' : 'template-parts';
+
+ return `/wp/v2/${ endpoint }${ templateId ? `/${ templateId }` : '' }`;
+}
+
/**
* Retrieves all available templates.
*/
-export async function getTemplates( this: RequestUtils ) {
+export async function getTemplates(
+ this: RequestUtils,
+ templateType: WPTemplateType = 'wp_template'
+) {
const templates = await this.rest< WPTemplate[] >( {
method: 'GET',
- path: '/wp/v2/templates',
+ path: getTemplateRestPath( templateType ),
} );
return templates;
}
/**
- * Reverts a template to its original state.
+ * Retrieves a template or template part.
*/
-export async function revertTemplate( this: RequestUtils, slug: string ) {
- const restPath = `/wp/v2/templates/${ slug }`;
-
- const template = await this.rest( {
+export async function getTemplate(
+ this: RequestUtils,
+ templateType: WPTemplateType,
+ templateId: string
+) {
+ return await this.rest< WPTemplate >( {
method: 'GET',
- path: restPath,
+ path: getTemplateRestPath( templateType, templateId ),
+ } );
+}
+
+/**
+ * Updates the content of a template or template part.
+ */
+export async function updateTemplateContent(
+ this: RequestUtils,
+ templateType: WPTemplateType,
+ templateId: string,
+ content: string
+) {
+ return await this.rest< WPTemplate >( {
+ method: 'POST',
+ path: getTemplateRestPath( templateType, templateId ),
+ data: {
+ id: templateId,
+ content,
+ },
} );
+}
+
+/**
+ * Reverts a template to its original state.
+ */
+export async function revertTemplate(
+ this: RequestUtils,
+ templateType: WPTemplateType,
+ templateId: string
+) {
+ const restPath = getTemplateRestPath( templateType, templateId );
+ const template = await this.getTemplate( templateType, templateId );
+
+ // User-created templates have no underlying theme or plugin template to
+ // restore, so remove the custom template instead of resetting its source.
+ if ( template.origin === null ) {
+ await this.rest( {
+ method: 'DELETE',
+ path: restPath,
+ params: { force: true },
+ } );
+ return;
+ }
await this.rest( {
method: 'POST',
path: restPath,
data: {
- id: slug,
+ id: templateId,
content: template.content.raw,
source: 'theme',
},