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;
} );
}