mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
cypress best practices updated
This commit is contained in:
@@ -1,10 +1,8 @@
|
|||||||
// TODO change tests to follow best practices https://docs.cypress.io/guides/references/best-practices
|
|
||||||
// TODO tests for tournament page:
|
// TODO tests for tournament page:
|
||||||
- map and table mounts in tournament page <- get data to send to map/table
|
- map and table mounts in tournament page <- get data to send to map/table
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
//TODO hover on table needs fixing - this only seemed to happen once I moved the logic into its own hook <- error is occurring on all hovers at the moment.
|
//TODO SRP for web and API data fetching
|
||||||
//TODO fix table hover colours
|
//TODO API should not display __v and _id should just be id
|
||||||
-----------------------------------------------------------------
|
|
||||||
//TODO about page
|
//TODO about page
|
||||||
//TODO contact page needs working mailer
|
//TODO contact page needs working mailer
|
||||||
//TODO font size on mobile screen
|
//TODO font size on mobile screen
|
||||||
@@ -13,13 +11,8 @@
|
|||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
//TODO logo for navbar and favicon
|
//TODO logo for navbar and favicon
|
||||||
//TODO mobile map needs improving
|
//TODO mobile map needs improving
|
||||||
|
|
||||||
//TODO multi-language i18n support - https://nextjs.org/docs/app/building-your-application/routing/internationalization
|
//TODO multi-language i18n support - https://nextjs.org/docs/app/building-your-application/routing/internationalization
|
||||||
|
|
||||||
//TODO error handling
|
//TODO error handling
|
||||||
|
|
||||||
//TODO consider offering GraphQL support
|
//TODO consider offering GraphQL support
|
||||||
|
|
||||||
//TODO move smaller ui components into a new folder, and make them reusable - such as using generic prop names
|
//TODO move smaller ui components into a new folder, and make them reusable - such as using generic prop names
|
||||||
|
|
||||||
//TODO readme
|
//TODO readme
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ export default function Contact() {
|
|||||||
<Layout>
|
<Layout>
|
||||||
<section className="grid place-items-center bg-white dark:bg-gray-800">
|
<section className="grid place-items-center bg-white dark:bg-gray-800">
|
||||||
<div className="pt-8 pb-32 lg:pt-16 px-4 mx-auto max-w-screen-md">
|
<div className="pt-8 pb-32 lg:pt-16 px-4 mx-auto max-w-screen-md">
|
||||||
<h2 className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 dark:text-white">
|
<h2
|
||||||
|
className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 dark:text-white"
|
||||||
|
data-cy="header2"
|
||||||
|
>
|
||||||
Contactez-Nous
|
Contactez-Nous
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mb-8 lg:mb-16 font-light text-center text-gray-500 dark:text-gray-400 sm:text-xl">
|
<p className="mb-8 lg:mb-16 font-light text-center text-gray-500 dark:text-gray-400 sm:text-xl">
|
||||||
|
|||||||
+3
-1
@@ -16,7 +16,9 @@ export default function Home() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="absolute text-center text-white">
|
<div className="absolute text-center text-white">
|
||||||
<h1 className="text-5xl p-5">Echecs France</h1>
|
<h1 className="text-5xl p-5" data-cy="header1">
|
||||||
|
Echecs France
|
||||||
|
</h1>
|
||||||
<h2 className="text-3xl p-5">
|
<h2 className="text-3xl p-5">
|
||||||
Trouvez Vos Tournois d'Echecs en France Sur Une Carte
|
Trouvez Vos Tournois d'Echecs en France Sur Une Carte
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ export default function About() {
|
|||||||
<header className="grid h-[calc(100%-216px)] md:h-[calc(100%-174px)] place-items-center">
|
<header className="grid h-[calc(100%-216px)] md:h-[calc(100%-174px)] place-items-center">
|
||||||
<div className="relative h-full w-full bg-white dark:bg-gray-800"></div>
|
<div className="relative h-full w-full bg-white dark:bg-gray-800"></div>
|
||||||
<div className="absolute">
|
<div className="absolute">
|
||||||
<h2 className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 dark:text-white">
|
<h2
|
||||||
|
className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 dark:text-white"
|
||||||
|
data-cy="header2"
|
||||||
|
>
|
||||||
Qui Sommes-Nous?
|
Qui Sommes-Nous?
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mb-8 lg:mb-16 font-light text-center text-gray-500 dark:text-gray-400 sm:text-xl">
|
<p className="mb-8 lg:mb-16 font-light text-center text-gray-500 dark:text-gray-400 sm:text-xl">
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import { FaGithub, FaRegEnvelope } from "react-icons/fa";
|
|||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
return (
|
return (
|
||||||
<footer className="grid w-full fixed bottom-0 justify-items-center py-2 px-5 text-white bg-teal-600 text-gray-900 dark:bg-gray-700">
|
<footer
|
||||||
|
className="grid w-full fixed bottom-0 justify-items-center py-2 px-5 text-white bg-teal-600 text-gray-900 dark:bg-gray-700"
|
||||||
|
data-cy="footer"
|
||||||
|
>
|
||||||
<div className="p-2">
|
<div className="p-2">
|
||||||
<p>© {new Date().getFullYear()} - Owen Rees</p>
|
<p>© {new Date().getFullYear()} - Owen Rees</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const Hamburger = () => {
|
|||||||
<div
|
<div
|
||||||
ref={hamburgerButtonRef}
|
ref={hamburgerButtonRef}
|
||||||
className="hamburger-button space-y-2 relative z-[99999]"
|
className="hamburger-button space-y-2 relative z-[99999]"
|
||||||
|
data-cy="hamburger-button"
|
||||||
onClick={() => setMenuVisible(!menuVisible)}
|
onClick={() => setMenuVisible(!menuVisible)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ import Hamburger from "@/components/Hamburger";
|
|||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
return (
|
return (
|
||||||
<nav className="w-full relative border-b-[1px] pt-5 mt-0 px-5 md:pt-2 bg-white dark:bg-gray-800 dark:border-gray-700 overflow-x-clip">
|
<nav
|
||||||
|
className="w-full relative border-b-[1px] pt-5 mt-0 px-5 md:pt-2 bg-white dark:bg-gray-800 dark:border-gray-700 overflow-x-clip"
|
||||||
|
data-cy="navbar"
|
||||||
|
>
|
||||||
<div className="container mx-auto flex items-center">
|
<div className="container mx-auto flex items-center">
|
||||||
<div className="pb-3 justify-center flex w-full md:w-1/2 md:pb-0 md:justify-start font-extrabold">
|
<div className="pb-3 justify-center flex w-full md:w-1/2 md:pb-0 md:justify-start font-extrabold">
|
||||||
<Link
|
<Link
|
||||||
@@ -14,11 +17,14 @@ export default function Navbar() {
|
|||||||
<span className="text-2xl">Echecs France</span>
|
<span className="text-2xl">Echecs France</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="mobile-menu pb-2 md:hidden">
|
<div className="pb-2 md:hidden" data-cy="mobile-menu">
|
||||||
<Hamburger />
|
<Hamburger />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="desktop-menu hidden pt-2 justify-center md:flex md:w-1/2 md:justify-end">
|
<div
|
||||||
|
className="hidden pt-2 justify-center md:flex md:w-1/2 md:justify-end"
|
||||||
|
data-cy="desktop-menu"
|
||||||
|
>
|
||||||
<ul className="list-reset text-gray-900 dark:text-white no-underline flex flex-1 justify-around md:flex-none items-center">
|
<ul className="list-reset text-gray-900 dark:text-white no-underline flex flex-1 justify-around md:flex-none items-center">
|
||||||
<li className="mr-10">
|
<li className="mr-10">
|
||||||
<Link
|
<Link
|
||||||
|
|||||||
@@ -20,11 +20,19 @@ const ThemeSwitcher = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{colorTheme === "light" ? (
|
{colorTheme === "light" ? (
|
||||||
<div className="toggle-dark" onClick={() => setTheme("light")}>
|
<div
|
||||||
|
className="toggle-dark"
|
||||||
|
data-cy="toggle-dark"
|
||||||
|
onClick={() => setTheme("light")}
|
||||||
|
>
|
||||||
<MdBrightness2 className="theme-icon-dark" />
|
<MdBrightness2 className="theme-icon-dark" />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="toggle" onClick={() => setTheme("dark")}>
|
<div
|
||||||
|
className="toggle"
|
||||||
|
data-cy="toggle"
|
||||||
|
onClick={() => setTheme("dark")}
|
||||||
|
>
|
||||||
<MdCircle className="theme-icon" />
|
<MdCircle className="theme-icon" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import Contact from "@/app/contactez-nous/page";
|
|||||||
|
|
||||||
const navbarFooterCheck = () => {
|
const navbarFooterCheck = () => {
|
||||||
it("includes navbar", () => {
|
it("includes navbar", () => {
|
||||||
cy.get("nav");
|
cy.get("[data-cy='navbar']");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes footer", () => {
|
it("includes footer", () => {
|
||||||
cy.get("footer");
|
cy.get("[data-cy='footer']");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,7 +19,9 @@ describe("Verify component mount", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("correct h1 tags with website name included", () => {
|
it("correct h1 tags with website name included", () => {
|
||||||
cy.get("h1").contains("echecs france", { matchCase: false });
|
cy.get("[data-cy='header1']").contains("echecs france", {
|
||||||
|
matchCase: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
navbarFooterCheck();
|
navbarFooterCheck();
|
||||||
@@ -31,7 +33,9 @@ describe("Verify component mount", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("correct h1 tags with page title included", () => {
|
it("correct h1 tags with page title included", () => {
|
||||||
cy.get("h2").contains("qui sommes-nous", { matchCase: false });
|
cy.get("[data-cy='header2']").contains("qui sommes-nous", {
|
||||||
|
matchCase: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
navbarFooterCheck();
|
navbarFooterCheck();
|
||||||
@@ -43,7 +47,9 @@ describe("Verify component mount", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("correct h1 tags with page title included", () => {
|
it("correct h1 tags with page title included", () => {
|
||||||
cy.get("h2").contains("contactez-nous", { matchCase: false });
|
cy.get("[data-cy='header2']").contains("contactez-nous", {
|
||||||
|
matchCase: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
navbarFooterCheck();
|
navbarFooterCheck();
|
||||||
|
|||||||
@@ -10,17 +10,17 @@ describe("ThemeSwitcher component", () => {
|
|||||||
cy.wait(100);
|
cy.wait(100);
|
||||||
|
|
||||||
// checking that the toggle is there and light mode is active
|
// checking that the toggle is there and light mode is active
|
||||||
cy.get(".toggle").should("exist");
|
cy.get("[data-cy='toggle']").should("exist");
|
||||||
cy.get(".toggle").should(($toggle) => {
|
cy.get("[data-cy='toggle']").should(($toggle) => {
|
||||||
const backgroundImage = $toggle.css("background-image");
|
const backgroundImage = $toggle.css("background-image");
|
||||||
expect(backgroundImage).to.include(
|
expect(backgroundImage).to.include(
|
||||||
"linear-gradient(rgb(0, 255, 255), rgb(135, 206, 235)"
|
"linear-gradient(rgb(0, 255, 255), rgb(135, 206, 235)"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// checking that the toggle is clickable and dark mode is active
|
// checking that the toggle is clickable and dark mode is active
|
||||||
cy.get(".toggle").click();
|
cy.get("[data-cy='toggle']").click();
|
||||||
cy.get(".toggle-dark").should("exist");
|
cy.get("[data-cy='toggle-dark']").should("exist");
|
||||||
cy.get(".toggle-dark").should(($toggle) => {
|
cy.get("[data-cy='toggle-dark']").should(($toggle) => {
|
||||||
const backgroundImage = $toggle.css("background-image");
|
const backgroundImage = $toggle.css("background-image");
|
||||||
expect(backgroundImage).to.include(
|
expect(backgroundImage).to.include(
|
||||||
"linear-gradient(rgb(25, 25, 112), rgb(102, 51, 153)"
|
"linear-gradient(rgb(25, 25, 112), rgb(102, 51, 153)"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ describe("Test all links", () => {
|
|||||||
cy.viewport(600, 600);
|
cy.viewport(600, 600);
|
||||||
cy.visit("/");
|
cy.visit("/");
|
||||||
pages.forEach((page) => {
|
pages.forEach((page) => {
|
||||||
cy.get(".hamburger-button").click();
|
cy.get("[data-cy='hamburger-button']").click();
|
||||||
cy.contains(page, { matchCase: false }).click();
|
cy.contains(page, { matchCase: false }).click();
|
||||||
cy.location("pathname").should("eq", `/${navLinkToSlug(page)}`); // url path matches link name, replacing whitespace with hyphens
|
cy.location("pathname").should("eq", `/${navLinkToSlug(page)}`); // url path matches link name, replacing whitespace with hyphens
|
||||||
cy.go("back");
|
cy.go("back");
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ describe("Mobile Navbar", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("hamburger menu on mobile screens", () => {
|
it("hamburger menu on mobile screens", () => {
|
||||||
cy.get(".mobile-menu").should("be.not.hidden");
|
cy.get("[data-cy='mobile-menu']").should("be.visible");
|
||||||
cy.get(".desktop-menu").should("be.hidden");
|
cy.get("[data-cy='desktop-menu']").should("be.not.visible");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hamburger button available", () => {
|
it("hamburger button available", () => {
|
||||||
cy.get(".hamburger-button").should("be.visible");
|
cy.get("[data-cy='hamburger-button']").should("be.visible");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -21,11 +21,11 @@ describe("Desktop Navbar", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("desktop menu on larger screens", () => {
|
it("desktop menu on larger screens", () => {
|
||||||
cy.get(".mobile-menu").should("be.hidden");
|
cy.get("[data-cy='mobile-menu']").should("be.hidden");
|
||||||
cy.get(".desktop-menu").should("be.not.hidden");
|
cy.get("[data-cy='desktop-menu']").should("be.not.hidden");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hamburger button hidden", () => {
|
it("hamburger button hidden", () => {
|
||||||
cy.get(".hamburger-button").should("be.not.visible");
|
cy.get("[data-cy='hamburger-button']").should("be.not.visible");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
import { Tournament } from "@/types";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
// TODO delete after testing
|
|
||||||
const useTournamentDataFilter = (
|
|
||||||
initialState: Tournament[]
|
|
||||||
): (any | ((searchQuery: string) => void))[] => {
|
|
||||||
const [filtered, setFiltered] = useState(initialState);
|
|
||||||
let state;
|
|
||||||
const setState = (searchQuery: string) => {
|
|
||||||
setFiltered(
|
|
||||||
initialState.filter((t) => t.town.includes(searchQuery.toUpperCase()))
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (filtered.length === 0) {
|
|
||||||
state = (
|
|
||||||
<tr className="bg-white text-gray-900 dark:bg-gray-800 dark:text-white">
|
|
||||||
<td colSpan={4} className="p-3">
|
|
||||||
No tournaments found
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
state = filtered.map((t) => (
|
|
||||||
<tr
|
|
||||||
className="text-gray-900 bg-white dark:bg-gray-800 dark:text-white hover:bg-gray-400 hover:text-black"
|
|
||||||
key={t._id}
|
|
||||||
>
|
|
||||||
<td className="p-3">
|
|
||||||
<a href={t.url} target="_blank">
|
|
||||||
{t.date}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td className="p-3">
|
|
||||||
<a href={t.url} target="_blank">
|
|
||||||
{t.town}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td className="p-3">
|
|
||||||
<a href={t.url} target="_blank">
|
|
||||||
{t.tournament}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td className="p-3">
|
|
||||||
<a href={t.url} target="_blank">
|
|
||||||
{t.time_control}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return [state, setState];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useTournamentDataFilter;
|
|
||||||
Reference in New Issue
Block a user