Commit 8d2799819e for woocommerce

commit 8d2799819eebd8a9ec9446d28690fe75fdd5b6cf
Author: theAverageDev (Luca Tumedei) <luca@theaveragedev.com>
Date:   Thu Feb 19 11:49:16 2026 +0100

    Convert e2e-pw fixtures and ESM utils to TypeScript (#63315)

diff --git a/plugins/woocommerce/changelog/e2e-pw-ts-conversion-08 b/plugins/woocommerce/changelog/e2e-pw-ts-conversion-08
new file mode 100644
index 0000000000..88e88c55dd
--- /dev/null
+++ b/plugins/woocommerce/changelog/e2e-pw-ts-conversion-08
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Convert fixtures and utils of the e2e-pw directory to TypeScript.
diff --git a/plugins/woocommerce/tests/e2e-pw/.eslintrc.cjs b/plugins/woocommerce/tests/e2e-pw/.eslintrc.cjs
index 079adc1763..96fec3c28a 100644
--- a/plugins/woocommerce/tests/e2e-pw/.eslintrc.cjs
+++ b/plugins/woocommerce/tests/e2e-pw/.eslintrc.cjs
@@ -36,6 +36,9 @@ module.exports = {
 				ecmaVersion: 'latest',
 				sourceType: 'module',
 			},
+			rules: {
+				'@typescript-eslint/no-explicit-any': 'off',
+			},
 		},
 	],
 };
diff --git a/plugins/woocommerce/tests/e2e-pw/envs/default-pressable/playwright.config.js b/plugins/woocommerce/tests/e2e-pw/envs/default-pressable/playwright.config.js
index ca1e6b60ff..f88f354221 100644
--- a/plugins/woocommerce/tests/e2e-pw/envs/default-pressable/playwright.config.js
+++ b/plugins/woocommerce/tests/e2e-pw/envs/default-pressable/playwright.config.js
@@ -15,7 +15,7 @@ config = {
 		{
 			name: 'reset',
 			testDir: `${ config.TESTS_ROOT_PATH }/fixtures`,
-			testMatch: 'reset.setup.js',
+			testMatch: 'reset.setup.ts',
 		},
 		{
 			name: 'e2e-pressable',
diff --git a/plugins/woocommerce/tests/e2e-pw/envs/default-wpcom/playwright.config.js b/plugins/woocommerce/tests/e2e-pw/envs/default-wpcom/playwright.config.js
index 3ebde179b4..683c074801 100644
--- a/plugins/woocommerce/tests/e2e-pw/envs/default-wpcom/playwright.config.js
+++ b/plugins/woocommerce/tests/e2e-pw/envs/default-wpcom/playwright.config.js
@@ -15,7 +15,7 @@ config = {
 		{
 			name: 'reset',
 			testDir: `${ config.TESTS_ROOT_PATH }/fixtures`,
-			testMatch: 'reset.setup.js',
+			testMatch: 'reset.setup.ts',
 		},
 		{
 			name: 'e2e-wpcom',
diff --git a/plugins/woocommerce/tests/e2e-pw/fixtures/auth.setup.js b/plugins/woocommerce/tests/e2e-pw/fixtures/auth.setup.ts
similarity index 77%
rename from plugins/woocommerce/tests/e2e-pw/fixtures/auth.setup.js
rename to plugins/woocommerce/tests/e2e-pw/fixtures/auth.setup.ts
index f5a2240b7a..f8683f3aa4 100644
--- a/plugins/woocommerce/tests/e2e-pw/fixtures/auth.setup.js
+++ b/plugins/woocommerce/tests/e2e-pw/fixtures/auth.setup.ts
@@ -1,20 +1,24 @@
 /**
  * External dependencies
  */
-import { test as setup } from '@playwright/test';
+import { test as setup, type APIRequestContext } from '@playwright/test';
 import fs from 'fs';

 /**
  * Internal dependencies
  */
-const { admin, customer } = require( '../test-data/data' );
+import { admin, customer } from '../test-data/data';
 import {
 	ADMIN_STATE_PATH,
 	CUSTOMER_STATE_PATH,
 	STORAGE_DIR_PATH,
 } from '../playwright.config';

-async function authenticate( request, user, storagePath ) {
+async function authenticate(
+	request: APIRequestContext,
+	user: { username: string; password: string },
+	storagePath: string
+) {
 	await request.post( './wp-login.php', {
 		form: {
 			log: user.username,
diff --git a/plugins/woocommerce/tests/e2e-pw/fixtures/block-editor-fixtures.js b/plugins/woocommerce/tests/e2e-pw/fixtures/block-editor-fixtures.ts
similarity index 100%
rename from plugins/woocommerce/tests/e2e-pw/fixtures/block-editor-fixtures.js
rename to plugins/woocommerce/tests/e2e-pw/fixtures/block-editor-fixtures.ts
diff --git a/plugins/woocommerce/tests/e2e-pw/fixtures/fixtures.js b/plugins/woocommerce/tests/e2e-pw/fixtures/fixtures.ts
similarity index 99%
rename from plugins/woocommerce/tests/e2e-pw/fixtures/fixtures.js
rename to plugins/woocommerce/tests/e2e-pw/fixtures/fixtures.ts
index 70cddc55c2..4d49353dd5 100644
--- a/plugins/woocommerce/tests/e2e-pw/fixtures/fixtures.js
+++ b/plugins/woocommerce/tests/e2e-pw/fixtures/fixtures.ts
@@ -97,4 +97,4 @@ export const tags = {
 	TO_BE_REMOVED: '@to-be-removed',
 	NOT_E2E: '@not-e2e',
 	WP_CORE: '@wp-core',
-};
+} as const;
diff --git a/plugins/woocommerce/tests/e2e-pw/fixtures/install-wc.setup.js b/plugins/woocommerce/tests/e2e-pw/fixtures/install-wc.setup.ts
similarity index 95%
rename from plugins/woocommerce/tests/e2e-pw/fixtures/install-wc.setup.js
rename to plugins/woocommerce/tests/e2e-pw/fixtures/install-wc.setup.ts
index 5096097202..5ba92979a8 100644
--- a/plugins/woocommerce/tests/e2e-pw/fixtures/install-wc.setup.js
+++ b/plugins/woocommerce/tests/e2e-pw/fixtures/install-wc.setup.ts
@@ -3,7 +3,7 @@
  */
 import { test as setup } from './fixtures';

-async function deactivateWooCommerce( restApi ) {
+async function deactivateWooCommerce( restApi: any ) {
 	try {
 		await restApi.get( 'wc-admin-test-helper/live-branches/deactivate/v1' );
 		console.log( 'WC deactivated.' );
@@ -12,10 +12,11 @@ async function deactivateWooCommerce( restApi ) {
 	}
 }

-async function getActivatedWooCommerceVersion( restApi ) {
+async function getActivatedWooCommerceVersion( restApi: any ) {
 	const response = await restApi.get( 'wp/v2/plugins', { status: 'active' } );
 	const plugins = await response.data;
-	return plugins.find( ( plugin ) => plugin.name === 'WooCommerce' )?.version;
+	return plugins.find( ( plugin: any ) => plugin.name === 'WooCommerce' )
+		?.version;
 }

 setup( 'Install WC using WC Beta Tester', async ( { restApi } ) => {
diff --git a/plugins/woocommerce/tests/e2e-pw/fixtures/reset.setup.js b/plugins/woocommerce/tests/e2e-pw/fixtures/reset.setup.ts
similarity index 100%
rename from plugins/woocommerce/tests/e2e-pw/fixtures/reset.setup.js
rename to plugins/woocommerce/tests/e2e-pw/fixtures/reset.setup.ts
diff --git a/plugins/woocommerce/tests/e2e-pw/fixtures/site.setup.js b/plugins/woocommerce/tests/e2e-pw/fixtures/site.setup.ts
similarity index 100%
rename from plugins/woocommerce/tests/e2e-pw/fixtures/site.setup.js
rename to plugins/woocommerce/tests/e2e-pw/fixtures/site.setup.ts
diff --git a/plugins/woocommerce/tests/e2e-pw/playwright.config.js b/plugins/woocommerce/tests/e2e-pw/playwright.config.js
index b8f028deeb..c760026db0 100644
--- a/plugins/woocommerce/tests/e2e-pw/playwright.config.js
+++ b/plugins/woocommerce/tests/e2e-pw/playwright.config.js
@@ -80,18 +80,18 @@ export const setupProjects = [
 	{
 		name: 'install wc',
 		testDir: `${ TESTS_ROOT_PATH }/fixtures`,
-		testMatch: 'install-wc.setup.js',
+		testMatch: 'install-wc.setup.ts',
 	},
 	{
 		name: 'global authentication',
 		testDir: `${ TESTS_ROOT_PATH }/fixtures`,
-		testMatch: 'auth.setup.js',
+		testMatch: 'auth.setup.ts',
 		dependencies: [ 'install wc' ],
 	},
 	{
 		name: 'site setup',
 		testDir: `${ TESTS_ROOT_PATH }/fixtures`,
-		testMatch: `site.setup.js`,
+		testMatch: `site.setup.ts`,
 		dependencies: [ 'global authentication' ],
 	},
 ];
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/api.js b/plugins/woocommerce/tests/e2e-pw/utils/api.js
deleted file mode 100644
index 92b3d0a601..0000000000
--- a/plugins/woocommerce/tests/e2e-pw/utils/api.js
+++ /dev/null
@@ -1,258 +0,0 @@
-/**
- * External dependencies
- */
-import { createClient, WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
-
-/**
- * Internal dependencies
- */
-import { admin } from '../test-data/data';
-import playwrightConfig from '../playwright.config';
-
-const api = createClient( playwrightConfig.use.baseURL, {
-	type: 'basic',
-	username: admin.username,
-	password: admin.password,
-} );
-
-const update = {
-	storeDetails: async ( store ) => {
-		await api.post( 'settings/general/batch', {
-			update: [
-				{
-					id: 'woocommerce_store_address',
-					value: store.address,
-				},
-				{
-					id: 'woocommerce_store_city',
-					value: store.city,
-				},
-				{
-					id: 'woocommerce_default_country',
-					value: store.countryCode,
-				},
-				{
-					id: 'woocommerce_store_postcode',
-					value: store.zip,
-				},
-			],
-		} );
-	},
-	enableCashOnDelivery: async () => {
-		await api.put( 'payment_gateways/cod', {
-			enabled: true,
-		} );
-	},
-	disableCashOnDelivery: async () => {
-		await api.put( 'payment_gateways/cod', {
-			enabled: false,
-		} );
-	},
-};
-
-const get = {
-	coupons: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/coupons`, params )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-	orders: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/orders`, params )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-	products: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/products`, params )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-	productAttributes: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/products/attributes`, params )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-	productCategories: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/products/categories`, params )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-	productTags: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/products/tags`, params )
-			.then( ( r ) => r );
-		return response.data;
-	},
-	shippingClasses: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/products/shipping_classes`, params )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-
-	shippingZones: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/shipping/zones`, params )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-
-	taxClasses: async () => {
-		const response = await api
-			.get( `${ WC_API_PATH }/taxes/classes` )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-	taxRates: async ( params ) => {
-		const response = await api
-			.get( `${ WC_API_PATH }/taxes`, params )
-			.then( ( r ) => r );
-
-		return response.data;
-	},
-};
-
-const create = {
-	product: async ( product ) => {
-		const response = await api.post( `${ WC_API_PATH }/products`, product );
-
-		return response.data.id;
-	},
-	shippingZone: async ( zone ) => {
-		const response = await api.post(
-			`${ WC_API_PATH }/shipping/zones`,
-			zone
-		);
-
-		return response.data.id;
-	},
-	shippingMethod: async ( zoneId, method ) => {
-		const response = await api.post(
-			`${ WC_API_PATH }/shipping/zones/${ zoneId }/methods`,
-			method
-		);
-
-		return response.data.id;
-	},
-	/**
-	 * Batch create product variations.
-	 *
-	 * @see {@link [Batch update product variations](https://woocommerce.github.io/woocommerce-rest-api-docs/#batch-update-product-variations)}
-	 * @param {number|string} productId  Product ID to add variations to
-	 * @param {object[]}      variations Array of variations to add. See [Product variation properties](https://woocommerce.github.io/woocommerce-rest-api-docs/#product-variation-properties)
-	 * @return {Promise<number[]>} Array of variation ID's.
-	 */
-	productVariations: async ( productId, variations ) => {
-		const response = await api.post(
-			`${ WC_API_PATH }/products/${ productId }/variations/batch`,
-			{
-				create: variations,
-			}
-		);
-
-		return response.data.create.map( ( { id } ) => id );
-	},
-};
-
-const deletePost = {
-	coupons: async ( ids ) => {
-		const res = await api
-			.post( `${ WC_API_PATH }/coupons/batch`, { delete: ids } )
-			.then( ( response ) => response );
-
-		return res.data;
-	},
-	product: async ( id ) => {
-		await api.delete( `${ WC_API_PATH }/products/${ id }`, {
-			force: true,
-		} );
-	},
-	products: async ( ids ) => {
-		const res = await api
-			.post( `${ WC_API_PATH }/products/batch`, { delete: ids } )
-			.then( ( response ) => response );
-		return res.data;
-	},
-	productAttributes: async ( id ) => {
-		const res = await api
-			.post( `${ WC_API_PATH }/products/attributes/batch`, {
-				delete: id,
-			} )
-			.then( ( response ) => response );
-		return res.data;
-	},
-	productCategories: async ( ids ) => {
-		const res = await api
-			.post( `${ WC_API_PATH }/products/categories/batch`, {
-				delete: ids,
-			} )
-			.then( ( response ) => response );
-		return res.data;
-	},
-	productTags: async ( ids ) => {
-		const res = await api
-			.post( `${ WC_API_PATH }/products/tags/batch`, { delete: ids } )
-			.then( ( response ) => response );
-		return res.data;
-	},
-	order: async ( id ) => {
-		await api.delete( `${ WC_API_PATH }/orders/${ id }`, {
-			force: true,
-		} );
-	},
-	orders: async ( ids ) => {
-		const res = await api
-			.post( `${ WC_API_PATH }/orders/batch`, { delete: ids } )
-			.then( ( response ) => response );
-		return res.data;
-	},
-	shippingClasses: async ( ids ) => {
-		const res = await api
-			.post( `${ WC_API_PATH }/products/shipping_classes/batch`, {
-				delete: ids,
-			} )
-			.then( ( response ) => response );
-		return res.data;
-	},
-	shippingZone: async ( id ) => {
-		const res = await api
-			.delete( `${ WC_API_PATH }/shipping/zones/${ id }`, {
-				force: true,
-			} )
-			.then( ( response ) => response );
-		return res.data;
-	},
-	taxClass: async ( slug ) => {
-		const res = await api
-			.delete( `${ WC_API_PATH }/taxes/classes/${ slug }`, {
-				force: true,
-			} )
-			.then( ( response ) => response );
-		return res.data;
-	},
-	taxRates: async ( ids ) => {
-		const res = await api
-			.post( `${ WC_API_PATH }/taxes/batch`, { delete: ids } )
-			.then( ( response ) => response );
-		return res.data;
-	},
-};
-
-module.exports = {
-	update,
-	get,
-	create,
-	deletePost,
-};
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/api.ts b/plugins/woocommerce/tests/e2e-pw/utils/api.ts
new file mode 100644
index 0000000000..74f728c883
--- /dev/null
+++ b/plugins/woocommerce/tests/e2e-pw/utils/api.ts
@@ -0,0 +1,232 @@
+/**
+ * External dependencies
+ */
+import { createClient, WC_API_PATH } from '@woocommerce/e2e-utils-playwright';
+
+/**
+ * Internal dependencies
+ */
+import { admin } from '../test-data/data';
+import playwrightConfig from '../playwright.config';
+
+const api = createClient( playwrightConfig.use.baseURL, {
+	type: 'basic',
+	username: admin.username,
+	password: admin.password,
+} );
+
+export const update = {
+	storeDetails: async ( store: any ) => {
+		await api.post( 'settings/general/batch', {
+			update: [
+				{
+					id: 'woocommerce_store_address',
+					value: store.address,
+				},
+				{
+					id: 'woocommerce_store_city',
+					value: store.city,
+				},
+				{
+					id: 'woocommerce_default_country',
+					value: store.countryCode,
+				},
+				{
+					id: 'woocommerce_store_postcode',
+					value: store.zip,
+				},
+			],
+		} );
+	},
+	enableCashOnDelivery: async () => {
+		await api.put( 'payment_gateways/cod', {
+			enabled: true,
+		} );
+	},
+	disableCashOnDelivery: async () => {
+		await api.put( 'payment_gateways/cod', {
+			enabled: false,
+		} );
+	},
+};
+
+export const get = {
+	coupons: async ( params: any ) => {
+		const response = await api.get( `${ WC_API_PATH }/coupons`, params );
+		return response.data;
+	},
+	orders: async ( params: any ) => {
+		const response = await api.get( `${ WC_API_PATH }/orders`, params );
+		return response.data;
+	},
+	products: async ( params: any ) => {
+		const response = await api.get( `${ WC_API_PATH }/products`, params );
+		return response.data;
+	},
+	productAttributes: async ( params: any ) => {
+		const response = await api.get(
+			`${ WC_API_PATH }/products/attributes`,
+			params
+		);
+		return response.data;
+	},
+	productCategories: async ( params: any ) => {
+		const response = await api.get(
+			`${ WC_API_PATH }/products/categories`,
+			params
+		);
+		return response.data;
+	},
+	productTags: async ( params: any ) => {
+		const response = await api.get(
+			`${ WC_API_PATH }/products/tags`,
+			params
+		);
+		return response.data;
+	},
+	shippingClasses: async ( params: any ) => {
+		const response = await api.get(
+			`${ WC_API_PATH }/products/shipping_classes`,
+			params
+		);
+		return response.data;
+	},
+	shippingZones: async ( params: any ) => {
+		const response = await api.get(
+			`${ WC_API_PATH }/shipping/zones`,
+			params
+		);
+		return response.data;
+	},
+	taxClasses: async () => {
+		const response = await api.get( `${ WC_API_PATH }/taxes/classes` );
+		return response.data;
+	},
+	taxRates: async ( params: any ) => {
+		const response = await api.get( `${ WC_API_PATH }/taxes`, params );
+		return response.data;
+	},
+};
+
+export const create = {
+	product: async ( product: any ) => {
+		const response = await api.post( `${ WC_API_PATH }/products`, product );
+
+		return response.data.id;
+	},
+	shippingZone: async ( zone: any ) => {
+		const response = await api.post(
+			`${ WC_API_PATH }/shipping/zones`,
+			zone
+		);
+
+		return response.data.id;
+	},
+	shippingMethod: async ( zoneId: number | string, method: any ) => {
+		const response = await api.post(
+			`${ WC_API_PATH }/shipping/zones/${ zoneId }/methods`,
+			method
+		);
+
+		return response.data.id;
+	},
+	/**
+	 * Batch create product variations.
+	 *
+	 * @see {@link [Batch update product variations](https://woocommerce.github.io/woocommerce-rest-api-docs/#batch-update-product-variations)}
+	 * @param {number|string} productId  Product ID to add variations to
+	 * @param {object[]}      variations Array of variations to add. See [Product variation properties](https://woocommerce.github.io/woocommerce-rest-api-docs/#product-variation-properties)
+	 * @return {Promise<number[]>} Array of variation ID's.
+	 */
+	productVariations: async (
+		productId: number | string,
+		variations: any[]
+	) => {
+		const response = await api.post(
+			`${ WC_API_PATH }/products/${ productId }/variations/batch`,
+			{
+				create: variations,
+			}
+		);
+
+		return response.data.create.map( ( { id }: { id: number } ) => id );
+	},
+};
+
+export const deletePost = {
+	coupons: async ( ids: number[] ) => {
+		const res = await api.post( `${ WC_API_PATH }/coupons/batch`, {
+			delete: ids,
+		} );
+		return res.data;
+	},
+	product: async ( id: number ) => {
+		await api.delete( `${ WC_API_PATH }/products/${ id }`, {
+			force: true,
+		} );
+	},
+	products: async ( ids: number[] ) => {
+		const res = await api.post( `${ WC_API_PATH }/products/batch`, {
+			delete: ids,
+		} );
+		return res.data;
+	},
+	productAttributes: async ( ids: number[] ) => {
+		const res = await api.post(
+			`${ WC_API_PATH }/products/attributes/batch`,
+			{ delete: ids }
+		);
+		return res.data;
+	},
+	productCategories: async ( ids: number[] ) => {
+		const res = await api.post(
+			`${ WC_API_PATH }/products/categories/batch`,
+			{ delete: ids }
+		);
+		return res.data;
+	},
+	productTags: async ( ids: number[] ) => {
+		const res = await api.post( `${ WC_API_PATH }/products/tags/batch`, {
+			delete: ids,
+		} );
+		return res.data;
+	},
+	order: async ( id: number ) => {
+		await api.delete( `${ WC_API_PATH }/orders/${ id }`, {
+			force: true,
+		} );
+	},
+	orders: async ( ids: number[] ) => {
+		const res = await api.post( `${ WC_API_PATH }/orders/batch`, {
+			delete: ids,
+		} );
+		return res.data;
+	},
+	shippingClasses: async ( ids: number[] ) => {
+		const res = await api.post(
+			`${ WC_API_PATH }/products/shipping_classes/batch`,
+			{ delete: ids }
+		);
+		return res.data;
+	},
+	shippingZone: async ( id: number ) => {
+		const res = await api.delete(
+			`${ WC_API_PATH }/shipping/zones/${ id }`,
+			{ force: true }
+		);
+		return res.data;
+	},
+	taxClass: async ( slug: string ) => {
+		const res = await api.delete(
+			`${ WC_API_PATH }/taxes/classes/${ slug }`,
+			{ force: true }
+		);
+		return res.data;
+	},
+	taxRates: async ( ids: number[] ) => {
+		const res = await api.post( `${ WC_API_PATH }/taxes/batch`, {
+			delete: ids,
+		} );
+		return res.data;
+	},
+};
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/cart.js b/plugins/woocommerce/tests/e2e-pw/utils/cart.ts
similarity index 89%
rename from plugins/woocommerce/tests/e2e-pw/utils/cart.js
rename to plugins/woocommerce/tests/e2e-pw/utils/cart.ts
index 548455eeb7..6feff27f06 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/cart.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/cart.ts
@@ -1,10 +1,11 @@
 /**
  * External dependencies
  */
+import type { Page } from '@playwright/test';
 import { expect } from '@playwright/test';

-function formatAmount( amount ) {
-	return parseFloat( amount ).toLocaleString( 'en-US', {
+function formatAmount( amount: number | string ) {
+	return parseFloat( String( amount ) ).toLocaleString( 'en-US', {
 		minimumFractionDigits: 2,
 		maximumFractionDigits: 2,
 	} );
@@ -18,9 +19,9 @@ function formatAmount( amount ) {
  * @param {number} expectedTotal - The expected total amount in the cart.
  */
 export async function checkCartContentInClassicCart(
-	page,
-	products,
-	expectedTotal
+	page: Page,
+	products: any[],
+	expectedTotal: number
 ) {
 	for ( const product of products ) {
 		const row = await page
@@ -52,9 +53,9 @@ export async function checkCartContentInClassicCart(
  * @param {number} expectedTotal - The expected total amount in the cart.
  */
 export async function checkCartContentInBlocksCart(
-	page,
-	products,
-	expectedTotal
+	page: Page,
+	products: any[],
+	expectedTotal: number
 ) {
 	for ( const product of products ) {
 		const row = await page
@@ -87,7 +88,12 @@ export async function checkCartContentInBlocksCart(
  * @param {Array}   products      - An array of objects in the format { data: { name: 'Product name', price: '12', }, qty: quantity } expected to be in the cart.
  * @param {Object}  tax           - The tax object containing the tax rate. Expected format: { rate: '0.00' }
  */
-export async function checkCartContent( isClassicCart, page, products, tax ) {
+export async function checkCartContent(
+	isClassicCart: boolean,
+	page: Page,
+	products: any[],
+	tax: any
+) {
 	if ( products.length === 0 ) {
 		await expect(
 			page.locator( 'main' ).getByText( 'Your cart is currently empty' )
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/data.js b/plugins/woocommerce/tests/e2e-pw/utils/data.ts
similarity index 81%
rename from plugins/woocommerce/tests/e2e-pw/utils/data.js
rename to plugins/woocommerce/tests/e2e-pw/utils/data.ts
index 9325a50c0f..f23bbe541a 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/data.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/data.ts
@@ -1,6 +1,9 @@
-const { faker } = require( '@faker-js/faker' );
+/**
+ * External dependencies
+ */
+import { faker } from '@faker-js/faker';

-function getFakeUser( role ) {
+export function getFakeUser( role: string ) {
 	const firstName = faker.person.firstName();
 	const lastName = faker.person.lastName();
 	const email = faker.internet.email( {
@@ -42,11 +45,11 @@ function getFakeUser( role ) {
 	};
 }

-function getFakeCustomer() {
+export function getFakeCustomer() {
 	return getFakeUser( 'customer' );
 }

-function getFakeProduct( options = {} ) {
+export function getFakeProduct( options: any = {} ) {
 	const dec = options.dec ?? 2;

 	return {
@@ -59,17 +62,10 @@ function getFakeProduct( options = {} ) {
 	};
 }

-function getFakeCategory( options = { extraRandomTerm: false } ) {
+export function getFakeCategory( options = { extraRandomTerm: false } ) {
 	return {
 		name: `${ faker.commerce.productMaterial() } ${ faker.commerce.department() } ${
 			options.extraRandomTerm ? faker.string.alphanumeric( 5 ) : ''
 		}`.trim(),
 	};
 }
-
-module.exports = {
-	getFakeUser,
-	getFakeCustomer,
-	getFakeProduct,
-	getFakeCategory,
-};
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/email.js b/plugins/woocommerce/tests/e2e-pw/utils/email.ts
similarity index 90%
rename from plugins/woocommerce/tests/e2e-pw/utils/email.js
rename to plugins/woocommerce/tests/e2e-pw/utils/email.ts
index e45cb2d125..0b32303b04 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/email.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/email.ts
@@ -1,6 +1,7 @@
 /**
  * External dependencies
  */
+import type { Page } from '@playwright/test';
 import { createClient, WP_API_PATH } from '@woocommerce/e2e-utils-playwright';

 /**
@@ -18,7 +19,11 @@ import playwrightConfig from '../playwright.config';
  * @param {RegExp}                           subject              The subject of the email, in regular expression format.
  * @return {Promise<*>} Returns the row element of the email in the Email Log page.
  */
-export async function expectEmail( page, receiverEmailAddress, subject ) {
+export async function expectEmail(
+	page: Page,
+	receiverEmailAddress: string,
+	subject: RegExp
+) {
 	await page.goto(
 		`wp-admin/tools.php?page=wpml_plugin_log&search[place]=receiver&search[term]=${ encodeURIComponent(
 			receiverEmailAddress
@@ -54,10 +59,10 @@ export async function expectEmail( page, receiverEmailAddress, subject ) {
  * @param {RegExp}                           emailContent         A part of the email content, in regular expression format.
  */
 export async function expectEmailContent(
-	page,
-	receiverEmailAddress,
-	emailSubject,
-	emailContent
+	page: Page,
+	receiverEmailAddress: string,
+	emailSubject: RegExp,
+	emailContent: RegExp
 ) {
 	const modalContent = page.locator(
 		'#wp-mail-logging-modal-content-body-content'
@@ -75,7 +80,7 @@ export async function expectEmailContent(
 	);
 }

-export async function getWooEmails( params ) {
+export async function getWooEmails( params: any ) {
 	const apiClient = createClient( playwrightConfig.use.baseURL, {
 		type: 'basic',
 		username: admin.username,
@@ -94,7 +99,10 @@ export async function getWooEmails( params ) {
  * @param {import('@playwright/test').Page } page       The Playwright page.
  * @param {string}                           emailTitle The transactional email title.
  */
-export async function accessTheEmailEditor( page, emailTitle = 'New order' ) {
+export async function accessTheEmailEditor(
+	page: Page,
+	emailTitle = 'New order'
+) {
 	await page.goto( '/wp-admin/admin.php?page=wc-settings&tab=email' );
 	const theRow = page.getByRole( 'row', {
 		name: new RegExp( emailTitle ),
@@ -106,7 +114,7 @@ export async function accessTheEmailEditor( page, emailTitle = 'New order' ) {
 	await expect( page.locator( '#woocommerce-email-editor' ) ).toBeVisible();
 }

-export async function ensureEmailEditorSettingsPanelIsOpened( page ) {
+export async function ensureEmailEditorSettingsPanelIsOpened( page: Page ) {
 	const status = await page.evaluate( async () => {
 		const elem = document.querySelector(
 			'.woocommerce-email-editor__settings-panel'
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/filters.js b/plugins/woocommerce/tests/e2e-pw/utils/filters.ts
similarity index 83%
rename from plugins/woocommerce/tests/e2e-pw/utils/filters.js
rename to plugins/woocommerce/tests/e2e-pw/utils/filters.ts
index 5bcb3b5ad2..c321fe2e02 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/filters.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/filters.ts
@@ -1,3 +1,8 @@
+/**
+ * External dependencies
+ */
+import type { Page } from '@playwright/test';
+
 /**
  * Internal dependencies
  */
@@ -11,10 +16,15 @@ const testURL = new URL( defaultConfig.use.baseURL );
  * code to observe the requested filter, you may need to `page.reload()` prior to writing assertions that rely on your
  * filter.
  */
-export async function setFilterValue( page, hook, value, priority = 10 ) {
+export async function setFilterValue(
+	page: Page,
+	hook: string,
+	value: any,
+	priority = 10
+) {
 	const context = page.context();
 	const existingCookies = await context.cookies();
-	let filterSpecs = {};
+	let filterSpecs: any = {};

 	for ( const cookie of existingCookies ) {
 		if ( cookie.name === 'e2e-filters' ) {
@@ -45,7 +55,7 @@ export async function setFilterValue( page, hook, value, priority = 10 ) {
  * before performing further assertions.
  *
  */
-export async function clearFilters( page ) {
+export async function clearFilters( page: Page ) {
 	await page.context().addCookies( [
 		{
 			name: 'e2e-filters',
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/onboarding.js b/plugins/woocommerce/tests/e2e-pw/utils/onboarding.ts
similarity index 95%
rename from plugins/woocommerce/tests/e2e-pw/utils/onboarding.js
rename to plugins/woocommerce/tests/e2e-pw/utils/onboarding.ts
index 4ebf36087e..70e7b8110a 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/onboarding.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/onboarding.ts
@@ -19,7 +19,7 @@ import playwrightConfig from '../playwright.config';
  * @return {Promise<void>} the value for the skipped field in the onboarding profile
  */

-export async function updateOnboardingProfile( data ) {
+export async function updateOnboardingProfile( data: any ) {
 	const apiClient = createClient( playwrightConfig.use.baseURL, {
 		type: 'basic',
 		username: admin.username,
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/options.js b/plugins/woocommerce/tests/e2e-pw/utils/options.ts
similarity index 75%
rename from plugins/woocommerce/tests/e2e-pw/utils/options.js
rename to plugins/woocommerce/tests/e2e-pw/utils/options.ts
index 72d8bac185..c33db778c0 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/options.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/options.ts
@@ -1,14 +1,19 @@
+/**
+ * External dependencies
+ */
+import type { APIRequest } from '@playwright/test';
+
 /**
  * Internal dependencies
  */
 import { encodeCredentials } from './plugin-utils';
-const { admin } = require( '../test-data/data' );
+import { admin } from '../test-data/data';

 export const setOption = async (
-	request,
-	baseURL,
-	optionName,
-	optionValue
+	request: APIRequest,
+	baseURL: string,
+	optionName: string,
+	optionValue: string
 ) => {
 	const apiContext = await request.newContext( {
 		baseURL,
@@ -31,7 +36,11 @@ export const setOption = async (
 		} );
 };

-export const deleteOption = async ( request, baseURL, optionName ) => {
+export const deleteOption = async (
+	request: APIRequest,
+	baseURL: string,
+	optionName: string
+) => {
 	const apiContext = await request.newContext( {
 		baseURL,
 		extraHTTPHeaders: {
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/pages.js b/plugins/woocommerce/tests/e2e-pw/utils/pages.ts
similarity index 86%
rename from plugins/woocommerce/tests/e2e-pw/utils/pages.js
rename to plugins/woocommerce/tests/e2e-pw/utils/pages.ts
index e46dcc1d8e..7c0d78d008 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/pages.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/pages.ts
@@ -1,6 +1,7 @@
 /**
  * External dependencies
  */
+import type { Browser } from '@playwright/test';
 import {
 	createClient,
 	goToPageEditor,
@@ -36,7 +37,7 @@ export const CLASSIC_CART_PAGE = {
 	slug: 'classic-cart',
 };

-export async function pageExists( slug ) {
+export async function pageExists( slug: string ) {
 	const apiClient = createClient( playwrightConfig.use.baseURL, {
 		type: 'basic',
 		username: admin.username,
@@ -53,7 +54,11 @@ export async function pageExists( slug ) {
 	return pages.data.length > 0;
 }

-async function createShortcodePage( slug, title, shortcode ) {
+async function createShortcodePage(
+	slug: string,
+	title: string,
+	shortcode: string
+) {
 	if ( ! ( await pageExists( slug ) ) ) {
 		console.log( `Creating ${ title } page` );
 		const apiClient = createClient( playwrightConfig.use.baseURL, {
@@ -96,7 +101,12 @@ export async function createClassicCartPage() {
 	);
 }

-async function createBlocksPage( browser, slug, title, blockName ) {
+async function createBlocksPage(
+	browser: Browser,
+	slug: string,
+	title: string,
+	blockName: string
+) {
 	if ( ! ( await pageExists( slug ) ) ) {
 		console.log( 'Creating Checkout Blocks page' );
 		const context = await browser.newContext( {
@@ -112,7 +122,7 @@ async function createBlocksPage( browser, slug, title, blockName ) {
 	}
 }

-export async function createBlocksCheckoutPage( browser ) {
+export async function createBlocksCheckoutPage( browser: Browser ) {
 	await createBlocksPage(
 		browser,
 		BLOCKS_CHECKOUT_PAGE.slug,
@@ -121,7 +131,7 @@ export async function createBlocksCheckoutPage( browser ) {
 	);
 }

-export async function createBlocksCartPage( browser ) {
+export async function createBlocksCartPage( browser: Browser ) {
 	await createBlocksPage(
 		browser,
 		BLOCKS_CART_PAGE.slug,
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/pdp.js b/plugins/woocommerce/tests/e2e-pw/utils/pdp.ts
similarity index 72%
rename from plugins/woocommerce/tests/e2e-pw/utils/pdp.js
rename to plugins/woocommerce/tests/e2e-pw/utils/pdp.ts
index 586059bdba..5d0d179bb1 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/pdp.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/pdp.ts
@@ -1,4 +1,8 @@
-const { expect } = require( '@playwright/test' );
+/**
+ * External dependencies
+ */
+import type { Page } from '@playwright/test';
+import { expect } from '@playwright/test';

 /**
  * Util helper made for adding multiple same products to cart
@@ -7,7 +11,11 @@ const { expect } = require( '@playwright/test' );
  * @param productName
  * @param quantityCount
  */
-export async function addProductsToCart( page, productName, quantityCount ) {
+export async function addProductsToCart(
+	page: Page,
+	productName: string,
+	quantityCount: string
+) {
 	await page.goto(
 		`product/${ productName.replace( / /gi, '-' ).toLowerCase() }`
 	);
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.js b/plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.ts
similarity index 84%
rename from plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.js
rename to plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.ts
index 2e0efad697..b22ecbaeb6 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/plugin-utils.ts
@@ -1,7 +1,16 @@
-const axios = require( 'axios' ).default;
-const fs = require( 'fs' );
-const path = require( 'path' );
-const { wpCLI } = require( './cli' );
+/**
+ * External dependencies
+ */
+import axios from 'axios';
+import fs from 'fs';
+import { pipeline } from 'stream/promises';
+import path from 'path';
+import type { APIRequest } from '@playwright/test';
+
+/**
+ * Internal dependencies
+ */
+import { wpCLI } from './cli';

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

@@ -30,6 +39,11 @@ export const getLatestReleaseZipUrl = async ( {
 	authorizationToken,
 	prerelease = false,
 	perPage = 3,
+}: {
+	repository: string;
+	authorizationToken?: string;
+	prerelease?: boolean;
+	perPage?: number;
 } ) => {
 	const requesturl = prerelease
 		? `https://api.github.com/repos/${ repository }/releases?per_page=${ perPage }`
@@ -49,7 +63,7 @@ export const getLatestReleaseZipUrl = async ( {
 	let response;
 	try {
 		response = await axios( options );
-	} catch ( error ) {
+	} catch ( error: any ) {
 		let errorMessage =
 			'Something went wrong when downloading the plugin.\n';

@@ -111,6 +125,12 @@ export const deletePlugin = async ( {
 	slug,
 	username,
 	password,
+}: {
+	request: APIRequest;
+	baseURL: string;
+	slug: string;
+	username: string;
+	password: string;
 } ) => {
 	// Check if plugin is installed by getting the list of installed plugins, and then finding the one whose `textdomain` property equals `slug`.
 	const apiContext = await request.newContext( {
@@ -128,7 +148,7 @@ export const deletePlugin = async ( {
 	);
 	const pluginsList = await listPluginsResponse.json();
 	const pluginToDelete = pluginsList.find(
-		( { textdomain } ) => textdomain === slug
+		( { textdomain }: { textdomain: string } ) => textdomain === slug
 	);

 	// If installed, get its `plugin` value and use it to deactivate and delete it.
@@ -162,6 +182,12 @@ export const downloadZip = async ( {
 	authorizationToken,
 	prerelease = false,
 	downloadDir = 'tmp',
+}: {
+	url?: string;
+	repository: string;
+	authorizationToken?: string;
+	prerelease?: boolean;
+	downloadDir?: string;
 } ) => {
 	let zipFilename = path.basename( url || repository );
 	zipFilename = zipFilename.endsWith( '.zip' )
@@ -184,7 +210,7 @@ export const downloadZip = async ( {
 	const options = {
 		method: 'get',
 		url: downloadURL,
-		responseType: 'stream',
+		responseType: 'stream' as const,
 		headers: {
 			Authorization: authorizationToken
 				? `token ${ authorizationToken }`
@@ -193,14 +219,14 @@ export const downloadZip = async ( {
 		},
 	};

-	const response = await axios( options ).catch( ( error ) => {
+	const response = await axios( options ).catch( ( error: any ) => {
 		if ( error.response ) {
 			console.error( error.response.data );
 		}
 		throw new Error( error.message );
 	} );

-	response.data.pipe( fs.createWriteStream( zipFilePath ) );
+	await pipeline( response.data, fs.createWriteStream( zipFilePath ) );

 	return zipFilePath;
 };
@@ -210,10 +236,8 @@ export const downloadZip = async ( {
  *
  * @param {string} zipFilePath Local file path to the ZIP.
  */
-export const deleteZip = async ( zipFilePath ) => {
-	await fs.unlink( zipFilePath, ( err ) => {
-		if ( err ) throw err;
-	} );
+export const deleteZip = async ( zipFilePath: string ) => {
+	await fs.promises.unlink( zipFilePath );
 };

 /**
@@ -224,7 +248,7 @@ export const deleteZip = async ( zipFilePath ) => {
  *
  * @param {string} pluginPath
  */
-export const installPluginThruWpCli = async ( pluginPath ) => {
+export const installPluginThruWpCli = async ( pluginPath: string ) => {
 	const wpEnvPluginPath = pluginPath.replace(
 		/.*\/plugins\/woocommerce/,
 		'wp-content/plugins/woocommerce'
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/settings.js b/plugins/woocommerce/tests/e2e-pw/utils/settings.ts
similarity index 88%
rename from plugins/woocommerce/tests/e2e-pw/utils/settings.js
rename to plugins/woocommerce/tests/e2e-pw/utils/settings.ts
index 9b76b59b19..6689e2709f 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/settings.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/settings.ts
@@ -15,7 +15,7 @@ const apiClient = createClient( playwrightConfig.use.baseURL, {
 	password: admin.password,
 } );

-function resolvePath( path ) {
+function resolvePath( path: string ) {
 	return `${ WC_API_PATH }/settings/${ path }`.replace( /\/+/g, '/' );
 }

@@ -26,7 +26,7 @@ function resolvePath( path ) {
  * @param {string} desiredValue - The new value to set for the setting. E.g. 'yes'.
  * @return {Promise<void>} A promise that resolves when the update is complete.
  */
-export async function updateValue( path, desiredValue ) {
+export async function updateValue( path: string, desiredValue: string ) {
 	await apiClient
 		.put( resolvePath( path ), { value: desiredValue } )
 		.catch( ( err ) => {
@@ -42,7 +42,7 @@ export async function updateValue( path, desiredValue ) {
  * @param {string} desiredValue - The desired value to set for the setting. E.g. 'yes'.
  * @return {Promise<{initial: string, updated: string}>} A promise that resolves to an object containing the initial and updated values.
  */
-export async function updateIfNeeded( path, desiredValue ) {
+export async function updateIfNeeded( path: string, desiredValue: string ) {
 	const initialValue = await apiClient
 		.get( resolvePath( path ) )
 		.then( ( r ) => r.data.value )
@@ -63,7 +63,10 @@ export async function updateIfNeeded( path, desiredValue ) {
  * @param {{initial: string, updated: string}} values - An object containing the initial and updated values of the setting. E.g. { initial: 'no', updated: 'yes' }.
  * @return {Promise<void>} A promise that resolves when the reset is complete.
  */
-export async function resetValue( path, values ) {
+export async function resetValue(
+	path: string,
+	values: { initial: string; updated: string }
+) {
 	if ( values.initial !== values.updated ) {
 		await updateValue( path, values.initial );
 	}
diff --git a/plugins/woocommerce/tests/e2e-pw/utils/themes.js b/plugins/woocommerce/tests/e2e-pw/utils/themes.ts
similarity index 65%
rename from plugins/woocommerce/tests/e2e-pw/utils/themes.js
rename to plugins/woocommerce/tests/e2e-pw/utils/themes.ts
index f0e391b02e..34b77bf22e 100644
--- a/plugins/woocommerce/tests/e2e-pw/utils/themes.js
+++ b/plugins/woocommerce/tests/e2e-pw/utils/themes.ts
@@ -1,10 +1,17 @@
-const { request } = require( '@playwright/test' );
-const { encodeCredentials } = require( '../utils/plugin-utils' );
-const { admin } = require( '../test-data/data' );
+/**
+ * External dependencies
+ */
+import { request } from '@playwright/test';
+
+/**
+ * Internal dependencies
+ */
+import { encodeCredentials } from '../utils/plugin-utils';
+import { admin } from '../test-data/data';

 export const DEFAULT_THEME = 'twentytwentythree';

-export const activateTheme = async ( baseURL, theme ) => {
+export const activateTheme = async ( baseURL: string, theme: string ) => {
 	const requestContext = await request.newContext( {
 		baseURL,
 		extraHTTPHeaders: {