Commit 713aeda4f2d for woocommerce
commit 713aeda4f2d242452c04c4aa8a5f73bcf044060b
Author: agent-sandbox-woocommerce[bot] <282076412+agent-sandbox-woocommerce[bot]@users.noreply.github.com>
Date: Fri Oct 23 13:09:25 2026 +0000
Fix cart-store nonce refresh E2E test timing flake in parallel runs (#70144)
diff --git a/plugins/woocommerce/changelog/fxlt-12-cart-store-nonce-e2e-timing b/plugins/woocommerce/changelog/fxlt-12-cart-store-nonce-e2e-timing
new file mode 100644
index 00000000000..df9de9831b2
--- /dev/null
+++ b/plugins/woocommerce/changelog/fxlt-12-cart-store-nonce-e2e-timing
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Make the cart-store nonce refresh E2E test independent of nonce expiry timing; no production change.
diff --git a/plugins/woocommerce/tests/e2e/tests/blocks/cart/cart-store.block_theme.spec.ts b/plugins/woocommerce/tests/e2e/tests/blocks/cart/cart-store.block_theme.spec.ts
index 9f1bc9945f2..e1d3609f682 100644
--- a/plugins/woocommerce/tests/e2e/tests/blocks/cart/cart-store.block_theme.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/blocks/cart/cart-store.block_theme.spec.ts
@@ -1,21 +1,17 @@
/**
* External dependencies
*/
+import type { APIResponse, Route } from '@playwright/test';
import { test, expect, guestFile } from '@woocommerce/e2e-utils';
/**
* Internal dependencies
*/
import { REGULAR_PRICED_PRODUCT_NAME } from '../checkout/constants';
-import { setFilterValue } from '../../../utils/filters';
test.describe( 'Cart Store', () => {
test.use( { storageState: guestFile } );
- test.beforeEach( async ( { page } ) => {
- await setFilterValue( page, 'nonce_life', 2 );
- } );
-
test( 'should refresh nonce from Store API and use it for cart mutations', async ( {
page,
frontendUtils,
@@ -23,13 +19,34 @@ test.describe( 'Cart Store', () => {
let refreshNonce: string | null = null;
let requestNonce: string | null = null;
let responseNonce: string | null = null;
+ let batchCount = 0;
+ // Between the first and second mutation, every response hands the
+ // client a stale nonce, so the second mutation is rejected without
+ // depending on the nonce lifetime.
+ const STALE_NONCE = 'stale-nonce';
+ const fulfillWithNonce = async (
+ route: Route,
+ response: APIResponse
+ ) => {
+ await route.fulfill(
+ batchCount === 1
+ ? {
+ response,
+ headers: {
+ ...response.headers(),
+ nonce: STALE_NONCE,
+ },
+ }
+ : { response }
+ );
+ };
// Intercept GET /cart (refreshCartItems) to capture the nonce.
await page.route( '**/wc/store/v1/cart**', async ( route ) => {
if ( route.request().method() === 'GET' ) {
const response = await route.fetch();
- refreshNonce = response.headers().nonce || null;
- await route.fulfill( { response } );
+ refreshNonce ??= response.headers().nonce || null;
+ await fulfillWithNonce( route, response );
} else {
await route.continue();
}
@@ -38,10 +55,11 @@ test.describe( 'Cart Store', () => {
// Intercept batch requests to track which nonce the client sends
// and which nonce the server returns.
await page.route( '**/wc/store/v1/batch**', async ( route ) => {
+ batchCount++;
requestNonce = route.request().headers().nonce || null;
const response = await route.fetch();
responseNonce = response.headers().nonce || null;
- await route.fulfill( { response } );
+ await fulfillWithNonce( route, response );
} );
await frontendUtils.goToShop();
@@ -54,18 +72,14 @@ test.describe( 'Cart Store', () => {
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
expect( requestNonce ).toBe( refreshNonce );
- // Wait for the nonce to expire.
- // eslint-disable-next-line playwright/no-wait-for-timeout, no-restricted-syntax
- await page.waitForTimeout( 2000 );
-
- // Adding another product should fail because it is using an expired nonce.
+ // Adding another product should fail because it is using a stale nonce.
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+ expect( requestNonce ).toBe( STALE_NONCE );
await expect( page.getByText( 'Nonce is invalid.' ) ).toBeVisible();
const previousResponseNonce = responseNonce;
- // Nonce should be updated now and the request should succeed.
+ // The client should use the nonce from the failed response and succeed.
await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
- expect( requestNonce ).not.toBe( refreshNonce );
expect( requestNonce ).toBe( previousResponseNonce );
// Verify the product was actually added to the cart properly.