diff --git a/e2e/fixtures/testFixture.ts b/e2e/fixtures/testFixture.ts index d12ee4237..569fbba7d 100644 --- a/e2e/fixtures/testFixture.ts +++ b/e2e/fixtures/testFixture.ts @@ -22,6 +22,8 @@ export const test = baseTest.extend<{ navigateToProvideTypeOfFinancialInstitution: Page; navigateToUploadFile: Page; navigateToReviewWarningsAfterOnlyWarningsUpload: Page; + navigateToSyntaxErrorsAfterSyntaxErrorsUpload: Page; + navigateToLogicErrorsAfterLogicErrorsUpload: Page; navigateToProvidePointOfContact: Page; navigateToSignAndSubmit: Page; }>({ @@ -190,6 +192,77 @@ export const test = baseTest.extend<{ }); }, + navigateToSyntaxErrorsAfterSyntaxErrorsUpload: async ( + { page, navigateToUploadFile }, + use, + ) => { + navigateToUploadFile; + await test.step('Upload file: navigate to Syntax Errors page after only errors upload', async () => { + await uploadFile({ + testUsed: test, + pageUsed: page, + newUpload: true, + testTitle: + 'Upload file: upload small file with only syntax errors (errors-page-1-syntax-few.csv)', + filePath: + '../test-data/sample-sblar-files/errors-page-1-syntax-few.csv', + resultMessage: ResultUploadMessage.syntax, + }); + + await test.step('Upload file: navigate to Resolve errors (syntax) with no errors after upload', async () => { + await page.waitForSelector('#nav-next'); + await page.waitForTimeout(500); + await page + .getByRole('button', { name: 'Continue to next step' }) + .click(); + await expect(page.locator('h1')).toContainText( + 'Resolve errors (syntax)', + ); + }); + + await use(page); + }); + }, + + navigateToLogicErrorsAfterLogicErrorsUpload: async ( + { page, navigateToUploadFile }, + use, + ) => { + navigateToUploadFile; + await test.step('Upload file: navigate to Logic Errors page after only errors upload', async () => { + await uploadFile({ + testUsed: test, + pageUsed: page, + newUpload: true, + testTitle: + 'Upload file: upload small file with only logic errors (errors-page-2-logic-few.csv)', + filePath: + '../test-data/sample-sblar-files/logic-errors_single&multi_and_warnings.csv', + resultMessage: ResultUploadMessage.logic, + }); + + await test.step('Upload file: navigate to Resolve errors (syntax) with no errors after upload', async () => { + await page.waitForSelector('#nav-next'); + await page.waitForTimeout(500); + await page + .getByRole('button', { name: 'Continue to next step' }) + .click(); + await expect(page.locator('h1')).toContainText( + 'Resolve errors (syntax)', + ); + }); + + await test.step('Resolve errors (logic): navigate to Resolve errors (logic) with errors after upload', async () => { + await page.getByRole('button', { name: 'Continue' }).click(); + await expect(page.locator('h1')).toContainText( + 'Resolve errors (logic)', + ); + }); + + await use(page); + }); + }, + navigateToReviewWarningsAfterOnlyWarningsUpload: async ( { page, navigateToUploadFile }, use, diff --git a/e2e/pages/filing-app/filing-step-routing/_shared.ts b/e2e/pages/filing-app/filing-step-routing/_shared.ts new file mode 100644 index 000000000..2988bc8c9 --- /dev/null +++ b/e2e/pages/filing-app/filing-step-routing/_shared.ts @@ -0,0 +1,39 @@ +/* eslint-disable no-await-in-loop */ + +import type { Page } from '@playwright/test'; +import { expect } from '@playwright/test'; +import type { test } from '../../../fixtures/testFixture'; + +interface VerifyRedirects { + page: Page; + userShouldNotAccess: string[]; // List of paths that a user should not be able to access + afterRedirectURL: RegExp; // RegExp that matches the URL a user should land on after redirect + afterRedirectHeading: string; // H1 text a user should see after redirect + currentStepPath: string; // A string at which to split the URL while preserving the LEI + testLabel: string; // Label displayed in the Playwright logs + test: typeof test; +} + +/** + * Ensure that, from the current Filing step, users cannot inappropriately access future steps. + */ +export const verifyRedirects = async ({ + page, + test, + userShouldNotAccess, + afterRedirectURL, + afterRedirectHeading, + currentStepPath, + testLabel, +}: VerifyRedirects) => { + const [baseURL] = page.url().split(currentStepPath); + + // Note: Tests failed when using Promise.all in place of this loop approach + for (const futureStep of userShouldNotAccess) { + await test.step(`${testLabel}: Verify user cannot access ${futureStep}`, async () => { + await page.goto(baseURL + futureStep); + await expect(page).toHaveURL(afterRedirectURL, { timeout: 10_000 }); + await expect(page.locator('h1')).toContainText(afterRedirectHeading); + }); + } +}; diff --git a/e2e/pages/filing-app/filing-step-routing/errorsLogic.spec.ts b/e2e/pages/filing-app/filing-step-routing/errorsLogic.spec.ts new file mode 100644 index 000000000..cfaf71938 --- /dev/null +++ b/e2e/pages/filing-app/filing-step-routing/errorsLogic.spec.ts @@ -0,0 +1,30 @@ +import { test } from '../../../fixtures/testFixture'; +import { verifyRedirects } from './_shared'; + +const testLabel = 'Filing step routing (Errors: Logic)'; + +const currentStepPath = '/error'; + +const userShouldNotAccess = ['/warnings', '/contact', '/submit']; + +const afterRedirectHeading = 'Resolve errors (syntax)'; +const afterRedirectURL = /.*errors\/errors-syntax$/; + +test( + testLabel, + async ({ page, navigateToLogicErrorsAfterLogicErrorsUpload }) => { + test.slow(); + + navigateToLogicErrorsAfterLogicErrorsUpload; + + await verifyRedirects({ + afterRedirectHeading, + afterRedirectURL, + currentStepPath, + page, + test, + testLabel, + userShouldNotAccess, + }); + }, +); diff --git a/e2e/pages/filing-app/filing-step-routing/errorsSyntax.spec.ts b/e2e/pages/filing-app/filing-step-routing/errorsSyntax.spec.ts new file mode 100644 index 000000000..ad27d1d8c --- /dev/null +++ b/e2e/pages/filing-app/filing-step-routing/errorsSyntax.spec.ts @@ -0,0 +1,35 @@ +import { test } from '../../../fixtures/testFixture'; +import { verifyRedirects } from './_shared'; + +const testLabel = 'Filing step routing (Errors: Syntax)'; + +const currentStepPath = '/error'; + +const userShouldNotAccess = [ + '/errors/errors-logic', + '/warnings', + '/contact', + '/submit', +]; + +const afterRedirectHeading = 'Resolve errors (syntax)'; +const afterRedirectURL = /.*errors\/errors-syntax$/; + +test( + testLabel, + async ({ page, navigateToSyntaxErrorsAfterSyntaxErrorsUpload }) => { + test.slow(); + + navigateToSyntaxErrorsAfterSyntaxErrorsUpload; + + await verifyRedirects({ + afterRedirectHeading, + afterRedirectURL, + currentStepPath, + page, + test, + testLabel, + userShouldNotAccess, + }); + }, +); diff --git a/e2e/pages/filing-app/filing-step-routing/noUpload.spec.ts b/e2e/pages/filing-app/filing-step-routing/noUpload.spec.ts new file mode 100644 index 000000000..78b7c39a0 --- /dev/null +++ b/e2e/pages/filing-app/filing-step-routing/noUpload.spec.ts @@ -0,0 +1,27 @@ +import { test } from '../../../fixtures/testFixture'; +import { verifyRedirects } from './_shared'; + +const testLabel = 'Filing step routing (Upload)'; + +const currentStepPath = '/upload'; + +const userShouldNotAccess = ['/errors', '/warnings', '/contact', '/submit']; + +const afterRedirectHeading = 'Upload file'; +const afterRedirectURL = /.*\/upload$/; + +test(testLabel, async ({ page, navigateToUploadFile }) => { + test.slow(); + + navigateToUploadFile; + + await verifyRedirects({ + afterRedirectHeading, + afterRedirectURL, + currentStepPath, + page, + test, + testLabel, + userShouldNotAccess, + }); +}); diff --git a/e2e/pages/filing-app/filing-step-routing/pointOfContact.spec.ts b/e2e/pages/filing-app/filing-step-routing/pointOfContact.spec.ts new file mode 100644 index 000000000..05720496b --- /dev/null +++ b/e2e/pages/filing-app/filing-step-routing/pointOfContact.spec.ts @@ -0,0 +1,27 @@ +import { test } from '../../../fixtures/testFixture'; +import { verifyRedirects } from './_shared'; + +const testLabel = 'Filing step routing (Point of Contact)'; + +const currentStepPath = '/contact'; + +const userShouldNotAccess = ['/submit']; + +const afterRedirectHeading = 'Provide point of contact'; +const afterRedirectURL = /.*\/contact$/; + +test(testLabel, async ({ page, navigateToProvidePointOfContact }) => { + test.slow(); + + navigateToProvidePointOfContact; + + await verifyRedirects({ + testLabel, + currentStepPath, + userShouldNotAccess, + afterRedirectHeading, + afterRedirectURL, + page, + test, + }); +}); diff --git a/e2e/pages/filing-app/filing-step-routing/warnings.spec.ts b/e2e/pages/filing-app/filing-step-routing/warnings.spec.ts new file mode 100644 index 000000000..c85670f55 --- /dev/null +++ b/e2e/pages/filing-app/filing-step-routing/warnings.spec.ts @@ -0,0 +1,30 @@ +import { test } from '../../../fixtures/testFixture'; +import { verifyRedirects } from './_shared'; + +const testLabel = 'Filing step routing (Warnings)'; + +const currentStepPath = '/warnings'; + +const userShouldNotAccess = ['/contact', '/submit']; + +const afterRedirectHeading = 'Review warnings'; +const afterRedirectURL = /.*\/warnings$/; + +test( + testLabel, + async ({ page, navigateToReviewWarningsAfterOnlyWarningsUpload }) => { + test.slow(); + + navigateToReviewWarningsAfterOnlyWarningsUpload; + + await verifyRedirects({ + afterRedirectHeading, + afterRedirectURL, + currentStepPath, + page, + test, + testLabel, + userShouldNotAccess, + }); + }, +);