Commit 00f6509804a for woocommerce

commit 00f6509804adfec733a79e1063f63a6109452325
Author: Adrian Moldovan <3854374+adimoldovan@users.noreply.github.com>
Date:   Wed Jun 24 15:56:23 2026 +0300

    e2e-tests: Split core E2E suite into core-serial and core-parallel projects (#65815)

diff --git a/plugins/woocommerce/changelog/update-e2e-core-serial-parallel-projects b/plugins/woocommerce/changelog/update-e2e-core-serial-parallel-projects
new file mode 100644
index 00000000000..3bd1964f6b5
--- /dev/null
+++ b/plugins/woocommerce/changelog/update-e2e-core-serial-parallel-projects
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Split the core E2E Playwright suite into core-serial and core-parallel projects to enable parallel test runs. Test-only change, no production impact.
diff --git a/plugins/woocommerce/package.json b/plugins/woocommerce/package.json
index a2d479d8862..5dd6af41b03 100644
--- a/plugins/woocommerce/package.json
+++ b/plugins/woocommerce/package.json
@@ -57,16 +57,17 @@
 		"make:collection": "pnpm exec wc-api-tests make:collection",
 		"makepot": "XDEBUG_MODE=off composer run-script makepot",
 		"test": "pnpm test:unit",
-		"test:api": "pnpm test:e2e:default --project=api --workers 4",
-		"test:api:hpos-off": "pnpm test:e2e:with-env default-hpos-disabled --project=api-hpos-disabled --workers 4",
-		"test:api:object-cache": "pnpm test:e2e:with-env default-object-cache --project=api --workers 4",
-		"test:e2e": "pnpm test:e2e:default --project=e2e",
+		"test:api": "pnpm test:e2e:default --project=api",
+		"test:api:hpos-off": "pnpm test:e2e:with-env default-hpos-disabled --project=api-hpos-disabled",
+		"test:api:object-cache": "pnpm test:e2e:with-env default-object-cache --project=api",
+		"test:e2e:core-serial": "pnpm test:e2e:default --project=core-serial",
+		"test:e2e:core-parallel": "pnpm test:e2e:default --project=core-parallel",
 		"test:e2e:default": "pnpm test:e2e:install && pnpm test:e2e:with-env default",
 		"test:e2e:install": "pnpm playwright install chromium",
 		"test:e2e:blocks": "pnpm playwright test --config=tests/e2e/playwright.config.ts --project=blocks-chromium",
 		"test:e2e:blocks:performance": "pnpm playwright test --config=tests/e2e/playwright.performance.config.ts --project=blocks-performance",
-		"test:e2e:email-update-propagation:pr": "pnpm test:e2e:default --project=e2e --grep @pr tests/email-editor/update-propagation",
-		"test:e2e:email-update-propagation:nightly": "pnpm test:e2e:default --project=e2e tests/email-editor/update-propagation",
+		"test:e2e:email-update-propagation:pr": "pnpm test:e2e:default --project=core-serial --project=core-parallel --grep @pr tests/email-editor/update-propagation",
+		"test:e2e:email-update-propagation:nightly": "pnpm test:e2e:default --project=core-serial --project=core-parallel tests/email-editor/update-propagation",
 		"test:e2e:with-env": "pnpm test:e2e:install && bash ./tests/e2e/run-tests-with-env.sh",
 		"test:e2e:pressable": "pnpm test:e2e:with-env default-pressable",
 		"test:e2e:wpcom": "pnpm test:e2e:with-env default-wpcom",
@@ -268,16 +269,49 @@
 					]
 				},
 				{
-					"name": "Core e2e tests",
+					"name": "Core e2e tests - parallel",
 					"testType": "e2e",
-					"command": "test:e2e",
+					"command": "test:e2e:core-parallel",
 					"shardingArguments": [
-						"--shard=1/6",
-						"--shard=2/6",
-						"--shard=3/6",
-						"--shard=4/6",
-						"--shard=5/6",
-						"--shard=6/6"
+						"--shard=1/2",
+						"--shard=2/2"
+					],
+					"changes": [
+						"client/admin/config/*.json",
+						"composer.json",
+						"composer.lock",
+						"i18n/**/*.php",
+						"includes/**/*.php",
+						"patterns/**/*.php",
+						"src/**/*.php",
+						"templates/**/*.php",
+						"tests/e2e/**",
+						".wp-env.json",
+						"woocommerce.php",
+						"uninstall.php"
+					],
+					"testEnv": {
+						"start": "env:test --debug"
+					},
+					"events": [
+						"pull_request",
+						"push",
+						"release-checks",
+						"core-e2e"
+					],
+					"report": {
+						"resultsBlobName": "core-e2e-report",
+						"resultsPath": "tests/e2e/test-results",
+						"allure": true
+					}
+				},
+				{
+					"name": "Core e2e tests - serial",
+					"testType": "e2e",
+					"command": "test:e2e:core-serial",
+					"shardingArguments": [
+						"--shard=1/2",
+						"--shard=2/2"
 					],
 					"changes": [
 						"client/admin/config/*.json",
@@ -344,10 +378,7 @@
 					"name": "Core e2e tests - Gutenberg stable",
 					"testType": "e2e",
 					"command": "test:e2e:gb-stable",
-					"shardingArguments": [
-						"--shard=1/2",
-						"--shard=2/2"
-					],
+					"shardingArguments": [],
 					"changes": [
 						"tests/e2e/**"
 					],
@@ -373,10 +404,7 @@
 					"name": "Core e2e tests - Gutenberg nightly",
 					"testType": "e2e",
 					"command": "test:e2e:gb-nightly",
-					"shardingArguments": [
-						"--shard=1/2",
-						"--shard=2/2"
-					],
+					"shardingArguments": [],
 					"changes": [
 						"tests/e2e/**"
 					],
@@ -424,15 +452,44 @@
 					}
 				},
 				{
-					"name": "Core e2e tests - PHP 8.5",
+					"name": "Core e2e tests - PHP 8.5 - serial",
+					"testType": "e2e",
+					"command": "test:e2e:core-serial",
+					"shardingArguments": [
+						"--shard=1/2",
+						"--shard=2/2"
+					],
+					"changes": [
+						"tests/e2e/**"
+					],
+					"onlyForDependencies": [
+						"@woocommerce/e2e-utils-playwright"
+					],
+					"testEnv": {
+						"start": "env:test --debug",
+						"config": {
+							"phpVersion": "8.5"
+						}
+					},
+					"events": [
+						"pull_request",
+						"nightly-checks",
+						"release-checks",
+						"core-e2e-php-8.5"
+					],
+					"report": {
+						"resultsBlobName": "core-e2e-report-php-8.5",
+						"resultsPath": "tests/e2e/test-results",
+						"allure": true
+					}
+				},
+				{
+					"name": "Core e2e tests - PHP 8.5 - parallel",
 					"testType": "e2e",
-					"command": "test:e2e",
+					"command": "test:e2e:core-parallel",
 					"shardingArguments": [
-						"--shard=1/5",
-						"--shard=2/5",
-						"--shard=3/5",
-						"--shard=4/5",
-						"--shard=5/5"
+						"--shard=1/2",
+						"--shard=2/2"
 					],
 					"changes": [
 						"tests/e2e/**"
@@ -459,15 +516,44 @@
 					}
 				},
 				{
-					"name": "Core e2e tests - WP latest-1",
+					"name": "Core e2e tests - WP L-1 - serial",
+					"testType": "e2e",
+					"command": "test:e2e:core-serial",
+					"shardingArguments": [
+						"--shard=1/2",
+						"--shard=2/2"
+					],
+					"changes": [
+						"tests/e2e/**"
+					],
+					"onlyForDependencies": [
+						"@woocommerce/e2e-utils-playwright"
+					],
+					"testEnv": {
+						"start": "env:test --debug",
+						"config": {
+							"wpVersion": "latest-1"
+						}
+					},
+					"events": [
+						"pull_request",
+						"nightly-checks",
+						"release-checks",
+						"core-e2e-wp-latest-1"
+					],
+					"report": {
+						"resultsBlobName": "core-e2e-report-wp-latest-1",
+						"resultsPath": "tests/e2e/test-results",
+						"allure": true
+					}
+				},
+				{
+					"name": "Core e2e tests - WP L-1 - parallel",
 					"testType": "e2e",
-					"command": "test:e2e",
+					"command": "test:e2e:core-parallel",
 					"shardingArguments": [
-						"--shard=1/5",
-						"--shard=2/5",
-						"--shard=3/5",
-						"--shard=4/5",
-						"--shard=5/5"
+						"--shard=1/2",
+						"--shard=2/2"
 					],
 					"changes": [
 						"tests/e2e/**"
@@ -494,16 +580,46 @@
 					}
 				},
 				{
-					"name": "Core e2e tests - WP pre-release",
+					"name": "Core e2e tests - WP pre-release - serial",
+					"optional": true,
+					"testType": "e2e",
+					"command": "test:e2e:core-serial",
+					"shardingArguments": [
+						"--shard=1/2",
+						"--shard=2/2"
+					],
+					"changes": [
+						"tests/e2e/**"
+					],
+					"onlyForDependencies": [
+						"@woocommerce/e2e-utils-playwright"
+					],
+					"testEnv": {
+						"start": "env:test --debug",
+						"config": {
+							"wpVersion": "prerelease"
+						}
+					},
+					"events": [
+						"pull_request",
+						"nightly-checks",
+						"release-checks",
+						"core-e2e-wp-pre-release"
+					],
+					"report": {
+						"resultsBlobName": "core-e2e-report-wp-pre-release",
+						"resultsPath": "tests/e2e/test-results",
+						"allure": true
+					}
+				},
+				{
+					"name": "Core e2e tests - WP pre-release - parallel",
 					"optional": true,
 					"testType": "e2e",
-					"command": "test:e2e",
+					"command": "test:e2e:core-parallel",
 					"shardingArguments": [
-						"--shard=1/5",
-						"--shard=2/5",
-						"--shard=3/5",
-						"--shard=4/5",
-						"--shard=5/5"
+						"--shard=1/2",
+						"--shard=2/2"
 					],
 					"changes": [
 						"tests/e2e/**"
diff --git a/plugins/woocommerce/tests/e2e/bin/test-helper-apis.php b/plugins/woocommerce/tests/e2e/bin/test-helper-apis.php
index 8310fda2e31..1da98c73672 100644
--- a/plugins/woocommerce/tests/e2e/bin/test-helper-apis.php
+++ b/plugins/woocommerce/tests/e2e/bin/test-helper-apis.php
@@ -108,6 +108,18 @@ function enable_experimental_features( $features ) {

 add_filter( 'woocommerce_admin_get_feature_config', 'enable_experimental_features' );

+/**
+ * Disable WordPress comment flood protection during E2E runs.
+ *
+ * Parallel specs post comments and reviews as the shared customer account.
+ * WordPress' 15-second flood throttle ("You are posting comments too quickly")
+ * then rejects whichever request lands second, causing cross-spec flakes that
+ * have nothing to do with the behaviour under test. Override core's
+ * `wp_throttle_comment_flood` (priority 10) with a later filter that always
+ * allows the comment.
+ */
+add_filter( 'comment_flood_filter', '__return_false', 99 );
+
 /**
  * Update a WordPress option.
  * @param WP_REST_Request $request
diff --git a/plugins/woocommerce/tests/e2e/fixtures/site.setup.ts b/plugins/woocommerce/tests/e2e/fixtures/site.setup.ts
index bed5b3c6e1f..c9738b1b10f 100644
--- a/plugins/woocommerce/tests/e2e/fixtures/site.setup.ts
+++ b/plugins/woocommerce/tests/e2e/fixtures/site.setup.ts
@@ -102,6 +102,14 @@ setup( 'setup site', async ( { baseURL, restApi } ) => {
 	await setup.step( 'general settings', async () => {
 		await restApi.post( `${ WC_API_PATH }/settings/general/batch`, {
 			update: [
+				// Enable tax calculation globally so tax-dependent specs don't each
+				// flip this global switch on/off mid-run. The shared baseline stays
+				// tax-free because no standard-rate tax rate exists (the next step
+				// clears any stray rates), so `core-parallel` specs asserting untaxed
+				// cart/refund totals are unaffected. A spec that needs taxes scopes
+				// its rate to a dedicated tax class and assigns only its own products
+				// to that class (see `cart.spec.ts`), so other workers never match it.
+				{ id: 'woocommerce_calc_taxes', value: 'yes' },
 				{ id: 'woocommerce_allowed_countries', value: 'all' },
 				{ id: 'woocommerce_currency', value: 'USD' },
 				{ id: 'woocommerce_price_thousand_sep', value: ',' },
@@ -114,4 +122,104 @@ setup( 'setup site', async ( { baseURL, restApi } ) => {
 			],
 		} );
 	} );
+
+	await setup.step( 'tax display settings', async () => {
+		// Pin the tax display mode deterministically. With taxes enabled globally,
+		// display mode now affects how class-scoped tax specs (e.g. `cart.spec.ts`)
+		// see prices, and a stray `incl` left by an interrupted blocks/settings-tax
+		// run would otherwise break their ex-tax line-price assertions. `excl` is
+		// the WooCommerce default: line prices shown ex-tax, totals tax-inclusive.
+		await restApi.post( `${ WC_API_PATH }/settings/tax/batch`, {
+			update: [
+				{ id: 'woocommerce_prices_include_tax', value: 'no' },
+				{ id: 'woocommerce_tax_display_shop', value: 'excl' },
+				{ id: 'woocommerce_tax_display_cart', value: 'excl' },
+			],
+		} );
+	} );
+
+	await setup.step( 'clear tax rates', async () => {
+		// With tax calculation enabled globally, the parallel baseline must have
+		// zero tax rates so untaxed-total assertions stay deterministic. Delete any
+		// rates left behind by an interrupted serial tax spec; specs that need a
+		// rate create (and clean up) a class-scoped one of their own.
+		let page = 1;
+		let allRates: { id: number }[] = [];
+		while ( true ) {
+			const { data: chunk } = await restApi.get< { id: number }[] >(
+				`${ WC_API_PATH }/taxes?per_page=100&page=${ page }`
+			);
+			allRates = allRates.concat( chunk );
+			if ( chunk.length < 100 ) break;
+			page++;
+		}
+
+		// The batch endpoint enforces a 100-item limit across all operations.
+		for ( let i = 0; i < allRates.length; i += 100 ) {
+			await restApi.post( `${ WC_API_PATH }/taxes/batch`, {
+				delete: allRates.slice( i, i + 100 ).map( ( rate ) => rate.id ),
+			} );
+		}
+	} );
+
+	await setup.step( 'clear orphaned tax classes', async () => {
+		// Specs that create a dedicated tax class (e.g. `cart.spec.ts`) clean up
+		// after themselves, but interrupted runs can leave orphaned classes. Remove
+		// any non-built-in class so the environment doesn't drift over time.
+		const BUILT_IN_SLUGS = new Set( [
+			'standard',
+			'reduced-rate',
+			'zero-rate',
+		] );
+		const { data: classes } = await restApi.get< { slug: string }[] >(
+			`${ WC_API_PATH }/taxes/classes`
+		);
+
+		await Promise.all(
+			classes
+				.filter( ( cls ) => ! BUILT_IN_SLUGS.has( cls.slug ) )
+				.map( ( cls ) =>
+					restApi.delete(
+						`${ WC_API_PATH }/taxes/classes/${ cls.slug }`,
+						{ force: true }
+					)
+				)
+		);
+	} );
+
+	await setup.step( 'enable offline payment gateways', async () => {
+		// Enable COD and BACS once for the whole shared site so specs that need an
+		// offline gateway at checkout don't each toggle them on/off. Toggling a
+		// gateway off in a spec's afterAll would disable it for every other worker
+		// mid-run, so the gateways are owned by the baseline instead. Set explicitly
+		// rather than relying on defaults (both ship disabled on a fresh install).
+		await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
+			enabled: true,
+		} );
+		await restApi.put( `${ WC_API_PATH }/payment_gateways/bacs`, {
+			enabled: true,
+		} );
+	} );
+
+	await setup.step( 'enable baseline free shipping', async () => {
+		// Provide one deterministic, always-available shipping method for every
+		// cart so specs that complete checkout don't each create/delete their own
+		// shipping zone. Concurrent zone churn makes shipping availability
+		// non-deterministic, which destabilises the block/classic checkout address
+		// rendering (a shipping method appearing or disappearing flips whether a
+		// separate billing group / "Use same address for billing" checkbox shows).
+		// Attach free shipping to zone 0 ("Locations not covered by your other
+		// zones"), the catch-all fallback, so any cart not matched by a more
+		// specific zone is offered free shipping. Free (cost 0) leaves order totals
+		// unchanged. Idempotent: only add the method if it isn't already there.
+		const { data: methods } = await restApi.get< { method_id: string }[] >(
+			`${ WC_API_PATH }/shipping/zones/0/methods`
+		);
+
+		if ( ! methods.some( ( m ) => m.method_id === 'free_shipping' ) ) {
+			await restApi.post( `${ WC_API_PATH }/shipping/zones/0/methods`, {
+				method_id: 'free_shipping',
+			} );
+		}
+	} );
 } );
diff --git a/plugins/woocommerce/tests/e2e/playwright.config.ts b/plugins/woocommerce/tests/e2e/playwright.config.ts
index 97460bb9e32..6e8e6281abf 100644
--- a/plugins/woocommerce/tests/e2e/playwright.config.ts
+++ b/plugins/woocommerce/tests/e2e/playwright.config.ts
@@ -114,6 +114,85 @@ export const setupProjects = [
 	},
 ];

+/**
+ * Spec folders that must run serially in `core-serial` (they mutate global
+ * state or share fixtures). Every other folder under `tests/` runs in
+ * `core-parallel` by default, except the other-project folders in `nonCoreSpecs`.
+ */
+const serialRunSpecs = [
+	// Drains the whole store's Action Scheduler queue via `?process-waiting-actions`
+	// (other workers' order/product churn floods it past the 10s timeout) and asserts
+	// exact store-wide totals, polluted by concurrent orders.
+	'**/tests/analytics/analytics-data.spec.ts',
+	// Asserts store-wide `$0.00 / Orders 0`, polluted by concurrent orders.
+	'**/tests/analytics/analytics-access.spec.ts',
+	// Mutates the shared admin's `woocommerce_meta.dashboard_sections` and flips the
+	// global `woocommerce_analytics_scheduled_import` option (racing analytics-settings).
+	'**/tests/analytics/analytics-overview.spec.ts',
+	// Flips the global `woocommerce_default_customer_address` (geolocation) and
+	// `woocommerce_enable_ajax_add_to_cart` settings, which change add-to-cart
+	// behavior for every other worker. (`cart.spec.ts` runs in core-parallel — it
+	// scopes its tax rate to a dedicated tax class instead of toggling global tax.)
+	'**/tests/cart/add-to-cart.spec.ts',
+	// Activates a custom-gateway test plugin globally, which would surface its extra
+	// payment button on every other worker's checkout.
+	'**/tests/checkout/checkout-shortcode-custom-place-order-button.spec.ts',
+	// Every spec toggles a global email feature flag via `setOption`:
+	// `editor-tracking-selectors`/`settings-email-listing` flip
+	// `woocommerce_feature_block_email_editor_enabled`, while `account-emails`/
+	// `order-emails`/`settings-email` flip `woocommerce_feature_email_improvements_enabled`.
+	// Run in parallel they race on those options — one file's afterAll disables the
+	// editor (or flips improvements) mid-test for the others. Proven not parallel-safe:
+	// an email-only `core-parallel` run failed across all three clusters.
+	'**/tests/email/**/*.spec.ts',
+	// Each spec toggles the global `woocommerce_feature_block_email_editor_enabled`
+	// flag in beforeAll/afterAll; running the files concurrently races on that option
+	// (`e2e-options/update` returns 400 "Update option FAILED") and the first file's
+	// afterAll disables the editor mid-test for the others. Proven not parallel-safe.
+	'**/tests/email-editor/**/*.spec.ts',
+	// Mutate the global onboarding profile/options, site-visibility options and
+	// the active theme.
+	'**/tests/onboarding/**/*.spec.ts',
+	// Toggles the global `woocommerce_downloads_grant_access_after_payment` setting.
+	'**/tests/order/order-edit.spec.ts',
+	// Submits and deletes product reviews via the Review Order form while it runs;
+	// that concurrent churn on the shared reviews list makes `product-reviews`'
+	// trash/undo/re-trash flow intermittently fail (proven by bisect: moving it
+	// serial turns 3 consecutive product-reviews failures green).
+	'**/tests/order/review-order-page.spec.ts',
+	// Imports a fixed-content CSV (fixed SKUs/names) and asserts the imported rows
+	// on the store-wide product list — collides with concurrently created products.
+	'**/tests/product/product-import-csv.spec.ts',
+	// Mutate global WooCommerce settings (store address/currency/country, tax)
+	// that other workers' cart/checkout/storefront specs depend on.
+	'**/tests/settings/settings-general.spec.ts',
+	'**/tests/settings/settings-tax.spec.ts',
+	// Unchecks and saves `woocommerce_enable_reviews`, flipping that global option
+	// to `no` mid-run (restored only in afterAll). While off, the front-end Reviews
+	// tab and admin review management disappear — proven to deterministically fail 3
+	// `product/product-reviews.spec.ts` tests (shopper post + the edit/reply Reviews
+	// tab assertions). Also toggles the global `settings-ui` feature flag and resets
+	// ALL e2e feature flags in afterAll.
+	'**/tests/settings/settings-ui-feature-flag.spec.ts',
+	// Toggles the global `woocommerce_cart_redirect_after_add` setting, which
+	// changes add-to-cart behavior for every other worker — not parallel-safe.
+	'**/tests/shop/cart-redirection.spec.ts',
+	// Trashes and restores the global Shop page in a fixture; while trashed, every
+	// other worker's shop/cart/account navigation 404s.
+	'**/tests/shop/shop-title-after-deletion.spec.ts',
+];
+
+/**
+ * Spec folders owned by other Playwright projects — excluded from both core projects.
+ * PayPal tests don't run well in parallel (https://github.com/woocommerce/woocommerce/pull/63068);
+ * blocks specs need the `blocks setup` project and its storage state.
+ */
+const nonCoreSpecs = [
+	'**/api-tests/**',
+	'**/tests/paypal/**',
+	'**/tests/blocks/**',
+];
+
 export default defineConfig( {
 	timeout: 120 * 1000,
 	expect: { timeout: CI ? 20 * 1000 : 10 * 1000 },
@@ -121,7 +200,6 @@ export default defineConfig( {
 	testDir: `${ TESTS_ROOT_PATH }/tests`,
 	retries: CI ? 1 : 0,
 	repeatEach: REPEAT_EACH ? Number( REPEAT_EACH ) : 1,
-	workers: 1,
 	reportSlowTests: { max: 5, threshold: 30 * 1000 }, // 30 seconds threshold
 	reporter,
 	maxFailures: E2E_MAX_FAILURES ? Number( E2E_MAX_FAILURES ) : 0,
@@ -139,7 +217,7 @@ export default defineConfig( {
 		contextOptions: {
 			reducedMotion: 'reduce',
 		},
-		channel: 'chrome',
+		channel: 'chromium',
 		...devices[ 'Desktop Chrome' ],
 	},
 	snapshotPathTemplate: '{testDir}/{testFilePath}-snapshots/{arg}',
@@ -147,37 +225,40 @@ export default defineConfig( {
 	projects: [
 		...setupProjects,
 		{
-			name: 'e2e',
-			testIgnore: [
-				'**/api-tests/**',
-				/* Exclude PayPal tests, as they don't run well in parallel - see https://github.com/woocommerce/woocommerce/pull/63068. */
-				'**/tests/paypal/**',
-				/* Blocks specs are run by the blocks-chromium and blocks-legacy-mini-cart projects below. */
-				'**/tests/blocks/**',
-			],
+			name: 'core-serial',
+			testMatch: serialRunSpecs,
+			dependencies: [ 'site setup' ],
+			workers: 1,
+		},
+		{
+			name: 'core-parallel',
+			testIgnore: [ ...serialRunSpecs, ...nonCoreSpecs ],
 			dependencies: [ 'site setup' ],
 		},
 		{
 			name: 'api',
 			testMatch: '**/api-tests/**',
 			dependencies: [ 'site setup' ],
+			workers: 4,
 		},
 		{
 			name: 'legacy-mini-cart',
 			testMatch: [ '**/tests/cart/**', '**/tests/checkout/**' ],
 			testIgnore: [ '**/tests/blocks/**' ],
 			dependencies: [ 'site setup' ],
+			workers: 1,
 		},
 		{
 			name: 'paypal-standard',
 			testMatch: [ '**/tests/paypal/**' ],
 			dependencies: [ 'site setup' ],
+			workers: 1,
 		},
 		{
 			name: 'blocks-chromium',
 			testDir: `${ TESTS_ROOT_PATH }/tests/blocks`,
 			dependencies: [ 'blocks setup' ],
-			fullyParallel: true,
+			workers: 1,
 			use: {
 				...devices[ 'Desktop Chrome' ],
 				storageState: BLOCKS_ADMIN_STATE,
@@ -193,7 +274,7 @@ export default defineConfig( {
 				'**/product-collection/**/*.spec.ts',
 			],
 			dependencies: [ 'blocks setup' ],
-			fullyParallel: true,
+			workers: 1,
 			use: {
 				...devices[ 'Desktop Chrome' ],
 				storageState: BLOCKS_ADMIN_STATE,
diff --git a/plugins/woocommerce/tests/e2e/tests/api-tests/payment-gateways/payment-gateways-crud.test.ts b/plugins/woocommerce/tests/e2e/tests/api-tests/payment-gateways/payment-gateways-crud.test.ts
index 9883c55588a..36d92f1d61f 100644
--- a/plugins/woocommerce/tests/e2e/tests/api-tests/payment-gateways/payment-gateways-crud.test.ts
+++ b/plugins/woocommerce/tests/e2e/tests/api-tests/payment-gateways/payment-gateways-crud.test.ts
@@ -27,7 +27,8 @@ test.describe( 'Payment Gateways API tests', () => {
 					description:
 						'Make your payment directly into our bank account. Please use your Order ID as the payment reference. Your order will not be shipped until the funds have cleared in our account.',
 					order: '',
-					enabled: false,
+					// Enabled by the shared site setup (offline gateway baseline).
+					enabled: true,
 					method_title: 'Direct bank transfer',
 					method_description:
 						'Take payments in person via BACS. More commonly known as direct bank/wire transfer.',
@@ -108,7 +109,8 @@ test.describe( 'Payment Gateways API tests', () => {
 					title: 'Cash on delivery',
 					description: 'Pay with cash upon delivery.',
 					order: '',
-					enabled: false,
+					// Enabled by the shared site setup (offline gateway baseline).
+					enabled: true,
 					method_title: 'Cash on delivery',
 					method_description:
 						'Let your shoppers pay upon delivery — by cash or other methods of payment.',
@@ -159,10 +161,15 @@ test.describe( 'Payment Gateways API tests', () => {
 						'Flat rate': {
 							flat_rate: 'Any &quot;Flat rate&quot; method',
 						},
-						'Free shipping': {
+						// The shared site setup attaches a free shipping method
+						// instance to zone 0, which adds a per-instance entry
+						// (free_shipping:<id>) alongside the base option. The
+						// instance ID is non-deterministic, so only assert the
+						// base option and tolerate the baseline instance.
+						'Free shipping': expect.objectContaining( {
 							free_shipping:
 								'Any &quot;Free shipping&quot; method',
-						},
+						} ),
 						'Local pickup': {
 							pickup_location:
 								'Any &quot;Local pickup&quot; method',
@@ -199,7 +206,8 @@ test.describe( 'Payment Gateways API tests', () => {
 				description:
 					'Make your payment directly into our bank account. Please use your Order ID as the payment reference. Your order will not be shipped until the funds have cleared in our account.',
 				order: '',
-				enabled: false,
+				// Enabled by the shared site setup (offline gateway baseline).
+				enabled: true,
 				method_title: 'Direct bank transfer',
 				method_description:
 					'Take payments in person via BACS. More commonly known as direct bank/wire transfer.',
@@ -233,12 +241,13 @@ test.describe( 'Payment Gateways API tests', () => {
 	} );

 	test( 'can update a payment gateway', async ( { request } ) => {
-		// call API to update a payment gateway
+		// BACS is enabled by the shared site setup, so toggle it off to prove the
+		// update works, then restore the baseline so no global state leaks.
 		const response = await request.put(
 			'./wp-json/wc/v3/payment_gateways/bacs',
 			{
 				data: {
-					enabled: true,
+					enabled: false,
 				},
 			}
 		);
@@ -247,14 +256,14 @@ test.describe( 'Payment Gateways API tests', () => {

 		expect( responseJSON ).toEqual(
 			expect.objectContaining( {
-				enabled: true,
+				enabled: false,
 			} )
 		);

-		// reset payment gateway setting
+		// restore the baseline payment gateway setting
 		await request.put( './wp-json/wc/v3/payment_gateways/bacs', {
 			data: {
-				enabled: false,
+				enabled: true,
 			},
 		} );
 	} );
diff --git a/plugins/woocommerce/tests/e2e/tests/brands/create-product-brand.spec.ts b/plugins/woocommerce/tests/e2e/tests/brands/create-product-brand.spec.ts
index 26840ef4491..9e09e710e43 100644
--- a/plugins/woocommerce/tests/e2e/tests/brands/create-product-brand.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/brands/create-product-brand.spec.ts
@@ -61,8 +61,12 @@ test( 'Merchant can add brands', async ( { page } ) => {
 			.fill( brand.description );
 		await page.getByRole( 'button', { name: 'Upload/Add image' } ).click();
 		await page.getByRole( 'tab', { name: 'Media Library' } ).click();
+		// `.first()` guards against duplicate fixture media sharing a title — the
+		// `wp media import` in test-env-setup.sh is not idempotent, so re-running it
+		// can leave several attachments named e.g. `image-01`.
 		await page
 			.getByRole( 'checkbox', { name: brand.thumbnailFileName } )
+			.first()
 			.click();
 		await page.getByRole( 'button', { name: 'Use image' } ).click();
 		await page.getByRole( 'button', { name: 'Add New Brand' } ).click();
@@ -103,7 +107,7 @@ test( 'Merchant can add brands', async ( { page } ) => {

 		await page.getByRole( 'button', { name: 'Upload/Add image' } ).click();
 		await page.getByRole( 'tab', { name: 'Media Library' } ).click();
-		await page.getByLabel( brand.thumbnailFileName ).click();
+		await page.getByLabel( brand.thumbnailFileName ).first().click();
 		await page.getByRole( 'button', { name: 'Use image' } ).click();

 		await page.getByRole( 'button', { name: 'Update' } ).click();
diff --git a/plugins/woocommerce/tests/e2e/tests/cart/cart.spec.ts b/plugins/woocommerce/tests/e2e/tests/cart/cart.spec.ts
index 51301e696bf..0336daac4d8 100644
--- a/plugins/woocommerce/tests/e2e/tests/cart/cart.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/cart/cart.spec.ts
@@ -14,7 +14,8 @@ import { expect, tags, test as baseTest } from '../../fixtures/fixtures';
 import { getFakeProduct } from '../../utils/data';
 import { createClassicCartPage, CLASSIC_CART_PAGE } from '../../utils/pages';
 import { checkCartContent } from '../../utils/cart';
-import { updateIfNeeded, resetValue } from '../../utils/settings';
+import { setGatewayEnabled } from '../../utils/payment-gateways';
+import { withScopedTaxClass } from '../../utils/taxes';

 const cartPages = [ { name: 'blocks cart', slug: 'cart' }, CLASSIC_CART_PAGE ];

@@ -27,55 +28,20 @@ const test = baseTest.extend( {
 	page: async ( { page, restApi }, use ) => {
 		await createClassicCartPage();

-		const calcTaxesState = await updateIfNeeded(
-			`general/woocommerce_calc_taxes`,
-			'yes'
-		);
-
-		// Check id COD payment is enabled and enable it if it is not
-		const codResponse = await restApi.get(
-			`${ WC_API_PATH }/payment_gateways/cod`
-		);
-		const codEnabled = codResponse.enabled;
-
-		if ( ! codEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: true,
-			} );
-		}
-
-		// Check id BACS payment is enabled and enable it if it is not
-		const bacsResponse = await restApi.get(
-			`${ WC_API_PATH }/payment_gateways/bacs`
-		);
-		const bacsEnabled = bacsResponse.enabled;
-
-		if ( ! bacsEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/bacs`, {
-				enabled: true,
-			} );
-		}
+		// COD and BACS are enabled globally in site setup; guard defensively in
+		// case they are somehow off, and restore their prior state afterwards.
+		const codWasEnabled = await setGatewayEnabled( restApi, 'cod', true );
+		const bacsWasEnabled = await setGatewayEnabled( restApi, 'bacs', true );

 		await page.context().clearCookies();
 		await use( page );

 		// revert the settings to initial state

-		await resetValue( `general/woocommerce_calc_taxes`, calcTaxesState );
-
-		if ( ! codEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: codEnabled,
-			} );
-		}
-
-		if ( ! bacsEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/bacs`, {
-				enabled: bacsEnabled,
-			} );
-		}
+		await setGatewayEnabled( restApi, 'cod', codWasEnabled );
+		await setGatewayEnabled( restApi, 'bacs', bacsWasEnabled );
 	},
-	products: async ( { restApi }, use ) => {
+	products: async ( { restApi, tax }, use ) => {
 		const products = [];

 		// Using dec: 0 to avoid small rounding issues
@@ -85,6 +51,10 @@ const test = baseTest.extend( {
 					...getFakeProduct( { dec: 0 } ),
 					manage_stock: true,
 					stock_quantity: 3,
+					// Assign to this spec's own tax class so only these products
+					// are taxed; other workers' products use the standard class,
+					// which has no rate under the taxes-on baseline.
+					tax_class: tax.taxClassSlug,
 				} )
 				.then( ( response ) => {
 					products.push( response.data );
@@ -100,26 +70,9 @@ const test = baseTest.extend( {
 		}
 	},
 	tax: async ( { restApi }, use ) => {
-		let tax;
-		await restApi
-			.post( `${ WC_API_PATH }/taxes`, {
-				country: 'US',
-				state: '*',
-				cities: '*',
-				postcodes: '*',
-				rate: '25',
-				name: 'US Tax',
-				shipping: false,
-			} )
-			.then( ( r ) => {
-				tax = r.data;
-			} );
-
-		await use( tax );
-
-		await restApi.delete( `${ WC_API_PATH }/taxes/${ tax.id }`, {
-			force: true,
-		} );
+		// Products in the `products` fixture are assigned to this scoped class so
+		// only this spec's products are taxed; concurrent workers are unaffected.
+		await withScopedTaxClass( restApi, 'Cart Spec', use );
 	},
 } );
 /* endregion */
@@ -195,7 +148,7 @@ test(
 			// Verify undo link is no longer visible (cleanup occurred)
 			await expect(
 				page.getByRole( 'link', { name: 'Undo?' } )
-			).not.toBeVisible();
+			).toBeHidden();
 		} );
 	}
 );
diff --git a/plugins/woocommerce/tests/e2e/tests/checkout/checkout-link.spec.ts b/plugins/woocommerce/tests/e2e/tests/checkout/checkout-link.spec.ts
index c9c5d48c62d..5003b0fb552 100644
--- a/plugins/woocommerce/tests/e2e/tests/checkout/checkout-link.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/checkout/checkout-link.spec.ts
@@ -2,6 +2,7 @@
  * External dependencies
  */
 import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
+import { faker } from '@faker-js/faker';

 /**
  * Internal dependencies
@@ -41,9 +42,14 @@ const test = baseTest.extend( {
 	},
 	coupon: async ( { restApi }, use ) => {
 		let coupon;
+		// Unique code per worker so parallel runs don't collide on a duplicate
+		// coupon code (WC rejects duplicates with a 400).
+		const code = `E2ECOUPON${ faker.string
+			.alphanumeric( 6 )
+			.toUpperCase() }`;
 		await restApi
 			.post( `${ WC_API_PATH }/coupons`, {
-				code: 'E2ECOUPON',
+				code,
 				discount_type: 'percent',
 				amount: '10',
 			} )
@@ -84,7 +90,7 @@ test.describe( 'Checkout Link Endpoint', () => {

 				// Assert coupon is applied
 				await expect(
-					page.getByText( 'Coupon: E2ECOUPON' )
+					page.getByText( `Coupon: ${ coupon.code }` )
 				).toBeVisible();
 			}
 		);
@@ -208,7 +214,7 @@ test.describe( 'Checkout Link Endpoint', () => {

 				// Assert coupon is applied
 				await expect(
-					page.getByText( 'Coupon: E2ECOUPON' )
+					page.getByText( `Coupon: ${ coupon.code }` )
 				).toBeVisible();
 			}
 		);
diff --git a/plugins/woocommerce/tests/e2e/tests/checkout/checkout-shortcode-custom-place-order-button.spec.ts b/plugins/woocommerce/tests/e2e/tests/checkout/checkout-shortcode-custom-place-order-button.spec.ts
index de322232394..27e8eb8b63a 100644
--- a/plugins/woocommerce/tests/e2e/tests/checkout/checkout-shortcode-custom-place-order-button.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/checkout/checkout-shortcode-custom-place-order-button.spec.ts
@@ -16,6 +16,7 @@ import {
 	CLASSIC_CHECKOUT_PAGE,
 } from '../../utils/pages';
 import { wpCLI } from '../../utils/cli';
+import { setGatewayEnabled } from '../../utils/payment-gateways';

 const test = baseTest.extend( {
 	page: async ( { page, restApi }, use ) => {
@@ -31,31 +32,25 @@ const test = baseTest.extend( {
 			`wp option set woocommerce_test-custom-button_settings --format=json '{"enabled":"yes"}'`
 		);

-		// Ensuring that COD is enabled, so it can _also_ be used during checkout.
-		const codResponse = await restApi.get(
-			`${ WC_API_PATH }/payment_gateways/cod`
-		);
-		const codEnabled = codResponse.enabled;
-
-		if ( ! codEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: true,
-			} );
-		}
+		// COD is enabled globally in site setup; guard defensively in case it is
+		// somehow off so it can _also_ be used during checkout.
+		const codWasEnabled = await setGatewayEnabled( restApi, 'cod', true );

 		await page.context().clearCookies();
 		await use( page );

-		// Cleanup: restoring COD and removing the custom gateway
+		// Cleanup: deactivate the test plugin so its custom gateway stops being
+		// registered on every checkout/order-pay page for the rest of the run.
+		// The gateway hardcodes `enabled = 'yes'` in its constructor, so deleting
+		// the option alone would NOT disable it — only deactivation does.
+		await wpCLI(
+			'wp plugin deactivate woocommerce-blocks-test-plugins/custom-place-order-button-test.php'
+		);
 		await wpCLI(
 			`wp option delete woocommerce_test-custom-button_settings`
 		);

-		if ( ! codEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: codEnabled,
-			} );
-		}
+		await setGatewayEnabled( restApi, 'cod', codWasEnabled );
 	},
 	product: async ( { restApi }, use ) => {
 		let product;
@@ -75,6 +70,35 @@ const test = baseTest.extend( {
 } );

 test.describe( 'Shortcode Checkout Custom Place Order Button', () => {
+	// The shared site setup attaches a free shipping method to zone 0, so every
+	// cart needs shipping. On the shortcode checkout that renders the collapsed
+	// "Ship to a different address?" block with hidden, empty required shipping
+	// fields. A custom place-order button's client-side validate() counts those
+	// hidden invalid fields and silently skips submission, so the order is never
+	// placed. Remove the baseline shipping for this spec so the cart does not
+	// need shipping, then restore it afterwards.
+	// TODO: Remove this workaround once the validation fix is merged.
+	// Bug fixed in https://github.com/woocommerce/woocommerce/pull/65933.
+	test.beforeAll( async ( { restApi } ) => {
+		const { data: methods } = await restApi.get<
+			{ instance_id: number }[]
+		>( `${ WC_API_PATH }/shipping/zones/0/methods` );
+
+		for ( const method of methods ) {
+			await restApi.delete(
+				`${ WC_API_PATH }/shipping/zones/0/methods/${ method.instance_id }`,
+				{ force: true }
+			);
+		}
+	} );
+
+	test.afterAll( async ( { restApi } ) => {
+		// Restore the baseline free shipping method on zone 0 (mirrors site setup).
+		await restApi.post( `${ WC_API_PATH }/shipping/zones/0/methods`, {
+			method_id: 'free_shipping',
+		} );
+	} );
+
 	test(
 		'clicking custom button triggers validation when form is invalid',
 		{ tag: [ tags.PAYMENTS ] },
diff --git a/plugins/woocommerce/tests/e2e/tests/checkout/checkout.spec.ts b/plugins/woocommerce/tests/e2e/tests/checkout/checkout.spec.ts
index 36655ae6023..c7ce4bc5330 100644
--- a/plugins/woocommerce/tests/e2e/tests/checkout/checkout.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/checkout/checkout.spec.ts
@@ -20,7 +20,12 @@ import {
 	CLASSIC_CHECKOUT_PAGE,
 } from '../../utils/pages';
 import { logInFromMyAccount } from '../../utils/login';
+import { setGatewayEnabled } from '../../utils/payment-gateways';
 import { updateIfNeeded, resetValue } from '../../utils/settings';
+import {
+	assertTaxCalculationEnabled,
+	withScopedTaxClass,
+} from '../../utils/taxes';

 //todo handle other countries and states than the default (US, CA) when filling the addresses

@@ -126,14 +131,36 @@ async function fillBillingDetails( page: Page, data, createAccount: boolean ) {
 			.getByRole( 'textbox', { name: 'Email address' } )
 			.fill( data.email );

-		await fillBillingCheckoutBlocks( page, {
+		const addressDetails = {
 			firstName: data.first_name,
 			lastName: data.last_name,
 			address: data.address_1,
 			city: data.city,
 			zip: data.postcode,
 			phone: data.phone,
+		};
+
+		// In the block checkout the address form shown depends on whether the
+		// cart has a shipping method available: with one, it renders a shipping
+		// address (billing mirrors it via the checked "Use same address for
+		// billing"); with none, it renders a billing-only address. Fill whichever
+		// address group is rendered rather than assuming billing.
+		const shippingGroup = page.getByRole( 'group', {
+			name: 'Shipping address',
+		} );
+		const billingGroup = page.getByRole( 'group', {
+			name: 'Billing address',
 		} );
+		await shippingGroup
+			.or( billingGroup )
+			.first()
+			.waitFor( { state: 'visible' } );
+
+		if ( await shippingGroup.isVisible() ) {
+			await fillShippingCheckoutBlocks( page, addressDetails );
+		} else {
+			await fillBillingCheckoutBlocks( page, addressDetails );
+		}

 		if ( createAccount ) {
 			await page
@@ -151,10 +178,7 @@ const test = baseTest.extend( {
 	page: async ( { page, restApi }, use ) => {
 		await createClassicCheckoutPage();

-		const calcTaxesState = await updateIfNeeded(
-			'general/woocommerce_calc_taxes',
-			'yes'
-		);
+		await assertTaxCalculationEnabled( restApi );

 		const loginAtCheckoutState = await updateIfNeeded(
 			'account/woocommerce_enable_checkout_login_reminder',
@@ -166,37 +190,16 @@ const test = baseTest.extend( {
 			'yes'
 		);

-		// Check id COD payment is enabled and enable it if it is not
-		const codResponse = await restApi.get(
-			`${ WC_API_PATH }/payment_gateways/cod`
-		);
-		const codEnabled = codResponse.enabled;
-
-		if ( ! codEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: true,
-			} );
-		}
-
-		// Check id BACS payment is enabled and enable it if it is not
-		const bacsResponse = await restApi.get(
-			`${ WC_API_PATH }/payment_gateways/bacs`
-		);
-		const bacsEnabled = bacsResponse.enabled;
-
-		if ( ! bacsEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/bacs`, {
-				enabled: true,
-			} );
-		}
+		// COD and BACS are enabled globally in site setup; guard defensively in
+		// case they are somehow off, and restore their prior state afterwards.
+		const codWasEnabled = await setGatewayEnabled( restApi, 'cod', true );
+		const bacsWasEnabled = await setGatewayEnabled( restApi, 'bacs', true );

 		await page.context().clearCookies();
 		await use( page );

 		// revert the settings to initial state

-		await resetValue( 'general/woocommerce_calc_taxes', calcTaxesState );
-
 		await resetValue(
 			'account/woocommerce_enable_checkout_login_reminder',
 			loginAtCheckoutState
@@ -207,24 +210,21 @@ const test = baseTest.extend( {
 			signUpAtCheckoutState
 		);

-		if ( ! codEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: codEnabled,
-			} );
-		}
-
-		if ( ! bacsEnabled ) {
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/bacs`, {
-				enabled: bacsEnabled,
-			} );
-		}
+		await setGatewayEnabled( restApi, 'cod', codWasEnabled );
+		await setGatewayEnabled( restApi, 'bacs', bacsWasEnabled );
 	},
-	product: async ( { restApi }, use ) => {
+	product: async ( { restApi, tax }, use ) => {
 		let product;

 		// Using dec: 0 to avoid small rounding issues
 		await restApi
-			.post( `${ WC_API_PATH }/products`, getFakeProduct( { dec: 0 } ) )
+			.post( `${ WC_API_PATH }/products`, {
+				...getFakeProduct( { dec: 0 } ),
+				// Assign to this spec's own tax class so only this product is
+				// taxed; other workers' products use the standard class, which
+				// has no rate under the taxes-on baseline.
+				tax_class: tax.taxClassSlug,
+			} )
 			.then( ( response ) => {
 				product = response.data;
 			} );
@@ -236,26 +236,9 @@ const test = baseTest.extend( {
 		// } );
 	},
 	tax: async ( { restApi }, use ) => {
-		let tax;
-		await restApi
-			.post( `${ WC_API_PATH }/taxes`, {
-				country: 'US',
-				state: '*',
-				cities: '*',
-				postcodes: '*',
-				rate: '25',
-				name: 'US Tax',
-				shipping: false,
-			} )
-			.then( ( r ) => {
-				tax = r.data;
-			} );
-
-		await use( tax );
-
-		await restApi.delete( `${ WC_API_PATH }/taxes/${ tax.id }`, {
-			force: true,
-		} );
+		// The `product` fixture is assigned to this scoped class so only this
+		// spec's product is taxed; concurrent workers are unaffected.
+		await withScopedTaxClass( restApi, 'Checkout Spec', use );
 	},
 	customer: async ( { restApi }, use ) => {
 		const customerData = getFakeCustomer();
@@ -268,42 +251,15 @@ const test = baseTest.extend( {
 				customer.password = customerData.password;
 			} );

-		// add a shipping zone and method for the customer
-		let shippingZoneId: number;
-		await restApi
-			.post( `${ WC_API_PATH }/shipping/zones`, {
-				name: `Free Shipping ${ customerData.shipping.city }`,
-			} )
-			.then( ( response: { data: { id: number } } ) => {
-				shippingZoneId = response.data.id;
-			} );
-		await restApi.put(
-			`${ WC_API_PATH }/shipping/zones/${ shippingZoneId }/locations`,
-			[
-				{
-					code: `${ customerData.shipping.country }:${ customerData.shipping.state }`,
-					type: 'state',
-				},
-			]
-		);
-		await restApi.post(
-			`${ WC_API_PATH }/shipping/zones/${ shippingZoneId }/methods`,
-			{
-				method_id: 'free_shipping',
-			}
-		);
+		// Shipping is provided by the baseline free-shipping zone in site setup,
+		// so this fixture no longer creates its own zone (concurrent zone churn
+		// made shipping availability non-deterministic at checkout).

 		await use( customer );

 		await restApi.delete( `${ WC_API_PATH }/customers/${ customer.id }`, {
 			force: true,
 		} );
-		await restApi.delete(
-			`${ WC_API_PATH }/shipping/zones/${ shippingZoneId }`,
-			{
-				force: true,
-			}
-		);
 	},
 } );
 /* endregion */
@@ -410,12 +366,34 @@ checkoutPages.forEach( ( { name, slug } ) => {
 				false
 			);

-			// Make sure after login the user is redirected to the right checkout page
-			// Login from classic checkout redirects to default checkout page: https://github.com/woocommerce/woocommerce/issues/56205
-			// Workaround until bug is fixed: extra navigation the test checkout page
+			// The at-checkout login is submitted with assertSuccess=false, so it
+			// isn't fully awaited, and its redirect target is unreliable
+			// (https://github.com/woocommerce/woocommerce/issues/56205). Under
+			// parallel load the session can lag, leaving the checkout in a guest
+			// state with an empty contact email that blocks the order. Confirm the
+			// session is established via My account before returning to checkout.
+			await page.goto( 'my-account/' );
+			await expect(
+				page
+					.getByLabel( 'Account pages' )
+					.getByRole( 'link', { name: 'Log out' } )
+			).toBeVisible();
+
 			await page.goto( slug );
 			await expect( page.url() ).toContain( slug );

+			// Block checkout hydrates the logged-in customer's contact email
+			// asynchronously from the Store API cart; under parallel load that
+			// can lag behind navigation, leaving the field empty and blocking
+			// the order. Wait for it to populate before placing the order.
+			if ( ! isClassicCheckout( page ) ) {
+				await expect(
+					page
+						.getByRole( 'textbox', { name: 'Email address' } )
+						.first()
+				).not.toHaveValue( '' );
+			}
+
 			await checkOrderDetails( page, product, qty, tax );

 			const shippingAddress = {
diff --git a/plugins/woocommerce/tests/e2e/tests/coupons/cart-checkout-coupons.spec.ts b/plugins/woocommerce/tests/e2e/tests/coupons/cart-checkout-coupons.spec.ts
index cf39fd6ddcb..c514e963ac9 100644
--- a/plugins/woocommerce/tests/e2e/tests/coupons/cart-checkout-coupons.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/coupons/cart-checkout-coupons.spec.ts
@@ -11,7 +11,6 @@ import {
  */
 import { tags, test, expect } from '../../fixtures/fixtures';
 import { createClassicCartPage, CLASSIC_CART_PAGE } from '../../utils/pages';
-import { updateIfNeeded } from '../../utils/settings';

 const firstProductName = 'Coupon test product';
 const coupon = {
@@ -31,8 +30,6 @@ test.describe(
 			// Make sure the classic cart page exists.
 			await createClassicCartPage();

-			await updateIfNeeded( 'general/woocommerce_calc_taxes', 'no' );
-
 			// Make sure the currency is USD.
 			await restApi.put(
 				`${ WC_API_PATH }/settings/general/woocommerce_currency`,
diff --git a/plugins/woocommerce/tests/e2e/tests/coupons/cart-checkout-restricted-coupons.spec.ts b/plugins/woocommerce/tests/e2e/tests/coupons/cart-checkout-restricted-coupons.spec.ts
index 69f9a05de19..9aa133c4170 100644
--- a/plugins/woocommerce/tests/e2e/tests/coupons/cart-checkout-restricted-coupons.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/coupons/cart-checkout-restricted-coupons.spec.ts
@@ -7,11 +7,13 @@ import {
 	getOrderIdFromUrl,
 	WC_API_PATH,
 } from '@woocommerce/e2e-utils-playwright';
+import { faker } from '@faker-js/faker';

 /**
  * Internal dependencies
  */
 import { tags, test, expect } from '../../fixtures/fixtures';
+import { setGatewayEnabled } from '../../utils/payment-gateways';
 import {
 	createClassicCartPage,
 	createClassicCheckoutPage,
@@ -22,6 +24,15 @@ import {
 const includedProductName = 'Included test product';
 const includedCategoryName = 'Included Category';

+// Coupon codes are global: suffix each with a random token so a run never
+// collides with a concurrent or leftover coupon of the same code. WooCommerce
+// stores codes lowercased, so keep the suffix lowercase for the error-message
+// assertions (which echo the stored code) to match.
+const couponSuffix = faker.string.alphanumeric( 8 ).toLowerCase();
+const EXPIRED_COUPON = `expired-coupon-${ couponSuffix }`;
+const INCLUDED_COUPON = `product-and-category-included-${ couponSuffix }`;
+const EMAIL_RESTRICTED_COUPON = `email-restricted-${ couponSuffix }`;
+
 const applyCoupon = async ( page: Page, couponCode: string ) => {
 	const responsePromise = page.waitForResponse(
 		( response ) =>
@@ -57,9 +68,8 @@ test.describe(
 	'Cart & Checkout Restricted Coupons',
 	{ tag: [ tags.PAYMENTS, tags.SERVICES, tags.HPOS ] },
 	() => {
-		let firstProductId: number;
-		let firstCategoryId: number;
-		let shippingZoneId: number;
+		let firstProductId: number, firstCategoryId: number;
+		let codWasEnabled: boolean;
 		const couponBatchId: number[] = [];

 		test.beforeAll( async ( { restApi } ) => {
@@ -78,20 +88,12 @@ test.describe(
 				`${ WC_API_PATH }/settings/general/woocommerce_currency`,
 				{ value: 'USD' }
 			);
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: true,
-			} );
-			await restApi
-				.post( `${ WC_API_PATH }/shipping/zones`, {
-					name: 'Free Shipping',
-				} )
-				.then( ( response: { data: { id: number } } ) => {
-					shippingZoneId = response.data.id;
-				} );
-			await restApi.post(
-				`${ WC_API_PATH }/shipping/zones/${ shippingZoneId }/methods`,
-				{ method_id: 'free_shipping' }
-			);
+			// COD is enabled globally in site setup; guard defensively in case it
+			// is somehow off, and restore its prior state in afterAll.
+			codWasEnabled = await setGatewayEnabled( restApi, 'cod', true );
+			// Free shipping is provided by the baseline zone in site setup, so this
+			// spec no longer creates its own (catch-all) shipping zone — that zone
+			// added a shipping method to every concurrent worker's cart.
 			await restApi
 				.post( `${ WC_API_PATH }/products/categories`, {
 					name: includedCategoryName,
@@ -112,20 +114,20 @@ test.describe(

 			const residualCoupons = [
 				{
-					code: 'expired-coupon',
+					code: EXPIRED_COUPON,
 					discount_type: 'fixed_cart',
 					amount: '10.00',
 					date_expires: '2020-01-01T00:00:00',
 				},
 				{
-					code: 'product-and-category-included',
+					code: INCLUDED_COUPON,
 					discount_type: 'fixed_cart',
 					amount: '10.00',
 					product_ids: [ firstProductId ],
 					product_categories: [ firstCategoryId ],
 				},
 				{
-					code: 'email-restricted',
+					code: EMAIL_RESTRICTED_COUPON,
 					discount_type: 'fixed_cart',
 					amount: '25.00',
 					email_restrictions: [ 'homer@example.com' ],
@@ -160,13 +162,8 @@ test.describe(
 			await restApi.post( `${ WC_API_PATH }/coupons/batch`, {
 				delete: [ ...couponBatchId ],
 			} );
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: false,
-			} );
-			await restApi.delete(
-				`${ WC_API_PATH }/shipping/zones/${ shippingZoneId }`,
-				{ force: true }
-			);
+
+			await setGatewayEnabled( restApi, 'cod', codWasEnabled );
 		} );

 		test( 'rejected coupon surfaces its error in cart and checkout', async ( {
@@ -176,9 +173,11 @@ test.describe(
 			await test.step( 'cart', async () => {
 				await addAProductToCart( page, firstProductId );
 				await page.goto( CLASSIC_CART_PAGE.slug );
-				await applyCoupon( page, 'expired-coupon' );
+				await applyCoupon( page, EXPIRED_COUPON );
 				await expect(
-					page.getByText( 'Coupon "expired-coupon" has expired.' )
+					page.getByText(
+						`Coupon "${ EXPIRED_COUPON }" has expired.`
+					)
 				).toBeVisible();
 			} );

@@ -188,9 +187,11 @@ test.describe(
 				await addAProductToCart( page, firstProductId );
 				await page.goto( CLASSIC_CHECKOUT_PAGE.slug );
 				await expandCouponForm( page );
-				await applyCoupon( page, 'expired-coupon' );
+				await applyCoupon( page, EXPIRED_COUPON );
 				await expect(
-					page.getByText( 'Coupon "expired-coupon" has expired.' )
+					page.getByText(
+						`Coupon "${ EXPIRED_COUPON }" has expired.`
+					)
 				).toBeVisible();
 			} );
 		} );
@@ -202,7 +203,7 @@ test.describe(
 			await test.step( 'cart', async () => {
 				await addAProductToCart( page, firstProductId );
 				await page.goto( CLASSIC_CART_PAGE.slug );
-				await applyCoupon( page, 'product-and-category-included' );
+				await applyCoupon( page, INCLUDED_COUPON );
 				await expect(
 					page.getByText( 'Coupon code applied successfully.' )
 				).toBeVisible();
@@ -214,7 +215,7 @@ test.describe(
 				await addAProductToCart( page, firstProductId );
 				await page.goto( CLASSIC_CHECKOUT_PAGE.slug );
 				await expandCouponForm( page );
-				await applyCoupon( page, 'product-and-category-included' );
+				await applyCoupon( page, INCLUDED_COUPON );
 				await expect(
 					page.getByText( 'Coupon code applied successfully.' )
 				).toBeVisible();
@@ -229,7 +230,7 @@ test.describe(
 			await page.goto( CLASSIC_CHECKOUT_PAGE.slug );
 			await fillBillingDetails( page, 'homer@example.com' );
 			await expandCouponForm( page );
-			await applyCoupon( page, 'email-restricted' );
+			await applyCoupon( page, EMAIL_RESTRICTED_COUPON );
 			await expect(
 				page.getByText( 'Coupon code applied successfully.' )
 			).toBeVisible();
@@ -244,7 +245,7 @@ test.describe(
 			await page.goto( CLASSIC_CHECKOUT_PAGE.slug );
 			await fillBillingDetails( page, 'homer@example.com' );
 			await expandCouponForm( page );
-			await applyCoupon( page, 'email-restricted' );
+			await applyCoupon( page, EMAIL_RESTRICTED_COUPON );
 			await expect(
 				page.getByText( 'Coupon code applied successfully.' )
 			).toBeVisible();
@@ -252,7 +253,7 @@ test.describe(
 			await page.getByRole( 'button', { name: 'Place order' } ).click();
 			await expect(
 				page.getByText(
-					'Usage limit for coupon "email-restricted" has been reached.'
+					`Usage limit for coupon "${ EMAIL_RESTRICTED_COUPON }" has been reached.`
 				)
 			).toBeVisible();

diff --git a/plugins/woocommerce/tests/e2e/tests/customer/customer-list.spec.ts b/plugins/woocommerce/tests/e2e/tests/customer/customer-list.spec.ts
index d2c88144961..0b1d46f3451 100644
--- a/plugins/woocommerce/tests/e2e/tests/customer/customer-list.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/customer/customer-list.spec.ts
@@ -232,14 +232,15 @@ test.describe( 'Merchant > Customer List', () => {
 			await page.getByRole( 'button', { name: 'Download' } ).click();
 			const download = await downloadPromise;

-			const today = new Date();
-			const year = today.getFullYear();
-			const month = String( today.getMonth() + 1 ).padStart( 2, '0' );
-			const day = String( today.getDate() ).padStart( 2, '0' );
-
-			const filename = `customers_${ year }-${ month }-${ day }_orderby-date-last-active_order-desc_page-wc-admin_path--customers.csv`;
-
-			await expect( download.suggestedFilename() ).toBe( filename );
+			// The date in the filename is generated server-side (WordPress
+			// timezone), which can differ from the test runner's local date
+			// around a midnight boundary. Assert the filename structure with a
+			// YYYY-MM-DD date rather than pinning an exact local date, which is
+			// what this step actually verifies (the orderby/order/path encoding).
+			const filenamePattern =
+				/^customers_\d{4}-\d{2}-\d{2}_orderby-date-last-active_order-desc_page-wc-admin_path--customers\.csv$/;
+
+			expect( download.suggestedFilename() ).toMatch( filenamePattern );
 		} );
 	} );

diff --git a/plugins/woocommerce/tests/e2e/tests/editor/command-palette.spec.ts b/plugins/woocommerce/tests/e2e/tests/editor/command-palette.spec.ts
index a0bb3a271dc..6f9d43cd18d 100644
--- a/plugins/woocommerce/tests/e2e/tests/editor/command-palette.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/editor/command-palette.spec.ts
@@ -11,10 +11,6 @@ import { ADMIN_STATE_PATH } from '../../playwright.config';
 import { expect, test as baseTest } from '../../fixtures/fixtures';
 import { getInstalledWordPressVersion } from '../../utils/wordpress';

-// need to figure out whether tests are being run on a mac
-const macOS = process.platform === 'darwin';
-const cmdKeyCombo = macOS ? 'Meta+k' : 'Control+k';
-
 const clickOnCommandPaletteOption = async ( {
 	page,
 	optionName,
@@ -22,15 +18,30 @@ const clickOnCommandPaletteOption = async ( {
 	page: Page;
 	optionName: string;
 } ) => {
-	// Press `Ctrl` + `K` to open the command palette.
-	await page.keyboard.press( cmdKeyCombo );
-
 	// Using a regex here because Gutenberg changes the text of the placeholder
-	await page
-		.getByPlaceholder(
-			/Search (?:commands(?: and settings)?|for commands)/
+	const searchBox = page.getByPlaceholder(
+		/Search (?:commands(?: and settings)?|for commands)/
+	);
+
+	// Playwright's browser reports a non-Apple platform even on macOS, so picking the combo from
+	// reports a non-Apple platform even on macOS, so picking the combo from
+	// `process.platform` would send Meta+K while WordPress listens for Ctrl+K and
+	// the palette would never open. Derive the modifier from the page instead.
+	const isApplePlatform = await page.evaluate( () =>
+		/Mac|iPhone|iPod|iPad/i.test(
+			(
+				navigator as Navigator & {
+					userAgentData?: { platform?: string };
+				}
+			 ).userAgentData?.platform || navigator.platform
 		)
-		.fill( optionName );
+	);
+	const cmdKeyCombo = isApplePlatform ? 'Meta+k' : 'Control+k';
+
+	// Press `Ctrl`/`Cmd` + `K` to open the command palette.
+	await page.keyboard.press( cmdKeyCombo );
+
+	await searchBox.fill( optionName );

 	// TODO: WP 7.0 compat - WP 7.0 appends "Action" to command palette option
 	// accessible names. Simplify when WP 7.0 is the minimum supported version.
diff --git a/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/backward-compat.spec.ts b/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/backward-compat.spec.ts
index 9b0a00b6788..463f77c2c39 100644
--- a/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/backward-compat.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/backward-compat.spec.ts
@@ -15,7 +15,7 @@ import { createClient } from '@woocommerce/e2e-utils-playwright';
  * (second backfill is a no-op).
  *
  * Reviewing in Playwright UI mode:
- *   1. Run `npx playwright test --project=e2e tests/email-editor/update-propagation --ui`
+ *   1. Run `npx playwright test --project=core-serial tests/email-editor/update-propagation --ui`
  *   2. Filter the tree by `backward-compat` and pick a test.
  *   3. All tests are REST-only except "BC no mass-fire" which attaches a Tracks
  *      spy via the page fixture (but does not navigate or interact with the UI).
diff --git a/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/core-flows.spec.ts b/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/core-flows.spec.ts
index 7060ff78b67..5c4234c3cef 100644
--- a/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/core-flows.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/core-flows.spec.ts
@@ -12,7 +12,7 @@ import { test, expect } from '@playwright/test';
  * dismiss flow, and the review-drawer-driven selective merge.
  *
  * Reviewing in Playwright UI mode:
- *   1. Run `npx playwright test --project=e2e tests/email-editor/update-propagation --ui`
+ *   1. Run `npx playwright test --project=core-serial tests/email-editor/update-propagation --ui`
  *   2. Filter the tree by `core-flows` and pick a test.
  *   3. For UI tests, toggle "Show browser" (👁 in the top-left toolbar) to watch the
  *      Chromium window drive the admin. For REST-only tests the Actions panel
diff --git a/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/round-trip-idempotency.spec.ts b/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/round-trip-idempotency.spec.ts
index 7c06835a982..8ba76aa203f 100644
--- a/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/round-trip-idempotency.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/round-trip-idempotency.spec.ts
@@ -13,7 +13,7 @@ import { test, expect } from '@playwright/test';
  * post identically and writes no new meta.
  *
  * Reviewing in Playwright UI mode:
- *   1. Run `npx playwright test --project=e2e tests/email-editor/update-propagation --ui`
+ *   1. Run `npx playwright test --project=core-serial tests/email-editor/update-propagation --ui`
  *   2. Filter the tree by `round-trip` and pick a test.
  *   3. All four tests are REST-only — no browser window is driven. The Actions
  *      panel in UI mode shows the full REST call sequence for each test.
diff --git a/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/scope.spec.ts b/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/scope.spec.ts
index 9fc5ef7e06a..892f9e76dbe 100644
--- a/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/scope.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/email-editor/update-propagation/scope.spec.ts
@@ -13,7 +13,7 @@ import { test, expect } from '@playwright/test';
  * core_updated_customized for the merchant to review.
  *
  * Reviewing in Playwright UI mode:
- *   1. Run `npx playwright test --project=e2e tests/email-editor/update-propagation --ui`
+ *   1. Run `npx playwright test --project=core-serial tests/email-editor/update-propagation --ui`
  *   2. Filter the tree by `scope` and pick a test.
  *   3. The first test ("Non-opted-in") attaches a Tracks spy via the page fixture
  *      but performs no navigation or UI interaction. The other two tests are
diff --git a/plugins/woocommerce/tests/e2e/tests/my-account/my-account-downloads.spec.ts b/plugins/woocommerce/tests/e2e/tests/my-account/my-account-downloads.spec.ts
index 5f55532ca36..05bb5bf6966 100644
--- a/plugins/woocommerce/tests/e2e/tests/my-account/my-account-downloads.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/my-account/my-account-downloads.spec.ts
@@ -1,6 +1,7 @@
 /**
  * External dependencies
  */
+import { faker } from '@faker-js/faker';
 import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';

 /**
@@ -8,7 +9,7 @@ import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
  */
 import { expect, test } from '../../fixtures/fixtures';

-const randomNum = new Date().getTime().toString();
+const randomNum = faker.string.alphanumeric( 10 );
 const customer = {
 	username: `customer${ randomNum }`,
 	password: 'password',
diff --git a/plugins/woocommerce/tests/e2e/tests/my-account/my-account-pay-order.spec.ts b/plugins/woocommerce/tests/e2e/tests/my-account/my-account-pay-order.spec.ts
index 5db85f852d3..35d4191d132 100644
--- a/plugins/woocommerce/tests/e2e/tests/my-account/my-account-pay-order.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/my-account/my-account-pay-order.spec.ts
@@ -1,14 +1,16 @@
 /**
  * External dependencies
  */
+import { faker } from '@faker-js/faker';
 import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';

 /**
  * Internal dependencies
  */
 import { tags, test, expect } from '../../fixtures/fixtures';
+import { setGatewayEnabled } from '../../utils/payment-gateways';

-const randomNum = new Date().getTime().toString();
+const randomNum = faker.string.alphanumeric( 10 );
 const customer = {
 	username: `customer${ randomNum }`,
 	password: 'password',
@@ -20,6 +22,7 @@ test.describe(
 	{ tag: [ tags.PAYMENTS, tags.SERVICES, tags.HPOS ] },
 	() => {
 		let productId, orderId;
+		let codWasEnabled: boolean;

 		test.beforeAll( async ( { restApi } ) => {
 			// add product
@@ -59,10 +62,9 @@ test.describe(
 			await restApi.put( `${ WC_API_PATH }/orders/${ orderId }`, {
 				customer_id: customer.id,
 			} );
-			// enable COD payment
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: true,
-			} );
+			// COD is enabled globally in site setup; guard defensively in case it
+			// is somehow off, and restore its prior state in afterAll.
+			codWasEnabled = await setGatewayEnabled( restApi, 'cod', true );
 		} );

 		test.afterAll( async ( { restApi } ) => {
@@ -76,9 +78,7 @@ test.describe(
 				`${ WC_API_PATH }/customers/${ customer.id }`,
 				{ force: true }
 			);
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/cod`, {
-				enabled: false,
-			} );
+			await setGatewayEnabled( restApi, 'cod', codWasEnabled );
 		} );

 		test( 'allows customer to pay for their order in My Account', async ( {
diff --git a/plugins/woocommerce/tests/e2e/tests/order/create-order.spec.ts b/plugins/woocommerce/tests/e2e/tests/order/create-order.spec.ts
index 6ba22898d4d..077735ce2f8 100644
--- a/plugins/woocommerce/tests/e2e/tests/order/create-order.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/order/create-order.spec.ts
@@ -10,6 +10,7 @@ import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
 import { expect, tags, test as baseTest } from '../../fixtures/fixtures';
 import { random } from '../../utils/helpers';
 import { ADMIN_STATE_PATH } from '../../playwright.config';
+import { assertTaxCalculationEnabled } from '../../utils/taxes';

 const taxClasses = [
 	{
@@ -192,10 +193,10 @@ const test = baseTest.extend( {
 				product = response.data;
 			} );

-		for ( const key in variations ) {
-			restApi.post(
+		for ( const variation of variations ) {
+			await restApi.post(
 				`${ WC_API_PATH }/products/${ product.id }/variations`,
-				variations[ key ]
+				variation
 			);
 		}

@@ -277,13 +278,7 @@ test.describe(
 	{ tag: [ tags.SERVICES, tags.HPOS ] },
 	() => {
 		test.beforeAll( async ( { restApi } ) => {
-			// enable taxes on the account
-			await restApi.put(
-				`${ WC_API_PATH }/settings/general/woocommerce_calc_taxes`,
-				{
-					value: 'yes',
-				}
-			);
+			await assertTaxCalculationEnabled( restApi );
 			// add tax classes
 			for ( const taxClass of taxClasses ) {
 				await restApi.post(
@@ -318,13 +313,6 @@ test.describe(
 						}
 					);
 			}
-			// turn off taxes
-			await restApi.put(
-				`${ WC_API_PATH }/settings/general/woocommerce_calc_taxes`,
-				{
-					value: 'no',
-				}
-			);
 		} );

 		test( 'can create a simple guest order', async ( {
diff --git a/plugins/woocommerce/tests/e2e/tests/order/customer-payment-page.spec.ts b/plugins/woocommerce/tests/e2e/tests/order/customer-payment-page.spec.ts
index cb4324ca378..2d1a49f20a9 100644
--- a/plugins/woocommerce/tests/e2e/tests/order/customer-payment-page.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/order/customer-payment-page.spec.ts
@@ -7,11 +7,15 @@ import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
  * Internal dependencies
  */
 import { tags, expect, test } from '../../fixtures/fixtures';
+import { getFakeProduct } from '../../utils/data';
+import { setGatewayEnabled } from '../../utils/payment-gateways';
 import { ADMIN_STATE_PATH } from '../../playwright.config';

 let productId: number, orderId: number;
-const productName = 'Simple Product Name';
-const productPrice = '15.99';
+// Unique per run so concurrent workers don't create products with the same name.
+const product = getFakeProduct( { regular_price: '15.99' } );
+const productName = product.name;
+const productPrice = product.regular_price;

 test.describe(
 	'WooCommerce Merchant Flow: Orders > Customer Payment Page',
@@ -19,6 +23,8 @@ test.describe(
 	() => {
 		test.use( { storageState: ADMIN_STATE_PATH } );

+		let bacsWasEnabled: boolean;
+
 		test.beforeAll( async ( { restApi } ) => {
 			// create a simple product
 			await restApi
@@ -43,10 +49,9 @@ test.describe(
 				.then( ( response: { data: { id: number } } ) => {
 					orderId = response.data.id;
 				} );
-			// enable bank transfer as a payment option
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/bacs`, {
-				enabled: 'true',
-			} );
+			// BACS is enabled globally in site setup; guard defensively in case it
+			// is somehow off, and restore its prior state in afterAll.
+			bacsWasEnabled = await setGatewayEnabled( restApi, 'bacs', true );
 		} );

 		test.afterAll( async ( { restApi } ) => {
@@ -56,9 +61,7 @@ test.describe(
 			await restApi.delete( `${ WC_API_PATH }/orders/${ orderId }`, {
 				force: true,
 			} );
-			await restApi.put( `${ WC_API_PATH }/payment_gateways/bacs`, {
-				enabled: 'false',
-			} );
+			await setGatewayEnabled( restApi, 'bacs', bacsWasEnabled );
 		} );

 		test(
diff --git a/plugins/woocommerce/tests/e2e/tests/order/order-bulk-edit.spec.ts b/plugins/woocommerce/tests/e2e/tests/order/order-bulk-edit.spec.ts
index 86ad29e4d52..1f2a37a9da0 100644
--- a/plugins/woocommerce/tests/e2e/tests/order/order-bulk-edit.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/order/order-bulk-edit.spec.ts
@@ -1,6 +1,7 @@
 /**
  * External dependencies
  */
+import { faker } from '@faker-js/faker';
 import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';

 /**
@@ -15,140 +16,70 @@ test.describe(
 	() => {
 		test.use( { storageState: ADMIN_STATE_PATH } );

-		let orderId1: number,
-			orderId2: number,
-			orderId3: number,
-			orderId4: number,
-			orderId5: number;
+		// A few orders are enough to prove bulk editing works. They share a unique
+		// billing email so the orders list can be filtered down to just these rows,
+		// and we select only those rows (not "select all"). Together this keeps the
+		// test mutating only its own orders and immune to other workers' orders
+		// pushing it off the first page — safe to run in parallel.
+		const billingEmail = `bulk-edit-${ faker.string
+			.alphanumeric( 10 )
+			.toLowerCase() }@example.com`;
+		const orderIds: number[] = [];

 		test.beforeAll( async ( { restApi } ) => {
-			await restApi
-				.post( `${ WC_API_PATH }/orders`, {
-					status: 'processing',
-				} )
-				.then( ( response: { data: { id: number } } ) => {
-					orderId1 = response.data.id;
-				} );
-			await restApi
-				.post( `${ WC_API_PATH }/orders`, {
-					status: 'processing',
-				} )
-				.then( ( response: { data: { id: number } } ) => {
-					orderId2 = response.data.id;
-				} );
-			await restApi
-				.post( `${ WC_API_PATH }/orders`, {
-					status: 'processing',
-				} )
-				.then( ( response: { data: { id: number } } ) => {
-					orderId3 = response.data.id;
-				} );
-			await restApi
-				.post( `${ WC_API_PATH }/orders`, {
-					status: 'processing',
-				} )
-				.then( ( response: { data: { id: number } } ) => {
-					orderId4 = response.data.id;
-				} );
-			await restApi
-				.post( `${ WC_API_PATH }/orders`, {
-					status: 'processing',
-				} )
-				.then( ( response: { data: { id: number } } ) => {
-					orderId5 = response.data.id;
-				} );
+			for ( let i = 0; i < 3; i++ ) {
+				const response = await restApi.post(
+					`${ WC_API_PATH }/orders`,
+					{
+						status: 'processing',
+						billing: { email: billingEmail },
+					}
+				);
+				orderIds.push( response.data.id );
+			}
 		} );

 		test.afterAll( async ( { restApi } ) => {
-			await restApi.delete( `${ WC_API_PATH }/orders/${ orderId1 }`, {
-				force: true,
-			} );
-			await restApi.delete( `${ WC_API_PATH }/orders/${ orderId2 }`, {
-				force: true,
-			} );
-			await restApi.delete( `${ WC_API_PATH }/orders/${ orderId3 }`, {
-				force: true,
-			} );
-			await restApi.delete( `${ WC_API_PATH }/orders/${ orderId4 }`, {
-				force: true,
-			} );
-			await restApi.delete( `${ WC_API_PATH }/orders/${ orderId5 }`, {
-				force: true,
-			} );
+			await Promise.all(
+				orderIds.map( ( id ) =>
+					restApi.delete( `${ WC_API_PATH }/orders/${ id }`, {
+						force: true,
+					} )
+				)
+			);
 		} );

 		test( 'can bulk update order status', async ( { page } ) => {
-			await page.goto( 'wp-admin/admin.php?page=wc-orders' );
+			const orderRow = ( id: number ) =>
+				page.locator( `:is(#order-${ id }, #post-${ id })` );

-			// expect order status 'processing' to show
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId1 }, #post-${ orderId1 })` )
-					.getByText( 'Processing' )
-					.nth( 1 )
-			).toBeVisible();
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId2 }, #post-${ orderId2 })` )
-					.getByText( 'Processing' )
-					.nth( 1 )
-			).toBeVisible();
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId3 }, #post-${ orderId3 })` )
-					.getByText( 'Processing' )
-					.nth( 1 )
-			).toBeVisible();
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId4 }, #post-${ orderId4 })` )
-					.getByText( 'Processing' )
-					.nth( 1 )
-			).toBeVisible();
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId5 }, #post-${ orderId5 })` )
-					.getByText( 'Processing' )
-					.nth( 1 )
-			).toBeVisible();
+			// Filter the orders list to just this test's orders (shared billing
+			// email) so concurrently-created orders can't push them off the page.
+			await page.goto(
+				`wp-admin/admin.php?page=wc-orders&s=${ encodeURIComponent(
+					billingEmail
+				) }`
+			);
+
+			// Expect each created order to show 'Processing', then select its row.
+			for ( const id of orderIds ) {
+				await expect(
+					orderRow( id ).getByText( 'Processing' ).nth( 1 )
+				).toBeVisible();
+				await page.locator( `#cb-select-${ id }` ).check();
+			}

-			await page.locator( '#cb-select-all-1' ).click();
 			await page
 				.locator( '#bulk-action-selector-top' )
 				.selectOption( 'Change status to completed' );
 			await page.locator( '#doaction' ).click();

-			// expect order status 'completed' to show
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId1 }, #post-${ orderId1 })` )
-					.getByText( 'Completed' )
-					.nth( 1 )
-			).toBeVisible();
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId2 }, #post-${ orderId2 })` )
-					.getByText( 'Completed' )
-					.nth( 1 )
-			).toBeVisible();
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId3 }, #post-${ orderId3 })` )
-					.getByText( 'Completed' )
-					.nth( 1 )
-			).toBeVisible();
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId4 }, #post-${ orderId4 })` )
-					.getByText( 'Completed' )
-					.nth( 1 )
-			).toBeVisible();
-			await expect(
-				page
-					.locator( `:is(#order-${ orderId5 }, #post-${ orderId5 })` )
-					.getByText( 'Completed' )
-					.nth( 1 )
-			).toBeVisible();
+			// Expect only the selected orders to now show 'Completed'.
+			for ( const id of orderIds ) {
+				await expect(
+					orderRow( id ).getByText( 'Completed' ).nth( 1 )
+				).toBeVisible();
+			}
 		} );
 	}
 );
diff --git a/plugins/woocommerce/tests/e2e/tests/product/create-variable-product.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/create-variable-product.spec.ts
index 8ac91b27944..b38f52a9a82 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/create-variable-product.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/create-variable-product.spec.ts
@@ -9,10 +9,11 @@ import { test, expect } from '@playwright/test';
 import { variableProducts as utils, api } from '../../utils';
 import { tags } from '../../fixtures/fixtures';
 import { ADMIN_STATE_PATH } from '../../playwright.config';
+import { getFakeProduct } from '../../utils/data';

 const { showVariableProductTour } = utils;
 const productPageURL = 'wp-admin/post-new.php?post_type=product';
-const variableProductName = 'Variable Product with Three Variations';
+const variableProductName = getFakeProduct( { type: 'variable' } ).name;

 let productId: number;

diff --git a/plugins/woocommerce/tests/e2e/tests/product/product-create-simple.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/product-create-simple.spec.ts
index 4201ebc477a..40bda3f3a45 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/product-create-simple.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/product-create-simple.spec.ts
@@ -9,6 +9,11 @@ import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
 import { test as baseTest, expect, tags } from '../../fixtures/fixtures';
 import { ADMIN_STATE_PATH } from '../../playwright.config';
 import { checkCartContent } from '../../utils/cart';
+import {
+	getFakeAttribute,
+	getFakeCategory,
+	getFakeTag,
+} from '../../utils/data';

 const productData = {
 	virtual: {
@@ -62,10 +67,13 @@ const test = baseTest.extend( {
 	category: async ( { restApi }, use ) => {
 		let category = {};

+		// Use a random term so parallel workers don't collide on the same
+		// `Date.now()` category name (which fails with a 400 term_exists).
 		await restApi
-			.post( `${ WC_API_PATH }/products/categories`, {
-				name: `cat_${ Date.now() }`,
-			} )
+			.post(
+				`${ WC_API_PATH }/products/categories`,
+				getFakeCategory( { extraRandomTerm: true } )
+			)
 			.then( ( response ) => {
 				category = response.data;
 			} );
@@ -85,6 +93,11 @@ for ( const productType of Object.keys( productData ) ) {
 		`can create a simple ${ productType } product`,
 		{ tag: [ tags.GUTENBERG ] },
 		async ( { page, category, product } ) => {
+			// Unique global tags per test, so parallel workers don't share the
+			// same product_tag terms.
+			const productTag1 = getFakeTag().name;
+			const productTag2 = getFakeTag().name;
+
 			await test.step( 'add new product', async () => {
 				await page.goto( 'wp-admin/post-new.php?post_type=product' );
 			} );
@@ -126,7 +139,7 @@ for ( const productType of Object.keys( productData ) ) {

 			await test.step( 'add product attributes', async () => {
 				// Product attributes
-				const attributeName = 'attribute name';
+				const attributeName = getFakeAttribute().name;
 				await page
 					.locator( '#woocommerce-product-data' )
 					.getByRole( 'link', { name: 'Attributes' } )
@@ -175,17 +188,20 @@ for ( const productType of Object.keys( productData ) ) {
 				// Tags
 				await page
 					.getByLabel( 'Add new tag' )
-					.fill( 'e2e,test products' );
+					.fill( `${ productTag1 },${ productTag2 }` );
 				await page
 					.getByRole( 'button', { name: 'Add', exact: true } )
 					.click();
+
 				await expect(
-					page.locator( '#tagsdiv-product_tag li' ).getByText( 'e2e' )
+					page.getByRole( 'button', {
+						name: `Remove term: ${ productTag1 }`,
+					} )
 				).toBeVisible();
 				await expect(
-					page
-						.locator( '#tagsdiv-product_tag li' )
-						.getByText( 'test products' )
+					page.getByRole( 'button', {
+						name: `Remove term: ${ productTag2 }`,
+					} )
 				).toBeVisible();
 			} );

@@ -314,11 +330,11 @@ for ( const productType of Object.keys( productData ) ) {

 				// Verify tags
 				await expect(
-					page.getByRole( 'link', { name: 'e2e', exact: true } )
+					page.getByRole( 'link', { name: productTag1, exact: true } )
 				).toBeVisible();
 				await expect(
 					page.getByRole( 'link', {
-						name: 'test products',
+						name: productTag2,
 						exact: true,
 					} )
 				).toBeVisible();
@@ -329,8 +345,11 @@ for ( const productType of Object.keys( productData ) ) {
 				await page.context().clearCookies();
 				await page.reload();

+				// Use an exact match so the related-products block buttons
+				// ("Add to cart: <name>") that may show products created by
+				// parallel workers don't collide with the single product's button.
 				await page
-					.getByRole( 'button', { name: 'Add to cart' } )
+					.getByRole( 'button', { name: 'Add to cart', exact: true } )
 					.click();
 				await page.getByRole( 'link', { name: 'View cart' } ).click();

diff --git a/plugins/woocommerce/tests/e2e/tests/product/product-export.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/product-export.spec.ts
index 208931c7fbc..528e381b684 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/product-export.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/product-export.spec.ts
@@ -8,25 +8,21 @@ import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
  */
 import { test as baseTest, expect } from '../../fixtures/fixtures';
 import { ADMIN_STATE_PATH } from '../../playwright.config';
-
-const simpleProductName = 'Export Simple Product';
-const variableProductName = 'Export Variable Product';
+import { getFakeProduct } from '../../utils/data';

 const test = baseTest.extend( {
 	storageState: ADMIN_STATE_PATH,
 	productsFixture: async ( { restApi }, use ) => {
 		const products = {};

-		let response = await restApi.post( `${ WC_API_PATH }/products`, {
-			name: simpleProductName,
-			type: 'simple',
-			regular_price: '15',
-		} );
+		let response = await restApi.post(
+			`${ WC_API_PATH }/products`,
+			getFakeProduct()
+		);
 		products.simple = await response.data;

 		response = await restApi.post( `${ WC_API_PATH }/products`, {
-			name: variableProductName,
-			type: 'variable',
+			...getFakeProduct( { type: 'variable' } ),
 			attributes: [
 				{
 					name: 'Size',
diff --git a/plugins/woocommerce/tests/e2e/tests/product/product-grouped.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/product-grouped.spec.ts
index 221f955b180..7aabc327e0c 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/product-grouped.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/product-grouped.spec.ts
@@ -8,49 +8,39 @@ import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
  */
 import { test, expect, tags } from '../../fixtures/fixtures';
 import { checkCartContent } from '../../utils/cart';
-
-const productPrice = '18.16';
-const simpleProductName = 'Simple single product';
-const groupedProductName = 'Grouped single product';
+import { getFakeProduct } from '../../utils/data';

 let simpleProductId: number, simpleProduct2Id: number, groupedProductId: number;
+let groupedProductSlug: string;

 test.describe(
 	'Grouped Product Page',
 	{ tag: [ tags.PAYMENTS, tags.SERVICES ] },
 	() => {
-		const slug = groupedProductName.replace( / /gi, '-' ).toLowerCase();
-		const simpleProduct1 = simpleProductName + ' 1';
-		const simpleProduct2 = simpleProductName + ' 2';
+		const simpleProduct1 = getFakeProduct();
+		const simpleProduct2 = getFakeProduct();
+		const groupedProduct = getFakeProduct( { type: 'grouped' } );

 		test.beforeAll( async ( { restApi } ) => {
 			// add products
 			await restApi
-				.post( `${ WC_API_PATH }/products`, {
-					name: simpleProduct1,
-					type: 'simple',
-					regular_price: productPrice,
-				} )
+				.post( `${ WC_API_PATH }/products`, simpleProduct1 )
 				.then( ( response ) => {
 					simpleProductId = response.data.id;
 				} );
 			await restApi
-				.post( `${ WC_API_PATH }/products`, {
-					name: simpleProduct2,
-					type: 'simple',
-					regular_price: productPrice,
-				} )
+				.post( `${ WC_API_PATH }/products`, simpleProduct2 )
 				.then( ( response ) => {
 					simpleProduct2Id = response.data.id;
 				} );
 			await restApi
 				.post( `${ WC_API_PATH }/products`, {
-					name: groupedProductName,
-					type: 'grouped',
+					...groupedProduct,
 					grouped_products: [ simpleProductId, simpleProduct2Id ],
 				} )
 				.then( ( response ) => {
 					groupedProductId = response.data.id;
+					groupedProductSlug = response.data.slug;
 				} );
 		} );

@@ -83,7 +73,7 @@ test.describe(
 		test( 'should be able to add grouped products to the cart', async ( {
 			page,
 		} ) => {
-			await page.goto( `product/${ slug }` );
+			await page.goto( `product/${ groupedProductSlug }` );

 			await page
 				.getByRole( 'button', { name: 'Add to cart', exact: true } )
@@ -102,7 +92,7 @@ test.describe(
 			await expect(
 				page.getByText(
 					new RegExp(
-						`${ simpleProduct1 }.*and.*${ simpleProduct2 }.*have been added to your cart`
+						`${ simpleProduct1.name }.*and.*${ simpleProduct2.name }.*have been added to your cart`
 					)
 				)
 			).toBeVisible();
@@ -114,15 +104,15 @@ test.describe(
 				[
 					{
 						data: {
-							name: simpleProduct1,
-							price: productPrice,
+							name: simpleProduct1.name,
+							price: simpleProduct1.regular_price,
 						},
 						qty: 5,
 					},
 					{
 						data: {
-							name: simpleProduct2,
-							price: productPrice,
+							name: simpleProduct2.name,
+							price: simpleProduct2.regular_price,
 						},
 						qty: 5,
 					},
@@ -134,7 +124,7 @@ test.describe(
 		test( 'should be able to remove grouped products from the cart', async ( {
 			page,
 		} ) => {
-			await page.goto( `product/${ slug }` );
+			await page.goto( `product/${ groupedProductSlug }` );
 			await page.locator( 'div.quantity input.qty >> nth=0' ).fill( '1' );
 			await page.locator( 'div.quantity input.qty >> nth=1' ).fill( '1' );
 			await page
@@ -144,7 +134,7 @@ test.describe(
 			await expect(
 				page.getByText(
 					new RegExp(
-						`${ simpleProduct1 }.*and.*${ simpleProduct2 }.*have been added to your cart`
+						`${ simpleProduct1.name }.*and.*${ simpleProduct2.name }.*have been added to your cart`
 					)
 				)
 			).toBeVisible();
diff --git a/plugins/woocommerce/tests/e2e/tests/product/product-images.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/product-images.spec.ts
index d3fa825ed42..3124315c58d 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/product-images.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/product-images.spec.ts
@@ -16,7 +16,12 @@ async function addImageFromLibrary(
 	imageName: string,
 	actionButtonName: string
 ) {
-	await page.getByRole( 'tab', { name: 'Media Library' } ).click();
+	// The WordPress media modal can be slow to open under parallel load; wait
+	// for its "Media Library" tab with extra headroom beyond the default action
+	// timeout before clicking, so a slow-opening modal doesn't fail the test.
+	const mediaLibraryTab = page.getByRole( 'tab', { name: 'Media Library' } );
+	await mediaLibraryTab.waitFor( { state: 'visible', timeout: 30_000 } );
+	await mediaLibraryTab.click();
 	await page.getByRole( 'searchbox', { name: 'Search' } ).fill( imageName );
 	const imageLocator = page.getByLabel( imageName ).nth( 0 );
 	await imageLocator.click();
diff --git a/plugins/woocommerce/tests/e2e/tests/product/product-linked-products.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/product-linked-products.spec.ts
index df3d698dc56..e68e268f5a2 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/product-linked-products.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/product-linked-products.spec.ts
@@ -3,12 +3,14 @@
  */
 import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
 import type { Page } from '@playwright/test';
+import { faker } from '@faker-js/faker';

 /**
  * Internal dependencies
  */
 import { test as baseTest, expect, tags } from '../../fixtures/fixtures';
 import { ADMIN_STATE_PATH } from '../../playwright.config';
+import { getFakeProduct } from '../../utils/data';

 const test = baseTest.extend( {
 	storageState: ADMIN_STATE_PATH,
@@ -17,12 +19,18 @@ const test = baseTest.extend( {
 		const products = {};

 		for ( const key of Object.values( keys ) ) {
+			// `getFakeProduct` names products with `faker.commerce.productName()`,
+			// which is NOT globally unique — concurrent workers can generate the
+			// same name. This spec searches the store-wide product picker by name
+			// and selects the matching option, so a duplicate name yields 2+
+			// options and a strict-mode violation. Suffix a random token to make
+			// each product name unique across workers.
+			const fakeProduct = getFakeProduct();
+			fakeProduct.name = `${
+				fakeProduct.name
+			} ${ faker.string.alphanumeric( 8 ) }`;
 			await restApi
-				.post( `${ WC_API_PATH }/products`, {
-					name: `${ key } ${ Date.now() }`,
-					type: 'simple',
-					regular_price: '12.99',
-				} )
+				.post( `${ WC_API_PATH }/products`, fakeProduct )
 				.then( ( response ) => {
 					products[ key ] = response.data;
 				} );
diff --git a/plugins/woocommerce/tests/e2e/tests/product/product-search.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/product-search.spec.ts
index 2db4d9a14f3..822f0397eb5 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/product-search.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/product-search.spec.ts
@@ -8,23 +8,17 @@ import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
  */
 import { test, expect } from '../../fixtures/fixtures';
 import { ADMIN_STATE_PATH } from '../../playwright.config';
+import { getFakeProduct } from '../../utils/data';

 let productId: number;
-const productName = `Unique thing that we sell ${ new Date()
-	.getTime()
-	.toString() }`;
-const productPrice = '9.99';
+const testProduct = getFakeProduct( { regular_price: '9.99' } );

 test.describe( 'Products > Search and View a product', () => {
 	test.use( { storageState: ADMIN_STATE_PATH } );

 	test.beforeAll( async ( { restApi } ) => {
 		await restApi
-			.post( `${ WC_API_PATH }/products`, {
-				name: productName,
-				type: 'simple',
-				regular_price: productPrice,
-			} )
+			.post( `${ WC_API_PATH }/products`, testProduct )
 			.then( ( response ) => {
 				productId = response.data.id;
 			} );
@@ -38,7 +32,10 @@ test.describe( 'Products > Search and View a product', () => {

 	test( 'can do a partial search for a product', async ( { page } ) => {
 		// create a partial search string
-		const searchString = productName.substring( 0, productName.length / 2 );
+		const searchString = testProduct.name.substring(
+			0,
+			testProduct.name.length / 2
+		);

 		await page.goto( 'wp-admin/edit.php?post_type=product' );

@@ -46,9 +43,12 @@ test.describe( 'Products > Search and View a product', () => {
 		await page.locator( '#post-search-input' ).fill( searchString );
 		await page.locator( '#search-submit' ).click();

-		await expect( page.locator( '.row-title' ) ).toContainText(
-			productName
-		);
+		// A partial search can match products that parallel workers create from
+		// this same spec, so scope the assertion to this test's product instead
+		// of asserting on every `.row-title` match.
+		await expect(
+			page.locator( '.row-title', { hasText: testProduct.name } )
+		).toBeVisible();
 	} );

 	test( "can view a product's details after search", async ( { page } ) => {
@@ -56,15 +56,19 @@ test.describe( 'Products > Search and View a product', () => {

 		await page.goto( 'wp-admin/edit.php?post_type=product' );

-		await page.locator( '#post-search-input' ).fill( productName );
+		await page.locator( '#post-search-input' ).fill( testProduct.name );
 		await page.locator( '#search-submit' ).click();

-		await page.locator( '.row-title' ).click();
+		await page
+			.locator( '.row-title', { hasText: testProduct.name } )
+			.click();

 		await expect( page ).toHaveURL( productIdInURL );
-		await expect( page.locator( '#title' ) ).toHaveValue( productName );
+		await expect( page.locator( '#title' ) ).toHaveValue(
+			testProduct.name
+		);
 		await expect( page.locator( '#_regular_price' ) ).toHaveValue(
-			productPrice
+			testProduct.regular_price
 		);
 	} );

diff --git a/plugins/woocommerce/tests/e2e/tests/product/product-tags-attributes.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/product-tags-attributes.spec.ts
index d926c971443..fc36d9e49c6 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/product-tags-attributes.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/product-tags-attributes.spec.ts
@@ -13,27 +13,28 @@ import {
 /**
  * Internal dependencies
  */
-import { tags, test, expect } from '../../fixtures/fixtures';
+import { tags, test, expect, request } from '../../fixtures/fixtures';
 import { ADMIN_STATE_PATH } from '../../playwright.config';
 import { fillPageTitle } from '../../utils/editor';
+import { getFakeProduct, getFakeTag, getFakeAttribute } from '../../utils/data';
+import { setOption } from '../../utils/options';

 const pageTitle = 'Product Showcase';
-const singleProductPrice1 = '5.00';
-const singleProductPrice2 = '10.00';
-const singleProductPrice3 = '15.00';

-const productTagName1 = 'product tag 1';
-const productTagName2 = 'product tag 2';
-const productTagName3 = 'product tag 3';
+const productTagName1 = getFakeTag().name;
+const productTagName2 = getFakeTag().name;
+const productTagName3 = getFakeTag().name;

-const productAttributeName = 'color';
-const productAttributeTerm = 'red';
-
-const simpleProductName = 'Single Product With Tags';
+// Both the attribute and its term must be unique: the attribute creates a
+// global `pa_*` taxonomy and the term a global term within it, so a fixed name
+// would collide across parallel workers.
+const productAttributeName = getFakeAttribute().name;
+const productAttributeTerm = getFakeAttribute().name;

 let product1Id: number,
 	product2Id: number,
 	product3Id: number,
+	product1Slug: string,
 	productTag1Id: number,
 	productTag2Id: number,
 	productTag3Id: number,
@@ -45,6 +46,10 @@ test.describe(
 	() => {
 		test.use( { storageState: ADMIN_STATE_PATH } );

+		const product1 = getFakeProduct();
+		const product2 = getFakeProduct();
+		const product3 = getFakeProduct();
+
 		test.beforeAll( async ( { restApi } ) => {
 			// add product tags
 			await restApi
@@ -90,9 +95,7 @@ test.describe(
 			// add products
 			await restApi
 				.post( `${ WC_API_PATH }/products`, {
-					name: simpleProductName + ' 1',
-					type: 'simple',
-					regular_price: singleProductPrice1,
+					...product1,
 					tags: [
 						{ id: productTag1Id },
 						{
@@ -112,12 +115,11 @@ test.describe(
 				} )
 				.then( ( response ) => {
 					product1Id = response.data.id;
+					product1Slug = response.data.slug;
 				} );
 			await restApi
 				.post( `${ WC_API_PATH }/products`, {
-					name: simpleProductName + ' 2',
-					type: 'simple',
-					regular_price: singleProductPrice2,
+					...product2,
 					tags: [
 						{ id: productTag1Id },
 						{
@@ -137,9 +139,7 @@ test.describe(
 				} );
 			await restApi
 				.post( `${ WC_API_PATH }/products`, {
-					name: simpleProductName + ' 3',
-					type: 'simple',
-					regular_price: singleProductPrice3,
+					...product3,
 					tags: [ { id: productTag1Id } ],
 					attributes: [
 						{
@@ -214,8 +214,11 @@ test.describe(
 		test( 'should see and sort tags page with all the products', async ( {
 			page,
 		} ) => {
-			await page.goto( 'shop/?orderby=date' );
-			await page.locator( `text=${ simpleProductName } 1` ).click();
+			// Navigate straight to the product by slug. Going through the
+			// shared, date-sorted shop listing is parallel-fragile: other
+			// workers' products can push this one onto a later page where the
+			// click would fail.
+			await page.goto( `product/${ product1Slug }` );
 			await page.getByRole( 'link', { name: productTagName1 } ).click();
 			await expect(
 				page.getByRole( 'heading', { name: productTagName1 } )
@@ -232,6 +235,7 @@ test.describe(

 		test( 'should see and sort attributes page with all its products', async ( {
 			page,
+			baseURL,
 		} ) => {
 			// the api setting for enabling attribute term page doesn't apply for some reason
 			// workaround for the change to take effect is to just update via the settings ui.
@@ -257,8 +261,22 @@ test.describe(

 			await expect( attributeLookupCheckbox ).toBeChecked();

-			const slug = simpleProductName.replace( / /gi, '-' ).toLowerCase();
-			await page.goto( `product/${ slug }` );
+			// wc_create_attribute() only queues the attribute-archive rewrite
+			// rules flush as a WP-Cron event, which doesn't run in the test env,
+			// so the term archive 404s. Set WooCommerce's own flush flag; it is
+			// applied on the next request's `init` (the product page load below).
+			await setOption(
+				request,
+				baseURL || '',
+				'woocommerce_queue_flush_rewrite_rules',
+				'yes'
+			);
+
+			await page.goto( `product/${ product1Slug }` );
+
+			await page
+				.getByRole( 'tab', { name: 'Additional information' } )
+				.click();
 			await page
 				.locator(
 					'.woocommerce-product-attributes-item__value > p > a',
diff --git a/plugins/woocommerce/tests/e2e/tests/product/product-variable.spec.ts b/plugins/woocommerce/tests/e2e/tests/product/product-variable.spec.ts
index 340e2105405..29fa7c99ded 100644
--- a/plugins/woocommerce/tests/e2e/tests/product/product-variable.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/product/product-variable.spec.ts
@@ -9,7 +9,7 @@ import { WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
  */
 import { tags, test, expect } from '../../fixtures/fixtures';
 import { checkCartContent } from '../../utils/cart';
-import { resetValue, updateIfNeeded } from '../../utils/settings';
+import { getFakeProduct } from '../../utils/data';

 const productPrice = 18.16;
 const cartDialogMessage =
@@ -172,17 +172,11 @@ test.describe(
 	'Variable Product Page',
 	{ tag: [ tags.PAYMENTS, tags.SERVICES ] },
 	() => {
-		const variableProductName = `Variable single product ${ Date.now() }`;
-		const slug = variableProductName.replace( / /gi, '-' ).toLowerCase();
+		const variableProductName = getFakeProduct( { type: 'variable' } ).name;
+		let slug: string;
 		let variableProductId: number;
-		let calcTaxesState;

 		test.beforeAll( async ( { restApi } ) => {
-			calcTaxesState = await updateIfNeeded(
-				`general/woocommerce_calc_taxes`,
-				'no'
-			);
-
 			// add product
 			await restApi
 				.post( `${ WC_API_PATH }/products`, {
@@ -199,6 +193,7 @@ test.describe(
 				} )
 				.then( async ( response ) => {
 					variableProductId = response.data.id;
+					slug = response.data.slug;
 					for ( const key in variations1 ) {
 						await restApi.post(
 							`${ WC_API_PATH }/products/${ variableProductId }/variations`,
@@ -220,11 +215,6 @@ test.describe(
 					force: true,
 				}
 			);
-
-			await resetValue(
-				`general/woocommerce_calc_taxes`,
-				calcTaxesState
-			);
 		} );

 		test( 'should be able to add variation products to the cart', async ( {
@@ -307,17 +297,11 @@ test.describe(
 	'Shopper > Update variable product',
 	{ tag: [ tags.PAYMENTS, tags.SERVICES ] },
 	() => {
-		const variableProductName = `Variable single product ${ Date.now() }`;
-		const slug = variableProductName.replace( / /gi, '-' ).toLowerCase();
+		const variableProductName = getFakeProduct( { type: 'variable' } ).name;
+		let slug: string;
 		let variableProductId: number;
-		let calcTaxesState;

 		test.beforeAll( async ( { restApi } ) => {
-			calcTaxesState = await updateIfNeeded(
-				`general/woocommerce_calc_taxes`,
-				'no'
-			);
-
 			// add product
 			await restApi
 				.post( `${ WC_API_PATH }/products`, {
@@ -340,6 +324,7 @@ test.describe(
 				} )
 				.then( async ( response ) => {
 					variableProductId = response.data.id;
+					slug = response.data.slug;
 					for ( const key in variations2 ) {
 						await restApi.post(
 							`${ WC_API_PATH }/products/${ variableProductId }/variations`,
@@ -361,11 +346,6 @@ test.describe(
 					force: true,
 				}
 			);
-
-			await resetValue(
-				`general/woocommerce_calc_taxes`,
-				calcTaxesState
-			);
 		} );

 		test(
diff --git a/plugins/woocommerce/tests/e2e/tests/settings/settings-tax.spec.ts b/plugins/woocommerce/tests/e2e/tests/settings/settings-tax.spec.ts
index 715a49033c9..546c953c473 100644
--- a/plugins/woocommerce/tests/e2e/tests/settings/settings-tax.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/settings/settings-tax.spec.ts
@@ -12,6 +12,24 @@ import { ADMIN_STATE_PATH } from '../../playwright.config';
 test.describe( 'WooCommerce Tax Settings > enable', () => {
 	test.use( { storageState: ADMIN_STATE_PATH } );

+	// Tax calculation is enabled globally in site setup, so disable it first to
+	// make the UI toggle an actual change — otherwise the checkbox is already
+	// checked, the form is unchanged, and the React "Save changes" button stays
+	// disabled. Restore the baseline (enabled) afterwards so the shared site
+	// doesn't drift off-baseline for concurrent workers.
+	test.beforeEach( async ( { restApi } ) => {
+		await restApi.put(
+			`${ WC_API_PATH }/settings/general/woocommerce_calc_taxes`,
+			{ value: 'no' }
+		);
+	} );
+	test.afterEach( async ( { restApi } ) => {
+		await restApi.put(
+			`${ WC_API_PATH }/settings/general/woocommerce_calc_taxes`,
+			{ value: 'yes' }
+		);
+	} );
+
 	test( 'can enable tax calculation', async ( { page } ) => {
 		await page.goto( 'wp-admin/admin.php?page=wc-settings&tab=general' );

@@ -49,10 +67,13 @@ test.describe.serial( 'WooCommerce Tax Settings', () => {
 		);
 	} );
 	test.afterEach( async ( { restApi } ) => {
+		// Restore the global baseline (tax calculation enabled in site setup)
+		// rather than leaving it off, which would disable tax for concurrent
+		// workers and drift the shared site off-baseline.
 		await restApi.put(
 			`${ WC_API_PATH }/settings/general/woocommerce_calc_taxes`,
 			{
-				value: 'no',
+				value: 'yes',
 			}
 		);
 	} );
diff --git a/plugins/woocommerce/tests/e2e/tests/shop/shop-search-browse-sort.spec.ts b/plugins/woocommerce/tests/e2e/tests/shop/shop-search-browse-sort.spec.ts
index aaa53b8ca73..511a76e9644 100644
--- a/plugins/woocommerce/tests/e2e/tests/shop/shop-search-browse-sort.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/shop/shop-search-browse-sort.spec.ts
@@ -13,24 +13,22 @@ test.describe(
 	'Search, browse by categories and sort items in the shop',
 	{ tag: [ tags.PAYMENTS, tags.SERVICES ] },
 	() => {
-		let categories = [];
+		// One dedicated category holds all of this spec's products, so browsing
+		// and sorting happen on the category archive — which only ever lists this
+		// spec's own products. That keeps the spec immune to the store-wide shop
+		// listing that other parallel workers pollute by creating/deleting
+		// products (and to its 16-per-page pagination).
+		let category;
 		let products = [];

 		test.beforeAll( async ( { restApi } ) => {
 			await restApi
-				.post( `${ WC_API_PATH }/products/categories/batch`, {
-					create: [
-						getFakeCategory( { extraRandomTerm: true } ),
-						getFakeCategory( { extraRandomTerm: true } ),
-						getFakeCategory( { extraRandomTerm: true } ),
-					],
-				} )
+				.post(
+					`${ WC_API_PATH }/products/categories`,
+					getFakeCategory( { extraRandomTerm: true } )
+				)
 				.then( ( response ) => {
-					categories = response.data.create;
-
-					if ( categories.map( ( c ) => c.id ).includes( 0 ) ) {
-						console.log( JSON.stringify( response.data ) );
-					}
+					category = response.data;
 				} )
 				.catch( ( error: { response: unknown } ) => {
 					console.error( error.response );
@@ -41,15 +39,15 @@ test.describe(
 					create: [
 						{
 							...getFakeProduct( { regular_price: '979.99' } ),
-							categories: [ { id: categories[ 0 ].id } ],
+							categories: [ { id: category.id } ],
 						},
 						{
 							...getFakeProduct( { regular_price: '989.99' } ),
-							categories: [ { id: categories[ 1 ].id } ],
+							categories: [ { id: category.id } ],
 						},
 						{
 							...getFakeProduct( { regular_price: '999.99' } ),
-							categories: [ { id: categories[ 2 ].id } ],
+							categories: [ { id: category.id } ],
 						},
 					],
 				} )
@@ -63,18 +61,10 @@ test.describe(

 		test.afterAll( async ( { restApi } ) => {
 			await restApi.post( `${ WC_API_PATH }/products/batch`, {
-				delete: [
-					products[ 0 ].id,
-					products[ 1 ].id,
-					products[ 2 ].id,
-				],
+				delete: products.map( ( product ) => product.id ),
 			} );
 			await restApi.post( `${ WC_API_PATH }/products/categories/batch`, {
-				delete: [
-					categories[ 0 ].id,
-					categories[ 1 ].id,
-					categories[ 2 ].id,
-				],
+				delete: [ category.id ],
 			} );
 		} );

@@ -98,13 +88,12 @@ test.describe(
 		test( 'should let user browse products by categories', async ( {
 			page,
 		} ) => {
-			await test.step( 'Go to the shop and browse by the category', async () => {
-				await page.goto( 'shop/' );
-				await page.locator( `text=${ products[ 1 ].name }` ).click();
+			await test.step( 'Open a product and browse to its category via the breadcrumb', async () => {
+				await page.goto( products[ 1 ].permalink );
 				await page
 					.getByLabel( 'Breadcrumb' )
 					.getByRole( 'link', {
-						name: categories[ 1 ].name,
+						name: category.name,
 						exact: true,
 					} )
 					.click();
@@ -112,7 +101,7 @@ test.describe(

 			await test.step( 'Ensure the category page contains all the relevant products', async () => {
 				await expect(
-					page.getByRole( 'heading', { name: categories[ 1 ].name } )
+					page.getByRole( 'heading', { name: category.name } )
 				).toBeVisible();
 				await expect(
 					page.getByRole( 'heading', {
@@ -132,73 +121,46 @@ test.describe(
 		test( 'should let user sort the products in the shop', async ( {
 			page,
 		} ) => {
-			await test.step( 'Go to the shop and sort by price high to low', async () => {
-				await page.goto( 'shop/' );
-				await expect(
-					page.getByLabel(
-						new RegExp(
-							`Add to cart: ["|“]${ products[ 0 ].name }["|”]`
-						)
-					)
-				).toBeVisible();
+			const categoryUrl = `product-category/${ category.slug }/`;

-				// sort by price high to low
+			// Reads the displayed price of every product on the (isolated)
+			// category archive, in DOM order, as plain numbers.
+			const getDisplayedPrices = async () => {
+				const priceTexts = await page
+					.locator( 'li.product .woocommerce-Price-amount' )
+					.allInnerTexts();
+				return priceTexts.map( ( text ) =>
+					parseFloat( text.replace( /[^0-9.]/g, '' ) )
+				);
+			};
+
+			await test.step( 'Sort by price high to low', async () => {
+				await page.goto( categoryUrl );
 				await page
 					.getByLabel( 'Shop order' )
 					.selectOption( 'price-desc' );
 				await page.waitForURL( /.*?orderby=price-desc.*/ );
-
-				await expect(
-					page.getByText( 'Add to cart View cart' ).nth( 2 )
-				).toBeVisible();
-
-				// Check that the priciest appears before the cheapest in the list
-				const highToLowList = await page
-					.getByRole( 'listitem' )
-					.getByRole( 'heading' )
-					.allInnerTexts();
-				const highToLow_index_priciest = highToLowList.indexOf(
-					`${ products[ 2 ].name }`
+				await expect( page.locator( 'li.product' ) ).toHaveCount(
+					products.length
 				);
-				const highToLow_index_cheapest = highToLowList.indexOf(
-					`${ products[ 0 ].name }`
-				);
-				expect( highToLow_index_priciest ).toBeLessThan(
-					highToLow_index_cheapest
+
+				const prices = await getDisplayedPrices();
+				expect( prices ).toEqual(
+					[ ...prices ].sort( ( a, b ) => b - a )
 				);
 			} );

-			await test.step( 'Go to the shop and sort by price low to high', async () => {
-				await page.goto( 'shop/' );
-				await expect(
-					page.getByLabel(
-						new RegExp(
-							`Add to cart: ["|“]${ products[ 0 ].name }["|”]`
-						)
-					)
-				).toBeVisible();
-
-				// sort by price low to high
+			await test.step( 'Sort by price low to high', async () => {
+				await page.goto( categoryUrl );
 				await page.getByLabel( 'Shop order' ).selectOption( 'price' );
-				await page.waitForURL( /.*?orderby=price.*/ );
-
-				await expect(
-					page.getByText( 'Add to cart View cart' ).nth( 2 )
-				).toBeVisible();
-
-				// Check that the cheapest appears before the priciest in the list
-				const lowToHighList = await page
-					.getByRole( 'listitem' )
-					.getByRole( 'heading' )
-					.allInnerTexts();
-				const lowToHigh_index_priciest = lowToHighList.indexOf(
-					`${ products[ 2 ].name }`
+				await page.waitForURL( /.*?orderby=price(?:&|$).*/ );
+				await expect( page.locator( 'li.product' ) ).toHaveCount(
+					products.length
 				);
-				const lowToHigh_index_cheapest = lowToHighList.indexOf(
-					`${ products[ 0 ].name }`
-				);
-				expect( lowToHigh_index_cheapest ).toBeLessThan(
-					lowToHigh_index_priciest
+
+				const prices = await getDisplayedPrices();
+				expect( prices ).toEqual(
+					[ ...prices ].sort( ( a, b ) => a - b )
 				);
 			} );
 		} );
diff --git a/plugins/woocommerce/tests/e2e/utils/data.ts b/plugins/woocommerce/tests/e2e/utils/data.ts
index f23bbe541ab..485d86b2433 100644
--- a/plugins/woocommerce/tests/e2e/utils/data.ts
+++ b/plugins/woocommerce/tests/e2e/utils/data.ts
@@ -69,3 +69,26 @@ export function getFakeCategory( options = { extraRandomTerm: false } ) {
 		}`.trim(),
 	};
 }
+
+// A unique taxonomy term name. Kept short so the generated `pa_*` attribute
+// taxonomy slug stays within WordPress' length limit, and suffixed with random
+// characters so parallel workers never share the same global term.
+function getFakeTermName() {
+	return `${ faker.commerce.productMaterial() } ${ faker.string.alphanumeric(
+		5
+	) }`;
+}
+
+// A unique product tag name, so parallel workers don't share global terms.
+export function getFakeTag() {
+	return {
+		name: getFakeTermName(),
+	};
+}
+
+// A unique product attribute (or attribute term) name.
+export function getFakeAttribute() {
+	return {
+		name: getFakeTermName(),
+	};
+}
diff --git a/plugins/woocommerce/tests/e2e/utils/payment-gateways.ts b/plugins/woocommerce/tests/e2e/utils/payment-gateways.ts
new file mode 100644
index 00000000000..80dced44e2d
--- /dev/null
+++ b/plugins/woocommerce/tests/e2e/utils/payment-gateways.ts
@@ -0,0 +1,43 @@
+/**
+ * External dependencies
+ */
+import { ApiClient, WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
+
+/**
+ * Set a payment gateway's enabled state and return its previous enabled state.
+ *
+ * The call is idempotent — it only issues a PUT when the current state differs
+ * from the target — so passing the returned previous value back restores the
+ * gateway without an extra read.
+ *
+ * Pair the two calls in beforeAll/afterAll to guard global state under parallel
+ * runs (offline gateways are enabled by the shared site setup, so the restore
+ * is normally a no-op):
+ *
+ *     const wasEnabled = await setGatewayEnabled( restApi, 'cod', true );
+ *     // ...test...
+ *     await setGatewayEnabled( restApi, 'cod', wasEnabled );
+ *
+ * @param restApi   The REST API client (the `restApi` fixture).
+ * @param gatewayId The gateway id, e.g. `cod` or `bacs`.
+ * @param enabled   The target enabled state.
+ * @return The gateway's enabled state before this call.
+ */
+export async function setGatewayEnabled(
+	restApi: ApiClient,
+	gatewayId: string,
+	enabled: boolean
+): Promise< boolean > {
+	const response = await restApi.get< { enabled: boolean } >(
+		`${ WC_API_PATH }/payment_gateways/${ gatewayId }`
+	);
+	const wasEnabled = Boolean( response.data.enabled );
+
+	if ( wasEnabled !== enabled ) {
+		await restApi.put( `${ WC_API_PATH }/payment_gateways/${ gatewayId }`, {
+			enabled,
+		} );
+	}
+
+	return wasEnabled;
+}
diff --git a/plugins/woocommerce/tests/e2e/utils/taxes.ts b/plugins/woocommerce/tests/e2e/utils/taxes.ts
new file mode 100644
index 00000000000..9b9d8b465ec
--- /dev/null
+++ b/plugins/woocommerce/tests/e2e/utils/taxes.ts
@@ -0,0 +1,101 @@
+/**
+ * External dependencies
+ */
+import { faker } from '@faker-js/faker';
+import { ApiClient, WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
+
+const CALC_TAXES_PATH = `${ WC_API_PATH }/settings/general/woocommerce_calc_taxes`;
+
+/**
+ * A created tax rate plus the slug of the dedicated tax class it is scoped to.
+ */
+export type ScopedTaxRate = {
+	id: number;
+	rate: string;
+	taxClassSlug: string;
+};
+
+/**
+ * Assert that `woocommerce_calc_taxes` is `yes` and throw if it is not.
+ *
+ * Call this at the start of any `beforeAll` / fixture that depends on the
+ * taxes-ON baseline set by `site.setup.ts`. An early, descriptive failure is
+ * easier to diagnose than a silent wrong-total assertion deep in the test.
+ *
+ * @param restApi The REST API client (the `restApi` fixture).
+ */
+export async function assertTaxCalculationEnabled(
+	restApi: ApiClient
+): Promise< void > {
+	const response = await restApi.get< { value: string } >( CALC_TAXES_PATH );
+	if ( response.data.value !== 'yes' ) {
+		throw new Error(
+			`Expected woocommerce_calc_taxes=yes (site.setup baseline) but got "${ response.data.value }". ` +
+				'A serial spec or afterAll hook may have turned taxes off — check for afterAll leaks or cross-project pollution.'
+		);
+	}
+}
+
+/**
+ * Provide a tax rate scoped to its own dedicated tax class, then clean both up.
+ *
+ * Tax calculation is enabled globally in site setup with no standard rate, so
+ * the shared baseline is tax-free. This creates a uniquely-named tax class and a
+ * 25% rate scoped to it; only products assigned to that class are taxed, so
+ * concurrent workers are never affected. The class and rate are always removed
+ * afterwards, even if the test body throws.
+ *
+ * Use it from a Playwright fixture, passing the fixture's own `use` callback:
+ *
+ *     tax: async ( { restApi }, use ) => {
+ *         await withScopedTaxClass( restApi, 'Cart Spec', use );
+ *     },
+ *
+ * @param restApi The REST API client (the `restApi` fixture).
+ * @param label   Human-readable prefix for the tax class and rate names.
+ * @param use     Callback receiving the created rate and its tax class slug.
+ */
+export async function withScopedTaxClass(
+	restApi: ApiClient,
+	label: string,
+	use: ( tax: ScopedTaxRate ) => Promise< void >
+): Promise< void > {
+	await assertTaxCalculationEnabled( restApi );
+
+	const className = `${ label } ${ faker.string.alphanumeric( 8 ) }`;
+	const { data: taxClass } = await restApi.post< { slug: string } >(
+		`${ WC_API_PATH }/taxes/classes`,
+		{ name: className }
+	);
+
+	let rate: { id: number; rate: string } | undefined;
+	try {
+		( { data: rate } = await restApi.post< { id: number; rate: string } >(
+			`${ WC_API_PATH }/taxes`,
+			{
+				country: 'US',
+				state: '*',
+				cities: '*',
+				postcodes: '*',
+				rate: '25',
+				name: `${ label } Tax`,
+				shipping: false,
+				class: taxClass.slug,
+			}
+		) );
+		await use( { ...rate, taxClassSlug: taxClass.slug } );
+	} finally {
+		if ( rate ) {
+			await restApi
+				.delete( `${ WC_API_PATH }/taxes/${ rate.id }`, {
+					force: true,
+				} )
+				.catch( console.error );
+		}
+		await restApi
+			.delete( `${ WC_API_PATH }/taxes/classes/${ taxClass.slug }`, {
+				force: true,
+			} )
+			.catch( console.error );
+	}
+}