Commit 67771198dfc for woocommerce

commit 67771198dfccfb433a6fbbb45fe6cefa623fe3fe
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date:   Thu Sep 24 17:55:31 2026 +0300

    Revert "[tests] Reduce additional checkout field E2E tests from 12 to 7" (#69049)

    revert: Revert "[tests] Reduce additional checkout field E2E tests from 12 to 7" (#68588)

    This reverts commit 95e0a58cefcbd16da79faa41ccea9c6ea1407e53.

    Rubik asked for the E2E migration's test changes in its areas to be
    reverted until the team can review them. #68588 is one of the 11 PRs on
    the revert list Rubik agreed on 2026-09-24.

    The revert brings back the browser tests the PR removed or cut down and
    removes the lower-layer tests it added in their place. Only test code
    and changelog entries change; nothing ships.

    Refs TESTOPS-234
    Refs #68588

    Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

diff --git a/plugins/woocommerce/changelog/testops-234-checkout-block-fields b/plugins/woocommerce/changelog/testops-234-checkout-block-fields
deleted file mode 100644
index 4352a4c5cd1..00000000000
--- a/plugins/woocommerce/changelog/testops-234-checkout-block-fields
+++ /dev/null
@@ -1,4 +0,0 @@
-Significance: patch
-Type: dev
-Comment: Reduce additional checkout field E2E tests from 12 to 7; a new CheckoutFieldsAdminTest owns the order admin field formatting and update contract.
-
diff --git a/plugins/woocommerce/client/blocks/packages/public-api/blocks-components/checkbox-control/test/validated-checkbox-control.tsx b/plugins/woocommerce/client/blocks/packages/public-api/blocks-components/checkbox-control/test/validated-checkbox-control.tsx
deleted file mode 100644
index 8206124aaa6..00000000000
--- a/plugins/woocommerce/client/blocks/packages/public-api/blocks-components/checkbox-control/test/validated-checkbox-control.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * External dependencies
- */
-import { act, fireEvent, render, screen } from '@testing-library/react';
-import { validationStore } from '@woocommerce/block-data';
-import { dispatch } from '@wordpress/data';
-import { useState } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import ValidatedCheckboxControl from '../validated-checkbox-control';
-
-describe( 'ValidatedCheckboxControl', () => {
-	const label = 'Test required checkbox';
-	const errorMessage = 'Please check the box or you will be unable to order';
-
-	const renderUnchecked = ( props = {} ) =>
-		render(
-			<ValidatedCheckboxControl
-				id="required-checkbox"
-				label={ label }
-				required
-				checked={ false }
-				onChange={ () => void 0 }
-				{ ...props }
-			/>
-		);
-
-	it( "Shows the field's own error message once errors are revealed", async () => {
-		renderUnchecked( { errorMessage } );
-
-		// Validation runs on mount but starts hidden, which is what a shopper sees
-		// before they try to place the order.
-		expect( screen.queryByText( errorMessage ) ).not.toBeInTheDocument();
-
-		await act( async () => {
-			dispatch( validationStore ).showAllValidationErrors();
-		} );
-
-		expect( screen.getByText( errorMessage ) ).toBeInTheDocument();
-	} );
-
-	it( 'Clears the error once the shopper checks the box', async () => {
-		// The two cases above render with checked fixed at false, so they only cover
-		// the reveal. The clear runs through a different path entirely --
-		// onChange -> validateInput( false ) -> clearValidationError -- and a
-		// regression there leaves a blocking error on screen after the shopper has
-		// already fixed the problem. Drive it through a stateful parent, the way
-		// checkout does, so the checkbox actually ends up checked.
-		const StatefulCheckbox = () => {
-			const [ checked, setChecked ] = useState( false );
-
-			return (
-				<ValidatedCheckboxControl
-					id="required-checkbox"
-					label={ label }
-					required
-					checked={ checked }
-					onChange={ setChecked }
-					errorMessage={ errorMessage }
-				/>
-			);
-		};
-
-		render( <StatefulCheckbox /> );
-
-		await act( async () => {
-			dispatch( validationStore ).showAllValidationErrors();
-		} );
-		expect( screen.getByText( errorMessage ) ).toBeInTheDocument();
-
-		fireEvent.click( screen.getByRole( 'checkbox' ) );
-
-		expect( screen.getByRole( 'checkbox' ) ).toBeChecked();
-		expect( screen.queryByText( errorMessage ) ).not.toBeInTheDocument();
-	} );
-
-	it( 'Falls back to the generated message when the field supplies none', async () => {
-		renderUnchecked();
-
-		await act( async () => {
-			dispatch( validationStore ).showAllValidationErrors();
-		} );
-
-		// Without this the test above would pass on any message at all, rather than
-		// on the one the field asked for.
-		expect( screen.queryByText( errorMessage ) ).not.toBeInTheDocument();
-		expect(
-			screen.getByText( 'Please check this box if you want to proceed.' )
-		).toBeInTheDocument();
-	} );
-} );
diff --git a/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.guest-shopper.block_theme.spec.ts b/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.guest-shopper.block_theme.spec.ts
index c4e0e7c12f1..cf45a55174d 100644
--- a/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.guest-shopper.block_theme.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.guest-shopper.block_theme.spec.ts
@@ -29,6 +29,96 @@ test.describe( 'Shopper → Additional Checkout Fields', () => {
 			);
 		} );

+		test( 'Shopper can see an error message when a required field is not filled in the checkout form', async ( {
+			checkoutPageObject,
+			frontendUtils,
+		} ) => {
+			await frontendUtils.goToShop();
+			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+			await frontendUtils.goToCheckout();
+
+			await checkoutPageObject.editShippingDetails();
+			await checkoutPageObject.unsyncBillingWithShipping();
+			await checkoutPageObject.editBillingDetails();
+			await checkoutPageObject.fillInCheckoutWithTestData(
+				{},
+				{
+					contact: {
+						'Alternative Email': 'test@test.com',
+						'Enter a gift message to include in the package':
+							'For my non-ascii named friend: niño',
+					},
+					address: {
+						shipping: {
+							'Government ID': '',
+							'Confirm government ID': '',
+						},
+						billing: {
+							'Government ID': '54321',
+							'Confirm government ID': '54321',
+						},
+					},
+					order: {
+						'How did you hear about us?': 'Other',
+						'What is your favourite colour?': 'Blue',
+					},
+				}
+			);
+
+			// Use the data store to specifically unset the field value - this is because it might be saved in the user-state.
+			await checkoutPageObject.page.evaluate( () => {
+				window.wp.data.dispatch( 'wc/store/cart' ).setShippingAddress( {
+					'first-plugin-namespace/road-size': '',
+				} );
+			} );
+
+			await checkoutPageObject.placeOrder( false );
+
+			// Test that the required checkbox warning shows up after submitting without interacting.
+			await expect(
+				checkoutPageObject.page.getByText(
+					'Please check the box or you will be unable to order'
+				)
+			).toBeVisible();
+
+			await checkoutPageObject.page
+				.getByLabel( 'Test required checkbox' )
+				.click();
+
+			await expect(
+				checkoutPageObject.page.getByText(
+					'Please check the box or you will be unable to order'
+				)
+			).toBeHidden();
+
+			// Test that unchecking shows and checking again hides the message.
+			await checkoutPageObject.page
+				.getByLabel( 'Test required checkbox' )
+				.uncheck();
+
+			await expect(
+				checkoutPageObject.page.getByText(
+					'Please check the box or you will be unable to order'
+				)
+			).toBeVisible();
+
+			await checkoutPageObject.page
+				.getByLabel( 'Test required checkbox' )
+				.click();
+
+			await expect(
+				checkoutPageObject.page.getByText(
+					'Please check the box or you will be unable to order'
+				)
+			).toBeHidden();
+
+			await expect(
+				checkoutPageObject.page.getByText(
+					'Please enter a valid government id'
+				)
+			).toBeVisible();
+		} );
+
 		test( 'Shopper can fill in the checkout form with additional fields and can have different value for same field in shipping and billing address', async ( {
 			checkoutPageObject,
 			frontendUtils,
@@ -312,21 +402,16 @@ test.describe( 'Shopper → Additional Checkout Fields', () => {
 			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
 			await frontendUtils.goToCheckout();

-			// The field is hidden while the cart total is at or below $40.
+			// The shipping insurance field should be hidden by default (cart total < 2000)
 			await expect(
 				checkoutPageObject.page.getByLabel( 'Add shipping insurance' )
 			).toBeHidden();

 			await frontendUtils.goToShop();
 			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
-			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
-			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
 			await frontendUtils.goToCheckout();

-			// Four $20 products against the field's $59 required threshold. Three
-			// would also clear it, but only by a dollar, so any sale price or
-			// total-computation change would silently drop the field out of
-			// "required" and fail the assertions below for an unrelated reason.
+			// The shipping insurance field should now be visible (cart total > 2000)
 			await expect(
 				checkoutPageObject.page.getByLabel( 'Add shipping insurance' )
 			).toBeVisible();
@@ -373,13 +458,10 @@ test.describe( 'Shopper → Additional Checkout Fields', () => {

 			await checkoutPageObject.waitForCheckoutToFinishUpdating();

-			// The error should be gone. Assert the same string the visible check
-			// above uses: "Add shipping insurance is a required field." appears
-			// nowhere in the plugin, so toBeHidden() was matching zero elements
-			// and passing whether or not the error had actually cleared.
+			// The error should be gone
 			await expect(
 				checkoutPageObject.page.getByText(
-					'Please check this box if you want to proceed.'
+					'Add shipping insurance is a required field.'
 				)
 			).toBeHidden();
 		} );
diff --git a/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.merchant.block_theme.spec.ts b/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.merchant.block_theme.spec.ts
index 070008aedc8..be1fa356551 100644
--- a/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.merchant.block_theme.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.merchant.block_theme.spec.ts
@@ -29,317 +29,387 @@ test.describe( 'Merchant → Additional Checkout Fields', () => {
 		await frontendUtils.goToCheckout();
 	} );

-	test( 'Merchant can view and edit additional fields in the order admin page', async ( {
+	test( 'Merchant can see additional fields in the order admin page', async ( {
 		checkoutPageObject,
 		admin,
 	} ) => {
-		await test.step( 'Merchant can see additional fields in the order admin page', async () => {
-			await checkoutPageObject.editShippingDetails();
-			await checkoutPageObject.unsyncBillingWithShipping();
-			await checkoutPageObject.editBillingDetails();
-			await checkoutPageObject.fillInCheckoutWithTestData(
-				{},
-				{
-					contact: {
-						'Alternative Email': 'test@test.com',
-						'Enter a gift message to include in the package':
-							'This is for you!',
-						'Is this a personal purchase or a business purchase?':
-							'business',
+		await checkoutPageObject.editShippingDetails();
+		await checkoutPageObject.unsyncBillingWithShipping();
+		await checkoutPageObject.editBillingDetails();
+		await checkoutPageObject.fillInCheckoutWithTestData(
+			{},
+			{
+				contact: {
+					'Alternative Email': 'test@test.com',
+					'Enter a gift message to include in the package':
+						'This is for you!',
+					'Is this a personal purchase or a business purchase?':
+						'business',
+				},
+				address: {
+					shipping: {
+						'Government ID': '12345',
+						'Confirm government ID': '12345',
 					},
-					address: {
-						shipping: {
-							'Government ID': '12345',
-							'Confirm government ID': '12345',
-						},
-						billing: {
-							'Government ID': '54321',
-							'Confirm government ID': '54321',
-						},
+					billing: {
+						'Government ID': '54321',
+						'Confirm government ID': '54321',
 					},
-					order: {
-						'How did you hear about us?': 'Other',
-						'What is your favourite colour?': 'Blue',
+				},
+				order: {
+					'How did you hear about us?': 'Other',
+					'What is your favourite colour?': 'Blue',
+				},
+			}
+		);
+
+		// Fill select fields "manually" (Not part of "fillInCheckoutWithTestData"). This is a workaround for select
+		// fields until we recreate th Combobox component. This is because the aria-label includes the value so getting
+		// by label alone is not reliable unless we know the value.
+		await checkoutPageObject.page
+			.getByRole( 'group', {
+				name: 'Shipping address',
+			} )
+			.getByLabel( 'How wide is your road?' )
+			.selectOption( 'wide' );
+		await checkoutPageObject.page
+			.getByRole( 'group', {
+				name: 'Billing address',
+			} )
+			.getByLabel( 'How wide is your road?' )
+			.selectOption( 'narrow' );
+
+		await checkoutPageObject.page.evaluate(
+			'document.activeElement.blur()'
+		);
+
+		await checkoutPageObject.page
+			.getByLabel( 'Would you like a free gift with your order?' )
+			.check();
+		await checkoutPageObject.page
+			.getByLabel( 'Do you want to subscribe to our newsletter?' )
+			.check();
+		await checkoutPageObject.page
+			.getByRole( 'group', {
+				name: 'Shipping address',
+			} )
+			.getByLabel( 'Can a truck fit down your road?' )
+			.check();
+
+		await checkoutPageObject.page
+			.getByRole( 'group', {
+				name: 'Billing address',
+			} )
+			.getByLabel( 'Can a truck fit down your road?' )
+			.uncheck();
+
+		await checkoutPageObject.page
+			.getByLabel( 'Test required checkbox' )
+			.check();
+
+		await checkoutPageObject.placeOrder();
+
+		const orderId = checkoutPageObject.getOrderId();
+		await admin.page.goto(
+			`wp-admin/post.php?post=${ orderId }&action=edit`
+		);
+
+		await expect(
+			admin.page.getByText( 'Government ID: 12345', { exact: true } )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Confirm government ID: 12345', {
+				exact: true,
+			} )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Government ID: 54321', { exact: true } )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Confirm government ID: 54321', {
+				exact: true,
+			} )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'What is your favourite colour?: Blue' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText(
+				'Enter a gift message to include in the package: This is for you!'
+			)
+		).toBeVisible();
+		await expect(
+			admin.page.getByText(
+				'Do you want to subscribe to our newsletter?: Yes'
+			)
+		).toBeVisible();
+		await expect(
+			admin.page.getByText(
+				'Would you like a free gift with your order?: Yes'
+			)
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Can a truck fit down your road?: Yes' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Can a truck fit down your road?: No' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'How wide is your road?: Wide' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'How wide is your road?: Narrow' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText(
+				'Is this a personal purchase or a business purchase?: Business'
+			)
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'How did you hear about us?: Other' )
+		).toBeVisible();
+	} );
+
+	test( 'Merchant can edit custom fields from the order admin page', async ( {
+		checkoutPageObject,
+		admin,
+	} ) => {
+		await checkoutPageObject.editShippingDetails();
+		await checkoutPageObject.unsyncBillingWithShipping();
+		await checkoutPageObject.editBillingDetails();
+		await checkoutPageObject.fillInCheckoutWithTestData(
+			{},
+			{
+				contact: {
+					'Alternative Email': 'test@test.com',
+					'Enter a gift message to include in the package':
+						'This is for you!',
+					'Is this a personal purchase or a business purchase?':
+						'business',
+				},
+				address: {
+					shipping: {
+						'Government ID': '12345',
+						'Confirm government ID': '12345',
 					},
-				}
-			);
-
-			// Fill select fields "manually" (Not part of "fillInCheckoutWithTestData"). This is a workaround for select
-			// fields until we recreate th Combobox component. This is because the aria-label includes the value so getting
-			// by label alone is not reliable unless we know the value.
-			await checkoutPageObject.page
-				.getByRole( 'group', {
-					name: 'Shipping address',
-				} )
-				.getByLabel( 'How wide is your road?' )
-				.selectOption( 'wide' );
-			await checkoutPageObject.page
-				.getByRole( 'group', {
-					name: 'Billing address',
-				} )
-				.getByLabel( 'How wide is your road?' )
-				.selectOption( 'narrow' );
-
-			await checkoutPageObject.page.evaluate(
-				'document.activeElement.blur()'
-			);
-
-			await checkoutPageObject.page
-				.getByLabel( 'Would you like a free gift with your order?' )
-				.check();
-			await checkoutPageObject.page
-				.getByLabel( 'Do you want to subscribe to our newsletter?' )
-				.check();
-			await checkoutPageObject.page
-				.getByRole( 'group', {
-					name: 'Shipping address',
-				} )
-				.getByLabel( 'Can a truck fit down your road?' )
-				.check();
-
-			await checkoutPageObject.page
-				.getByRole( 'group', {
-					name: 'Billing address',
-				} )
-				.getByLabel( 'Can a truck fit down your road?' )
-				.uncheck();
-
-			await checkoutPageObject.page
-				.getByLabel( 'Test required checkbox' )
-				.check();
-
-			await checkoutPageObject.placeOrder();
-
-			const orderId = checkoutPageObject.getOrderId();
-			await admin.page.goto(
-				`wp-admin/admin.php?page=wc-orders&action=edit&id=${ orderId }`
-			);
-			await expect( admin.page ).toHaveURL(
-				new RegExp(
-					`admin\\.php\\?page=wc-orders&action=edit&id=${ orderId }$`
-				)
-			);
-
-			await expect(
-				admin.page.getByText( 'Government ID: 12345', { exact: true } )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Confirm government ID: 12345', {
-					exact: true,
-				} )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Government ID: 54321', { exact: true } )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Confirm government ID: 54321', {
-					exact: true,
-				} )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'What is your favourite colour?: Blue' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText(
-					'Enter a gift message to include in the package: This is for you!'
-				)
-			).toBeVisible();
-			await expect(
-				admin.page.getByText(
-					'Do you want to subscribe to our newsletter?: Yes'
-				)
-			).toBeVisible();
-			await expect(
-				admin.page.getByText(
-					'Would you like a free gift with your order?: Yes'
-				)
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Can a truck fit down your road?: Yes' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Can a truck fit down your road?: No' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'How wide is your road?: Wide' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'How wide is your road?: Narrow' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText(
-					'Is this a personal purchase or a business purchase?: Business'
-				)
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'How did you hear about us?: Other' )
-			).toBeVisible();
-		} );
+					billing: {
+						'Government ID': '54321',
+						'Confirm government ID': '54321',
+					},
+				},
+				order: {
+					'How did you hear about us?': 'Other',
+					'What is your favourite colour?': 'Blue',
+				},
+			}
+		);

-		const orderAdminUrl = admin.page.url();
-
-		await test.step( 'Merchant can edit custom fields from the order admin page', async () => {
-			await admin.page.goto( orderAdminUrl );
-
-			await admin.page
-				.getByRole( 'heading', { name: 'Billing Edit' } )
-				.getByRole( 'link' )
-				.click();
-
-			// Change all the billing details
-			await admin.page
-				.getByRole( 'textbox', {
-					name: 'Government ID',
-					exact: true,
-				} )
-				.fill( '99999' );
-			await admin.page
-				.getByRole( 'textbox', {
-					name: 'Confirm government ID',
-					exact: true,
-				} )
-				.fill( '99999' );
-			await admin.page
-				.getByRole( 'checkbox', {
-					name: 'Can a truck fit down your road?',
-				} )
-				.check();
-
-			// Use Locator here because the select2 box is duplicated in shipping.
-			await admin.page
-				.locator(
-					'[id="\\_wc_billing\\/first-plugin-namespace\\/road-size"]'
-				)
-				.selectOption( 'wide' );
-
-			// Handle changing the contact fields.
-			await admin.page
-				.getByLabel( 'Do you want to subscribe to our newsletter?' )
-				.uncheck();
-			await admin.page
-				.getByLabel( 'Enter a gift message to include in the package' )
-				.fill( 'Some other message' );
-			await admin.page
-				.getByLabel(
-					'Is this a personal purchase or a business purchase?'
-				)
-				.selectOption( 'personal' );
-
-			const clickPromise = admin.page
-				.getByRole( 'button', { name: 'Update' } )
-				.first()
-				.click();
-
-			const navigationPromise =
-				admin.page.waitForEvent( 'domcontentloaded' );
-
-			// When update is clicked without waiting for DOMContentLoaded the page becomes
-			// available before click handlers are attached to the shipping edit link.
-			await Promise.all( [ clickPromise, navigationPromise ] );
-
-			await admin.page
-				.getByRole( 'heading', { name: 'Shipping Edit' } )
-				.getByRole( 'link' )
-				.click();
-
-			// Change all the shipping details
-			await admin.page
-				.getByRole( 'textbox', {
-					name: 'Government ID',
-					exact: true,
-				} )
-				.fill( '88888' );
-			await admin.page
-				.getByRole( 'textbox', {
-					name: 'Confirm government ID',
-					exact: true,
-				} )
-				.fill( '88888' );
-			await admin.page
-				.getByRole( 'checkbox', {
-					name: 'Can a truck fit down your road?',
-				} )
-				.uncheck();
-
-			// Use Locator here because the select2 box is duplicated in billing.
-			await admin.page
-				.locator(
-					'[id="\\_wc_shipping\\/first-plugin-namespace\\/road-size"]'
-				)
-				.selectOption( 'super-wide' );
-
-			// Handle changing the additional information fields.
-			await admin.page
-				.getByLabel( 'Would you like a free gift with your order?' )
-				.uncheck();
-			await admin.page
-				.getByLabel( 'What is your favourite colour?' )
-				.fill( 'Green' );
-			await admin.page
-				.getByLabel( 'How did you hear about us?' )
-				.selectOption( 'google' );
-
-			await admin.page
-				.getByRole( 'button', { name: 'Update' } )
-				.first()
-				.click();
-
-			await admin.page.waitForLoadState( 'domcontentloaded' );
-
-			await expect(
-				admin.page.getByText( 'Government ID: 88888', { exact: true } )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Confirm government ID: 88888', {
-					exact: true,
-				} )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Government ID: 99999', { exact: true } )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Confirm government ID: 99999', {
-					exact: true,
-				} )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'What is your favourite colour?: Green' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText(
-					'Enter a gift message to include in the package: Some other message'
-				)
-			).toBeVisible();
-			await expect(
-				admin.page.getByText(
-					'Do you want to subscribe to our newsletter?: No'
-				)
-			).toBeVisible();
-			await expect(
-				admin.page.getByText(
-					'Would you like a free gift with your order?: No'
-				)
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Can a truck fit down your road?: Yes' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'Can a truck fit down your road?: No' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'How wide is your road?: Super wide' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'How wide is your road?: Wide' )
-			).toBeVisible();
-			await expect(
-				admin.page.getByText(
-					'Is this a personal purchase or a business purchase?: Personal'
-				)
-			).toBeVisible();
-			await expect(
-				admin.page.getByText( 'How did you hear about us?: Google' )
-			).toBeVisible();
-		} );
+		// Fill select fields "manually" (Not part of "fillInCheckoutWithTestData"). This is a workaround for select
+		// fields until we recreate th Combobox component. This is because the aria-label includes the value so getting
+		// by label alone is not reliable unless we know the value.
+		await checkoutPageObject.page
+			.getByRole( 'group', {
+				name: 'Shipping address',
+			} )
+			.getByLabel( 'How wide is your road?' )
+			.selectOption( 'wide' );
+		await checkoutPageObject.page
+			.getByRole( 'group', {
+				name: 'Billing address',
+			} )
+			.getByLabel( 'How wide is your road?' )
+			.selectOption( 'narrow' );
+
+		await checkoutPageObject.page.evaluate(
+			'document.activeElement.blur()'
+		);
+
+		await checkoutPageObject.page
+			.getByLabel( 'Would you like a free gift with your order?' )
+			.check();
+		await checkoutPageObject.page
+			.getByLabel( 'Do you want to subscribe to our newsletter?' )
+			.check();
+		await checkoutPageObject.page
+			.getByRole( 'group', {
+				name: 'Shipping address',
+			} )
+			.getByLabel( 'Can a truck fit down your road?' )
+			.check();
+
+		await checkoutPageObject.page
+			.getByRole( 'group', {
+				name: 'Billing address',
+			} )
+			.getByLabel( 'Can a truck fit down your road?' )
+			.uncheck();
+
+		await checkoutPageObject.page
+			.getByLabel( 'Test required checkbox' )
+			.check();
+
+		await checkoutPageObject.placeOrder();
+
+		const orderId = checkoutPageObject.getOrderId();
+		await admin.page.goto(
+			`wp-admin/post.php?post=${ orderId }&action=edit`
+		);
+
+		await admin.page
+			.getByRole( 'heading', { name: 'Billing Edit' } )
+			.getByRole( 'link' )
+			.click();
+
+		// Change all the billing details
+		await admin.page
+			.getByRole( 'textbox', {
+				name: 'Government ID',
+				exact: true,
+			} )
+			.fill( '99999' );
+		await admin.page
+			.getByRole( 'textbox', {
+				name: 'Confirm government ID',
+				exact: true,
+			} )
+			.fill( '99999' );
+		await admin.page
+			.getByRole( 'checkbox', {
+				name: 'Can a truck fit down your road?',
+			} )
+			.check();
+
+		// Use Locator here because the select2 box is duplicated in shipping.
+		await admin.page
+			.locator(
+				'[id="\\_wc_billing\\/first-plugin-namespace\\/road-size"]'
+			)
+			.selectOption( 'wide' );
+
+		// Handle changing the contact fields.
+		await admin.page
+			.getByLabel( 'Do you want to subscribe to our newsletter?' )
+			.uncheck();
+		await admin.page
+			.getByLabel( 'Enter a gift message to include in the package' )
+			.fill( 'Some other message' );
+		await admin.page
+			.getByLabel( 'Is this a personal purchase or a business purchase?' )
+			.selectOption( 'personal' );
+
+		const clickPromise = admin.page
+			.getByRole( 'button', { name: 'Update' } )
+			.first()
+			.click();
+
+		const navigationPromise = admin.page.waitForEvent( 'domcontentloaded' );
+
+		// When update is clicked without waiting for DOMContentLoaded the page becomes
+		// available before click handlers are attached to the shipping edit link.
+		await Promise.all( [ clickPromise, navigationPromise ] );
+
+		await admin.page
+			.getByRole( 'heading', { name: 'Shipping Edit' } )
+			.getByRole( 'link' )
+			.click();
+
+		// Change all the shipping details
+		await admin.page
+			.getByRole( 'textbox', {
+				name: 'Government ID',
+				exact: true,
+			} )
+			.fill( '88888' );
+		await admin.page
+			.getByRole( 'textbox', {
+				name: 'Confirm government ID',
+				exact: true,
+			} )
+			.fill( '88888' );
+		await admin.page
+			.getByRole( 'checkbox', {
+				name: 'Can a truck fit down your road?',
+			} )
+			.uncheck();
+
+		// Use Locator here because the select2 box is duplicated in billing.
+		await admin.page
+			.locator(
+				'[id="\\_wc_shipping\\/first-plugin-namespace\\/road-size"]'
+			)
+			.selectOption( 'super-wide' );
+
+		// Handle changing the additional information fields.
+		await admin.page
+			.getByLabel( 'Would you like a free gift with your order?' )
+			.uncheck();
+		await admin.page
+			.getByLabel( 'What is your favourite colour?' )
+			.fill( 'Green' );
+		await admin.page
+			.getByLabel( 'How did you hear about us?' )
+			.selectOption( 'google' );
+
+		await admin.page
+			.getByRole( 'button', { name: 'Update' } )
+			.first()
+			.click();
+
+		await admin.page.waitForLoadState( 'domcontentloaded' );
+
+		await expect(
+			admin.page.getByText( 'Government ID: 88888', { exact: true } )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Confirm government ID: 88888', {
+				exact: true,
+			} )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Government ID: 99999', { exact: true } )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Confirm government ID: 99999', {
+				exact: true,
+			} )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'What is your favourite colour?: Green' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText(
+				'Enter a gift message to include in the package: Some other message'
+			)
+		).toBeVisible();
+		await expect(
+			admin.page.getByText(
+				'Do you want to subscribe to our newsletter?: No'
+			)
+		).toBeVisible();
+		await expect(
+			admin.page.getByText(
+				'Would you like a free gift with your order?: No'
+			)
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Can a truck fit down your road?: Yes' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'Can a truck fit down your road?: No' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'How wide is your road?: Super wide' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'How wide is your road?: Wide' )
+		).toBeVisible();
+		await expect(
+			admin.page.getByText(
+				'Is this a personal purchase or a business purchase?: Personal'
+			)
+		).toBeVisible();
+		await expect(
+			admin.page.getByText( 'How did you hear about us?: Google' )
+		).toBeVisible();
 	} );
 } );
diff --git a/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.shopper.block_theme.spec.ts b/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.shopper.block_theme.spec.ts
index 62ab317b26a..d42f15a840f 100644
--- a/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.shopper.block_theme.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/blocks/checkout/additional-fields.shopper.block_theme.spec.ts
@@ -29,6 +29,529 @@ test.describe( 'Shopper → Additional Checkout Fields', () => {
 			);
 		} );

+		test( 'Shopper can fill in the checkout form with additional fields and can have different value for same field in shipping and billing address', async ( {
+			checkoutPageObject,
+			frontendUtils,
+		} ) => {
+			await frontendUtils.goToShop();
+			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+			await frontendUtils.goToCheckout();
+
+			await checkoutPageObject.editShippingDetails();
+			await checkoutPageObject.unsyncBillingWithShipping();
+			await checkoutPageObject.editBillingDetails();
+			await checkoutPageObject.fillInCheckoutWithTestData(
+				{},
+				{
+					contact: {
+						'Alternative Email': 'test@test.com',
+						'Enter a gift message to include in the package':
+							'This is for you!',
+						'Is this a personal purchase or a business purchase?':
+							'business',
+					},
+					address: {
+						shipping: {
+							'Government ID': '12345',
+							'Confirm government ID': '12345',
+							'How wide is your road? (optional)': 'wide',
+						},
+						billing: {
+							'Government ID': '54321',
+							'Confirm government ID': '54321',
+							'How wide is your road? (optional)': 'narrow',
+						},
+					},
+					order: {
+						'How did you hear about us?': 'Other',
+						'What is your favourite colour?': 'Blue',
+					},
+				}
+			);
+
+			await checkoutPageObject.page
+				.getByLabel( 'Would you like a free gift with your order?' )
+				.check();
+			await checkoutPageObject.page
+				.getByLabel( 'Do you want to subscribe to our newsletter?' )
+				.check();
+			await checkoutPageObject.page
+				.getByRole( 'group', {
+					name: 'Shipping address',
+				} )
+				.getByLabel( 'Can a truck fit down your road?' )
+				.check();
+
+			await checkoutPageObject.page
+				.getByRole( 'group', {
+					name: 'Billing address',
+				} )
+				.getByLabel( 'Can a truck fit down your road?' )
+				.uncheck();
+
+			await checkoutPageObject.page
+				.getByLabel( 'Test required checkbox' )
+				.check();
+
+			await checkoutPageObject.placeOrder();
+
+			expect(
+				await checkoutPageObject.verifyAdditionalFieldsDetails( [
+					[ 'Government ID', '12345' ],
+					[ 'Government ID', '54321' ],
+					[ 'What is your favourite colour?', 'Blue' ],
+					[
+						'Enter a gift message to include in the package',
+						'This is for you!',
+					],
+					[ 'Do you want to subscribe to our newsletter?', 'Yes' ],
+					[ 'Would you like a free gift with your order?', 'Yes' ],
+					[ 'Can a truck fit down your road?', 'Yes' ],
+					[ 'Can a truck fit down your road?', 'No' ],
+					[ 'How wide is your road?', 'Wide' ],
+					[ 'How wide is your road?', 'Narrow' ],
+					[
+						'Is this a personal purchase or a business purchase?',
+						'business',
+					],
+				] )
+			).toBe( true );
+
+			await frontendUtils.emptyCart();
+			await frontendUtils.goToShop();
+			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+			await frontendUtils.goToCheckout();
+
+			await checkoutPageObject.editShippingDetails();
+			await checkoutPageObject.editBillingDetails();
+
+			// Now check all the fields previously filled are still filled on a fresh checkout.
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Contact information',
+					} )
+					.getByLabel(
+						'Enter a gift message to include in the package'
+					)
+			).toHaveValue( 'This is for you!' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Contact information',
+					} )
+					.getByLabel(
+						'Is this a personal purchase or a business purchase?'
+					)
+			).toHaveValue( 'business' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Contact information',
+					} )
+					.getByLabel( 'Do you want to subscribe to our newsletter?' )
+			).toBeChecked();
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Shipping address',
+					} )
+					.getByLabel( 'Government ID', { exact: true } )
+			).toHaveValue( '12345' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Shipping address',
+					} )
+					.getByLabel( 'Confirm Government ID' )
+			).toHaveValue( '12345' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Shipping address',
+					} )
+					.getByLabel( 'Can a truck fit down your road?' )
+			).toBeChecked();
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Shipping address',
+					} )
+					.getByLabel( 'How wide is your road? (optional)' )
+			).toHaveValue( 'wide' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Billing address',
+					} )
+					.getByLabel( 'Government ID', { exact: true } )
+			).toHaveValue( '54321' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Billing address',
+					} )
+					.getByLabel( 'Confirm Government ID' )
+			).toHaveValue( '54321' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Billing address',
+					} )
+					.getByLabel( 'Can a truck fit down your road?' )
+			).not.toBeChecked();
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Billing address',
+					} )
+					.getByLabel( 'How wide is your road? (optional)' )
+			).toHaveValue( 'narrow' );
+		} );
+
+		test( 'Shopper can change the values of fields multiple times and place the order', async ( {
+			checkoutPageObject,
+			frontendUtils,
+		} ) => {
+			await frontendUtils.goToShop();
+			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+			await frontendUtils.goToCheckout();
+
+			await checkoutPageObject.editShippingDetails();
+			await checkoutPageObject.unsyncBillingWithShipping();
+			await checkoutPageObject.editBillingDetails();
+			await checkoutPageObject.fillInCheckoutWithTestData(
+				{},
+				{
+					contact: {
+						'Alternative Email': 'test@test.com',
+						'Enter a gift message to include in the package':
+							'This is for you!',
+						'Is this a personal purchase or a business purchase?':
+							'business',
+					},
+					address: {
+						shipping: {
+							'Government ID': '12345',
+							'Confirm government ID': '12345',
+							'How wide is your road? (optional)': 'wide',
+						},
+						billing: {
+							'Government ID': '54321',
+							'Confirm government ID': '54321',
+							'How wide is your road? (optional)': 'narrow',
+						},
+					},
+					order: {
+						'How did you hear about us?': 'Other',
+						'What is your favourite colour?': 'Blue',
+					},
+				}
+			);
+
+			// Change the shipping and billing select fields again.
+			await checkoutPageObject.fillInCheckoutWithTestData(
+				{},
+				{
+					address: {
+						shipping: {
+							'How wide is your road? (optional)': 'super-wide',
+						},
+						billing: {
+							'How wide is your road? (optional)': 'wide',
+						},
+					},
+				}
+			);
+
+			await checkoutPageObject.page
+				.getByLabel( 'Would you like a free gift with your order?' )
+				.check();
+			await checkoutPageObject.page
+				.getByLabel( 'Do you want to subscribe to our newsletter?' )
+				.check();
+
+			// Check both "Can a truck fit down your road?" checkboxes (one in shipping, one in billing).
+			await checkoutPageObject.page
+				.getByRole( 'group', {
+					name: 'Shipping address',
+				} )
+				.getByLabel( 'Can a truck fit down your road?' )
+				.check();
+			// Check this one here, but don't uncheck it later.
+			await checkoutPageObject.page
+				.getByRole( 'group', {
+					name: 'Billing address',
+				} )
+				.getByLabel( 'Can a truck fit down your road?' )
+				.check();
+
+			await checkoutPageObject.page
+				.getByLabel( 'Would you like a free gift with your order?' )
+				.uncheck();
+			await checkoutPageObject.page
+				.getByLabel( 'Do you want to subscribe to our newsletter?' )
+				.uncheck();
+			await checkoutPageObject.page
+				.getByRole( 'group', {
+					name: 'Shipping address',
+				} )
+				.getByLabel( 'Can a truck fit down your road?' )
+				.uncheck();
+
+			await checkoutPageObject.fillInCheckoutWithTestData(
+				{},
+				{
+					contact: {
+						'Alternative Email': 'test@test.com',
+						'Enter a gift message to include in the package':
+							'This is for you, from me!',
+						'Is this a personal purchase or a business purchase?':
+							'personal',
+					},
+					address: {
+						shipping: {
+							'Government ID': '98765',
+							'Confirm government ID': '98765',
+						},
+						billing: {
+							'Government ID': '43210',
+							'Confirm government ID': '43210',
+						},
+					},
+					order: {
+						'What is your favourite colour?': 'Red',
+						'How did you hear about us?':
+							'Select a how did you hear about us? (optional)',
+					},
+				}
+			);
+			await checkoutPageObject.page
+				.getByLabel( 'Test required checkbox' )
+				.check();
+			await checkoutPageObject.placeOrder();
+
+			expect(
+				await checkoutPageObject.verifyAdditionalFieldsDetails( [
+					[ 'Government ID', '98765' ],
+					[ 'Government ID', '43210' ],
+					[ 'What is your favourite colour?', 'Red' ],
+					[ 'Would you like a free gift with your order?', 'No' ],
+					// One checkbox is checked, the other is unchecked.
+					[ 'Can a truck fit down your road?', 'No' ],
+					[ 'Can a truck fit down your road?', 'Yes' ],
+					// Different values in different address types.
+					[ 'How wide is your road?', 'Wide' ],
+					[ 'How wide is your road?', 'Super wide' ],
+					[
+						'Enter a gift message to include in the package',
+						'This is for you, from me!',
+					],
+					[ 'Do you want to subscribe to our newsletter?', 'No' ],
+				] )
+			).toBe( true );
+
+			// This optional select field was unset, so it should not be visible on the confirmation. Can't check this
+			// with the above function so we will check it "manually".
+			await expect(
+				checkoutPageObject.page.getByText(
+					'How did you hear about us?'
+				)
+			).toBeHidden();
+
+			// Checking that one of the boxes is checked, and one is unchecked
+			await expect(
+				checkoutPageObject.page.getByText(
+					'Can a truck fit down your road?No'
+				)
+			).toBeVisible();
+			await expect(
+				checkoutPageObject.page.getByText(
+					'Can a truck fit down your road?Yes'
+				)
+			).toBeVisible();
+		} );
+
+		test( 'Shopper can input unsanitized values that become sanitized after checkout', async ( {
+			checkoutPageObject,
+			frontendUtils,
+		} ) => {
+			await frontendUtils.goToShop();
+			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+			await frontendUtils.goToCheckout();
+
+			await checkoutPageObject.editShippingDetails();
+			await checkoutPageObject.unsyncBillingWithShipping();
+			await checkoutPageObject.editBillingDetails();
+			await checkoutPageObject.fillInCheckoutWithTestData(
+				{},
+				{
+					contact: {
+						'Alternative Email': 'test@test.com',
+						'Enter a gift message to include in the package':
+							'This is for you!',
+						'Is this a personal purchase or a business purchase?':
+							'business',
+					},
+					address: {
+						shipping: {
+							'Government ID': ' 1. 2 3 4 5 ',
+							'Confirm government ID': '1      2345',
+							'How wide is your road? (optional)': 'wide',
+						},
+						billing: {
+							'Government ID': ' 5. 4 3 2 1 ',
+							'Confirm government ID': '543 21',
+							'How wide is your road? (optional)': 'narrow',
+						},
+					},
+					order: {
+						'How did you hear about us?': 'Other',
+						'What is your favourite colour?': 'Blue',
+					},
+				}
+			);
+
+			await checkoutPageObject.page
+				.getByLabel( 'Would you like a free gift with your order?' )
+				.check();
+			await checkoutPageObject.page
+				.getByLabel( 'Do you want to subscribe to our newsletter?' )
+				.check();
+			await checkoutPageObject.page
+				.getByRole( 'group', {
+					name: 'Shipping address',
+				} )
+				.getByLabel( 'Can a truck fit down your road?' )
+				.check();
+
+			await checkoutPageObject.page
+				.getByRole( 'group', {
+					name: 'Billing address',
+				} )
+				.getByLabel( 'Can a truck fit down your road?' )
+				.uncheck();
+
+			await checkoutPageObject.page
+				.getByLabel( 'Test required checkbox' )
+				.check();
+
+			await checkoutPageObject.placeOrder();
+
+			expect(
+				await checkoutPageObject.verifyAdditionalFieldsDetails( [
+					[ 'Government ID', '12345' ],
+					[ 'Government ID', '54321' ],
+					[ 'What is your favourite colour?', 'Blue' ],
+					[
+						'Enter a gift message to include in the package',
+						'This is for you!',
+					],
+					[ 'Do you want to subscribe to our newsletter?', 'Yes' ],
+					[ 'Would you like a free gift with your order?', 'Yes' ],
+					[ 'Can a truck fit down your road?', 'Yes' ],
+					[ 'Can a truck fit down your road?', 'No' ],
+					[ 'How wide is your road?', 'Wide' ],
+					[ 'How wide is your road?', 'Narrow' ],
+					[
+						'Is this a personal purchase or a business purchase?',
+						'business',
+					],
+				] )
+			).toBe( true );
+
+			await frontendUtils.emptyCart();
+			await frontendUtils.goToShop();
+			await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME );
+			await frontendUtils.goToCheckout();
+
+			await checkoutPageObject.editShippingDetails();
+			await checkoutPageObject.editBillingDetails();
+
+			// Now check all the fields previously filled are still filled on a fresh checkout.
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Contact information',
+					} )
+					.getByLabel(
+						'Enter a gift message to include in the package'
+					)
+			).toHaveValue( 'This is for you!' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Contact information',
+					} )
+					.getByLabel(
+						'Is this a personal purchase or a business purchase?'
+					)
+			).toHaveValue( 'business' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Contact information',
+					} )
+					.getByLabel( 'Do you want to subscribe to our newsletter?' )
+			).toBeChecked();
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Shipping address',
+					} )
+					.getByLabel( 'Government ID', { exact: true } )
+			).toHaveValue( '12345' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Shipping address',
+					} )
+					.getByLabel( 'Confirm Government ID' )
+			).toHaveValue( '12345' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Shipping address',
+					} )
+					.getByLabel( 'Can a truck fit down your road?' )
+			).toBeChecked();
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Shipping address',
+					} )
+					.getByLabel( 'How wide is your road? (optional)' )
+			).toHaveValue( 'wide' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Billing address',
+					} )
+					.getByLabel( 'Government ID', { exact: true } )
+			).toHaveValue( '54321' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Billing address',
+					} )
+					.getByLabel( 'Confirm Government ID' )
+			).toHaveValue( '54321' );
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Billing address',
+					} )
+					.getByLabel( 'Can a truck fit down your road?' )
+			).not.toBeChecked();
+			await expect(
+				checkoutPageObject.page
+					.getByRole( 'group', {
+						name: 'Billing address',
+					} )
+					.getByLabel( 'How wide is your road? (optional)' )
+			).toHaveValue( 'narrow' );
+		} );
+
 		test( 'Shopper can see server-side validation errors', async ( {
 			checkoutPageObject,
 			frontendUtils,
diff --git a/plugins/woocommerce/tests/php/src/Blocks/Domain/Services/CheckoutFieldsAdminTest.php b/plugins/woocommerce/tests/php/src/Blocks/Domain/Services/CheckoutFieldsAdminTest.php
deleted file mode 100644
index 64b324b5856..00000000000
--- a/plugins/woocommerce/tests/php/src/Blocks/Domain/Services/CheckoutFieldsAdminTest.php
+++ /dev/null
@@ -1,310 +0,0 @@
-<?php
-declare( strict_types = 1 );
-
-namespace Automattic\WooCommerce\Tests\Blocks\Domain\Services;
-
-use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
-use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFieldsAdmin;
-use Automattic\WooCommerce\Blocks\Package;
-use WC_Order;
-use WC_Unit_Test_Case;
-
-/**
- * Tests for the CheckoutFieldsAdmin class.
- */
-class CheckoutFieldsAdminTest extends WC_Unit_Test_Case {
-
-	/**
-	 * The System Under Test.
-	 *
-	 * @var CheckoutFieldsAdmin
-	 */
-	private $sut;
-
-	/**
-	 * Checkout fields controller.
-	 *
-	 * @var CheckoutFields
-	 */
-	private $controller;
-
-	/**
-	 * Field IDs registered by the test.
-	 *
-	 * @var string[]
-	 */
-	private $registered_fields = array();
-
-	/**
-	 * Whether this test registered the admin hooks.
-	 *
-	 * @var bool
-	 */
-	private $registered_hooks = false;
-
-	/**
-	 * Set up test fixtures.
-	 */
-	public function setUp(): void {
-		parent::setUp();
-
-		$this->sut        = Package::container()->get( CheckoutFieldsAdmin::class );
-		$this->controller = Package::container()->get( CheckoutFields::class );
-
-		if ( false === has_filter( 'woocommerce_admin_billing_fields', array( $this->sut, 'admin_address_fields' ) ) ) {
-			$this->sut->init();
-			$this->registered_hooks = true;
-		}
-	}
-
-	/**
-	 * Tear down test fixtures.
-	 */
-	public function tearDown(): void {
-		foreach ( $this->registered_fields as $field_id ) {
-			__internal_woocommerce_blocks_deregister_checkout_field( $field_id );
-		}
-
-		if ( $this->registered_hooks ) {
-			remove_filter( 'woocommerce_admin_billing_fields', array( $this->sut, 'admin_address_fields' ), 10 );
-			remove_filter( 'woocommerce_admin_billing_fields', array( $this->sut, 'admin_contact_fields' ), 10 );
-			remove_filter( 'woocommerce_admin_shipping_fields', array( $this->sut, 'admin_address_fields' ), 10 );
-			remove_filter( 'woocommerce_admin_shipping_fields', array( $this->sut, 'admin_order_fields' ), 10 );
-		}
-
-		parent::tearDown();
-	}
-
-	/**
-	 * @testdox Should inject formatted fields and persist admin updates in the correct groups.
-	 */
-	public function test_injects_and_updates_additional_fields_for_each_admin_group(): void {
-		$address_field = 'test-namespace/delivery-note';
-		$contact_field = 'test-namespace/contact-method';
-		$order_field   = 'test-namespace/gift-wrap';
-
-		$this->register_checkout_field(
-			array(
-				'id'       => $address_field,
-				'label'    => 'Delivery note',
-				'location' => 'address',
-				'type'     => 'text',
-			)
-		);
-		$this->register_checkout_field(
-			array(
-				'id'       => $contact_field,
-				'label'    => 'Preferred contact method',
-				'location' => 'contact',
-				'type'     => 'select',
-				'options'  => array(
-					array(
-						'label' => 'Email',
-						'value' => 'email',
-					),
-					array(
-						'label' => 'Phone',
-						'value' => 'phone',
-					),
-				),
-			)
-		);
-		$this->register_checkout_field(
-			array(
-				'id'       => $order_field,
-				'label'    => 'Add gift wrap',
-				'location' => 'order',
-				'type'     => 'checkbox',
-			)
-		);
-
-		$order = \WC_Helper_Order::create_order();
-		$order->set_created_via( 'store-api' );
-		$this->controller->persist_field_for_order( $address_field, 'Reception', $order, 'billing', false );
-		$this->controller->persist_field_for_order( $address_field, 'Side door', $order, 'shipping', false );
-		$this->controller->persist_field_for_order( $contact_field, 'email', $order, 'other', false );
-		$this->controller->persist_field_for_order( $order_field, true, $order, 'other', false );
-		$order->save();
-
-		$base_fields = array( 'state' => array( 'label' => 'State' ) );
-		// phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment -- Firing an existing admin filter to exercise its callbacks, not declaring a new hook.
-		$billing_fields = apply_filters( 'woocommerce_admin_billing_fields', $base_fields, $order, 'edit' );
-		// phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment -- Firing an existing admin filter to exercise its callbacks, not declaring a new hook.
-		$shipping_fields     = apply_filters( 'woocommerce_admin_shipping_fields', $base_fields, $order, 'edit' );
-		$billing_address_id  = '_wc_billing/' . $address_field;
-		$shipping_address_id = '_wc_shipping/' . $address_field;
-		$contact_admin_id    = '_wc_other/' . $contact_field;
-		$order_admin_id      = '_wc_other/' . $order_field;
-		$billing_address     = $this->find_field_by_id( $billing_fields, $billing_address_id );
-		$shipping_address    = $this->find_field_by_id( $shipping_fields, $shipping_address_id );
-
-		$this->assertSame( $base_fields['state'], $billing_fields['state'] ?? null, 'The existing billing state field should remain unchanged.' );
-		$this->assertSame( $base_fields['state'], $shipping_fields['state'] ?? null, 'The existing shipping state field should remain unchanged.' );
-		$this->assert_field_follows_state( $billing_fields, $billing_address_id, 'billing' );
-		$this->assert_field_follows_state( $shipping_fields, $shipping_address_id, 'shipping' );
-		$this->assertSame( $contact_field, array_key_last( $billing_fields ), 'Contact fields should be appended to the billing field list.' );
-		$this->assertSame( $order_field, array_key_last( $shipping_fields ), 'Order fields should be appended to the shipping field list.' );
-		$this->assertSame( 1, $this->count_fields_by_id( $billing_fields, $billing_address_id ), 'The billing address field should be injected exactly once.' );
-		$this->assertSame( 1, $this->count_fields_by_id( $billing_fields, $contact_admin_id ), 'The contact field should be injected exactly once in billing.' );
-		$this->assertSame( 0, $this->count_fields_by_id( $billing_fields, $shipping_address_id ), 'The shipping address field should not be injected in billing.' );
-		$this->assertSame( 0, $this->count_fields_by_id( $billing_fields, $order_admin_id ), 'The order field should not be injected in billing.' );
-		$this->assertSame( 1, $this->count_fields_by_id( $shipping_fields, $shipping_address_id ), 'The shipping address field should be injected exactly once.' );
-		$this->assertSame( 1, $this->count_fields_by_id( $shipping_fields, $order_admin_id ), 'The order field should be injected exactly once in shipping.' );
-		$this->assertSame( 0, $this->count_fields_by_id( $shipping_fields, $billing_address_id ), 'The billing address field should not be injected in shipping.' );
-		$this->assertSame( 0, $this->count_fields_by_id( $shipping_fields, $contact_admin_id ), 'The contact field should not be injected in shipping.' );
-
-		$this->assert_field_properties(
-			array(
-				'id'              => $billing_address_id,
-				'label'           => 'Delivery note',
-				'value'           => 'Reception',
-				'type'            => 'text',
-				'update_callback' => array( $this->sut, 'update_callback' ),
-				'show'            => true,
-				'wrapper_class'   => 'form-field-wide',
-			),
-			$billing_address,
-			'Billing address fields should be injected with their current value and billing-prefixed ID.'
-		);
-		$this->assert_field_properties(
-			array(
-				'id'              => $shipping_address_id,
-				'label'           => 'Delivery note',
-				'value'           => 'Side door',
-				'type'            => 'text',
-				'update_callback' => array( $this->sut, 'update_callback' ),
-				'show'            => true,
-				'wrapper_class'   => 'form-field-wide',
-			),
-			$shipping_address,
-			'Shipping address fields should be injected with their current value and shipping-prefixed ID.'
-		);
-		$this->assert_field_properties(
-			array(
-				'id'              => $contact_admin_id,
-				'label'           => 'Preferred contact method',
-				'value'           => 'email',
-				'type'            => 'select',
-				'update_callback' => array( $this->sut, 'update_callback' ),
-				'show'            => true,
-				'wrapper_class'   => 'form-field-wide',
-				'options'         => array(
-					'email' => 'Email',
-					'phone' => 'Phone',
-				),
-			),
-			$billing_fields[ $contact_field ],
-			'Contact select fields should expose their labels, options, current value, and update callback.'
-		);
-		$this->assert_field_properties(
-			array(
-				'id'              => $order_admin_id,
-				'label'           => 'Add gift wrap',
-				'value'           => true,
-				'type'            => 'checkbox',
-				'update_callback' => array( $this->sut, 'update_callback' ),
-				'show'            => true,
-				'wrapper_class'   => 'form-field-wide',
-				'checked_value'   => '1',
-				'unchecked_value' => '0',
-			),
-			$shipping_fields[ $order_field ],
-			'Order checkbox fields should expose their checked and unchecked representations.'
-		);
-
-		call_user_func( $billing_address['update_callback'], $billing_address['id'], 'Warehouse', $order );
-		call_user_func( $shipping_address['update_callback'], $shipping_address['id'], 'Loading bay', $order );
-		call_user_func( $billing_fields[ $contact_field ]['update_callback'], $billing_fields[ $contact_field ]['id'], 'phone', $order );
-		call_user_func( $shipping_fields[ $order_field ]['update_callback'], $shipping_fields[ $order_field ]['id'], '0', $order );
-		$order->save();
-
-		$reloaded_order = wc_get_order( $order->get_id() );
-		$this->assertInstanceOf( WC_Order::class, $reloaded_order, 'The updated order should reload from storage.' );
-		if ( ! $reloaded_order instanceof WC_Order ) {
-			throw new \RuntimeException( 'The updated order could not be reloaded from storage.' );
-		}
-		$this->assertSame( 'Warehouse', $this->controller->get_field_from_object( $address_field, $reloaded_order, 'billing' ), 'Billing updates should remain in the billing group.' );
-		$this->assertSame( 'Loading bay', $this->controller->get_field_from_object( $address_field, $reloaded_order, 'shipping' ), 'Shipping updates should remain in the shipping group.' );
-		$this->assertSame( 'phone', $this->controller->get_field_from_object( $contact_field, $reloaded_order, 'other' ), 'Contact updates should remain in the other group.' );
-		$this->assertFalse( $this->controller->get_field_from_object( $order_field, $reloaded_order, 'other' ), 'Unchecked order fields should reload as false from the other group.' );
-	}
-
-	/**
-	 * Register a checkout field and track it for cleanup.
-	 *
-	 * @param array $field Field registration arguments.
-	 */
-	private function register_checkout_field( array $field ): void {
-		woocommerce_register_additional_checkout_field( $field );
-		$this->registered_fields[] = $field['id'];
-	}
-
-	/**
-	 * Assert selected field properties without rejecting compatible additions.
-	 *
-	 * @param array  $expected Expected field properties.
-	 * @param array  $actual Actual field properties.
-	 * @param string $message Assertion context.
-	 */
-	private function assert_field_properties( array $expected, array $actual, string $message ): void {
-		foreach ( $expected as $property => $value ) {
-			$this->assertArrayHasKey( $property, $actual, sprintf( '%s Missing property: %s.', $message, $property ) );
-			$this->assertSame( $value, $actual[ $property ], sprintf( '%s Unexpected property: %s.', $message, $property ) );
-		}
-	}
-
-	/**
-	 * Assert that an injected address field immediately follows the state field.
-	 *
-	 * @param array  $fields Admin field definitions.
-	 * @param string $field_id Generated address field ID.
-	 * @param string $group Address group name.
-	 */
-	private function assert_field_follows_state( array $fields, string $field_id, string $group ): void {
-		$field_keys   = array_keys( $fields );
-		$field_values = array_values( $fields );
-		$state_index  = array_search( 'state', $field_keys, true );
-
-		$this->assertNotFalse( $state_index, sprintf( 'The %s state field should remain in the field list.', $group ) );
-		$this->assertSame(
-			$field_id,
-			$field_values[ false === $state_index ? 0 : $state_index + 1 ]['id'] ?? null,
-			sprintf( 'The %s address field should be injected immediately after state.', $group )
-		);
-	}
-
-	/**
-	 * Count formatted admin fields with a generated ID.
-	 *
-	 * @param array  $fields Admin field definitions.
-	 * @param string $field_id Generated field ID.
-	 */
-	private function count_fields_by_id( array $fields, string $field_id ): int {
-		return count(
-			array_filter(
-				$fields,
-				static function ( array $field ) use ( $field_id ): bool {
-					return ( $field['id'] ?? '' ) === $field_id;
-				}
-			)
-		);
-	}
-
-	/**
-	 * Find a formatted admin field by its generated ID.
-	 *
-	 * @param array  $fields Admin field definitions.
-	 * @param string $field_id Generated field ID.
-	 * @return array
-	 */
-	private function find_field_by_id( array $fields, string $field_id ): array {
-		foreach ( $fields as $field ) {
-			if ( ( $field['id'] ?? '' ) === $field_id ) {
-				return $field;
-			}
-		}
-
-		$this->fail( sprintf( 'Expected to find admin field with ID %s.', $field_id ) );
-		return array();
-	}
-}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/AdditionalFields.php b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/AdditionalFields.php
index e767ec3f370..1257a1e2122 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/AdditionalFields.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/AdditionalFields.php
@@ -2400,98 +2400,6 @@ class AdditionalFields extends \WP_Test_REST_TestCase {
 		$this->assertEquals( 'shipping-saved-gov-id', ( (array) $data['shipping_address'] )['plugin-namespace/gov-id'], print_r( $data, true ) );
 	}

-	/**
-	 * Ensures an additional field is sanitized before it is validated, and the sanitized value is what gets stored.
-	 */
-	public function test_additional_field_is_sanitized_before_it_is_validated() {
-		$id = 'plugin-namespace/upper-code';
-
-		// Uppercasing is the point: no generic sanitizer in the request pipeline does it,
-		// so a lowercase value can only reach a passing validation through this field's
-		// own `sanitize_callback`. Trimming would not work here, because the address
-		// sanitizers already trim whatever the field callback is given.
-		\woocommerce_register_additional_checkout_field(
-			array(
-				'id'                => $id,
-				'label'             => 'Upper code',
-				'location'          => 'order',
-				'type'              => 'text',
-				'required'          => true,
-				'sanitize_callback' => function ( $value ) {
-					return strtoupper( $value );
-				},
-				'validate_callback' => function ( $value ) {
-					return ctype_upper( $value );
-				},
-			)
-		);
-
-		// Still invalid after uppercasing, so a rejection here is the field's rule doing
-		// its job rather than the ordering.
-		$response = $this->checkout_with_upper_code( $id, 'ab1' );
-		$data     = $response->get_data();
-
-		$this->assertEquals( 400, $response->get_status(), print_r( $data, true ) );
-
-		// Invalid as submitted and valid once uppercased.
-		$response = $this->checkout_with_upper_code( $id, 'abc' );
-		$data     = $response->get_data();
-
-		$this->assertEquals( 200, $response->get_status(), print_r( $data, true ) );
-		$this->assertEquals( 'ABC', ( (array) $data['additional_fields'] )[ $id ], print_r( $data, true ) );
-	}
-
-	/**
-	 * Dispatch a checkout request carrying one value for a registered order-location field.
-	 *
-	 * @param string $id Field ID.
-	 * @param string $value Value to submit.
-	 * @return \WP_REST_Response
-	 */
-	private function checkout_with_upper_code( string $id, string $value ) {
-		$request = new \WP_REST_Request( 'POST', '/wc/store/v1/checkout' );
-		$request->set_header( 'Nonce', wp_create_nonce( 'wc_store_api' ) );
-		$request->set_body_params(
-			array(
-				'billing_address'   => (object) array(
-					'first_name'              => 'test',
-					'last_name'               => 'test',
-					'company'                 => '',
-					'address_1'               => 'test',
-					'address_2'               => '',
-					'city'                    => 'test',
-					'state'                   => '',
-					'postcode'                => 'cb241ab',
-					'country'                 => 'GB',
-					'phone'                   => '',
-					'email'                   => 'testaccount@test.com',
-					'plugin-namespace/gov-id' => 'gov id',
-				),
-				'shipping_address'  => (object) array(
-					'first_name'              => 'test',
-					'last_name'               => 'test',
-					'company'                 => '',
-					'address_1'               => 'test',
-					'address_2'               => '',
-					'city'                    => 'test',
-					'state'                   => '',
-					'postcode'                => 'cb241ab',
-					'country'                 => 'GB',
-					'phone'                   => '',
-					'plugin-namespace/gov-id' => 'gov id',
-				),
-				'payment_method'    => WC_Gateway_BACS::ID,
-				'additional_fields' => array(
-					'plugin-namespace/job-function'   => 'engineering',
-					'plugin-namespace/leave-on-porch' => true,
-					$id                               => $value,
-				),
-			)
-		);
-
-		return rest_get_server()->dispatch( $request );
-	}
-
 	/**
 	 * Ensures that saved values are returned in the checkout response.
 	 */