Commit e662f6c25f for woocommerce

commit e662f6c25f52b132c262c50b888c09902f05f538
Author: Roy Ho <roykho77@gmail.com>
Date:   Tue Jul 1 01:30:09 2025 -0700

    Remove product editor feature from UI (#56709)

    * Remove product editor feature from UI

    * chore: move changelog file to correct location

    * fix: only hide the setting ui, not the whole feature

    * fix E2E tests

    * Update plugins/woocommerce/src/Internal/Features/FeaturesController.php

    Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

    * fix import

    * fix JSDoc lint errors

    * fix import

    * fix E2E test

    * fix lint error

    * fix E2E test

    * fix lint errors

    * fix E2E test

    * fix import

    * fix lint error

    ---------

    Co-authored-by: Tung Du <dinhtungdu@gmail.com>
    Co-authored-by: Luigi Teschio <gigitux@gmail.com>
    Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

diff --git a/plugins/woocommerce/changelog/remove-product-editor-feature b/plugins/woocommerce/changelog/remove-product-editor-feature
new file mode 100644
index 0000000000..9a16e09513
--- /dev/null
+++ b/plugins/woocommerce/changelog/remove-product-editor-feature
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Remove experimental product editor feature from UI
diff --git a/plugins/woocommerce/src/Internal/Features/FeaturesController.php b/plugins/woocommerce/src/Internal/Features/FeaturesController.php
index 9e14be024d..ddaea26cb0 100644
--- a/plugins/woocommerce/src/Internal/Features/FeaturesController.php
+++ b/plugins/woocommerce/src/Internal/Features/FeaturesController.php
@@ -572,6 +572,14 @@ class FeaturesController {
 			}
 		}

+		// We're deprecating the product block editor feature in favor of a v3 coming out.
+		// We want to hide this setting in the UI for users that don't have it enabled.
+		// If users have it enabled, we won't hide it until they explicitly disable it.
+		if ( isset( $features['product_block_editor'] )
+			&& ! $this->feature_is_enabled( 'product_block_editor' ) ) {
+			$features['product_block_editor']['disable_ui'] = true;
+		}
+
 		return $features;
 	}

@@ -1535,9 +1543,9 @@ class FeaturesController {

 		wc_enqueue_js(
 			"
-	    const warningRows = document.querySelectorAll('tr[data-plugin-row-type=\"feature-incomp-warn\"]');
-	    for(const warningRow of warningRows) {
-	    	const pluginName = warningRow.getAttribute('data-plugin');
+		const warningRows = document.querySelectorAll('tr[data-plugin-row-type=\"feature-incomp-warn\"]');
+		for(const warningRow of warningRows) {
+			const pluginName = warningRow.getAttribute('data-plugin');
 			const pluginInfoRow = document.querySelector('tr.active[data-plugin=\"' + pluginName + '\"]:not(.plugin-update-tr), tr.inactive[data-plugin=\"' + pluginName + '\"]:not(.plugin-update-tr)');
 			if(pluginInfoRow.classList.contains('update')) {
 				warningRow.classList.remove('plugin-update-tr');
@@ -1546,7 +1554,7 @@ class FeaturesController {
 			else {
 				pluginInfoRow.classList.add('update');
 			}
-	    }
+		}
 		"
 		);
 	}
diff --git a/plugins/woocommerce/tests/e2e-pw/fixtures/block-editor-fixtures.js b/plugins/woocommerce/tests/e2e-pw/fixtures/block-editor-fixtures.js
index 5111450363..b4e7930919 100644
--- a/plugins/woocommerce/tests/e2e-pw/fixtures/block-editor-fixtures.js
+++ b/plugins/woocommerce/tests/e2e-pw/fixtures/block-editor-fixtures.js
@@ -2,17 +2,13 @@
  * Internal dependencies
  */
 import { test as baseTest } from './fixtures';
-import { WC_API_PATH } from '../utils/api-client';
 import { ADMIN_STATE_PATH } from '../playwright.config';
+import { wpCLI } from '../utils/cli';

 export const test = baseTest.extend( {
 	page: async ( { page, restApi }, use ) => {
-		// Enable product block editor
-		await restApi.put(
-			`${ WC_API_PATH }/settings/advanced/woocommerce_feature_product_block_editor_enabled`,
-			{
-				value: 'yes',
-			}
+		await wpCLI(
+			'wp option set woocommerce_feature_product_block_editor_enabled yes'
 		);

 		// Disable the product editor tour
@@ -22,12 +18,8 @@ export const test = baseTest.extend( {

 		await use( page );

-		// Disable product block editor
-		await restApi.put(
-			`${ WC_API_PATH }/settings/advanced/woocommerce_feature_product_block_editor_enabled`,
-			{
-				value: 'no',
-			}
+		await wpCLI(
+			'wp option set woocommerce_feature_product_block_editor_enabled no'
 		);
 	},
 	storageState: ADMIN_STATE_PATH,
diff --git a/plugins/woocommerce/tests/e2e-pw/tests/product/block-editor/disable-block-product-editor.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/product/block-editor/disable-block-product-editor.spec.js
index 688995c49c..d37869128b 100644
--- a/plugins/woocommerce/tests/e2e-pw/tests/product/block-editor/disable-block-product-editor.spec.js
+++ b/plugins/woocommerce/tests/e2e-pw/tests/product/block-editor/disable-block-product-editor.spec.js
@@ -1,18 +1,13 @@
-const { test } = require( '@playwright/test' );
+const { test, expect } = require( '@playwright/test' );
 const {
 	clickAddNewMenuItem,
 	expectBlockProductEditor,
 	expectOldProductEditor,
-	isBlockProductEditorEnabled,
-	toggleBlockProductEditor,
 } = require( '../../../utils/simple-products' );
 const { toggleBlockProductTour } = require( '../../../utils/tours' );
 const { tags } = require( '../../../fixtures/fixtures' );
 const { ADMIN_STATE_PATH } = require( '../../../playwright.config' );
-
-let isNewProductEditorEnabled = false;
-
-const isTrackingSupposedToBeEnabled = !! process.env.ENABLE_TRACKING;
+const { wpCLI } = require( '../../../utils/cli' );

 async function dismissFeedbackModalIfShown( page ) {
 	try {
@@ -32,37 +27,28 @@ test.describe.serial(
 			await toggleBlockProductTour( request, false );
 		} );

-		test.beforeEach( async ( { page } ) => {
-			isNewProductEditorEnabled = await isBlockProductEditorEnabled(
-				page
+		test.beforeEach( async () => {
+			await wpCLI(
+				'wp option set woocommerce_feature_product_block_editor_enabled yes'
 			);
-			if ( ! isNewProductEditorEnabled ) {
-				await toggleBlockProductEditor( 'enable', page );
-			}
 		} );

-		test.afterEach( async ( { browser } ) => {
-			const context = await browser.newContext();
-			const page = await context.newPage();
-			isNewProductEditorEnabled = await isBlockProductEditorEnabled(
-				page
+		test.afterAll( async () => {
+			await wpCLI(
+				'wp option set woocommerce_feature_product_block_editor_enabled no'
 			);
-			if ( isNewProductEditorEnabled ) {
-				await toggleBlockProductEditor( 'disable', page );
-			}
 		} );

-		test.skip(
-			isNewProductEditorEnabled && isTrackingSupposedToBeEnabled,
-			'The block product editor is not being tested'
-		);
-
+		// expectBlockProductEditor function contains the assertion
+		// eslint-disable-next-line playwright/expect-expect
 		test( 'is hooked up to sidebar "Add New"', async ( { page } ) => {
 			await page.goto( 'wp-admin/edit.php?post_type=product' );
 			await clickAddNewMenuItem( page );
 			await expectBlockProductEditor( page );
 		} );

+		// expectOldProductEditor function contains the assertion
+		// eslint-disable-next-line playwright/expect-expect
 		test( 'can be disabled from the header', async ( { page } ) => {
 			await page.goto(
 				'wp-admin/admin.php?page=wc-admin&path=%2Fadd-product'
@@ -86,8 +72,28 @@ test.describe.serial(
 			await expectOldProductEditor( page );
 		} );

+		// expectOldProductEditor function contains the assertion
+		// eslint-disable-next-line playwright/expect-expect
 		test( 'can be disabled from settings', async ( { page } ) => {
-			await toggleBlockProductEditor( 'disable', page );
+			await page.goto(
+				'wp-admin/admin.php?page=wc-settings&tab=advanced&section=features'
+			);
+
+			await page
+				.locator( '#woocommerce_feature_product_block_editor_enabled' )
+				.click();
+
+			await page
+				.getByRole( 'button', {
+					name: 'Save changes',
+				} )
+				.click();
+
+			await expect(
+				page
+					.locator( '#message' )
+					.getByText( 'Your settings have been saved' )
+			).toBeVisible();
 			await page.goto( 'wp-admin/edit.php?post_type=product' );
 			await clickAddNewMenuItem( page );
 			await expectOldProductEditor( page );
diff --git a/plugins/woocommerce/tests/e2e-pw/tests/product/block-editor/enable-block-product-editor.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/product/block-editor/enable-block-product-editor.spec.js
deleted file mode 100644
index 5e46bb2b92..0000000000
--- a/plugins/woocommerce/tests/e2e-pw/tests/product/block-editor/enable-block-product-editor.spec.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const { test } = require( '@playwright/test' );
-const {
-	clickAddNewMenuItem,
-	expectBlockProductEditor,
-	expectOldProductEditor,
-	isBlockProductEditorEnabled,
-	toggleBlockProductEditor,
-} = require( '../../../utils/simple-products' );
-const { tags } = require( '../../../fixtures/fixtures' );
-const { ADMIN_STATE_PATH } = require( '../../../playwright.config' );
-
-const ALL_PRODUCTS_URL = 'wp-admin/edit.php?post_type=product';
-const NEW_EDITOR_ADD_PRODUCT_URL =
-	'wp-admin/admin.php?page=wc-admin&path=%2Fadd-product';
-
-let isNewProductEditorEnabled = false;
-
-const isTrackingSupposedToBeEnabled = !! process.env.ENABLE_TRACKING;
-
-async function disableNewEditorIfEnabled( browser ) {
-	const context = await browser.newContext();
-	const page = await context.newPage();
-	isNewProductEditorEnabled = await isBlockProductEditorEnabled( page );
-	if ( isNewProductEditorEnabled ) {
-		await toggleBlockProductEditor( 'disable', page );
-	}
-}
-
-test.describe.configure( { mode: 'serial' } );
-
-test.describe( 'Enable block product editor', { tag: tags.GUTENBERG }, () => {
-	test.describe( 'Enabled', () => {
-		test.use( { storageState: ADMIN_STATE_PATH } );
-
-		test.beforeEach( async ( { browser } ) => {
-			await disableNewEditorIfEnabled( browser );
-		} );
-
-		test.afterEach( async ( { browser } ) => {
-			await disableNewEditorIfEnabled( browser );
-		} );
-
-		test.skip(
-			isTrackingSupposedToBeEnabled,
-			'The block product editor is not being tested'
-		);
-
-		test( 'is not hooked up to sidebar "Add New"', async ( { page } ) => {
-			await page.goto( ALL_PRODUCTS_URL );
-			await clickAddNewMenuItem( page );
-			await expectOldProductEditor( page );
-		} );
-
-		test( 'can enable the block product editor', async ( { page } ) => {
-			await toggleBlockProductEditor( 'enable', page );
-			await page.goto( NEW_EDITOR_ADD_PRODUCT_URL );
-			await expectBlockProductEditor( page );
-		} );
-	} );
-} );
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/cli.js b/plugins/woocommerce/tests/e2e-pw/utils/cli.js
new file mode 100644
index 0000000000..4f27730efc
--- /dev/null
+++ b/plugins/woocommerce/tests/e2e-pw/utils/cli.js
@@ -0,0 +1,15 @@
+const { promisify } = require( 'util' );
+
+const execAsync = promisify( require( 'child_process' ).exec );
+
+const wpCLI = async ( command ) => {
+	const { stdout, stderr } = await execAsync(
+		`pnpm exec wp-env run tests-cli -- ${ command }`
+	);
+
+	return { stdout, stderr };
+};
+
+module.exports = {
+	wpCLI,
+};
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/index.js b/plugins/woocommerce/tests/e2e-pw/utils/index.js
index 01515f5e53..5ab4a9cbf0 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/index.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/index.js
@@ -6,6 +6,7 @@ const login = require( './login' );
 const editor = require( './editor' );
 const helpers = require( './helpers' );
 const comingSoon = require( './coming-soon' );
+const cli = require( './cli' );

 module.exports = {
 	api,
@@ -16,4 +17,5 @@ module.exports = {
 	editor,
 	helpers,
 	comingSoon,
+	cli,
 };
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.js b/plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.js
index 9b7e4ca97e..2e0efad697 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.js
@@ -1,30 +1,109 @@
-const { APIRequest } = require( '@playwright/test' );
 const axios = require( 'axios' ).default;
 const fs = require( 'fs' );
 const path = require( 'path' );
-const { promisify } = require( 'util' );
-const execAsync = promisify( require( 'child_process' ).exec );
+const { wpCLI } = require( './cli' );

 /**
  * Encode basic auth username and password to be used in HTTP Authorization header.
  *
  * @param {string} username
  * @param {string} password
- * @returns Base64-encoded string
+ * @return {string} Base64-encoded string
  */
 export const encodeCredentials = ( username, password ) => {
 	return Buffer.from( `${ username }:${ password }` ).toString( 'base64' );
 };

+/**
+ * Get the download URL of the latest release zip for a plugin using GitHub API.
+ *
+ * @param {Object}  param
+ * @param {string}  param.repository
+ * @param {string}  param.authorizationToken
+ * @param {boolean} param.prerelease
+ * @param {number}  param.perPage
+ *
+ * @return {string} Download URL for the release zip file.
+ */
+export const getLatestReleaseZipUrl = async ( {
+	repository,
+	authorizationToken,
+	prerelease = false,
+	perPage = 3,
+} ) => {
+	const requesturl = prerelease
+		? `https://api.github.com/repos/${ repository }/releases?per_page=${ perPage }`
+		: `https://api.github.com/repos/${ repository }/releases/latest`;
+
+	const options = {
+		method: 'get',
+		url: requesturl,
+		headers: {
+			Authorization: authorizationToken
+				? `token ${ authorizationToken }`
+				: '',
+		},
+	};
+
+	// Get the first prerelease, or the latest release.
+	let response;
+	try {
+		response = await axios( options );
+	} catch ( error ) {
+		let errorMessage =
+			'Something went wrong when downloading the plugin.\n';
+
+		if ( error.response ) {
+			// The request was made and the server responded with a status code
+			// that falls out of the range of 2xx
+			errorMessage = errorMessage.concat(
+				`Response status: ${ error.response.status } ${ error.response.statusText }`,
+				'\n',
+				`Response body:`,
+				'\n',
+				JSON.stringify( error.response.data, null, 2 ),
+				'\n'
+			);
+		} else if ( error.request ) {
+			// The request was made but no response was received
+			// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
+			// http.ClientRequest in node.js
+			errorMessage = errorMessage.concat(
+				JSON.stringify( error.request, null, 2 ),
+				'\n'
+			);
+		} else {
+			// Something happened in setting up the request that triggered an Error
+			errorMessage = errorMessage.concat( error.toJSON(), '\n' );
+		}
+
+		throw new Error( errorMessage );
+	}
+
+	const release = prerelease
+		? // eslint-disable-next-line @typescript-eslint/no-shadow
+		  response.data.find( ( { prerelease } ) => prerelease )
+		: response.data;
+
+	// If response contains assets, return URL of first asset.
+	// Otherwise, return the github.com URL from the tag name.
+	const { assets } = release;
+	if ( assets && assets.length ) {
+		return assets[ 0 ].url;
+	}
+	const tagName = release.tag_name;
+	return `https://github.com/${ repository }/archive/${ tagName }.zip`;
+};
+
 /**
  * Deactivate and delete a plugin specified by the given `slug` using the WordPress API.
  *
- * @param {object} params
- * @param {APIRequest} params.request
- * @param {string} params.baseURL
- * @param {string} params.slug
- * @param {string} params.username
- * @param {string} params.password
+ * @param {Object}                                params
+ * @param {import('@playwright/test').APIRequest} params.request
+ * @param {string}                                params.baseURL
+ * @param {string}                                params.slug
+ * @param {string}                                params.username
+ * @param {string}                                params.password
  */
 export const deletePlugin = async ( {
 	request,
@@ -68,18 +147,12 @@ export const deletePlugin = async ( {
 /**
  * Download the zip file from a remote location.
  *
- * @param {object} param
- * @param {string} param.url
- * @param {string} param.repository
- * @param {string} param.authorizationToken
+ * @param {Object}  param
+ * @param {string}  param.url
+ * @param {string}  param.repository
+ * @param {string}  param.authorizationToken
  * @param {boolean} param.prerelease
- * @param {string} param.downloadDir
- *
- * @param {string} url The URL where the zip file is located. Takes precedence over `repository`.
- * @param {string} repository The repository owner and name. For example: `woocommerce/woocommerce`. Ignored when `url` was given.
- * @param {string} authorizationToken Authorization token used to authenticate with the GitHub API if required.
- * @param {boolean} prerelease Flag on whether to get a prelease or not. Default `false`.
- * @param {string} downloadDir Relative path to the download directory. Non-existing folders will be auto-created. Defaults to `tmp` under current working directory.
+ * @param {string}  param.downloadDir
  *
  * @return {string} Absolute path to the downloaded zip.
  */
@@ -96,8 +169,6 @@ export const downloadZip = async ( {
 		: zipFilename.concat( '.zip' );
 	const zipFilePath = path.resolve( downloadDir, zipFilename );

-	let response;
-
 	// Create destination folder.
 	fs.mkdirSync( downloadDir, { recursive: true } );

@@ -122,7 +193,7 @@ export const downloadZip = async ( {
 		},
 	};

-	response = await axios( options ).catch( ( error ) => {
+	const response = await axios( options ).catch( ( error ) => {
 		if ( error.response ) {
 			console.error( error.response.data );
 		}
@@ -145,88 +216,6 @@ export const deleteZip = async ( zipFilePath ) => {
 	} );
 };

-/**
- * Get the download URL of the latest release zip for a plugin using GitHub API.
- *
- * @param {{repository: string, authorizationToken: string, prerelease: boolean, perPage: number}} param
- * @param {string} repository The repository owner and name. For example: `woocommerce/woocommerce`.
- * @param {string} authorizationToken Authorization token used to authenticate with the GitHub API if required.
- * @param {boolean} prerelease Flag on whether to get a prelease or not.
- * @param {number} perPage Limit of entries returned from the latest releases list, defaults to 3.
- * @return {string} Download URL for the release zip file.
- */
-export const getLatestReleaseZipUrl = async ( {
-	repository,
-	authorizationToken,
-	prerelease = false,
-	perPage = 3,
-} ) => {
-	let release;
-
-	const requesturl = prerelease
-		? `https://api.github.com/repos/${ repository }/releases?per_page=${ perPage }`
-		: `https://api.github.com/repos/${ repository }/releases/latest`;
-
-	const options = {
-		method: 'get',
-		url: requesturl,
-		headers: {
-			Authorization: authorizationToken
-				? `token ${ authorizationToken }`
-				: '',
-		},
-	};
-
-	// Get the first prerelease, or the latest release.
-	let response;
-	try {
-		response = await axios( options );
-	} catch ( error ) {
-		let errorMessage =
-			'Something went wrong when downloading the plugin.\n';
-
-		if ( error.response ) {
-			// The request was made and the server responded with a status code
-			// that falls out of the range of 2xx
-			errorMessage = errorMessage.concat(
-				`Response status: ${ error.response.status } ${ error.response.statusText }`,
-				'\n',
-				`Response body:`,
-				'\n',
-				JSON.stringify( error.response.data, null, 2 ),
-				'\n'
-			);
-		} else if ( error.request ) {
-			// The request was made but no response was received
-			// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
-			// http.ClientRequest in node.js
-			errorMessage = errorMessage.concat(
-				JSON.stringify( error.request, null, 2 ),
-				'\n'
-			);
-		} else {
-			// Something happened in setting up the request that triggered an Error
-			errorMessage = errorMessage.concat( error.toJSON(), '\n' );
-		}
-
-		throw new Error( errorMessage );
-	}
-
-	release = prerelease
-		? response.data.find( ( { prerelease } ) => prerelease )
-		: response.data;
-
-	// If response contains assets, return URL of first asset.
-	// Otherwise, return the github.com URL from the tag name.
-	const { assets } = release;
-	if ( assets && assets.length ) {
-		return assets[ 0 ].url;
-	} else {
-		const tagName = release.tag_name;
-		return `https://github.com/${ repository }/archive/${ tagName }.zip`;
-	}
-};
-
 /**
  * Install a plugin using WP CLI within a WP ENV environment.
  * This is a workaround to the "The uploaded file exceeds the upload_max_filesize directive in php.ini" error encountered when uploading a plugin to the local WP Env E2E environment through the UI.
@@ -236,25 +225,14 @@ export const getLatestReleaseZipUrl = async ( {
  * @param {string} pluginPath
  */
 export const installPluginThruWpCli = async ( pluginPath ) => {
-	const runWpCliCommand = async ( command ) => {
-		const { stdout, stderr } = await execAsync(
-			`pnpm exec wp-env run tests-cli -- ${ command }`
-		);
-
-		console.log( stdout );
-		console.error( stderr );
-	};
-
 	const wpEnvPluginPath = pluginPath.replace(
 		/.*\/plugins\/woocommerce/,
 		'wp-content/plugins/woocommerce'
 	);

-	await runWpCliCommand( `ls  ${ wpEnvPluginPath }` );
+	await wpCLI( `ls  ${ wpEnvPluginPath }` );

-	await runWpCliCommand(
-		`wp plugin install --activate --force ${ wpEnvPluginPath }`
-	);
+	await wpCLI( `wp plugin install --activate --force ${ wpEnvPluginPath }` );

-	await runWpCliCommand( `wp plugin list` );
+	await wpCLI( `wp plugin list` );
 };
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/simple-products.js b/plugins/woocommerce/tests/e2e-pw/utils/simple-products.js
index bd51da42ef..8876e2fd3e 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/simple-products.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/simple-products.js
@@ -1,63 +1,5 @@
 const { expect } = require( '@playwright/test' );

-const SETTINGS_URL =
-	'wp-admin/admin.php?page=wc-settings&tab=advanced&section=features';
-
-/**
- * This function checks whether the block product editor is enabled on a page.
- *
- * Navigates to the block product editor and verifies it's enabled.
- *
- * @param {import('@playwright/test').Page} page
- *
- * @return {Promise<boolean>} Boolean value based on the visibility of the element.
- */
-async function isBlockProductEditorEnabled( page ) {
-	await page.goto( SETTINGS_URL );
-	return await page
-		.locator( '#woocommerce_feature_product_block_editor_enabled' )
-		.isChecked();
-}
-
-/**
- * This function is typically used for enabling/disabling the block product editor in settings page.
- *
- * @param {string}                          action The action that will be performed.
- * @param {import('@playwright/test').Page} page
- */
-async function toggleBlockProductEditor( action = 'enable', page ) {
-	await page.goto( SETTINGS_URL );
-
-	const enableProductEditor = page.locator(
-		'#woocommerce_feature_product_block_editor_enabled'
-	);
-	const isEnabled = await enableProductEditor.isChecked();
-
-	if (
-		( action === 'enable' && isEnabled ) ||
-		( action === 'disable' && ! isEnabled )
-	) {
-		// No need to toggle the setting.
-		return;
-	}
-
-	if ( action === 'enable' ) {
-		await enableProductEditor.check();
-	} else if ( action === 'disable' ) {
-		await enableProductEditor.uncheck();
-	}
-
-	await page
-		.getByRole( 'button', {
-			name: 'Save changes',
-		} )
-		.click();
-
-	await expect(
-		page.locator( '#message' ).getByText( 'Your settings have been saved' )
-	).toBeVisible();
-}
-
 /**
  * This function simulates the clicking of the "Add New" link under the "product" section in the menu.
  *
@@ -110,6 +52,4 @@ module.exports = {
 	expectOldProductEditor,
 	clickAddNewMenuItem,
 	clickOnTab,
-	isBlockProductEditorEnabled,
-	toggleBlockProductEditor,
 };
diff --git a/plugins/woocommerce/tests/metrics/specs/product-editor.spec.js b/plugins/woocommerce/tests/metrics/specs/product-editor.spec.js
index b23eab5dda..7e52583c01 100644
--- a/plugins/woocommerce/tests/metrics/specs/product-editor.spec.js
+++ b/plugins/woocommerce/tests/metrics/specs/product-editor.spec.js
@@ -9,7 +9,7 @@ import { test, Metrics } from '@wordpress/e2e-test-utils-playwright';
  * Internal dependencies
  */
 import { getTotalBlockingTime, median } from '../utils';
-import { toggleBlockProductEditor } from '../../e2e-pw/utils/simple-products';
+import { wpCLI } from '../../e2e-pw/utils/cli';

 // See https://github.com/WordPress/gutenberg/issues/51383#issuecomment-1613460429
 const BROWSER_IDLE_WAIT = 1000;
@@ -30,6 +30,12 @@ test.describe( 'Product editor performance', () => {
 		},
 	} );

+	test.beforeAll( async () => {
+		await wpCLI(
+			'wp option set woocommerce_feature_product_block_editor_enabled yes'
+		);
+	} );
+
 	test.afterAll( async ( {}, testInfo ) => {
 		const medians = {};
 		Object.keys( results ).forEach( ( metric ) => {
@@ -39,10 +45,10 @@ test.describe( 'Product editor performance', () => {
 			body: JSON.stringify( { 'product-editor': medians }, null, 2 ),
 			contentType: 'application/json',
 		} );
-	} );

-	test( 'Enable Product Editor', async ( { page } ) => {
-		await toggleBlockProductEditor( 'enable', page );
+		await wpCLI(
+			'wp option set woocommerce_feature_product_block_editor_enabled no'
+		);
 	} );

 	test.describe( 'Loading', () => {
@@ -124,6 +130,7 @@ test.describe( 'Product editor performance', () => {
 					.getByLabel( 'Close Tour' )
 					.click( { timeout: 3000 } );
 			} catch ( e ) {
+				// eslint-disable-next-line no-console -- We want to see this in the console.
 				console.log( 'Tour was not visible, skipping.' );
 			}