Skip to content

Commit

Permalink
Set up Cypress runner + starting suite (#1320)
Browse files Browse the repository at this point in the history
* fix: selection of loos

* fix: loo selection problems

* fix: login and map loading in a more sustainable way

* fix: check in env production file with mapping for auth0

* feat: add cypress base files and first working test

* feat: write lotsa tests

* feat: finish first suite

* feat: add gh action for cypress
  • Loading branch information
ob6160 committed Apr 21, 2022
1 parent 61e5c99 commit c3adb6c
Show file tree
Hide file tree
Showing 24 changed files with 1,128 additions and 117 deletions.
1 change: 1 addition & 0 deletions .env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AUTH0_BASE_URL="http://localhost:3000"
2 changes: 2 additions & 0 deletions .env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Map the AUTH0_BASE_URL to the VERCEL_URL
AUTH0_BASE_URL=${VERCEL_URL}
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AUTH0_BASE_URL="http://localhost:3000"
33 changes: 33 additions & 0 deletions .github/workflows/cypress-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: E2E Cypress Tests
on: push
jobs:
cypress-e2e:
name: Cypress E2E
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Cypress run
uses: cypress-io/github-action@v2
env:
MONGODB_URI: ${{ secrets.MONGODB_URI }}
DATABASE_NAME: toiletmap
AUTH0_SECRET: ${{ secrets.AUTH0_SECRET }}
AUTH0_ISSUER_BASE_URL: https://gbptm.eu.auth0.com
AUTH0_CLIENT_ID: ${{ secrets.AUTH0_CLIENT_ID }}
AUTH0_CLIENT_SECRET: ${{ secrets.AUTH0_CLIENT_SECRET }}
AUTH0_AUDIENCE: https://www.toiletmap.org.uk/graphql
AUTH0_PERMISSIONS_KEY: https://toiletmap.org.uk/permissions
AUTH0_PROFILE_KEY: https://toiletmap.org.uk/profile
with:
build: yarn build
start: yarn start
wait-on: 'http://localhost:3000/'
wait-on-timeout: 60
browser: chrome
spec: cypress/integration/*.ts
8 changes: 8 additions & 0 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"baseUrl": "http://localhost:3000",
"video": false,
"chromeWebSecurity": false,
"defaultCommandTimeout": 15000,
"responseTimeout": 15000,
"requestTimeout": 15000
}
5 changes: 5 additions & 0 deletions 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": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
29 changes: 29 additions & 0 deletions cypress/integration/about.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
describe('About page tests', () => {
it('is correctly titled', () => {
cy.visit('/about');
cy.title().should('equal', 'Toilet Map: About');
});

it('renders as expected', () => {
cy.visit('/about');
cy.contains('About the Toilet Map');
});

it('has a download for the volunteer help guide', () => {
cy.visit('/about');

cy.findByText('Download volunteer help guide')
.scrollIntoView()
.invoke('attr', 'href')
.should('eq', 'Toilet.Map.Volunteer.Help.Guide.pdf');
});

it('has a download for the toilet checklist', () => {
cy.visit('/about');

cy.findByText('Download toilet checklist')
.scrollIntoView()
.invoke('attr', 'href')
.should('eq', '/GBPTM.Toilet.Checklist.pdf');
});
});
14 changes: 14 additions & 0 deletions cypress/integration/contact.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
describe('Contact page tests', () => {
it('is correctly titled', () => {
cy.visit('/contact');
cy.title().should('equal', 'Toilet Map: Contact Us');
});

it('renders as expected', () => {
cy.visit('/contact');
cy.contains('Contact Us');
cy.contains(
'If you have any problems updating the toilets, or wish to send us toilet details or comments, please contact gbtoiletmap@gmail.com.'
);
});
});
148 changes: 148 additions & 0 deletions cypress/integration/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
describe('Home page tests', () => {
it('is correctly titled', () => {
cy.visit('/');
cy.title().should('equal', 'Toilet Map: Home');
});

it('renders toilet markers', () => {
cy.visit('/');
cy.get('.toilet-marker').should('exist');
});

it('lets you search by location', () => {
cy.visit('/');
cy.findByPlaceholderText('Search location…').type('Hammersmith');
cy.findByText(
'Hammersmith, Greater London, England, W6 9YA, United Kingdom'
).click();
cy.get('[data-toiletid="cb92afde0b7ac9483e5d9639"]').should('exist');
});

it('should load different toilets when the map is dragged', () => {
// Drag the map and check that we have fewer markers than when we started
cy.visit('/');
cy.get('.toilet-marker').should('have.length.above', 50);
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').should('exist');
cy.get('[data-toiletid=1dd0f403d1694d6f7dd33f9a]').should('not.exist');
cy.get('#gbptm-map')
.trigger('mousedown', { which: 1 })
.trigger('mousemove', { which: 1, x: 900, y: 0 })
.trigger('mouseup')
.wait(100)
.trigger('mousedown', { which: 1 })
.trigger('mousemove', { which: 1, x: 900, y: 0 })
.trigger('mouseup')
.wait(100)
.trigger('mousedown', { which: 1 })
.trigger('mousemove', { which: 1, x: 900, y: 0 })
.trigger('mouseup')
.wait(500);
cy.get('.toilet-marker').should('have.length.below', 40);
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').should('not.exist');
cy.get('[data-toiletid=1dd0f403d1694d6f7dd33f9a]').should('exist');
});

it('should open the toilet details panel when a marker is clicked', () => {
cy.visit('/');
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').click();

cy.url().should('include', '/loos/51f6b4d8b792e3531efe5152');

// Check that the loo we picked is now highlighted.
cy.get('#highlighted-loo').invoke(
'attr',
'data-toiletid',
'51f6b4d8b792e3531efe5152'
);

// Check standard loo panel stuff is there.
cy.contains('Test loo 2.1');
cy.contains('Features');
cy.contains('Opening Hours');

// Check that today is highlighted
const dayOfWeekName = new Date().toLocaleString('default', {
weekday: 'long',
});

cy.findByText(dayOfWeekName)
.parent()
.should('have.css', 'background-color', 'rgb(210, 255, 242)');
});

it('should collapse the toilet panel when the close button is clicked and reopen when details is clicked', () => {
cy.visit('/');
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').click();
cy.get('[aria-label="Close toilet details"]').click();

cy.url().should('include', '/loos/51f6b4d8b792e3531efe5152');

cy.contains('Test loo 2.1');
cy.contains('Features').should('not.exist');
cy.contains('Opening Hours').should('not.exist');

cy.contains('Close');
cy.contains('Directions')
.invoke('attr', 'href')
.should('include', 'https://maps.apple.com/?dirflg=w&daddr=');

const detailsExpandButton = cy.contains('Details');
detailsExpandButton.click();

cy.contains('Features');
cy.contains('Opening Hours');
});

it('should close the toilet panel fully when the close button is clicked twice', () => {
cy.visit('/');
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').click();
cy.url().should('include', '/loos/51f6b4d8b792e3531efe5152');
cy.get('[aria-label="Close toilet details"]').scrollIntoView().click();
cy.contains('Close').scrollIntoView().click();
cy.url().should('not.include', '/loos/51f6b4d8b792e3531efe5152');
});

it('should close the toilet panel when the esc key is pressed', () => {
cy.visit('/');
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').click();
cy.url().should('include', '/loos/51f6b4d8b792e3531efe5152');
cy.contains('Test loo 2.1');
cy.contains('Features');
cy.contains('Opening Hours');
cy.get('body').trigger('keydown', { key: 'Escape' });
cy.contains('Test loo 2.1');
cy.contains('Features').should('not.exist');
cy.contains('Opening Hours').should('not.exist');
cy.get('body').trigger('keydown', { key: 'Escape' });
cy.url().should('not.include', '/loos/51f6b4d8b792e3531efe5152');
});

it('should go to the edit page if the toilet edit button is clicked', () => {
cy.visit('/');
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').click();
cy.findByText('Edit').scrollIntoView().click();
cy.url().should('include', 'loos/51f6b4d8b792e3531efe5152/edit');
cy.contains('Want to Contribute Toilet Data?');
});

it('should open directions if the directions button is clicked', () => {
cy.visit('/');
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').click();

cy.findByText('Directions')
.scrollIntoView()
.invoke('attr', 'href')
.should('include', 'https://maps.apple.com/?dirflg=w&daddr=');
});

it('should allow users to confirm that the toilet information is correct', () => {
cy.visit('/');
cy.get('[data-toiletid=51f6b4d8b792e3531efe5152]').click();
cy.intercept('POST', '/api', (req) => {
expect(req.body.operationName).to.equal(
'submitVerificationReportMutation'
);
});
cy.findByText('Yes').click();
});
});
14 changes: 14 additions & 0 deletions cypress/integration/privacy.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
describe('Privacy page tests', () => {
it('is correctly titled', () => {
cy.visit('/privacy');
cy.title().should('equal', 'Toilet Map: Privacy Policy');
});

it('renders as expected', () => {
cy.visit('/privacy');
cy.contains('Privacy Policy');
cy.contains('Visitors to the site');
cy.contains('Contributors to the site');
cy.contains('gbtoiletmap@gmail.com');
});
});
29 changes: 29 additions & 0 deletions cypress/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

const pluginConfig: Cypress.PluginConfig = (on) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config

on('task', {
log(message) {
console.log(message);

return null;
},
table(message) {
console.table(message);

return null;
},
});
};

export default pluginConfig;
27 changes: 27 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// ***********************************************
// 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 cypress/support/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.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';

// Alternatively you can use CommonJS syntax:
// require('./commands')
15 changes: 15 additions & 0 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2019",
"lib": ["ES2019", "DOM"],
"noEmit": true,
// be explicit about types included
// to avoid clashing with Jest types
"types": ["node", "cypress", "@testing-library/cypress"],
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true
},
"include": ["**/*.ts"]
}

0 comments on commit c3adb6c

Please sign in to comment.