Frontend engineers use end-to-end tests in vets-websiteto validate multipage applications with client-side routing. They are primarily used to assert that:

  • client applications render their inputs

  • client-side navigation occurs when the required fields are populated

End-to-end testing overview

vets-websiteuses Cypress to write end-to-end tests.

  • Some older end-to-end tests were written in Nightwatch prior to Cypress. All new tests should be written using Cypress. Nightwatch tests are being deprecated/migrated to Cypress.

  • Refer to the Cypress migration guide to convert old tests or write new tests.

  • End-to-end tests are collocated in application folder with the application they test

  • Cypress tests can be run using the command yarn cy:run(after yarn watchto yarn build).

See Cypress Best Practices on the VA.gov Platform and Cypress Resources Reference Guide for detailed use cases and documented helpers/mocks.

End-to-end tests conventions

  • Use a comment to indicate what page is being tested

  • Disable scrolling

  • Assert navigation is successful

  • Use functions from the helper file to perform all actions on the page

These are recommendations, not requirements, except where labeled as 'REQUIRED'

  • Separate navigation from field input

    • Use a main test file for navigation, assertions, and calls helpers

    • Use a helper file for filling out forms

  • Create separate, numbered main test files to organize tests by their focus:

    • 00-all-fields.cypress.spec.js - required and optional fields

    • 01-required.cypress.spec.js - only required fields

    • 02-accessibility.cypress.spec.js - validates accessibility

    • 03-auth.cypress.spec.js - validates authentication

    • 04-cross-cutting-feature.cypress.spec.js - validates one feature used across several pages (Example: save in progress)

  • Group tests by pages and use a comment to indicate what page is being tested

  • Mock all api responses before starting the test. See Mock API responses

  • Use waitForElementVisiblebefore interacting with any element on the page

  • Use Timeoutsconstants for setting timeouts (platform/testing/e2e/timeouts.js)

  • Use helpers for filling data and performing actions on the page

  • (REQUIRED) Perform axeCheckon the main body of the application on each page - see axeCheck

  • Assert that each navigation is successful

  • Cypress uses chai to handle assertions.

Test dependencies

You generally don’t need to import any modules for helpers, timeouts, etc.

Test structure

Cypress uses Mocha's behavior-driven development (BDD) syntax, which is what we use for our unit tests.

Each spec file starts a new browser instance and runs the suite of tests according to the describe() and it() blocks.

  • Note that it() blocks are individual tests, so each it() block should be independent of others in the same test suite.

  • Everything executed in the browser needs to be inside of an it() block.

Visit the Cypress docs for more context.

Form tests

Applications that are built with the VA Forms Library should be tested with the Cypress form tester.

Visiting a page

When visiting a page, you don't need to specify the baseUrl. The Cypress configuration file takes care of this. You can visit the page with a relative path:

cy.visit("health-care/apply/application");
CODE

Interacting with page elements

The most common interactions you'll probably use are clicking, selecting elements from dropdowns, and entering text inputs.

Below are examples of these interactions in Cypress:

Clicking
cy.get(".form-panel .usa-button-primary").click()
CODE
Selecting from dropdown
cy.findByLabelText(/country/i).select(testData.veteranAddress.country);
CODE
Entering data
cy.findByLabelText(/first name/i).type(testData.veteranFullName.first);
CODE

For more information about how Cypress interactions behave, visit the Cypress guide for interacting with elements.

For additional ways to interact with the DOM, we've also included the Cypress Testing Library as a dependency.

Active element

Checks if the given element is focused on the page.

// BDD assertion
cy.findByLabelText("First name").should("have.focus");
CODE
Disabled element

Checks if the given element is disabled on the page.

// BDD assertion
cy.findByRole("button", { name: "Submit" }).should("be.disabled");
CODE

Examples

Cypress test for VAOS

Cypress test for the 21-526EZ form using the form tester

Mocking API responses

A mock server runs with the end-to-end tests to allow tests to make production-like calls.

See the Mocks section of Cypress Resources Reference Guide for detailed mock API examples currently used.

Below are some of the commonly used Cypress mocks (accessible from the link above).

  • confirmedVA

  • confirmedCC

  • requests

  • cancelReasons

  • supportedSites

  • facilities

  • facilities983

  • clinicList983

  • slots

  • getVAAppointmentMock

  • getExpressCareRequestCriteriaMock

  • getParentSiteMock

Custom Cypress commands

Custom Cypress commands can be found in src/platform/testing/e2e/cypress/support/commands.

Cypress supports extending its client API with custom commands.

Below are some of the commonly used custom Cypress commands.

  • axeCheck - Callback from a11y check that logs aXe violations to console output.

  • expandAccordions - Expands all accordions and AdditionalInfo components.

  • injectAxeThenAxeCheck - Combines two common, sequentially called functions.

  • login - Simulates a logged in session.

  • syncFixtures - Runs task to sync fixtures under a temp path in the Cypress fixtures folder then overwrites cy.fixtureand the fixture shorthand in cy.routeto look for fixtures under that temp path.

  • upload - Workaround to support file upload functionality in tests, which is currently not officially implemented.

  • viewportPreset - Sets the viewport by preset name.

Helpers

The Cypress Resources Reference Guide contains a list of currently utilized Cypress & VAOS Helpers and Appointment Helpers.