Commit 076da176869 for woocommerce

commit 076da176869bcdc33ee79e9acb8922f1267285ec
Author: Adrian Moldovan <3854374+adimoldovan@users.noreply.github.com>
Date:   Mon Aug 3 16:07:28 2026 +0300

    e2e tests: Fix lost-response race in analytics and variable product specs (#67341)

diff --git a/plugins/woocommerce/changelog/fix-analytics-overview-e2e-waitforresponse-race b/plugins/woocommerce/changelog/fix-analytics-overview-e2e-waitforresponse-race
new file mode 100644
index 00000000000..95f2ef70d4e
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-analytics-overview-e2e-waitforresponse-race
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Fix lost-response race in the Analytics Overview and variable product E2E tests by registering waitForResponse before the click that triggers the save.
diff --git a/plugins/woocommerce/tests/e2e/tests/analytics/analytics-overview.spec.ts b/plugins/woocommerce/tests/e2e/tests/analytics/analytics-overview.spec.ts
index e49a6ea617b..e78092c31a5 100644
--- a/plugins/woocommerce/tests/e2e/tests/analytics/analytics-overview.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/analytics/analytics-overview.spec.ts
@@ -2,7 +2,11 @@
  * External dependencies
  */
 import { test, expect } from '@playwright/test';
-import type { Page, Locator } from '@playwright/test';
+import type {
+	Page,
+	Locator,
+	Response as PlaywrightResponse,
+} from '@playwright/test';

 /**
  * Internal dependencies
@@ -30,6 +34,22 @@ const headers = {
 	cookie: '',
 };

+// Call this before the click that triggers the save, and await the returned
+// promise after it — registering the listener after the click can miss a
+// response that already arrived.
+const waitForUserPrefsSave = () =>
+	page.waitForResponse(
+		( res ) =>
+			res.url().includes( `/users/${ userId }` ) &&
+			res.request().method() !== 'GET'
+	);
+
+const expectSaved = ( response: PlaywrightResponse ) =>
+	expect(
+		response.ok(),
+		`${ response.status() } ${ response.url() }`
+	).toBeTruthy();
+
 const hidePerformanceSection = async () => {
 	const response =
 		await test.step( `Send POST request to hide Performance section`, async () => {
@@ -212,12 +232,9 @@ test.describe(

 					await test.step( `Move first section down`, async () => {
 						await buttons_ellipsis.first().click();
+						const savePromise = waitForUserPrefsSave();
 						await menuitem_moveDown.click();
-						await page.waitForResponse(
-							( response ) =>
-								response.url().includes( '/users' ) &&
-								response.ok()
-						);
+						expectSaved( await savePromise );
 					} );

 					await test.step( `Expect the second section to become first, and first becomes second.`, async () => {
@@ -241,12 +258,9 @@ test.describe(

 					await test.step( `Move second section up`, async () => {
 						await buttons_ellipsis.nth( 1 ).click();
+						const savePromise = waitForUserPrefsSave();
 						await menuitem_moveUp.click();
-						await page.waitForResponse(
-							( response ) =>
-								response.url().includes( '/users' ) &&
-								response.ok()
-						);
+						expectSaved( await savePromise );
 					} );

 					await test.step( `Expect second section becomes first section, first becomes second`, async () => {
@@ -268,13 +282,11 @@ test.describe(
 						name: 'Choose which analytics to display and the section name',
 					} )
 					.click();
+				const savePromise = waitForUserPrefsSave();
 				await page
 					.getByRole( 'menuitem', { name: 'Remove section' } )
 					.click();
-				await page.waitForResponse(
-					( response ) =>
-						response.url().includes( '/users' ) && response.ok()
-				);
+				expectSaved( await savePromise );
 			} );

 			await test.step( `Expect the Performance section to be hidden`, async () => {
@@ -284,16 +296,14 @@ test.describe(
 		} );

 		test( 'should allow a user to add a section back in', async () => {
-			await hidePerformanceSection( page );
+			await hidePerformanceSection();
 			await page.reload();

 			await test.step( `Add the Performance section back in.`, async () => {
 				await page.getByTitle( 'Add more sections' ).click();
+				const savePromise = waitForUserPrefsSave();
 				await page.getByTitle( 'Add Performance section' ).click();
-				await page.waitForResponse(
-					( response ) =>
-						response.url().includes( '/users' ) && response.ok()
-				);
+				expectSaved( await savePromise );
 			} );

 			await test.step( `Expect the Performance section to be added back.`, async () => {
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 b38f52a9a82..a4fd27ec587 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
@@ -66,6 +66,16 @@ test.describe( 'Add variable product', { tag: tags.GUTENBERG }, () => {
 			} );

 		if ( tourWasDisplayed ) {
+			// Start listening before the click — the save can complete before
+			// the click call returns, and a listener registered afterwards
+			// would never see it.
+			const savePromise = page.waitForResponse(
+				( response ) =>
+					response.url().includes( '/users/' ) &&
+					response.request().method() !== 'GET' &&
+					response.ok()
+			);
+
 			await test.step( 'Tour was displayed, so dismiss it.', async () => {
 				await page
 					.getByRole( 'button', { name: 'Close Tour' } )
@@ -73,11 +83,7 @@ test.describe( 'Add variable product', { tag: tags.GUTENBERG }, () => {
 			} );

 			await test.step( "Wait for the tour's dismissal to be saved", async () => {
-				await page.waitForResponse(
-					( response ) =>
-						response.url().includes( '/users/' ) &&
-						response.status() === 200
-				);
+				await savePromise;
 			} );
 		}