Commit 3a57a10fb3 for woocommerce

commit 3a57a10fb346e02aab1c6cecfb9a8064ec7d275a
Author: Chi-Hsuan Huang <chihsuan.tw@gmail.com>
Date:   Wed Dec 10 18:21:00 2025 +0900

    Add E2E tests for analytics scheduled updates feature (#62332)

    * Add E2E tests for analytics scheduled imports feature

    Comprehensive E2E tests for the analytics scheduled imports feature including:

    - Settings mode switching tests (scheduled ↔ immediate)
    - Confirmation modal behavior when switching to immediate mode
    - Manual update trigger functionality in scheduled mode
    - Default values for new installations

    Created new test file:
    - analytics-settings.spec.js: Tests for import mode switching with confirmation modal

    Extended existing test file:
    - analytics-overview.spec.js: Tests for manual import trigger visibility and functionality

    Tests verify both UI state and backend option values using REST API.

    Fixes WOOA7S-796

    🤖 Generated with [Claude Code](https://claude.com/claude-code)

    Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

    * Add changefile(s) from automation for the following project(s): woocommerce

    * Update plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-settings.spec.js

    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

    * Update plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-settings.spec.js

    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

    * Update plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.js

    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

    * Add back Page

    * Fix lint

    ---------

    Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
    Co-authored-by: github-actions <github-actions@github.com>
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

diff --git a/plugins/woocommerce/changelog/62332-wooa7s-796-add-e2e-tests b/plugins/woocommerce/changelog/62332-wooa7s-796-add-e2e-tests
new file mode 100644
index 0000000000..6e09e5775f
--- /dev/null
+++ b/plugins/woocommerce/changelog/62332-wooa7s-796-add-e2e-tests
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Add E2E tests for analytics scheduled updates feature
\ No newline at end of file
diff --git a/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.js
index 64535f49a1..654afe4f2e 100644
--- a/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.js
+++ b/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.js
@@ -1,7 +1,8 @@
-const { test, expect, Page, Locator } = require( '@playwright/test' );
+const { test, expect, request, Page, Locator } = require( '@playwright/test' );
 const { admin } = require( '../../test-data/data' );
 const { tags } = require( '../../fixtures/fixtures' );
 const { ADMIN_STATE_PATH } = require( '../../playwright.config' );
+const { setOption } = require( '../../utils/options' );

 const EXPECTED_SECTION_HEADERS = [ 'Performance', 'Charts', 'Leaderboards' ];

@@ -46,7 +47,7 @@ const headers = {
 const hidePerformanceSection = async () => {
 	const response =
 		await test.step( `Send POST request to hide Performance section`, async () => {
-			const request = page.request;
+			const pageRequest = page.request;
 			const url = `./wp-json/wp/v2/users/${ userId }`;
 			const params = { _locale: 'user' };
 			const dashboard_sections = JSON.stringify( [
@@ -59,7 +60,7 @@ const hidePerformanceSection = async () => {
 				},
 			};

-			return await request.post( url, {
+			return await pageRequest.post( url, {
 				data,
 				params,
 				headers,
@@ -84,7 +85,7 @@ const hidePerformanceSection = async () => {
 const resetSections = async () => {
 	const response =
 		await test.step( `Send POST request to reset all sections`, async () => {
-			const request = page.request;
+			const pageRequest = page.request;
 			const url = `./wp-json/wp/v2/users/${ userId }`;
 			const params = { _locale: 'user' };
 			const data = {
@@ -94,7 +95,7 @@ const resetSections = async () => {
 				},
 			};

-			return await request.post( url, {
+			return await pageRequest.post( url, {
 				data,
 				params,
 				headers,
@@ -123,11 +124,11 @@ test.describe(
 			page = await browser.newPage();

 			await test.step( `Send GET request to get the current user id`, async () => {
-				const request = page.request;
+				const pageRequest = page.request;
 				const data = {
 					_fields: 'id',
 				};
-				const response = await request.get(
+				const response = await pageRequest.get(
 					'./wp-json/wp/v2/users/me',
 					{
 						data,
@@ -315,3 +316,85 @@ test.describe(
 		} );
 	}
 );
+
+test.describe(
+	'Analytics Overview - Manual Import Trigger',
+	{ tag: [ tags.PAYMENTS, tags.SERVICES ] },
+	() => {
+		test.use( { storageState: ADMIN_STATE_PATH } );
+
+		test.beforeAll( async ( { browser } ) => {
+			page = await browser.newPage();
+		} );
+
+		test.beforeEach( async () => {
+			await test.step( `Go to Analytics > Overview`, async () => {
+				await page.goto(
+					'wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Foverview'
+				);
+			} );
+		} );
+
+		test.afterAll( async () => {
+			await page.close();
+		} );
+
+		test( 'should show manual update trigger in scheduled mode', async ( {
+			baseURL,
+		} ) => {
+			// Set to scheduled mode
+			await setOption(
+				request,
+				baseURL,
+				'woocommerce_analytics_scheduled_import',
+				'yes'
+			);
+
+			// Reload the page
+			await page.reload();
+
+			// Verify import status bar is visible
+			await expect( page.getByText( 'Data status:' ) ).toBeVisible();
+			// Verify "Update now" button is visible
+			const updateButton = page.getByRole( 'button', {
+				name: 'Manually trigger analytics',
+			} );
+			await expect( updateButton ).toBeVisible();
+
+			// Click "Update now" button
+			const responsePromise = page.waitForResponse(
+				( response ) =>
+					response
+						.url()
+						.includes( '/wc-analytics/imports/trigger' ) &&
+					response.ok()
+			);
+
+			await updateButton.click();
+
+			// Verify button shows loading state (isBusy)
+			await expect( updateButton ).toBeDisabled();
+
+			// Wait for API response
+			await responsePromise;
+		} );
+
+		test( 'should hide manual update trigger in immediate mode', async ( {
+			baseURL,
+		} ) => {
+			// Set to immediate mode
+			await setOption(
+				request,
+				baseURL,
+				'woocommerce_analytics_scheduled_import',
+				'no'
+			);
+
+			// Reload the page
+			await page.reload();
+
+			// Verify import status bar wrapper is NOT rendered
+			await expect( page.getByText( 'Data status:' ) ).toBeHidden();
+		} );
+	}
+);
diff --git a/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-settings.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-settings.spec.js
new file mode 100644
index 0000000000..de30bb98ed
--- /dev/null
+++ b/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-settings.spec.js
@@ -0,0 +1,197 @@
+const { test, expect, request, Page } = require( '@playwright/test' );
+const { tags } = require( '../../fixtures/fixtures' );
+const { setOption, deleteOption } = require( '../../utils/options' );
+const { ADMIN_STATE_PATH } = require( '../../playwright.config' );
+
+/**
+ * @type {Page}
+ */
+let page;
+
+test.describe(
+	'Analytics Settings - Scheduled Import',
+	{ tag: [ tags.PAYMENTS, tags.SERVICES ] },
+	() => {
+		test.use( { storageState: ADMIN_STATE_PATH } );
+
+		test.beforeAll( async ( { browser } ) => {
+			page = await browser.newPage();
+		} );
+
+		test.beforeEach( async () => {
+			await test.step( `Go to Analytics > Settings`, async () => {
+				await page.goto(
+					'wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2Fsettings'
+				);
+			} );
+		} );
+
+		test.afterAll( async () => {
+			await page.close();
+		} );
+
+		test( 'should show Immediate mode by default when option is not set', async ( {
+			baseURL,
+		} ) => {
+			// Delete the option to simulate a new installation
+			await deleteOption(
+				request,
+				baseURL,
+				'woocommerce_analytics_scheduled_import'
+			);
+
+			// Reload the page
+			await page.reload();
+
+			// Verify "Immediately" is selected
+			await expect(
+				page.getByRole( 'radio', {
+					name: /Immediately/i,
+				} )
+			).toBeChecked();
+		} );
+
+		test( 'should switch from scheduled to immediate mode with confirmation modal - cancel flow', async ( {
+			baseURL,
+		} ) => {
+			// Set to scheduled mode
+			await setOption(
+				request,
+				baseURL,
+				'woocommerce_analytics_scheduled_import',
+				'yes'
+			);
+
+			// Reload the page
+			await page.reload();
+
+			// Verify "Scheduled (recommended)" is selected
+			await expect(
+				page.getByRole( 'radio', {
+					name: /Scheduled \(recommended\)/i,
+				} )
+			).toBeChecked();
+
+			// Click "Immediately" radio option
+			await page.getByRole( 'radio', { name: /Immediately/i } ).click();
+
+			// Verify confirmation modal appears
+			await expect(
+				page.getByRole( 'heading', { name: 'Are you sure?' } )
+			).toBeVisible();
+
+			// Click "Cancel" button
+			await page
+				.getByRole( 'button', { name: /Cancel/i, exact: false } )
+				.click();
+
+			// Verify modal closes
+			await expect(
+				page.locator(
+					'.woocommerce-analytics-import-mode-confirmation-modal'
+				)
+			).toBeHidden();
+
+			// Verify "Scheduled (recommended)" is still selected on page
+			await expect(
+				page.getByRole( 'radio', {
+					name: /Scheduled \(recommended\)/i,
+				} )
+			).toBeChecked();
+		} );
+
+		test( 'should switch from scheduled to immediate mode with confirmation modal - confirm flow', async ( {
+			baseURL,
+		} ) => {
+			// Set to scheduled mode
+			await setOption(
+				request,
+				baseURL,
+				'woocommerce_analytics_scheduled_import',
+				'yes'
+			);
+
+			// Reload the page
+			await page.reload();
+
+			// Click "Immediately" radio option
+			await page.getByRole( 'radio', { name: /Immediately/i } ).click();
+
+			// Verify confirmation modal appears
+			await expect(
+				page.getByRole( 'heading', { name: 'Are you sure?' } )
+			).toBeVisible();
+
+			// Click "Confirm" button
+			await page
+				.getByRole( 'button', { name: /Confirm/i, exact: false } )
+				.click();
+
+			// Click "Save settings" button
+			await page.getByRole( 'button', { name: 'Save settings' } ).click();
+
+			// Verify success message
+			await expect(
+				page
+					.getByText( 'Your settings have been successfully saved.' )
+					.first()
+			).toBeVisible();
+
+			// Refresh page and verify "Immediately" is selected
+			await page.reload();
+			await expect(
+				page.getByRole( 'radio', { name: /Immediately/i } )
+			).toBeChecked();
+		} );
+
+		test( 'should switch from immediate to scheduled mode without confirmation modal', async ( {
+			baseURL,
+		} ) => {
+			// Set to immediate mode
+			await setOption(
+				request,
+				baseURL,
+				'woocommerce_analytics_scheduled_import',
+				'no'
+			);
+
+			// Reload the page
+			await page.reload();
+
+			// Verify "Immediately" is selected
+			await expect(
+				page.getByRole( 'radio', { name: /Immediately/i } )
+			).toBeChecked();
+
+			// Click "Scheduled (recommended)" radio option
+			await page
+				.getByRole( 'radio', {
+					name: /Scheduled \(recommended\)/i,
+				} )
+				.click();
+
+			// Verify NO modal appears (no warning when switching back to recommended mode)
+			await expect(
+				page.getByRole( 'heading', { name: 'Are you sure?' } )
+			).toBeHidden();
+
+			// Click "Save settings" button
+			await page.getByRole( 'button', { name: 'Save settings' } ).click();
+
+			// Verify success message
+			await expect(
+				page
+					.getByText( 'Your settings have been successfully saved.' )
+					.first()
+			).toBeVisible();
+
+			// Refresh page and verify "Scheduled (recommended)" is selected
+			await page.reload();
+			await expect(
+				page.getByRole( 'radio', {
+					name: /Scheduled \(recommended\)/i,
+				} )
+			).toBeChecked();
+		} );
+	}
+);