Developer docs

Resources reference guide for Cypress

This is a reference guide of active Cypress-related resources.

The following helpers and mocks are currently used within Cypress tests on vets-website.

GI & VAOS Cypress helpers

Custom helpers are reusable components for commonly needed test situations, like loading custom data, profiles, or appointments. Below is a list of helpers currently written and in use, along with a simple reference guide. Purpose and import paths can be found via their respective files.

The helpers are located in src/applications/gi/tests/helpers.js and src/applications/vaos/tests/e2e/vaos-cypress-helpers.js. Consider writing a reusable helper when an action is needed to perform certain tests.

GI

mockConstants

Reference:

export function mockConstants() {
  const constants = [];
  calculatorConstants.data.forEach(c => {
    constants[c.attributes.name] = c.attributes.value;
  });

  return { constants };
}

createTestHistory

Reference:

export function createTestHistory(path = '/') {
  const history = createMemoryHistory({ initialEntries: [path] });
  sinon.spy(history, 'replace');
  sinon.spy(history, 'push');

  return history;
}

renderWithStoreAndRouter

Reference:

export function renderWithStoreAndRouter(
  ui,
  { initialState, store = null, path = '/', history = null },
) {
  const testStore =
    store ||
    createStore(
      combineReducers({ ...commonReducer, ...reducers }),
      initialState,
      applyMiddleware(thunk),
    );

  const historyObject = history || createTestHistory(path);
  const screen = renderInReduxProvider(
    <Router history={historyObject}>{ui}</Router>,
    {
      store: testStore,
      initialState,
      reducers,
    },
  );

  return { ...screen, history: historyObject };
}


VAOS

mockFeatureToggles

Reference:

export function mockFeatureToggles(toggles = {}) {
  cy.intercept(
    {
      method: 'GET',
      pathname: '/v0/feature_toggles',
    },
    req => {
      req.reply({
        data: {
          features: featureFlags.map(feature => {
            if (Object.keys(toggles).includes(feature.name)) {
              return { ...feature, value: toggles[feature.name] };
            }
            return feature;
          }),
        },
      });
    },
  ).as('v0:get:feature_toggles');
}

mockCCProvidersApi

Reference:

export function mockCCProvidersApi({
  response: data,
  responseCode = 200,
} = {}) {
  cy.intercept(
    {
      method: 'GET',
      pathname: '/facilities_api/v1/ccp/provider',
    },
    req => {
      if (responseCode !== 200) {
        req.reply({
          forceNetworkError: true,
        });

        return;
      }

      req.reply({ data });
    },
  ).as('v1:get:provider');
}

mockAppointmentGetApi

Reference:

export function mockAppointmentGetApi({
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        pathname: `/vaos/v2/appointments/${data.id}`,
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });
          return;
        }

        req.reply({ data });
      },
    ).as('v2:get:appointment');
  }
}

mockAppointmentUpdateApi

Reference:

export function mockAppointmentUpdateApi({
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'PUT',
        url: '/vaos/v2/appointments/1',
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });
          return;
        }

        req.reply({
          data,
        });
      },
    ).as('v2:update:appointment');
  }
}

mockAppointmentCreateApi

Reference:

export function mockAppointmentCreateApi({
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'POST',
        pathname: '/vaos/v2/appointments',
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });
          return;
        }

        req.reply({
          data,
        });
      },
    ).as('v2:create:appointment');
  }
}

mockAppointmentsGetApi

Reference:

export function mockAppointmentsGetApi({
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        pathname: '/vaos/v2/appointments',
        query: {
          _include: '*',
          start: '*',
          end: '*',
        },
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });
          return;
        }

        if (data) {
          req.reply({
            data: data.flat().map((resp, index) => resp.setId(index + 1)),
          });
        }
      },
    ).as('v2:get:appointments');
  }
}

mockFacilityApi

Reference:

export function mockFacilityApi({
  id,
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        pathname: `/vaos/v2/facilities/${id}`,
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });

          return;
        }

        req.reply({
          data,
        });
      },
    ).as(`v2:get:facility`);
  }
}

mockFacilitiesApi

Reference:

export function mockFacilitiesApi({
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        pathname: '/vaos/v2/facilities',
        query: {
          children: '*',
          'ids[]': '*',
        },
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });

          return;
        }

        if (data) {
          req.reply({ data });
        }
      },
    ).as('v2:get:facilities');
  }
}

mockSchedulingConfigurationApi

Reference:

eexport function mockSchedulingConfigurationApi({
  facilityIds,
  typeOfCareId = null,
  isDirect = false,
  isRequest = false,
} = {}) {
  cy.intercept(
    {
      method: 'GET',
      pathname: '/vaos/v2/scheduling/configurations*',
    },
    req => {
      let data;

      if (facilityIds && typeOfCareId) {
        data = schedulingConfigurations.data
          .filter(facility =>
            facilityIds.some(id => {
              return id === facility.id;
            }),
          )
          .map(facility => {
            const services = facility.attributes.services
              .map(
                service =>
                  service.id === typeOfCareId
                    ? {
                        ...service,
                        direct: { ...service.direct, enabled: isDirect },
                        request: { ...service.request, enabled: isRequest },
                      }
                    : null,
              )
              // Remove all falsey values from array
              .filter(Boolean);

            return {
              ...facility,
              id: facility.id,
              attributes: {
                communityCare: true,
                ...facility.attributes,
                facilityId: facility.id,
                services,
              },
            };
          });
      } else {
        data = schedulingConfigurations.data;
      }

      req.reply({ data });
    },
  ).as('v2:get:scheduling-configurations');
}

mockEligibilityApi

Reference:

export function mockEligibilityApi({
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        pathname: '/vaos/v2/eligibility',
        query: { facility_id: '*', clinical_service_id: '*', type: '*' },
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });

          return;
        }

        req.reply({
          data: {
            ...data,
            attributes: {
              ...data.attributes,
              type: data.attributes?.type || req.query.type,
            },
          },
        });
      },
    ).as('v2:get:eligibility');
  }
}

mockEligibilityDirectApi

Reference:

export function mockEligibilityDirectApi({
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        pathname: '/vaos/v2/eligibility',
        query: { facility_id: '*', clinical_service_id: '*', type: 'direct' },
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });

          return;
        }

        req.reply({
          data,
        });
      },
    ).as('v2:get:eligibility:direct');
  }
}

MockEligibilityRequestApi

Reference:

export function mockEligibilityRequestApi({
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        pathname: '/vaos/v2/eligibility',
        query: { facility_id: '*', clinical_service_id: '*', type: 'request' },
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });

          return;
        }

        req.reply({
          data,
        });
      },
    ).as('v2:get:eligibility:request');
  }
}

MockEligibilityCCApi

Reference:

export function mockEligibilityCCApi({ cceType, isEligible: eligible = true }) {
  cy.intercept(`/vaos/v2/community_care/eligibility/${cceType}`, req => {
    req.reply({
      data: {
        id: cceType,
        type: 'cc_eligibility',
        attributes: { eligible },
      },
    });
  }).as('v2:get:eligibility-cc');
}

MockClinicsApi

Reference:

export function mockClinicsApi({
  locationId,
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        path: `/vaos/v2/locations/${locationId}/clinics?clinical_service*`,
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });

          return;
        }

        req.reply({
          data,
        });
      },
    ).as(`v2:get:clinics`);
  }
}

MockSlotsApi

Reference:

export function mockSlotsApi({
  locationId,
  clinicId,
  response: data,
  responseCode = 200,
  version = 2,
}) {
  if (version === 2) {
    cy.intercept(
      {
        method: 'GET',
        pathname: `/vaos/v2/locations/${locationId}/clinics/${clinicId}/slots`,
        query: {
          start: '*',
          end: '*',
        },
      },
      req => {
        if (responseCode !== 200) {
          req.reply({
            forceNetworkError: true,
          });

          return;
        }

        req.reply({
          data,
        });
      },
    ).as('v2:get:slots');
  }
}

MockUserTransitionAvailabilities

Reference:

export function mockUserTransitionAvailabilities({ version = 0 } = {}) {
  if (version === 0) {
    cy.intercept(
      {
        method: 'GET',
        pathname: `/v0/user_transition_availabilities`,
      },
      req => {
        req.reply({
          data: {
            organicModal: false,
            credentialType: 'idme',
          },
        });
      },
    ).as('v0:get:user_transition');
  }
}

vaosSetup

Reference:

export function vaosSetup() {
  Cypress.Commands.add('axeCheckBestPractice', (context = 'main') => {
    cy.axeCheck(context, {
      runOnly: {
        type: 'tag',
        values: [
          'section508',
          'wcag2a',
          'wcag2aa',
          'wcag21a',
          'wcag21aa',
          'best-practice',
        ],
      },
    });
  });

vaosSetup

Reference:

export function vaosSetup() {
  Cypress.Commands.add('axeCheckBestPractice', (context = 'main') => {
    cy.axeCheck(context, {
      runOnly: {
        type: 'tag',
        values: [
          'section508',
          'wcag2a',
          'wcag2aa',
          'wcag21a',
          'wcag21aa',
          'best-practice',
        ],
      },
    });
  });

mockVamcEhrApi

Reference:

export function mockVamcEhrApi({ isCerner = false } = {}) {
  const fieldVamcEhrSystem = isCerner ? 'cerner' : 'vista';

  cy.intercept(
    {
      method: 'GET',
      pathname: '/data/cms/vamc-ehr.json',
    },
    req => {
      req.reply({
        data: {
          nodeQuery: {
            count: 2,
            entities: [
              {
                fieldFacilityLocatorApiId: 'vha_983',
                title: 'Cheyenne VA Medical Center',
                fieldRegionPage: {
                  entity: {
                    title: 'VA Cheyenne health care',
                    fieldVamcEhrSystem,
                  },
                },
              },
              {
                fieldFacilityLocatorApiId: 'vha_984',
                title: 'Dayton VA Medical Center',
                fieldRegionPage: {
                  entity: {
                    title: 'VA Dayton health care',
                    fieldVamcEhrSystem,
                  },
                },
              },
            ],
          },
        },
      });
    },
  ).as('drupal-source-of-truth');
}

Mock data and Fixtures

Many Cypress test and helpers are dependent on JSON data located within the data orfixtures folders within the test or e2e folders nested within their respective apps. The following is a list of such files within the GI and VAOS apps.

GI

  • calculator-constants.json

  • calculate-benefits-data.js

VAOS

  • MockAppointmentResponse.js

  • MockClinicResponse.js

  • MockEligibilityResponse.js

  • MockFacilityResponse.js

  • MockProviderResponse.js

  • MockSlotResponse.js

  • MockUser.js


Help and feedback