Merge pull request #109 from TheRealOwenRees/remove-tests

Remove Front end tests
This commit is contained in:
Owen Rees
2023-07-19 16:27:27 +02:00
committed by GitHub
21 changed files with 12 additions and 1883 deletions
-1
View File
@@ -2,7 +2,6 @@
"extends": [
"next",
"next/core-web-vitals",
"plugin:cypress/recommended",
"prettier"
],
"globals": {
-52
View File
@@ -1,52 +0,0 @@
name: Cypress Tests
on: [push]
jobs:
cypress-run:
runs-on: ubuntu-latest
# Runs tests in parallel with matrix strategy https://docs.cypress.io/guides/guides/parallelization
# https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs
# Also see warning here https://github.com/cypress-io/github-action#parallel
strategy:
fail-fast: false # https://github.com/cypress-io/github-action/issues/48
matrix:
containers: [1, 2] # Uses 2 parallel instances
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cache npm and NextJs build
uses: actions/cache@v3
with:
# See here for caching with `yarn` https://github.com/actions/cache/blob/main/examples#node---yarn, or you can leverage caching with actions/setup-node https://github.com/actions/setup-node
path: |
~/.npm
${{ github.workspace }}/.next/cache
# Generate a new cache whenever packages or source files change.
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
# If source files changed but packages didn't, rebuild from a prior cache.
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
- name: Cypress run
# Uses the official Cypress GitHub action https://github.com/cypress-io/github-action
uses: cypress-io/github-action@v4
with:
# Starts web server for E2E tests - replace with your own server invocation
# https://docs.cypress.io/guides/continuous-integration/introduction#Boot-your-server
# browser: chrome
build: npm run build
start: npm start
wait-on: echo ${{ env.NEXT_PUBLIC_URL }}# Waits for above
# Records to Cypress Cloud
# https://docs.cypress.io/guides/cloud/projects#Set-up-a-project-to-record
record: true
parallel: true # Runs test in parallel using settings above
env:
# For recording and parallelization to work you must set your CYPRESS_RECORD_KEY
# in GitHub repo → Settings → Secrets → Actions
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
MONGODB_URI: ${{ secrets.MONGODB_URI }}
GMAIL_USER: ${{ secrets.GMAIL_USER }}
GMAIL_PASS: ${{ secrets.GMAIL_PASS }}
# Creating a token https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-2
View File
@@ -5,7 +5,6 @@
![GitHub](https://img.shields.io/github/license/therealowenrees/echecsfrance?style=for-the-badge)
![Vercel](https://vercelbadge.vercel.app/api/therealowenrees/echecsfrance?style=for-the-badge)
![Depfu](https://img.shields.io/depfu/dependencies/github/TheRealOwenRees/echecsfrance?style=for-the-badge)
[![Echecs France](https://img.shields.io/endpoint?url=https://cloud.cypress.io/badge/simple/1nghs5&style=for-the-badge&logo=cypress)](https://cloud.cypress.io/projects/1nghs5/runs)
## Un site web indiquant sur une carte les prochains tournois d'échecs de la [FFE](http://www.echecs.asso.fr/)
@@ -16,7 +15,6 @@ Ce site utilise Typescript avec :
- [Next.js](https://nextjs.org/)
- [Tailwind](https://tailwindcss.com/)
- [MongoDB](https://www.mongodb.com/)
- [Cypress](https://www.cypress.io/)
et est déployé sur [Vercel](https://vercel.com/)
-2
View File
@@ -5,7 +5,6 @@
![GitHub](https://img.shields.io/github/license/therealowenrees/echecsfrance?style=for-the-badge)
![Vercel](https://vercelbadge.vercel.app/api/therealowenrees/echecsfrance?style=for-the-badge)
![Depfu](https://img.shields.io/depfu/dependencies/github/TheRealOwenRees/echecsfrance?style=for-the-badge)
[![Echecs France](https://img.shields.io/endpoint?url=https://cloud.cypress.io/badge/simple/1nghs5&style=for-the-badge&logo=cypress)](https://cloud.cypress.io/projects/1nghs5/runs)
## A website displaying upcoming chess tournaments for the [FFE](http://www.echecs.asso.fr/) on a map
@@ -16,7 +15,6 @@ This website is built in Typescript using:
- [Next.js](https://nextjs.org/)
- [Tailwind](https://tailwindcss.com/)
- [MongoDB](https://www.mongodb.com/)
- [Cypress](https://www.cypress.io/)
and is deployed on [Vercel](https://vercel.com/)
+10 -5
View File
@@ -1,6 +1,6 @@
import { Analytics } from "@vercel/analytics/react";
import { Inter, Julius_Sans_One } from "next/font/google";
import { useLocale } from "next-intl";
import { useLocale, NextIntlClientProvider } from "next-intl";
import { getTranslator } from "next-intl/server";
import { notFound } from "next/navigation";
import { ReactNode } from "react";
@@ -8,7 +8,8 @@ import { ReactNode } from "react";
import "@/css/globals.css";
import Providers from "./providers";
import TestableLayout from "./components/TestableLayout";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
const title = Julius_Sans_One({
@@ -58,9 +59,13 @@ export default async function RootLayout({
<html lang={locale} className={`${inter.variable} ${title.variable}`}>
<body>
<Providers>
<TestableLayout locale={locale} messages={messages}>
{children}
</TestableLayout>
<NextIntlClientProvider locale={locale} messages={messages}>
<div className="bg-white font-sans leading-normal tracking-normal dark:bg-gray-800">
<Navbar />
<div className="relative min-h-content">{children}</div>
<Footer />
</div>
</NextIntlClientProvider>
</Providers>
<Analytics />
</body>
-20
View File
@@ -1,20 +0,0 @@
// noinspection JSUnusedGlobalSymbols
import { defineConfig } from "cypress";
export default defineConfig({
projectId: "1nghs5",
e2e: {
baseUrl: "http://localhost:3000",
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
chromeWebSecurity: false,
component: {
devServer: {
framework: "next",
bundler: "webpack",
},
},
});
-57
View File
@@ -1,57 +0,0 @@
import Home from "@/app/[lang]/page";
import About from "@/app/[lang]/qui-sommes-nous/page";
import Contact from "@/app/[lang]/contactez-nous/page";
const navbarFooterCheck = () => {
it("includes navbar", () => {
cy.getByData("navbar");
});
it("includes footer", () => {
cy.getByData("footer");
});
};
describe("Verify component mount", () => {
describe("Verify home page", () => {
beforeEach(() => {
cy.mount(<Home />);
});
it("correct h1 tags with website name included", () => {
cy.getByData("header1").contains("échecs france", {
matchCase: false,
});
});
navbarFooterCheck();
});
describe("Verify about page", () => {
beforeEach(() => {
cy.mount(<About />);
});
it("correct h1 tags with page title included", () => {
cy.getByData("header2").contains("qui sommes-nous", {
matchCase: false,
});
});
navbarFooterCheck();
});
describe("Verify contact page", () => {
beforeEach(() => {
cy.mount(<Contact />);
});
it("correct h1 tags with page title included", () => {
cy.getByData("header2").contains("contactez-nous", {
matchCase: false,
});
});
navbarFooterCheck();
});
});
-15
View File
@@ -1,15 +0,0 @@
import ScrollToTopButton from "@/app/[lang]/tournois/ScrollToTopButton";
describe("Scroll to top button", () => {
it("desktop scroll button clickable", () => {
cy.viewport("macbook-15");
cy.mount(<ScrollToTopButton />);
cy.getByData("scroll-to-top-button").should("exist").click();
});
it("mobile scroll button clickable", () => {
cy.viewport(600, 600);
cy.mount(<ScrollToTopButton />);
cy.getByData("scroll-to-top-button").should("exist").click();
});
});
-28
View File
@@ -1,28 +0,0 @@
import React from "react";
import ThemeSwitcher from "@/app/[lang]/components/ThemeSwitcher";
import "@/css/theme-toggle.css";
describe("ThemeSwitcher component", () => {
it("should toggle between light and dark mode", () => {
cy.mount(<ThemeSwitcher />);
// checking that the toggle is there and light mode is active
cy.getByData("toggle").should("exist");
cy.getByData("toggle").should(($toggle) => {
const backgroundImage = $toggle.css("background-image");
expect(backgroundImage).to.include(
"linear-gradient(rgb(0, 255, 255), rgb(135, 206, 235)",
);
});
// checking that the toggle is clickable and dark mode is active
cy.getByData("toggle").last().click();
cy.getByData("toggle-dark").should("exist");
cy.getByData("toggle-dark").should(($toggle) => {
const backgroundImage = $toggle.css("background-image");
expect(backgroundImage).to.include(
"linear-gradient(rgb(25, 25, 112), rgb(102, 51, 153)",
);
});
});
});
-50
View File
@@ -1,50 +0,0 @@
describe("Contact form", () => {
const email = "test@test.com";
const invalidEmail = "test@";
const subject = "Test Subject";
const message = "Test message";
describe("Invalid data", () => {
beforeEach(() => {
cy.visit("/contactez-nous");
});
it("invalid email address", () => {
cy.getByData("email-input").type(invalidEmail);
cy.getByData("subject-input").type(subject);
cy.getByData("message-input").type(message);
cy.getByData("submit-button").click();
cy.getByData("info-message").should("have.text", "");
});
it("missing subject", () => {
cy.getByData("email-input").type(email);
cy.getByData("message-input").type(message);
cy.getByData("submit-button").click();
cy.getByData("info-message").should("have.text", "");
});
it("missing message", () => {
cy.getByData("email-input").type(email);
cy.getByData("subject-input").type(subject);
cy.getByData("submit-button").click();
cy.getByData("info-message").should("have.text", "");
});
});
describe("Valid data", () => {
beforeEach(() => {
cy.visit("/contactez-nous");
});
it("valid input", () => {
cy.getByData("email-input").type(email);
cy.getByData("subject-input").type(subject);
cy.getByData("message-input").type(message);
cy.getByData("submit-button").click().should("be.disabled");
cy.wait(3000);
cy.getByData("info-message").contains("Merci pour votre message.");
cy.getByData("submit-button").click().should("be.not.disabled");
});
});
});
-27
View File
@@ -1,27 +0,0 @@
let tableRows: number;
describe("Data fetching for map", () => {
it("map markers is equal to table rows", () => {
cy.visit("/tournois");
cy.getByData("tournament-table")
.find("tr")
.then((rows) => {
tableRows = rows.length - 1;
});
cy.get(".leaflet-marker-icon").then((markers) => {
expect(markers.length).to.eq(tableRows);
});
});
});
describe("Data fetching from API endpoints", () => {
it("api call should equal website data count", () => {
cy.request("GET", "http://localhost:3000/api/v1/tournaments/france").then(
(response) => {
expect(response.status).to.eq(200);
const responseData = response.body;
const itemCount = responseData.length;
expect(itemCount).to.eq(tableRows);
},
);
});
});
-72
View File
@@ -1,72 +0,0 @@
describe("Test links", () => {
const pages = ["tournois", "qui sommes-nous", "contactez-nous"];
const navLinkToSlug = (navLink: string) => {
return navLink.replace(/\s+/g, "-");
};
const testLinks = () => {
cy.get("a:not([href*='mailto:']):not(nav a):not(footer a)").each((link) => {
if (
!link
.prop("href")
.includes("http://www.echecs.asso.fr/FicheTournoi.aspx") // ignore every external FFE tournament link
) {
cy.request({
url: link.prop("href"),
failOnStatusCode: false,
});
cy.log(link.prop("href"));
}
});
};
it("navbar links point to correct pathname as a slug", () => {
cy.viewport(600, 600);
cy.visit("/");
pages.forEach((page) => {
cy.getByData("hamburger-button").click();
cy.contains(page, { matchCase: false }).click();
cy.location("pathname").should("eq", `/${navLinkToSlug(page)}`); // url path matches link name, replacing whitespace with hyphens
cy.go("back");
});
});
// TODO consider doing .each from pages array once links are on each page
// TODO at present, the commented out tests have no links so fail
it("homepage dead links", () => {
cy.visit("/");
testLinks();
});
it("tournois dead links", () => {
cy.visit("/tournois");
testLinks();
});
// it("qui-sommes-nous dead links", () => {s
// cy.visit("/qui-sommes-nous");
// testLinks();
// });
//
// it("contactez-nous dead links", () => {
// cy.visit("/contactez-nous");
// testLinks();
// });
//TODO consider 5 random links rather than first 5
it("first 5 tournament external links", () => {
cy.visit("/tournois");
cy.get("a:not([href*='mailto:']):not(nav a):not(footer a)").each(
(link, index) => {
if (index < 5) {
cy.request({
url: link.prop("href"),
failOnStatusCode: false,
});
cy.log(link.prop("href"));
}
},
);
});
});
-31
View File
@@ -1,31 +0,0 @@
describe("Mobile Navbar", () => {
beforeEach(() => {
cy.viewport(600, 600);
cy.visit("/");
});
it("hamburger menu on mobile screens", () => {
cy.getByData("mobile-menu").should("be.visible");
cy.getByData("desktop-menu").should("be.not.visible");
});
it("hamburger button available", () => {
cy.getByData("hamburger-button").should("be.visible");
});
});
describe("Desktop Navbar", () => {
beforeEach(() => {
cy.viewport("macbook-15");
cy.visit("/");
});
it("desktop menu on larger screens", () => {
cy.getByData("mobile-menu").should("be.hidden");
cy.getByData("desktop-menu").should("be.not.hidden");
});
it("hamburger button hidden", () => {
cy.getByData("hamburger-button").should("be.not.visible");
});
});
-26
View File
@@ -1,26 +0,0 @@
describe("Scroll to top button", () => {
beforeEach(() => {
cy.visit("/tournois");
});
it("desktop scroll to top", () => {
cy.viewport(1024, 800);
cy.getByData("tournament-table-div").scrollTo("bottom");
cy.getByData("scroll-to-top-button").click();
// cy.get("[data-cy='tournament-table-div']")
// .invoke("scrollTop")
// .should("equal", 0);
// cy.get("[data-cy='tournament-table-div']")
// .its("scrollY")
// .should("not.equal", 0);
// TODO need to test element scrolls back to 0
});
it("mobile scroll to top", () => {
cy.viewport(600, 600);
cy.scrollTo("bottom");
cy.window().its("scrollY").should("not.equal", 0);
cy.getByData("scroll-to-top-button").click();
cy.window().its("scrollY").should("equal", 0);
});
});
-49
View File
@@ -1,49 +0,0 @@
// noinspection JSUnusedGlobalSymbols
declare namespace Cypress {
interface Chainable {
getByData(dataTestAttribute: string): Chainable<JQuery<HTMLElement>>;
}
}
Cypress.Commands.add("getByData", (selector) => {
return cy.get(`[data-test=${selector}]`);
});
/// <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>
// }
// }
// }
-16
View File
@@ -1,16 +0,0 @@
<!doctype html>
<!--suppress HtmlRequiredLangAttribute, HtmlUnknownTag -->
lUnknownTag -->
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Components App</title>
<!-- Used by Next.js to inject CSS. -->
<div id="__next_css__DO_NOT_USE__"></div>
</head>
<body>
<div data-cy-root></div>
</body>
</html>
-49
View File
@@ -1,49 +0,0 @@
// ***********************************************************
// This example support/component.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 { mount } from "cypress/react18";
import TestableLayout from "@/app/[lang]/components/TestableLayout";
import messages from "@/messages/fr.json";
import "./commands";
// Alternatively you can use CommonJS syntax:
// require('./commands')
// Augment the Cypress namespace to include type definitions for
// your custom command.
// Alternatively, can be defined in cypress/support/component.d.ts
// with a <reference path="./component" /> at the top of your spec.
declare global {
namespace Cypress {
// noinspection JSUnusedGlobalSymbols
interface Chainable {
mount: typeof mount;
}
}
}
Cypress.Commands.add("mount", (component, options) => {
const wrapped = (
<TestableLayout locale="fr" messages={messages}>
{component}
</TestableLayout>
);
return mount(wrapped, options);
});
// Example use:
// cy.mount(<MyComponent />)
-20
View File
@@ -1,20 +0,0 @@
// ***********************************************************
// 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')
-1352
View File
File diff suppressed because it is too large Load Diff
+1 -7
View File
@@ -6,11 +6,7 @@
"dev": "next dev",
"build": "ANALYZE=true next build",
"start": "next start",
"lint": "next lint",
"test:e2e": "cypress run",
"test:component": "cypress run --component",
"test": "npm run test:component && npm run test:e2e",
"cypress": "cypress open"
"lint": "next lint"
},
"dependencies": {
"@kodingdotninja/use-tailwind-breakpoint": "^0.0.5",
@@ -52,11 +48,9 @@
"@types/leaflet.markercluster": "^1.5.1",
"@types/lodash": "^4.14.195",
"@types/nodemailer": "^6.4.8",
"cypress": "^12.16.0",
"eslint": "8.43.0",
"eslint-config-next": "^13.4.7",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-cypress": "^2.13.3",
"prettier": "3.0.0",
"prettier-plugin-tailwindcss": "^0.4.0"
}
-1
View File
@@ -3,7 +3,6 @@
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"types": ["cypress"],
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,