Skip to content

Commit

Permalink
Merge branch 'staging' into 10429-design-debt
Browse files Browse the repository at this point in the history
  • Loading branch information
jimlerza committed Aug 19, 2024
2 parents f484199 + 3f775ec commit 6f0c1e0
Show file tree
Hide file tree
Showing 184 changed files with 3,519 additions and 1,948 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/typescript-all-files-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ jobs:
working-directory: ./targetBranch
run: npm ci

- name: Check untouched files
- name: Check files for increased error count
run: npx ts-node scripts/checkAllFilesForTypeErrorCount.ts
65 changes: 65 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ import {
getNewAccountVerificationCode,
toggleFeatureFlag,
} from './cypress/helpers/cypressTasks/dynamo/dynamo-helpers';
import { overrideIdleTimeouts } from './cypress/local-only/support/idleLogoutHelpers';
import { unzipFile } from './cypress/helpers/file/unzip-file';
import { waitForNoce } from './cypress/helpers/cypressTasks/wait-for-noce';
import { waitForPractitionerEmailUpdate } from './cypress/helpers/cypressTasks/wait-for-practitioner-email-update';

import type { Page } from 'puppeteer-core';

import { retry, setup } from '@cypress/puppeteer';

// eslint-disable-next-line import/no-default-export
export default defineConfig({
chromeWebSecurity: false,
Expand Down Expand Up @@ -77,6 +82,66 @@ export default defineConfig({
});
},
});
// Setup for puppeteer, which supports multi-tab tests
// Define your function in onMessage, and call it like cy.puppeteer('yourFunctionName', arg1, arg2 ...)
setup({
on,
onMessage: {
async closeTab(browser: any, url: string) {
const desiredPage = await retry<Promise<Page>>(async () => {
const pages = await browser.pages();
const page = pages.find(p => p.url().includes(url));
if (!page) throw new Error('Could not find page');
return page;
});
await desiredPage.close();
},
async openExistingTabAndCheckSelectorExists(
browser: any,
url: string,
selector: string,
close: boolean = true,
) {
// Note that browser.pages is *not* sorted in any particular order.
// Therefore we pass in the URL we want to find rather than an index.

// Wait until the new tab loads
const desiredPage = await retry<Promise<Page>>(async () => {
const pages = await browser.pages();
const page = pages.find(p => p.url().includes(url));
if (!page) throw new Error('Could not find page');
return page;
});

// Activate it
await desiredPage.bringToFront();

// Make sure selector exists
await desiredPage.waitForSelector(selector, { timeout: 30000 });

if (close) {
await desiredPage.close();
}
return true;
},
async openNewTab(
browser: any,
url: string,
sessionModalTimeout: number,
sessionTimeout: number,
) {
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle2' });

await page.evaluate(overrideIdleTimeouts, {
sessionModalTimeout,
sessionTimeout,
});

return page;
},
},
});
},
specPattern: 'cypress/local-only/tests/**/*.cy.ts',
supportFile: 'cypress/local-only/support/index.ts',
Expand Down
4 changes: 2 additions & 2 deletions cypress/CYPRESS-README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# Best Practices

In order to write a realiable cypress test suites, there are some best practices we should follow that our outlined in the cypress documentation and also some best practices we have learned from trying to write realiable tests.
In order to write a reliable cypress test suites, there are some best practices we should follow that our outlined in the cypress documentation and also some best practices we have learned from trying to write reliable tests.

## DO'S
- Access DOM elements using `data-testid selector`.
Expand All @@ -11,7 +11,7 @@ In order to write a realiable cypress test suites, there are some best practices
- Avoid cy.get('#my-id').
- Wait for actions to finish explicitly.
- Always verify something on the page after running an action or loading a new page. For example, if you click on a button which updates a practitioner name, be sure to wait for a success alert to appear before trying to move onto the next steps in your test. Failing to do this will result in race conditions and flaky tests.
- This is especially important for accessibilty tests, wait explicitly for the page to full load before running an accessibility scan. If you are seeing 'color-contrast' violations that are intermittent you are most likely not waiting for the right element to be loaded before running a scan.
- This is especially important for accessibility tests, wait explicitly for the page to full load before running an accessibility scan. If you are seeing 'color-contrast' violations that are intermittent you are most likely not waiting for the right element to be loaded before running a scan.
- Extract reusable steps.
- Try to find ways to create helper functions which we can re-use in other tests. For example, creating a case as a petitioner is a good re-usable flow. When writing these helpers, be sure they do not contain asserts related to the high level test you are writing. They should just login as a user, create or modify the data, then return any new created values we may need.
- Test should be re-runnable.
Expand Down
8 changes: 8 additions & 0 deletions cypress/helpers/ITestableWindow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// An interface for exposing the cerebral controller on the window object, which
// can be useful for temporarily overwriting constants in cypress.
export interface ITestableWindow {
cerebral: {
getState: () => any;
getModel: () => any;
};
}
2 changes: 1 addition & 1 deletion cypress/helpers/authentication/login-as-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function loginAsIrsPractitioner1() {
}

export function loginAsPetitioner(
petitionerUser: 'petitioner' | 'petitioner1' = 'petitioner1',
petitionerUser: 'petitioner' | 'petitioner1' | 'petitioner7' = 'petitioner1',
) {
cy.login(petitionerUser);
cy.get('[data-testid="file-a-petition"]').should('exist');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function petitionerCreatesElectronicCaseUpdated(
cy.get('[data-testid="contactPrimary.city"]').type('Orlando');
cy.get('[data-testid="contactPrimary.state"]').select('AL');
cy.get('[data-testid="contactPrimary.postalCode"]').type('12345');
cy.get('[data-testid="contactPrimary.placeOfLegalResidence"]').select('AL');
cy.get('[data-testid="contactPrimary-placeOfLegalResidence"]').select('AL');
cy.get('[data-testid="contact-primary-phone"]').type('1111111111');
cy.get('[data-testid="step-1-next-button"]').click();

Expand Down Expand Up @@ -105,7 +105,7 @@ export function petitionerAttemptsToUploadCorruptPdfUpdated() {
cy.get('[data-testid="contactPrimary.city"]').type('Orlando');
cy.get('[data-testid="contactPrimary.state"]').select('AL');
cy.get('[data-testid="contactPrimary.postalCode"]').type('12345');
cy.get('[data-testid="contactPrimary.placeOfLegalResidence"]').select('AL');
cy.get('[data-testid="contactPrimary-placeOfLegalResidence"]').select('AL');
cy.get('[data-testid="contact-primary-phone"]').type('1111111111');
cy.get('[data-testid="step-1-next-button"]').click();

Expand Down
19 changes: 19 additions & 0 deletions cypress/local-only/support/idleLogoutHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ITestableWindow } from '../../helpers/ITestableWindow';

// This is a hack, but I do not know a better way.
export const overrideIdleTimeouts = ({
modalTimeout,
sessionTimeout,
windowObj, // For native cypress, this needs to be defined. For the puppeteer plugin, it should be left blank.
}: {
modalTimeout: number;
sessionTimeout: number;
windowObj?: ITestableWindow;
}) => {
const currentWindow = windowObj || (window as unknown as ITestableWindow);
currentWindow.cerebral.getModel().set(['constants'], {
...currentWindow.cerebral.getState().constants,
SESSION_MODAL_TIMEOUT: modalTimeout,
SESSION_TIMEOUT: sessionTimeout,
});
};
1 change: 1 addition & 0 deletions cypress/local-only/support/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import './commands';
import '@cypress/puppeteer/support';
import 'cypress-axe';

before(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { checkA11y } from '../../../support/generalCommands/checkA11y';
import { loginAsPetitioner } from '../../../../helpers/authentication/login-as-helpers';

describe('Petition generation - intro pages', () => {
it('welcome to dawson: should be free of a11y issues', () => {
loginAsPetitioner('petitioner7');
checkA11y();
});

it('before filing a case: should be free of a11y issues', () => {
loginAsPetitioner();
cy.visit('/before-filing-a-petition');
checkA11y();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { checkA11y } from '../../../support/generalCommands/checkA11y';
import { loginAsPetitioner } from '../../../../helpers/authentication/login-as-helpers';

describe('Petition generation - step 1', () => {
beforeEach(() => {
loginAsPetitioner();
cy.visit('/file-a-petition/new');
});

describe('Myself', () => {
it('Myself - domestic: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-0"').click();
checkA11y();
});

it('Myself - international: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-0"').click();
cy.get('[data-testid="international-country-btn"]').click();
checkA11y();
});
});
describe('Myself and my spouse', () => {
it('Myself and my spouse - deceased: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-1"').click();
cy.get('[data-testid="is-spouse-deceased-0"]').click();
checkA11y();
});

it('Myself and my spouse - not deceased: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-1"').click();
cy.get('[data-testid="is-spouse-deceased-1"]').click();
cy.get('[data-testid="have-spouse-consent-label"').click();
checkA11y();
});
});
describe('Business', () => {
it('Corporation: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-2"').click();
cy.get('.business-type-radio-option').eq(0).click();
checkA11y();
});

it('Partnership (as the Tax Matters Partner): should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-2"').click();
cy.get('.business-type-radio-option').eq(1).click();
checkA11y();
});

it('Partnership (as a partner other than Tax Matters Partner): should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-2"').click();
cy.get('.business-type-radio-option').eq(2).click();
checkA11y();
});

it('Partnership (as a partnership representative under BBA): should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-2"').click();
cy.get('.business-type-radio-option').eq(3).click();
checkA11y();
});
});
describe('Other', () => {
describe('An estate or trust', () => {
it('Estate with an executor/personal representative/fiduciary/etc.: should be free of a11y issues: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-0"]').click();
cy.get('[data-testid="estate-type-radio-option-0"]').click();
checkA11y();
});

it('Estate without an executor/personal representative/fiduciary/etc.: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-0"]').click();
cy.get('[data-testid="estate-type-radio-option-1"]').click();
checkA11y();
});

it('Trust: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-0"]').click();
cy.get('[data-testid="estate-type-radio-option-2"]').click();
checkA11y();
});
});

describe('A minor or legally incompetent person', () => {
it('Conservator: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-1"]').click();
cy.get('[data-testid="minor-incompetent-type-radio-option-0"]').click();
checkA11y();
});

it('Guardian: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-1"]').click();
cy.get('[data-testid="minor-incompetent-type-radio-option-1"]').click();
checkA11y();
});

it('Custodian: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-1"]').click();
cy.get('[data-testid="minor-incompetent-type-radio-option-2"]').click();
checkA11y();
});

it('Next friend for a minor (without a guardian, conservator, or other like fiduciary): should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-1"]').click();
cy.get('[data-testid="minor-incompetent-type-radio-option-3"]').click();
checkA11y();
});

it('Next friend for a legally incompetent person (without a guardian, conservator, or other like fiduciary): should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-1"]').click();
cy.get('[data-testid="minor-incompetent-type-radio-option-4"]').click();
checkA11y();
});
});

describe('Donor', () => {
it('Donor: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-2"]').click();
checkA11y();
});
});

describe('Transferee', () => {
it('Transferee: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-3"]').click();
checkA11y();
});
});

describe('Deceased Spouse', () => {
it('Deceased Spouse: should be free of a11y issues', () => {
cy.get('[data-testid="filing-type-3"').click();
cy.get('[data-testid="other-type-radio-option-4"]').click();
checkA11y();
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { checkA11y } from '../../../support/generalCommands/checkA11y';
import { fillPetitionerInformation } from '../../integration/fileAPetitionUpdated/petition-helper';
import { loginAsPetitioner } from '../../../../helpers/authentication/login-as-helpers';

describe('Petition generation - step 2', () => {
beforeEach(() => {
loginAsPetitioner();
cy.visit('/file-a-petition/new');
fillPetitionerInformation();
});

it('Auto generate Petition: should be free of a11y issues', () => {
cy.get('[data-testid="add-another-reason-link-button"').click();
cy.get('[data-testid="add-another-fact-link-button"').click();
checkA11y();
});

it('Upload PDF Petition: should be free of a11y issues', () => {
cy.get('[data-testid="upload-a-petition-label"').click();
checkA11y();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { checkA11y } from '../../../support/generalCommands/checkA11y';
import {
fillPetitionFileInformation,
fillPetitionerInformation,
} from '../../integration/fileAPetitionUpdated/petition-helper';
import { loginAsPetitioner } from '../../../../helpers/authentication/login-as-helpers';

describe('Petition generation - step 3', () => {
const VALID_FILE = '../../helpers/file/sample.pdf';

beforeEach(() => {
loginAsPetitioner();
cy.visit('/file-a-petition/new');
fillPetitionerInformation();
fillPetitionFileInformation(VALID_FILE);
});

it('IRS Notice Provided: should be free of a11y issues', () => {
cy.get('[data-testid="irs-notice-Yes"]').click();
checkA11y();
});

it('IRS Notice not Provided: should be free of a11y issues', () => {
cy.get('[data-testid="irs-notice-No"]').click();
checkA11y();
});
});
Loading

0 comments on commit 6f0c1e0

Please sign in to comment.