Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Alert Updates #881

Merged
merged 18 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 253 additions & 0 deletions e2e/pages/filing-app/formAlerts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
import { expect } from '@playwright/test';
import { test } from '../../fixtures/testFixture';
import uploadFile from '../../utils/uploadFile';

test('Form Alerts', async ({
page,
navigateToProvideTypeOfFinancialInstitution,
}) => {
test.slow();

// Type of financial institution page
await test.step('Type of financial institution page', async () => {
navigateToProvideTypeOfFinancialInstitution;
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Provide type of financial institution',
);

// Submit Incomplete form
await test.step('Submit Incomplete form', async () => {
await test.step('Click: Continue', async () => {
await page.getByRole('button', { name: 'Continue' }).click();
});
await test.step('Error Alert is visible', async () => {
await page.waitForSelector('#TypesFinancialInstitutionsErrors', {
timeout: 10_000,
});
await expect(
page.locator(
'#TypesFinancialInstitutionsErrors div.m-notification_content',
),
'Alert is visible',
).toContainText(
'There was a problem updating your type of financial institution',
);
});
});

// Submit Completed Form
await test.step('Submit Completed form', async () => {
await test.step('Complete form', async () => {
await page.getByText('Bank or savings association').check();
});
await test.step('Click: Continue', async () => {
await page.getByRole('button', { name: 'Continue' }).click();
});
});
});

// Upload file with syntax errors
await test.step('Upload syntax errors file', async () => {
await uploadFile(page, true, 'syntax');

// Continue to next page
await test.step('Click: Continue', async () => {
await page.waitForSelector('#nav-next');
await page.waitForTimeout(500);
await page.getByRole('button', { name: 'Continue to next step' }).click();
});
});

// Resolve errors (syntax) page
await test.step('Resolve errors (syntax) page', async () => {
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Resolve errors (syntax)',
);
await expect(
page.locator('#error-header-alert'),
'Error alert is visible',
).toContainText(
'Your register contains syntax errorsThere may be an issue with the data type or format of one or more values in your file. Make sure your register meets the requirements detailed in the filing instructions guide (section 4, "Data validation"), make the corrections, and upload a new file.',
);
await test.step('Click: Continue', async () => {
await page
.getByRole('button', { name: 'Continue' })
.click({ timeout: 500 });
});

await expect(
page.locator('#error-footer-alert'),
'Footer alert is visible',
).toContainText('You must resolve syntax errors to continue.');

await test.step('Click: Upload new file', async () => {
await page.getByRole('link', { name: 'Upload a new file' }).click();
});
});

// Upload file with logic errors
await test.step('Upload logic errors file', async () => {
await uploadFile(page, false, 'logic');

// Continue to next page
await test.step('Click: Continue', async () => {
await page.waitForSelector('#nav-next');
await page.waitForTimeout(500);
await page.getByRole('button', { name: 'Continue to next step' }).click();
});
});

// Resolve errors (syntax) page
await test.step('Resolve errors (syntax) page', async () => {
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Resolve errors (syntax)',
);
await expect(
page.locator('.m-notification__success'),
'Success message is visible',
).toContainText('Your register contains no syntax errors');
await test.step('Click: Continue', async () => {
await page.getByRole('button', { name: 'Continue' }).click();
});
});

// Resolve errors (logic) page
await test.step('Resolve errors (logic) page', async () => {
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Resolve errors (logic)',
);
await expect(
page.locator('#error-header-alert'),
'Error alert is visible',
).toContainText(
'Your register contains logic errorsThere is missing data, incorrect data, or conflicting information in your file. Make sure your register meets the requirements detailed in the filing instructions guide (section 4, "Data validation"), make the corrections, and upload a new file.',
);
await test.step('Click: Continue', async () => {
await page
.getByRole('button', { name: 'Continue to next step' })
.click({ timeout: 500 });
});

await expect(
page.locator('#error-footer-alert'),
'Footer alert is visible',
).toContainText(
'You must resolve all errors to continue to the next step.',
);
await test.step('Click: Upload new file', async () => {
await page.getByRole('link', { name: 'Upload a new file' }).click();
});
});

// Upload file with warnings
await test.step('Upload warnings file', async () => {
await uploadFile(page, false, 'warning');

await test.step('Click: Continue', async () => {
await page
.getByRole('button', { name: 'Continue to next step' })
.click({ timeout: 5000 });
});
});

// Resolve errors (syntax) page
await test.step('Resolve errors (syntax) page', async () => {
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Resolve errors (syntax)',
);
await expect(
page.locator('.m-notification__success'),
'Success message is visible',
).toContainText('Your register contains no syntax errors');

await test.step('Click: Continue', async () => {
await page
.getByRole('button', { name: 'Continue' })
.click({ timeout: 5000 });
});
});

// Resolve errors (logic) page
await test.step('Resolve errors (logic) page', async () => {
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Resolve errors (logic)',
);
await expect(
page.locator('.m-notification__success'),
'Success message is visible',
).toContainText('Your register contains no logic errors');
await test.step('Click: Continue', async () => {
await page
.getByRole('button', { name: 'Continue to next step' })
.click({ timeout: 5000 });
});
});

// Review warnings page
await test.step('Review warnings page', async () => {
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Review warnings',
);
await test.step('Click: Continue', async () => {
await page.getByRole('button', { name: 'Continue to next step' }).click();
});
await expect(
page.locator('#error-header-alert'),
'Error alert is visible',
).toContainText(
'You must correct or verify the accuracy of register values to continue to the next step.',
);
await test.step('Click: Verify checkbox', async () => {
await page.getByText('I verify the accuracy of').check({ timeout: 500 });
});
await test.step('Click: Continue', async () => {
await page.getByRole('button', { name: 'Continue to next step' }).click();
});
});

// Point of contact page
await test.step('Point of contact page', async () => {
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Provide point of contact',
);

// Submit Incomplete form
await test.step('Submit Incomplete form', async () => {
await test.step('Click: Continue', async () => {
await page
.getByRole('button', { name: 'Continue to next step' })
.click();
});
await expect(
page.locator('.m-notification__error'),
'Error alert is visible',
).toContainText(
'There was a problem updating your point of contact informationEnter the first name of the point of contactEnter the last name of the point of contactEnter the phone number of the point of contactEnter the email address of the point of contactEnter the street address of the point of contactEnter the city of the point of contactSelect the state or territory of the point of contactEnter the ZIP code of the point of contact',
);
});

// Submit Completed form
await test.step('Submit Completed form', async () => {
await test.step('Complete form', async () => {
await page.getByLabel('First name').fill('Playwright');
await page.getByLabel('Last name').fill('Test');
await page.getByLabel('Work phone').fill('555-555-5555');
await page.getByLabel('Email address').fill('[email protected]');
await page.getByLabel('Street address line 1').fill('555 Main St.');
await page.getByLabel('City').fill('Utah (U');
await page.selectOption('select#state', 'UT');
await page.getByLabel('Zip code').fill('55555');
});
});
await test.step('Click: Continue', async () => {
await page.getByRole('button', { name: 'Continue to next step' }).click();
});
});

// Sign and submit page
await test.step('Sign and submit page', async () => {
await expect(page.locator('h1'), 'h1 is correct').toContainText(
'Sign and submit',
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
uid,app_date,app_method,app_recipient,ct_credit_product,ct_credit_product_ff,ct_guarantee,ct_guarantee_ff,ct_loan_term_flag,ct_loan_term,credit_purpose,credit_purpose_ff,amount_applied_for_flag,amount_applied_for,amount_approved,action_taken,action_taken_date,denial_reasons,denial_reasons_ff,pricing_interest_rate_type,pricing_init_rate_period,pricing_fixed_rate,pricing_adj_margin,pricing_adj_index_name,pricing_adj_index_name_ff,pricing_adj_index_value,pricing_origination_charges,pricing_broker_fees,pricing_initial_charges,pricing_mca_addcost_flag,pricing_mca_addcost,pricing_prepenalty_allowed,pricing_prepenalty_exists,census_tract_adr_type,census_tract_number,gross_annual_revenue_flag,gross_annual_revenue,naics_code_flag,naics_code,number_of_workers,time_in_business_type,time_in_business,business_ownership_status,num_principal_owners_flag,num_principal_owners,po_1_ethnicity,po_1_ethnicity_ff,po_1_race,po_1_race_anai_ff,po_1_race_asian_ff,po_1_race_baa_ff,po_1_race_pi_ff,po_1_gender_flag,po_1_gender_ff,po_2_ethnicity,po_2_ethnicity_ff,po_2_race,po_2_race_anai_ff,po_2_race_asian_ff,po_2_race_baa_ff,po_2_race_pi_ff,po_2_gender_flag,po_2_gender_ff,po_3_ethnicity,po_3_ethnicity_ff,po_3_race,po_3_race_anai_ff,po_3_race_asian_ff,po_3_race_baa_ff,po_3_race_pi_ff,po_3_gender_flag,po_3_gender_ff,po_4_ethnicity,po_4_ethnicity_ff,po_4_race,po_4_race_anai_ff,po_4_race_asian_ff,po_4_race_baa_ff,po_4_race_pi_ff,po_4_gender_flag,po_4_gender_ff
000TESTFIUIDDONOTUSEXBXVID451XTC1,20241201,1,1,988,,999,,999,,999,,999,,,5,20241231,999,,999,,,,999,,,,,,999,,999,999,988,,988,,988,,988,988,,988,900,9001,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
000TESTFIUIDDONOTUSEXBXVID452XTC1,20241201,1,1,988,,999,,999,,999,,999,,,5,20241231,999,,999,,,,999,,,,,,999,,999,999,988,,988,,988,,988,988,,988,988,must be blank,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
000TESTFIUIDDONOTUSEXBXVID21XTC2,12012024,1,1,988,,999,,999,,999,,999,,,5,20241231,999,,999,,,,999,,,,,,999,,999,999,988,,988,,988,,988,988,,988,988,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
uid,app_date,app_method,app_recipient,ct_credit_product,ct_credit_product_ff,ct_guarantee,ct_guarantee_ff,ct_loan_term_flag,ct_loan_term,credit_purpose,credit_purpose_ff,amount_applied_for_flag,amount_applied_for,amount_approved,action_taken,action_taken_date,denial_reasons,denial_reasons_ff,pricing_interest_rate_type,pricing_init_rate_period,pricing_fixed_rate,pricing_adj_margin,pricing_adj_index_name,pricing_adj_index_name_ff,pricing_adj_index_value,pricing_origination_charges,pricing_broker_fees,pricing_initial_charges,pricing_mca_addcost_flag,pricing_mca_addcost,pricing_prepenalty_allowed,pricing_prepenalty_exists,census_tract_adr_type,census_tract_number,gross_annual_revenue_flag,gross_annual_revenue,naics_code_flag,naics_code,number_of_workers,time_in_business_type,time_in_business,business_ownership_status,num_principal_owners_flag,num_principal_owners,po_1_ethnicity,po_1_ethnicity_ff,po_1_race,po_1_race_anai_ff,po_1_race_asian_ff,po_1_race_baa_ff,po_1_race_pi_ff,po_1_gender_flag,po_1_gender_ff,po_2_ethnicity,po_2_ethnicity_ff,po_2_race,po_2_race_anai_ff,po_2_race_asian_ff,po_2_race_baa_ff,po_2_race_pi_ff,po_2_gender_flag,po_2_gender_ff,po_3_ethnicity,po_3_ethnicity_ff,po_3_race,po_3_race_anai_ff,po_3_race_asian_ff,po_3_race_baa_ff,po_3_race_pi_ff,po_3_gender_flag,po_3_gender_ff,po_4_ethnicity,po_4_ethnicity_ff,po_4_race,po_4_race_anai_ff,po_4_race_asian_ff,po_4_race_baa_ff,po_4_race_pi_ff,po_4_gender_flag,po_4_gender_ff
123456789TESTBANK12300001,20201201,1,1,988,test,999;999;999;999;999;999,test,988,0,999;999;999;999,test,999,0,0,3,20241031,999;999;999;999;999,test,5,,0,,999,test,0,,,,900,,999,999,988,01001020100,988,0,988,1234,988,988,0,988;988,900,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
123456789TESTBANK12300001,20241201,1,1,988,test,999;999;999;999;999;999,test,988,0,999;999;999;999,test,999,0,0,1,20201231,977,,5,,0,,999,test,0,,,,900,,999,999,988,01001020100,988,0,988,1234,988,988,0,988;988,900,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
123456789TESTBANK12300001,20241201,1,1,988,test,999;999;999;999;999;999,test,988,0,999;999;999;999,test,999,0,0,1,20201231,977,,5,0,0,,999,test,0,,,,900,,999,999,988,01001020100,988,0,988,1234,988,988,0,988;988,900,4,966;966,test,966;966,test,test,test,test,,test,966;966,test,966;966,test,test,test,test,,test,966;966,test,966;966,test,test,test,test,,test,966;966,test,966;966,test,test,test,test,,test
3 changes: 3 additions & 0 deletions e2e/test-data/sample-sblar-files/warnings-page-few.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
uid,app_date,app_method,app_recipient,ct_credit_product,ct_credit_product_ff,ct_guarantee,ct_guarantee_ff,ct_loan_term_flag,ct_loan_term,credit_purpose,credit_purpose_ff,amount_applied_for_flag,amount_applied_for,amount_approved,action_taken,action_taken_date,denial_reasons,denial_reasons_ff,pricing_interest_rate_type,pricing_init_rate_period,pricing_fixed_rate,pricing_adj_margin,pricing_adj_index_name,pricing_adj_index_name_ff,pricing_adj_index_value,pricing_origination_charges,pricing_broker_fees,pricing_initial_charges,pricing_mca_addcost_flag,pricing_mca_addcost,pricing_prepenalty_allowed,pricing_prepenalty_exists,census_tract_adr_type,census_tract_number,gross_annual_revenue_flag,gross_annual_revenue,naics_code_flag,naics_code,number_of_workers,time_in_business_type,time_in_business,business_ownership_status,num_principal_owners_flag,num_principal_owners,po_1_ethnicity,po_1_ethnicity_ff,po_1_race,po_1_race_anai_ff,po_1_race_asian_ff,po_1_race_baa_ff,po_1_race_pi_ff,po_1_gender_flag,po_1_gender_ff,po_2_ethnicity,po_2_ethnicity_ff,po_2_race,po_2_race_anai_ff,po_2_race_asian_ff,po_2_race_baa_ff,po_2_race_pi_ff,po_2_gender_flag,po_2_gender_ff,po_3_ethnicity,po_3_ethnicity_ff,po_3_race,po_3_race_anai_ff,po_3_race_asian_ff,po_3_race_baa_ff,po_3_race_pi_ff,po_3_gender_flag,po_3_gender_ff,po_4_ethnicity,po_4_ethnicity_ff,po_4_race,po_4_race_anai_ff,po_4_race_asian_ff,po_4_race_baa_ff,po_4_race_pi_ff,po_4_gender_flag,po_4_gender_ff
000TESTFIUIDDONOTUSEXGXVID11XTC1,20241201,1,1,988,,999,,999,,999,,999,,,5,20241231,999,,999,,,,999,,,,,,999,,999,999,988,,988,,988,,988,988,,988,988,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
000TESTFIUIDDONOTUSEXGXVID12XTC1,20241201,1,1,1,,999,,900,1300,999,,999,,,5,20241231,999,,999,,,,999,,,,,,999,,999,999,988,,988,,988,,988,988,,988,988,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
13 changes: 6 additions & 7 deletions src/components/AlertApiUnavailable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,31 @@ import type { ComponentProps } from 'react';
import { sblHelpMail } from 'utils/common';

interface AlertApiUnavailableProperties {
message: string;
// eslint-disable-next-line react/require-default-props
message?: string;
// eslint-disable-next-line react/require-default-props
href?: string;
}
/**
* For use when an API call fails
*/
export function AlertApiUnavailable({
ojbravo marked this conversation as resolved.
Show resolved Hide resolved
message,
message = 'Unable to connect at the moment',
href = sblHelpMail,
...others
}: AlertApiUnavailableProperties & ComponentProps<typeof Alert>): JSX.Element {
return (
<Alert
className='mb-[2.8125rem] [&_div]:max-w-[41.875rem] [&_p]:max-w-[41.875rem]'
className='u-mt45 mx-auto mb-[2.8125rem] [&_div]:max-w-[41.875rem] [&_p]:max-w-[41.875rem]'
message={message}
status='error'
aria-live='polite'
aria-atomic='true'
{...others}
>
<Paragraph>
There was a connection issue or our service may be temporarily
unavailable. Make sure your computer is connected to the internet, and
try again. If this issue persists,{' '}
<Link href={href}>contact our support staff</Link>.
Try again in a few minutes. If this issue persists,{' '}
<Link href={href}>email our support staff</Link>.
</Paragraph>
</Alert>
);
Expand Down
40 changes: 37 additions & 3 deletions src/pages/Filing/FilingApp/FilingErrors/FilingErrorsAlerts.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Link } from 'components/Link';
import { Alert, Paragraph } from 'design-system-react';
import { Alert, Link, Paragraph } from 'design-system-react';
import { ValidationInitialFetchFailAlert } from 'pages/Filing/FilingApp/FileSubmission.data';
import { dataValidationLink } from 'utils/common';

Expand All @@ -14,7 +13,6 @@ function SuccessAlert({ isStep2 }: { isStep2: boolean }): JSX.Element {
/>
);
}

function SyntaxErrorsAlert(): JSX.Element {
return (
<Alert
Expand Down Expand Up @@ -57,12 +55,48 @@ function LogicErrorsAlert(): JSX.Element {
);
}

function SyntaxErrorsAlertFooter(): JSX.Element {
return (
<Alert
className='mb-[2.8125rem] [&_div]:max-w-[41.875rem] [&_p]:max-w-[41.875rem]'
message='You must resolve syntax errors to continue.'
status='error'
id='error-footer-alert'
/>
);
}

function LogicErrorsAlertFooter(): JSX.Element {
return (
<Alert
className='mb-[2.8125rem] [&_div]:max-w-[41.875rem] [&_p]:max-w-[41.875rem]'
message='You must resolve all errors to continue to the next step.'
status='error'
id='error-footer-alert'
/>
);
}

interface FilingErrorsAlertsProperties {
isStep2: boolean;
errorState: boolean;
errorGetSubmissionLatest: unknown;
}

export function FilingErrorsAlertsFooter({
isStep2,
errorState,
errorGetSubmissionLatest,
}: FilingErrorsAlertsProperties): JSX.Element | null {
return errorGetSubmissionLatest ? (
<ValidationInitialFetchFailAlert />
) : errorState && isStep2 ? (
<LogicErrorsAlertFooter />
) : errorState && !isStep2 ? (
<SyntaxErrorsAlertFooter />
) : null;
}

function FilingErrorsAlerts({
isStep2,
errorState,
Expand Down
Loading