diff --git a/tests/e2e/specs/notifications.test.js b/tests/e2e/specs/notifications.test.js new file mode 100644 index 0000000000..85bcc6d344 --- /dev/null +++ b/tests/e2e/specs/notifications.test.js @@ -0,0 +1,136 @@ +/** + * External dependencies + */ +import { expect, test } from '@playwright/test'; + +/** + * Internal dependencies + */ +import SettingsPage from '../utils/pages/settings'; +import { clearOnboardedMerchant, setOnboardedMerchant } from '../utils/api'; +import { LOAD_STATE } from '../utils/constants'; + +test.use( { storageState: process.env.ADMINSTATE } ); + +test.describe.configure( { mode: 'serial' } ); + +/** + * @type {import('../utils/pages/settings.js').default } settingsPage + */ +let settingsPage = null; + +/** + * @type {import('@playwright/test').Page} page + */ +let page = null; + +test.describe( 'Notifications Feature', () => { + test.beforeAll( async ( { browser } ) => { + page = await browser.newPage(); + settingsPage = new SettingsPage( page ); + await setOnboardedMerchant(); + await Promise.all( [ + // Mock Jetpack as connected + settingsPage.mockJetpackConnected(), + + // Mock google as connected. + settingsPage.mockGoogleConnected(), + ] ); + + settingsPage.goto(); + } ); + + test.afterAll( async () => { + await clearOnboardedMerchant(); + await page.close(); + } ); + + test( 'Grant Access button is not visible on Settings page when notifications service is disabled', async () => { + const button = settingsPage.getGrantAccessBtn(); + await expect( button ).not.toBeVisible(); + } ); + + test( 'Grant Access button is visible on Settings page when notifications service is enabled', async () => { + // Mock Merchant Center as connected + settingsPage.mockMCConnected( 1234, true ); + const button = settingsPage.getGrantAccessBtn(); + + await expect( button ).toBeVisible(); + } ); + + test( 'When click on Grant Access button redirect to Auth page', async () => { + const mockAuthURL = 'https://example.com'; + // Mock Merchant Center as connected + settingsPage.mockMCConnected( 1234, true ); + settingsPage.fulfillRESTApiAuthorize( { auth_url: mockAuthURL } ); + const button = settingsPage.getGrantAccessBtn(); + + button.click(); + await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED ); + await page.waitForURL( mockAuthURL ); + expect( page.url() ).toMatch( mockAuthURL ); + } ); + + test( 'When REST API is Approved it shows a success notice in MC and allows to disable it', async () => { + settingsPage.goto(); + settingsPage.mockMCConnected( 1234, true, 'approved' ); + const grantedAccessMessage = page + .locator( '#woocommerce-layout__primary' ) + .getByText( + 'Google has been granted access to fetch your product data.' + ); + await expect( grantedAccessMessage ).toBeVisible(); + + const disableDataFetchButton = page.getByRole( 'button', { + name: 'Disable product data fetch', + exact: true, + } ); + const modalConfirmBtn = page.getByRole( 'button', { + name: 'Disable data fetching', + exact: true, + } ); + const modalDismissBtn = page.getByRole( 'button', { + name: 'Never mind', + exact: true, + } ); + const modalCheck = page.getByRole( 'checkbox', { + name: 'Yes, I want to disable the data fetching feature.', + exact: true, + } ); + + await expect( disableDataFetchButton ).toBeVisible(); + disableDataFetchButton.click(); + + await expect( modalConfirmBtn ).toBeDisabled(); + await expect( modalDismissBtn ).toBeEnabled(); + await expect( modalCheck ).toBeVisible(); + modalCheck.check(); + await expect( modalConfirmBtn ).toBeEnabled(); + modalConfirmBtn.click(); + await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED ); + await page.waitForURL( /path=%2Fgoogle%2Fsettings/ ); + await expect( modalConfirmBtn ).not.toBeVisible(); + } ); + + test( 'When REST API is Error it shows a waring notice in MC and allows to grant access', async () => { + settingsPage.goto(); + settingsPage.mockMCConnected( 1234, true, 'error' ); + const mockAuthURL = 'https://example.com'; + settingsPage.fulfillRESTApiAuthorize( { auth_url: mockAuthURL } ); + const errorAccessMessage = page + .locator( '#woocommerce-layout__primary' ) + .getByText( + 'There was an issue granting access to Google for fetching your products.' + ); + const grantAccessBtn = page.getByRole( 'button', { + name: 'Grant access', + exact: true, + } ); + await expect( errorAccessMessage ).toBeVisible(); + await expect( grantAccessBtn ).toBeVisible(); + grantAccessBtn.click(); + await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED ); + await page.waitForURL( mockAuthURL ); + expect( page.url() ).toMatch( mockAuthURL ); + } ); +} ); diff --git a/tests/e2e/utils/mock-requests.js b/tests/e2e/utils/mock-requests.js index 5054c1ad89..8cb320cc6f 100644 --- a/tests/e2e/utils/mock-requests.js +++ b/tests/e2e/utils/mock-requests.js @@ -545,11 +545,19 @@ export default class MockRequests { * Mock MC as connected. * * @param {number} id + * @param {boolean} notificationServiceEnabled + * @param {null|'approved'|'error'|'dissaproved'} wpcomRestApiStatus */ - async mockMCConnected( id = 1234 ) { + async mockMCConnected( + id = 1234, + notificationServiceEnabled = false, + wpcomRestApiStatus = null + ) { await this.fulfillMCConnection( { id, status: 'connected', + notification_service_enabled: notificationServiceEnabled, + wpcom_rest_api_status: wpcomRestApiStatus, } ); } @@ -707,4 +715,20 @@ export default class MockRequests { message: 'Successfully synchronized settings with Google.', } ); } + + /** + * Fulfill the REST API Authorize request. + * + * @param {Object} payload + * @param {Array} methods + * @return {Promise} + */ + async fulfillRESTApiAuthorize( payload, methods = [] ) { + await this.fulfillRequest( + /\/wc\/gla\/rest-api\/authorize\b/, + payload, + 200, + methods + ); + } } diff --git a/tests/e2e/utils/pages/settings.js b/tests/e2e/utils/pages/settings.js new file mode 100644 index 0000000000..4ae90c4385 --- /dev/null +++ b/tests/e2e/utils/pages/settings.js @@ -0,0 +1,48 @@ +/** + * Internal dependencies + */ +import MockRequests from '../mock-requests'; +import { LOAD_STATE } from '../constants'; + +export default class SettingsPage extends MockRequests { + /** + * @param {import('@playwright/test').Page} page + */ + constructor( page ) { + super( page ); + this.page = page; + } + + /** + * Close the Settings page. + * + * @return {Promise} + */ + async closePage() { + await this.page.close(); + } + + /** + * Go to the Settings page. + * + * @return {Promise} + */ + async goto() { + await this.page.goto( + '/wp-admin/admin.php?page=wc-admin&path=%2Fgoogle%2Fsettings', + { waitUntil: LOAD_STATE.DOM_CONTENT_LOADED } + ); + } + + /** + * Get the Grant Access Button. + * + * @return {Promise} The Grant Access Button + */ + getGrantAccessBtn() { + return this.page.getByRole( 'button', { + name: 'Get early access', + exact: true, + } ); + } +}