Commit 8a27adc50e0 for woocommerce

commit 8a27adc50e0672a9a65f4be52e982af7837ed225
Author: Daniel Mallory <daniel.mallory@automattic.com>
Date:   Tue Jun 9 15:44:07 2026 +0100

    Fix checkout address helpers for collapsed forms (#65548)

diff --git a/packages/js/e2e-utils-playwright/changelog/fix-checkout-address-fill-idempotent b/packages/js/e2e-utils-playwright/changelog/fix-checkout-address-fill-idempotent
new file mode 100644
index 00000000000..a8b75965ce7
--- /dev/null
+++ b/packages/js/e2e-utils-playwright/changelog/fix-checkout-address-fill-idempotent
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Make checkout address field helpers open collapsed address forms before filling fields.
diff --git a/packages/js/e2e-utils-playwright/src/checkout.ts b/packages/js/e2e-utils-playwright/src/checkout.ts
index 87ea4b791e7..c9446c45958 100644
--- a/packages/js/e2e-utils-playwright/src/checkout.ts
+++ b/packages/js/e2e-utils-playwright/src/checkout.ts
@@ -16,6 +16,9 @@ const addressLabels: Record< AddressType, string > = {
 	billing: 'Billing address',
 };

+const addressFieldVisibilityTimeout = 20_000;
+const addressFieldProbeTimeout = 1000;
+
 /**
  * Sets a field value based on its element type (select or input).
  *
@@ -32,6 +35,48 @@ async function setDynamicFieldType( field: Locator, value: string ) {
 	}
 }

+/**
+ * Ensures address fields are editable before filling them.
+ *
+ * Checkout address forms may be rendered either expanded, or collapsed behind
+ * an edit button when an existing customer already has an address. This helper
+ * accepts both valid states so tests do not need to click edit buttons manually.
+ *
+ * @param page - Playwright page object
+ * @param type - The address type ('shipping' or 'billing')
+ */
+async function ensureAddressFieldsEditable( page: Page, type: AddressType ) {
+	const label = addressLabels[ type ];
+	const addressGroup = page.getByRole( 'group', { name: label } );
+	const firstNameField = addressGroup.getByLabel( 'First name' );
+
+	await addressGroup.waitFor( {
+		state: 'visible',
+		timeout: addressFieldVisibilityTimeout,
+	} );
+
+	try {
+		await firstNameField.waitFor( {
+			state: 'visible',
+			timeout: addressFieldProbeTimeout,
+		} );
+		return;
+	} catch {
+		const editButton = page.getByRole( 'button', {
+			name: `Edit ${ label.toLowerCase() }`,
+		} );
+
+		if ( await editButton.isVisible() ) {
+			await editButton.click();
+		}
+	}
+
+	await firstNameField.waitFor( {
+		state: 'visible',
+		timeout: addressFieldVisibilityTimeout,
+	} );
+}
+
 /**
  * Util helper made to fill the Checkout details in the block-based checkout.
  *
@@ -67,6 +112,8 @@ async function fillCheckoutBlocks(

 	const label = addressLabels[ type ];

+	await ensureAddressFieldsEditable( page, type );
+
 	await page
 		.getByRole( 'group', { name: label } )
 		.getByLabel( 'First name' )
@@ -192,6 +239,8 @@ async function fillCheckoutBlocks(
 /**
  * Convenience function to fill Shipping Address fields.
  *
+ * Opens a collapsed shipping address form automatically before filling fields.
+ *
  * @param page            - Playwright page object
  * @param shippingDetails - See CheckoutDetails type for available fields
  */
@@ -205,6 +254,8 @@ export async function fillShippingCheckoutBlocks(
 /**
  * Convenience function to fill Billing Address fields.
  *
+ * Opens a collapsed billing address form automatically before filling fields.
+ *
  * @param page           - Playwright page object
  * @param billingDetails - See CheckoutDetails type for available fields
  */
diff --git a/plugins/woocommerce/changelog/fix-checkout-address-fill-idempotent b/plugins/woocommerce/changelog/fix-checkout-address-fill-idempotent
new file mode 100644
index 00000000000..72918bd72aa
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-checkout-address-fill-idempotent
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Use idempotent checkout address helpers in checkout e2e tests.
diff --git a/plugins/woocommerce/tests/e2e-pw/tests/checkout/checkout.spec.ts b/plugins/woocommerce/tests/e2e-pw/tests/checkout/checkout.spec.ts
index 8222bcf6d60..36655ae6023 100644
--- a/plugins/woocommerce/tests/e2e-pw/tests/checkout/checkout.spec.ts
+++ b/plugins/woocommerce/tests/e2e-pw/tests/checkout/checkout.spec.ts
@@ -445,9 +445,6 @@ checkoutPages.forEach( ( { name, slug } ) => {
 					.locator( '#shipping_postcode' )
 					.fill( shippingAddress.zip );
 			} else {
-				await page
-					.getByRole( 'button', { name: 'Edit shipping address' } )
-					.click();
 				await fillShippingCheckoutBlocks( page, shippingAddress );
 			}