Skip to content

Commit

Permalink
Merge pull request #56 from dgading/cypress-tests
Browse files Browse the repository at this point in the history
Add Cypress and basic tests
  • Loading branch information
acabouet authored Feb 3, 2025
2 parents 254f1c9 + 3cf67d6 commit 7209496
Show file tree
Hide file tree
Showing 15 changed files with 3,372 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

# dependencies
/node_modules
/tests/node_modules
/.pnp
.pnp.js
vendor
Expand Down
25 changes: 25 additions & 0 deletions docs/cypress-tags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Cypress tags available for grep

The list below contains tags currently used in the Cypress tests. These are available as variables when using cypress-grep.

## Test type
- @smoke (Used for quick checks to make sure elements load and look correct. Does not test all interactable actions.)

## Viewport
- @mobile
- @desktop

## Component
- @header
- @footer
- @goalSearch

## Page
- @homepage (The site homepage.)
- @agencies (This is the /agencies listing page.)
- @agencyPage (An individual agency, like NASA.)
- @goalPage (An individual goal.)

## Goal types
- @apg
- @strategic
2 changes: 1 addition & 1 deletion src/frontend/components/view--goal-search--fulltext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function ViewGoalSearchFulltext({
<input
id="search-goals"
className="usa-input"
name="search"
name="Search goals"
type="search"
value={fulltext}
onChange={(e) => setFulltext(e.target.value)}
Expand Down
11 changes: 11 additions & 0 deletions tests/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const { defineConfig } = require("cypress");

module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
setupNodeEvents(on, config) {
require('@cypress/grep/src/plugin')(config);
return config;
},
},
});
23 changes: 23 additions & 0 deletions tests/cypress/e2e/agencies.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
describe('The /agencies page', () => {
beforeEach(() => {
cy.visit('/agencies');
});
it('successfully loads', {tags: ['@agencies', '@smoke']}, () => {
cy.findByRole('img', {name: "Performance.gov logo"}).should('exist');
cy.findByRole('link', {name: 'Home'}).should('exist');
cy.get('.usa-breadcrumb').within(($group) => {
cy.findByText('Agencies').should('exist');
cy.findAllByRole('listitem').should('have.length', 2);
});
cy.findByRole('heading', {level: 1, name: 'Explore federal goals'}).should('exist');
cy.get('.usa-card-group').within(($group) => {
cy.findAllByRole('listitem').should('have.length', 29);
cy.findAllByRole('listitem').each(($card) => {
cy.wrap($card).within(($innerGroup) => {
cy.findByRole('heading', {level: 4}).should('exist');
cy.findByRole('link', {name: 'Explore agency goals'}).should('exist');
});
});
});
});
});
10 changes: 10 additions & 0 deletions tests/cypress/e2e/footer.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
describe('The site footer', () => {
beforeEach(() => {
cy.visit('/');
});
it('successfully loads', {tags: ['@footer', '@smoke']}, () => {
cy.get('footer').should('exist');
cy.get('footer').should('have.class', 'height-8');
cy.get('footer').should('have.class', 'bg-black');
});
});
121 changes: 121 additions & 0 deletions tests/cypress/e2e/goal.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
describe('An individual goal page', () => {
it('successfully loads an Agency priority goal', {tags: ['@goalPage', '@goals', '@apg', '@smoke']}, () => {
cy.visit('/agencies/nasa/space-technology-leadership');
cy.findByRole('img', {name: "Performance.gov logo"}).should('exist');
cy.get('.usa-breadcrumb').within(($group) => {
cy.findByRole('link', {name: 'Home'}).should('exist');
cy.findByRole('link', {name: 'Agencies'}).should('exist');
cy.findByRole('link', {name: 'NASA'}).should('exist');
cy.findByText('Space Technology Leadership').should('exist');
cy.findAllByRole('listitem').should('have.length', 4);
});
cy.get('.goal-type').within(($item) => {
cy.wrap($item).should('have.class', 'goal-type--apg');
cy.findByText('Agency priority goal').should('exist');
cy.get('span').should('has.class', 'bg-primary-vivid');
cy.get('span').should('has.class', 'usa-tag');
});
cy.findByRole('img', {name: 'NASA-Seal'}).should('exist');
cy.findByRole('heading', {level: 1, name: 'Space Technology Leadership'}).should('exist');
cy.findByRole('heading', {level: 2, name: 'About this NASA priority goal'}).should('exist');
cy.get('#goal-description + div.font-body-md').should('exist');
cy.findByText('Strategic plan:').should('exist');
cy.findByRole('link', {name: 'National Aeronautics and Space Administration Strategic Plan (FY2022-26)'}).should('exist');
cy.findByRole('heading', {level: 2, name: 'Objectives'}).should('exist');
cy.get('#objectives + ol').should('exist');
cy.get('#objectives + ol > li').each(($item) => {
cy.wrap($item).within(($inner) => {
cy.findByRole('heading', {level: 3}).should('exist');
cy.findByRole('heading', {level: 4, name: 'Performance indicators'}).should('exist');
cy.get('p').should('exist');
cy.get('table').should('exist');
cy.findByRole('columnheader', {name: 'Start date'}).should('exist');
cy.findByRole('columnheader', {name: 'End date'}).should('exist');
cy.findByRole('columnheader', {name: 'Actual result'}).should('exist');
cy.findByRole('columnheader', {name: 'Target result'}).should('exist');
});
});
cy.get('div + ul > li').each(($item) => {
cy.wrap($item).within(($inner) => {
cy.findByText('General science/space/technology').should('exist');
cy.get('span').should('have.class', 'usa-tag');
})
});
// Test side nav.
cy.findByRole('heading', {level: 4, name: 'On this page'}).should('exist');
cy.get('.usa-in-page-nav__nav').within(($nav) => {
cy.findAllByRole('listitem').should('have.length', 6);
cy.findAllByRole('link').should('have.length', 6);
cy.findAllByRole('listitem').each(($item, $index) => {
const primaryIndexes = [0,1];
cy.wrap($item).should('have.class', 'usa-in-page-nav__item');
if(primaryIndexes.includes($index)) {
cy.wrap($item).should('have.class', 'usa-in-page-nav__item--primary');
}
})
});
});

it('successfully loads an Strategic goal', {tags: ['@goalPage', '@goals', '@strategic', '@smoke']}, () => {
cy.visit('/agencies/nasa/expand-human-knowledge-through-new-scientific-discoveries');
cy.findByRole('img', {name: "Performance.gov logo"}).should('exist');

cy.get('.usa-breadcrumb').within(($group) => {
cy.findByRole('link', {name: 'Home'}).should('exist');
cy.findByRole('link', {name: 'Agencies'}).should('exist');
cy.findByRole('link', {name: 'NASA'}).should('exist');
cy.findByText('Expand human knowledge through new scientific discoveries').should('exist');
cy.findAllByRole('listitem').should('have.length', 4);
});
cy.get('.goal-type').within(($item) => {
cy.wrap($item).should('have.class', 'goal-type--strategic');
cy.findByText('Strategic goal').should('exist');
cy.get('span').should('has.class', 'bg-base-darkest');
cy.get('span').should('has.class', 'usa-tag');
});
cy.findByRole('img', {name: 'NASA-Seal'}).should('exist');
cy.findByRole('heading', {level: 1, name: 'Expand human knowledge through new scientific discoveries'}).should('exist');
cy.findByRole('heading', {level: 2, name: 'About this NASA strategic goal'}).should('exist');
cy.get('#goal-description + div.font-body-md').should('exist');
cy.findByText('Strategic plan:').should('exist');
cy.findByRole('link', {name: 'National Aeronautics and Space Administration Strategic Plan (FY2022-26)'}).should('exist');
cy.findByRole('heading', {level: 2, name: 'Objectives'}).should('exist');
cy.get('#objectives + ol').should('exist');
cy.get('#objectives + ol > li').each(($item) => {
cy.wrap($item).within(($inner) => {

cy.findByRole('heading', {level: 3}).should('exist');
cy.findByRole('heading', {level: 4, name: 'Performance indicators'}).should('exist');
cy.get('p').should('exist');
cy.get('ol > li').each(($subItem) => {
cy.wrap($subItem).within(($subInner) => {
cy.get('table').should('exist');
cy.findByRole('columnheader', {name: 'Start date'}).should('exist');
cy.findByRole('columnheader', {name: 'End date'}).should('exist');
cy.findByRole('columnheader', {name: 'Actual result'}).should('exist');
cy.findByRole('columnheader', {name: 'Target result'}).should('exist');
});
});
});
});
cy.get('div + ul > li').each(($item) => {
cy.wrap($item).within(($inner) => {
cy.findByText('General science/space/technology').should('exist');
cy.get('span').should('have.class', 'usa-tag');
})
});
// Test side nav.
cy.findByRole('heading', {level: 4, name: 'On this page'}).should('exist');
cy.get('.usa-in-page-nav__nav').within(($nav) => {
cy.findAllByRole('listitem').should('have.length', 5);
cy.findAllByRole('link').should('have.length', 5);
cy.findAllByRole('listitem').each(($item, $index) => {
const primaryIndexes = [0,1];
cy.wrap($item).should('have.class', 'usa-in-page-nav__item');
if(primaryIndexes.includes($index)) {
cy.wrap($item).should('have.class', 'usa-in-page-nav__item--primary');
}
})
});
});
});
33 changes: 33 additions & 0 deletions tests/cypress/e2e/header.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
describe('The site header', () => {
beforeEach(() => {
cy.visit('/');
});
it('successfully loads on desktop', {tags: ['@header', '@smoke', '@desktop']}, () => {
cy.viewport('macbook-13');
cy.findByRole('img', {name: "Performance.gov logo"}).should('exist');
cy.get('.usa-header--basic').within(($group) => {
cy.findAllByRole('link').should('have.length', 2);
});
cy.findByLabelText('Search', {selector: 'input'}).should('exist');
cy.findByRole('button', {name: 'Search'}).should('exist');
cy.findByRole('button', {name: 'Menu'}).should('not.exist');
});

it('successfully loads on mobile', {tags: ['@header', '@smoke', '@mobile']}, () => {
cy.viewport('iphone-8');
cy.findByRole('img', {name: "Performance.gov logo"}).should('exist');
cy.get('.usa-header--basic').within(($group) => {
cy.findAllByRole('link').should('have.length', 0);
});
cy.findByLabelText('Search', {selector: 'input'}).should('not.to.be.visible');
cy.findByRole('button', {name: 'Search'}).should('not.exist');
cy.findByRole('button', {name: 'Menu'}).should('exist');
cy.findByRole('button', {name: 'Menu'}).click();
cy.get('.usa-header--basic').within(($group) => {
cy.findAllByRole('link').should('have.length', 2);
});
cy.findByLabelText('Search', {selector: 'input'}).should('exist');
cy.findByRole('button', {name: 'Search'}).should('exist');
cy.findByRole('button', {name: 'Close Navigation Menu'}).should('exist');
});
});
29 changes: 29 additions & 0 deletions tests/cypress/e2e/homepage.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
describe('The home page', () => {
beforeEach(() => {
cy.visit('/');
});

it('successfully loads', {tags: ['@homepage', '@smoke']}, () => {
cy.findByRole('img', {name: "Performance.gov logo"}).should('exist');
cy.findByRole('heading', {level: 1, name: "Track the U.S. Government's goals"}).should('exist');
cy.get('.usa-breadcrumb').should('not.exist');
});

it('has goal search', {tags: ['@homepage', '@smoke', '@goalSearch', '@goals']}, () => {
cy.findByLabelText('Search goals', {selector: 'input'}).should('exist');
cy.findByRole('button', {name: 'Search goals'}).should('exist');
// 30 tags
cy.get('form + ul').within(($group) => {
cy.findAllByRole('listitem').should('have.length', 30);
cy.findAllByRole('listitem').each(($item) => {
cy.wrap($item).within(($inner) => {
cy.findByRole('button').should('have.class', 'usa-button--outline');
});
});
});
cy.get('.usa-card-group').within(($group) => {
cy.findAllByRole('listitem').should('have.length', 9);
});
cy.findByRole('button', {name: 'Show more'}).should('exist');
});
});
48 changes: 48 additions & 0 deletions tests/cypress/e2e/individual_agency.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
describe('The NASA agency page', () => {
beforeEach(() => {
cy.visit('/agencies/nasa');
});
it('successfully loads', {tags: ['@agencyPage', '@smoke']}, () => {
cy.findByRole('img', {name: "Performance.gov logo"}).should('exist');
cy.findByRole('link', {name: 'Home'}).should('exist');
cy.findByRole('link', {name: 'Agencies'}).should('exist');
cy.get('.usa-breadcrumb').within(($group) => {
cy.findByText('NASA').should('exist');
cy.findAllByRole('listitem').should('have.length', 3);
});
cy.findByRole('img', {name: 'NASA-Seal'}).should('exist');
cy.findByRole('heading', {level: 1, name: 'National Aeronautics and Space Administration'}).should('exist');
cy.findByRole('heading', {level: 2, name: 'Mission'}).should('exist');
cy.findByText('NASA explores the unknown in air and space, innovates for the benefit of humanity, and inspires the world through discovery.').should('exist');
cy.findAllByRole('heading', {level: 2, name: 'National Aeronautics and Space Administration Strategic Plan (FY2022-26)'}).should('have.length', 2);
// Should there be double?
// cy.findByRole('heading', {level: 2, name: 'National Aeronautics and Space Administration Strategic Plan (FY2022-26)'}).should('exist');
cy.findByRole('heading', {level: 3, name: 'Strategic goals'}).should('exist');
cy.findByRole('heading', {level: 3, name: 'Agency priority goals'}).should('exist');
cy.findAllByRole('heading', {level: 3, name: 'Related documents'}).should('have.length', 2);
cy.findAllByRole('heading', {level: 2, name: 'Related Resources'}).should('exist');
cy.get('main section').within(($main) => {
cy.findAllByRole('listitem').should('have.length', 13);
cy.findAllByRole('link').should('have.length', 13);
});
cy.get('#related-resources + ul').within(($list) => {
cy.findAllByRole('listitem').should('have.length', 1);
cy.findByRole('link', {name: 'Visit the NASA website'});
});
});

it('has a side nav', {tags: ['@agencyPage', '@smoke']}, () => {
cy.findByRole('heading', {level: 4, name: 'On this page'}).should('exist');
cy.get('.usa-in-page-nav__nav').within(($nav) => {
cy.findAllByRole('listitem').should('have.length', 8);
cy.findAllByRole('link').should('have.length', 8);
cy.findAllByRole('listitem').each(($item, $index) => {
const primaryIndexes = [0,1,5,7];
cy.wrap($item).should('have.class', 'usa-in-page-nav__item');
if(primaryIndexes.includes($index)) {
cy.wrap($item).should('have.class', 'usa-in-page-nav__item--primary');
}
})
});
});
});
5 changes: 5 additions & 0 deletions tests/cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "[email protected]",
"body": "Fixtures are a great way to mock data for responses to routes"
}
26 changes: 26 additions & 0 deletions tests/cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
import '@testing-library/cypress/add-commands'
20 changes: 20 additions & 0 deletions tests/cypress/support/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands';
import registerCypressGrep from '@cypress/grep/src/support';

registerCypressGrep();
Loading

0 comments on commit 7209496

Please sign in to comment.