basic e2e tests

This commit is contained in:
Owen Rees
2023-06-08 13:37:28 +02:00
parent c5aac42344
commit b038d3fee8
10 changed files with 150 additions and 25 deletions
+4 -1
View File
@@ -1,3 +1,6 @@
{ {
"extends": "next/core-web-vitals" "extends": [
"next/core-web-vitals",
"plugin:cypress/recommended"
]
} }
+10
View File
@@ -0,0 +1,10 @@
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: "http://localhost:3000",
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});
+21
View File
@@ -0,0 +1,21 @@
describe("Test all links", () => {
// TODO traverse entire site
it("Test all links on homepage return 200 status", () => {
cy.visit("/");
cy.get("a").each((page) => {
cy.request(page.prop("href"));
});
});
it("Check navbar links point to correct pathname", () => {
const pages = ["tournois", "about", "contact"];
cy.visit("/");
pages.forEach((page) => {
cy.contains(page, { matchCase: false }).click();
cy.location("pathname").should("eq", `/${page}`); // url path matches link name
cy.go("back");
});
});
});
+5
View File
@@ -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"
}
+37
View File
@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts 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) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
+20
View File
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts 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')
Binary file not shown.
+22
View File
@@ -30,6 +30,7 @@
"@testing-library/react": "^14.0.0", "@testing-library/react": "^14.0.0",
"@types/leaflet": "^1.9.3", "@types/leaflet": "^1.9.3",
"cypress": "^12.13.0", "cypress": "^12.13.0",
"eslint-plugin-cypress": "^2.13.3",
"jest": "^29.5.0", "jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0" "jest-environment-jsdom": "^29.5.0"
} }
@@ -3974,6 +3975,27 @@
"ms": "^2.1.1" "ms": "^2.1.1"
} }
}, },
"node_modules/eslint-plugin-cypress": {
"version": "2.13.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.13.3.tgz",
"integrity": "sha512-nAPjZE5WopCsgJwl3vHm5iafpV+ZRO76Z9hMyRygWhmg5ODXDPd+9MaPl7kdJ2azj+sO87H3P1PRnggIrz848g==",
"dev": true,
"dependencies": {
"globals": "^11.12.0"
},
"peerDependencies": {
"eslint": ">= 3.2.1"
}
},
"node_modules/eslint-plugin-cypress/node_modules/globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/eslint-plugin-import": { "node_modules/eslint-plugin-import": {
"version": "2.27.5", "version": "2.27.5",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz",
+7 -1
View File
@@ -7,7 +7,12 @@
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint", "lint": "next lint",
"test": "jest --watch" "jest": "jest",
"jest:watch": "jest --watch",
"cypress:open": "cypress open",
"cypress:run": "cypress run",
"test": "npm run cypress:run && npm run jest",
"test:watch": "npm run cypress:open && npm run jest:watch"
}, },
"dependencies": { "dependencies": {
"@types/node": "20.2.3", "@types/node": "20.2.3",
@@ -32,6 +37,7 @@
"@testing-library/react": "^14.0.0", "@testing-library/react": "^14.0.0",
"@types/leaflet": "^1.9.3", "@types/leaflet": "^1.9.3",
"cypress": "^12.13.0", "cypress": "^12.13.0",
"eslint-plugin-cypress": "^2.13.3",
"jest": "^29.5.0", "jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0" "jest-environment-jsdom": "^29.5.0"
} }
+8 -7
View File
@@ -12,6 +12,7 @@ export const createLayerGroups = (
(t) => t.time_control === timeControl (t) => t.time_control === timeControl
); );
// TODO consider moving this into its own function
const iconOptions = new L.Icon({ const iconOptions = new L.Icon({
iconUrl: `images/leaflet/marker-icon-2x-${colour}.png`, iconUrl: `images/leaflet/marker-icon-2x-${colour}.png`,
shadowUrl: "images/leaflet/marker-shadow.png", shadowUrl: "images/leaflet/marker-shadow.png",
@@ -21,15 +22,12 @@ export const createLayerGroups = (
shadowSize: [41, 41], shadowSize: [41, 41],
}); });
return ( const layerGroup = filteredTournaments.map((t) => {
<LayersControl.Overlay checked name={timeControl}> // TODO move this coorindate randomisation into its own function to follow SRP
<LayerGroup>
{filteredTournaments.map((t) => {
const coordinates = { const coordinates = {
lat: t.coordinates[0] + Math.random() * (-0.01 - 0.01) + 0.01, lat: t.coordinates[0] + Math.random() * (-0.01 - 0.01) + 0.01,
lng: t.coordinates[1] + Math.random() * (-0.01 - 0.01) + 0.01, lng: t.coordinates[1] + Math.random() * (-0.01 - 0.01) + 0.01,
}; };
return ( return (
<Marker position={coordinates} key={t._id} icon={iconOptions}> <Marker position={coordinates} key={t._id} icon={iconOptions}>
<Popup> <Popup>
@@ -44,8 +42,11 @@ export const createLayerGroups = (
</Popup> </Popup>
</Marker> </Marker>
); );
})} });
</LayerGroup>
return (
<LayersControl.Overlay checked name={timeControl}>
<LayerGroup>{layerGroup}</LayerGroup>
</LayersControl.Overlay> </LayersControl.Overlay>
); );
}; };