mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
@@ -1,16 +1,12 @@
|
|||||||
TESTS
|
TESTS
|
||||||
// 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 data fetching tests
|
|
||||||
//TODO redo layer groups tests
|
|
||||||
//TODO write tests for contact form
|
|
||||||
//TODO dead link tests take too long, split them into separate tests per page
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
BUGS
|
BUGS
|
||||||
//TODO about page is not centred in Safari
|
//TODO about page is not centred in Safari
|
||||||
//TODO tournament page load is weird on 2nd click. On safari it pauses for a few seconds. Is it trying to load the entire page before displaying?
|
//TODO tournament page load is weird on 2nd click. On safari it pauses for a few seconds. Is it trying to load the entire page before displaying?
|
||||||
//TODO Nodemailer 'from' reverts to echecsfrance@gmail.com
|
//TODO Nodemailer 'from' reverts to echecsfrance@gmail.com - quick fix done with sender address in subject line
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
PAGES
|
PAGES
|
||||||
@@ -20,23 +16,19 @@ PAGES
|
|||||||
DESIGN CHANGES
|
DESIGN CHANGES
|
||||||
//TODO test entire site for english to french translations
|
//TODO test entire site for english to french translations
|
||||||
//TODO success and error messages into french - mailer
|
//TODO success and error messages into french - mailer
|
||||||
//TODO disable send message button while sending - isSending = true
|
|
||||||
//TODO font size on mobile screen
|
//TODO font size on mobile screen
|
||||||
//TODO bottom of map is a few pixels short
|
//TODO mobile navbar is creeping into the page by a few pixels when hidden - move it to the right a bit. It is easier to see in light mode. I cant see this on Linux
|
||||||
//TODO mobile navbar is creeping into the page by a few pixels when hidden - move it to the right a bit. It is easier to see in light mode
|
|
||||||
//TODO logo for navbar and favicon
|
//TODO logo for navbar and favicon
|
||||||
//TODO mobile map needs improving
|
//TODO mobile map needs improving
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
LOGIC
|
LOGIC
|
||||||
//TODO SRP for web and API data fetching
|
|
||||||
//TODO error handling
|
//TODO error handling
|
||||||
//TODO consider offering GraphQL support
|
//TODO consider offering GraphQL support
|
||||||
|
|
||||||
MISC
|
MISC
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
//TODO write logger (fullstack open examples)
|
//TODO write logger (fullstack open examples)
|
||||||
//TODO SEO - next headers etc
|
|
||||||
//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 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
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ export async function GET() {
|
|||||||
try {
|
try {
|
||||||
const client = await clientPromise;
|
const client = await clientPromise;
|
||||||
const db = client.db("tournamentsFranceDB");
|
const db = client.db("tournamentsFranceDB");
|
||||||
|
|
||||||
const results = await dateOrderingFrance(db);
|
const results = await dateOrderingFrance(db);
|
||||||
const data = results.map(({ _id, ...rest }) => ({
|
const data = results.map(({ _id, ...rest }) => ({
|
||||||
id: _id,
|
id: _id,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default function Contact() {
|
|||||||
<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
|
<h2
|
||||||
className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 dark:text-white"
|
className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 dark:text-white"
|
||||||
data-cy="header2"
|
data-test="header2"
|
||||||
>
|
>
|
||||||
Contactez-Nous
|
Contactez-Nous
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
+2
-1
@@ -7,7 +7,8 @@ const inter = Inter({ subsets: ["latin"] });
|
|||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: "Echecs France",
|
title: "Echecs France",
|
||||||
description: "Generated by create next app", // TODO give the website a description + maybe keywords if they go here
|
description: "Trouvez Vos Tournois d'Echecs en France Sur Une Carte",
|
||||||
|
keywords: "echecs, France, tournoi, tournois, FFE",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ 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" data-cy="header1">
|
<h1 className="text-5xl p-5" data-test="header1">
|
||||||
Echecs France
|
Echecs France
|
||||||
</h1>
|
</h1>
|
||||||
<h2 className="text-3xl p-5">
|
<h2 className="text-3xl p-5">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default function About() {
|
|||||||
<div className="absolute">
|
<div className="absolute">
|
||||||
<h2
|
<h2
|
||||||
className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 dark:text-white"
|
className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 dark:text-white"
|
||||||
data-cy="header2"
|
data-test="header2"
|
||||||
>
|
>
|
||||||
Qui Sommes-Nous?
|
Qui Sommes-Nous?
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ const getTournaments = async () => {
|
|||||||
try {
|
try {
|
||||||
const client = await clientPromise;
|
const client = await clientPromise;
|
||||||
const db = client.db("tournamentsFranceDB");
|
const db = client.db("tournamentsFranceDB");
|
||||||
|
|
||||||
const data = await dateOrderingFrance(db);
|
const data = await dateOrderingFrance(db);
|
||||||
|
|
||||||
return JSON.stringify(data);
|
return JSON.stringify(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error("Error fetching tournament data");
|
throw new Error("Error fetching tournament data");
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const ContactForm = () => {
|
|||||||
className={`${
|
className={`${
|
||||||
responseMessage.isSuccessful ? "text-green-600" : "text-red-600"
|
responseMessage.isSuccessful ? "text-green-600" : "text-red-600"
|
||||||
} italic`}
|
} italic`}
|
||||||
|
data-test="info-message"
|
||||||
>
|
>
|
||||||
{responseMessage.message}
|
{responseMessage.message}
|
||||||
</p>
|
</p>
|
||||||
@@ -51,6 +52,7 @@ const ContactForm = () => {
|
|||||||
className="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 dark:shadow-sm-light"
|
className="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 dark:shadow-sm-light"
|
||||||
placeholder="nom@exemple.com"
|
placeholder="nom@exemple.com"
|
||||||
required
|
required
|
||||||
|
data-test="email-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -68,6 +70,7 @@ const ContactForm = () => {
|
|||||||
className="block p-3 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 shadow-sm focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 dark:shadow-sm-light"
|
className="block p-3 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 shadow-sm focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 dark:shadow-sm-light"
|
||||||
placeholder="Le motif de ma demande"
|
placeholder="Le motif de ma demande"
|
||||||
required
|
required
|
||||||
|
data-test="subject-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="sm:col-span-2">
|
<div className="sm:col-span-2">
|
||||||
@@ -84,12 +87,15 @@ const ContactForm = () => {
|
|||||||
rows={6}
|
rows={6}
|
||||||
className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg shadow-sm border border-gray-300 focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
|
className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg shadow-sm border border-gray-300 focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
|
||||||
placeholder="Détaillez ici votre demande..."
|
placeholder="Détaillez ici votre demande..."
|
||||||
|
data-test="message-input"
|
||||||
|
required
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
disabled={isSending}
|
disabled={isSending}
|
||||||
type="submit"
|
type="submit"
|
||||||
className="py-3 px-5 text-sm font-medium text-center text-white rounded-lg bg-teal-600 sm:w-fit hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 dark:hover:bg-primary-700 dark:focus:ring-primary-800 dark:text-white disabled:opacity-25"
|
className="py-3 px-5 text-sm font-medium text-center text-white rounded-lg bg-teal-600 sm:w-fit hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 dark:hover:bg-primary-700 dark:focus:ring-primary-800 dark:text-white disabled:opacity-25"
|
||||||
|
data-test="submit-button"
|
||||||
>
|
>
|
||||||
{isSending ? "Sending..." : "Send Message"}
|
{isSending ? "Sending..." : "Send Message"}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export default function Footer() {
|
|||||||
return (
|
return (
|
||||||
<footer
|
<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 z-30"
|
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 z-30"
|
||||||
data-cy="footer"
|
data-test="footer"
|
||||||
>
|
>
|
||||||
<div className="p-2">
|
<div className="p-2">
|
||||||
<p>© {new Date().getFullYear()} - Owen Rees</p>
|
<p>© {new Date().getFullYear()} - Owen Rees</p>
|
||||||
|
|||||||
@@ -11,7 +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"
|
data-test="hamburger-button"
|
||||||
onClick={() => setMenuVisible(!menuVisible)}
|
onClick={() => setMenuVisible(!menuVisible)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export default function Navbar() {
|
|||||||
return (
|
return (
|
||||||
<nav
|
<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"
|
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"
|
data-test="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">
|
||||||
@@ -17,13 +17,13 @@ export default function Navbar() {
|
|||||||
<span className="text-2xl">Echecs France</span>
|
<span className="text-2xl">Echecs France</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="pb-2 md:hidden" data-cy="mobile-menu">
|
<div className="pb-2 md:hidden" data-test="mobile-menu">
|
||||||
<Hamburger />
|
<Hamburger />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="hidden pt-2 justify-center md:flex md:w-1/2 md:justify-end"
|
className="hidden pt-2 justify-center md:flex md:w-1/2 md:justify-end"
|
||||||
data-cy="desktop-menu"
|
data-test="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">
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const ScrollToTopButton = () => {
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={`${scrollToTopButtonClass} z-10 text-2xl text-teal-900 dark:text-white`}
|
className={`${scrollToTopButtonClass} z-10 text-2xl text-teal-900 dark:text-white`}
|
||||||
data-cy="scroll-to-top-button"
|
data-test="scroll-to-top-button"
|
||||||
>
|
>
|
||||||
<FaArrowUp
|
<FaArrowUp
|
||||||
onClick={() => handleScrollToTop(scrollToTopElementRef.current)}
|
onClick={() => handleScrollToTop(scrollToTopElementRef.current)}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const ThemeSwitcher = () => {
|
|||||||
{colorTheme === "light" ? (
|
{colorTheme === "light" ? (
|
||||||
<div
|
<div
|
||||||
className="toggle-dark"
|
className="toggle-dark"
|
||||||
data-cy="toggle-dark"
|
data-test="toggle-dark"
|
||||||
onClick={() => setTheme("light")}
|
onClick={() => setTheme("light")}
|
||||||
>
|
>
|
||||||
<MdBrightness2 className="theme-icon-dark" />
|
<MdBrightness2 className="theme-icon-dark" />
|
||||||
@@ -30,7 +30,7 @@ const ThemeSwitcher = () => {
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className="toggle"
|
className="toggle"
|
||||||
data-cy="toggle"
|
data-test="toggle"
|
||||||
onClick={() => setTheme("dark")}
|
onClick={() => setTheme("dark")}
|
||||||
>
|
>
|
||||||
<MdCircle className="theme-icon" />
|
<MdCircle className="theme-icon" />
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default function TournamentMap({ tournamentData }: TournamentDataProps) {
|
|||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
id="tournament-map"
|
id="tournament-map"
|
||||||
className="grid h-[calc(100vh-153px)] md:h-[calc(100vh-83px)] lg:h-[calc(100vh-174px)]"
|
className="grid h-[calc(100vh-153px)] md:h-[calc(100vh-83px)] lg:h-[calc(100vh-173px)]"
|
||||||
>
|
>
|
||||||
<MapContainer
|
<MapContainer
|
||||||
center={center}
|
center={center}
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ export default function TournamentTable({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
className="tournament-table w-full grid auto-rows-max pb-20 lg:h-[calc(100vh-174px)] lg:col-start-2 lg:col-end-3 lg:overflow-y-scroll"
|
className="tournament-table w-full grid auto-rows-max pb-20 lg:h-[calc(100vh-173px)] lg:col-start-2 lg:col-end-3 lg:overflow-y-scroll"
|
||||||
id="tournament-table"
|
id="tournament-table"
|
||||||
data-cy="tournament-table-div"
|
data-test="tournament-table-div"
|
||||||
>
|
>
|
||||||
<div className="flex z-10">
|
<div className="flex z-10">
|
||||||
<SearchBar
|
<SearchBar
|
||||||
@@ -75,7 +75,7 @@ export default function TournamentTable({
|
|||||||
</div>
|
</div>
|
||||||
<table
|
<table
|
||||||
className="relative table-fixed w-full text-center text-xs"
|
className="relative table-fixed w-full text-center text-xs"
|
||||||
data-cy="tournament-table"
|
data-test="tournament-table"
|
||||||
>
|
>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import Contact from "@/app/contactez-nous/page";
|
|||||||
|
|
||||||
const navbarFooterCheck = () => {
|
const navbarFooterCheck = () => {
|
||||||
it("includes navbar", () => {
|
it("includes navbar", () => {
|
||||||
cy.get("[data-cy='navbar']");
|
cy.getByData("navbar");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes footer", () => {
|
it("includes footer", () => {
|
||||||
cy.get("[data-cy='footer']");
|
cy.getByData("footer");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ describe("Verify component mount", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("correct h1 tags with website name included", () => {
|
it("correct h1 tags with website name included", () => {
|
||||||
cy.get("[data-cy='header1']").contains("echecs france", {
|
cy.getByData("header1").contains("echecs france", {
|
||||||
matchCase: false,
|
matchCase: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -33,7 +33,7 @@ describe("Verify component mount", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("correct h1 tags with page title included", () => {
|
it("correct h1 tags with page title included", () => {
|
||||||
cy.get("[data-cy='header2']").contains("qui sommes-nous", {
|
cy.getByData("header2").contains("qui sommes-nous", {
|
||||||
matchCase: false,
|
matchCase: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -47,7 +47,7 @@ describe("Verify component mount", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("correct h1 tags with page title included", () => {
|
it("correct h1 tags with page title included", () => {
|
||||||
cy.get("[data-cy='header2']").contains("contactez-nous", {
|
cy.getByData("header2").contains("contactez-nous", {
|
||||||
matchCase: false,
|
matchCase: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ describe("Scroll to top button", () => {
|
|||||||
it("desktop scroll button clickable", () => {
|
it("desktop scroll button clickable", () => {
|
||||||
cy.viewport("macbook-15");
|
cy.viewport("macbook-15");
|
||||||
cy.mount(<ScrollToTopButton />);
|
cy.mount(<ScrollToTopButton />);
|
||||||
cy.get("[data-cy='scroll-to-top-button']").should("exist").click();
|
cy.getByData("scroll-to-top-button").should("exist").click();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("mobile scroll button clickable", () => {
|
it("mobile scroll button clickable", () => {
|
||||||
cy.viewport(600, 600);
|
cy.viewport(600, 600);
|
||||||
cy.mount(<ScrollToTopButton />);
|
cy.mount(<ScrollToTopButton />);
|
||||||
cy.get("[data-cy='scroll-to-top-button']").should("exist").click();
|
cy.getByData("scroll-to-top-button").should("exist").click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ describe("ThemeSwitcher component", () => {
|
|||||||
cy.mount(<ThemeSwitcher />);
|
cy.mount(<ThemeSwitcher />);
|
||||||
|
|
||||||
// checking that the toggle is there and light mode is active
|
// checking that the toggle is there and light mode is active
|
||||||
cy.get("[data-cy='toggle']").should("exist");
|
cy.getByData("toggle").should("exist");
|
||||||
cy.get("[data-cy='toggle']").should(($toggle) => {
|
cy.getByData("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("[data-cy='toggle']").click();
|
cy.getByData("toggle").click();
|
||||||
cy.get("[data-cy='toggle-dark']").should("exist");
|
cy.getByData("toggle-dark").should("exist");
|
||||||
cy.get("[data-cy='toggle-dark']").should(($toggle) => {
|
cy.getByData("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)"
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
// import { Tournament } from "@/types";
|
|
||||||
// import getTournaments from "@/utils/getTournamentData";
|
|
||||||
// import { createLayerGroups } from "@/utils/layerGroups";
|
|
||||||
//
|
|
||||||
|
|
||||||
// // TODO rewrite this test suite since I no longer use fetch for the map
|
|
||||||
// // TODO add tests for the API once it is active
|
|
||||||
// describe("Unit tests of utils directory", () => {
|
|
||||||
// describe("Retrieve tournament data from DB", () => {
|
|
||||||
// let response: Tournament[];
|
|
||||||
// let results: Tournament[];
|
|
||||||
//
|
|
||||||
// describe("France", () => {
|
|
||||||
// before(async () => {
|
|
||||||
// response = await getTournaments("france");
|
|
||||||
// results = response.splice(0, 5);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it("log first 5 results", () => {
|
|
||||||
// results.forEach((result) => cy.log(JSON.stringify(result)));
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it("check tournament urls are active", () => {
|
|
||||||
// results.forEach((result) => cy.request(result.url));
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe("Create layer groups for map markers", () => {
|
|
||||||
// let response: Tournament[];
|
|
||||||
// let results: Tournament[];
|
|
||||||
// describe("France", () => {
|
|
||||||
// const timeControls = [
|
|
||||||
// { name: "Cadence Lente", colour: "green" },
|
|
||||||
// { name: "Rapide", colour: "blue" },
|
|
||||||
// { name: "Blitz", colour: "yellow" },
|
|
||||||
// { name: "1h KO", colour: "red" },
|
|
||||||
// ];
|
|
||||||
//
|
|
||||||
// before(async () => {
|
|
||||||
// response = await getTournaments("france");
|
|
||||||
// results = response.splice(0, 5);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it("generate layer groups", () => {
|
|
||||||
// const result = timeControls.map((timeControl) => {
|
|
||||||
// return createLayerGroups(timeControl.name, timeControl.colour, {
|
|
||||||
// tournamentData: results,
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// cy.wrap(result.length).should("be.greaterThan", 0);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
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("Thank you");
|
||||||
|
cy.getByData("submit-button").click().should("be.not.disabled");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -2,7 +2,7 @@ let tableRows: number;
|
|||||||
describe("Data fetching for map", () => {
|
describe("Data fetching for map", () => {
|
||||||
it("map markers is equal to table rows", () => {
|
it("map markers is equal to table rows", () => {
|
||||||
cy.visit("/tournois");
|
cy.visit("/tournois");
|
||||||
cy.get('[data-cy="tournament-table"]')
|
cy.getByData("tournament-table")
|
||||||
.find("tr")
|
.find("tr")
|
||||||
.then((rows) => {
|
.then((rows) => {
|
||||||
tableRows = rows.length - 1;
|
tableRows = rows.length - 1;
|
||||||
+49
-14
@@ -1,37 +1,72 @@
|
|||||||
describe("Test all links", () => {
|
describe("Test links", () => {
|
||||||
const pages = ["tournois", "qui sommes-nous", "contactez-nous"];
|
const pages = ["tournois", "qui sommes-nous", "contactez-nous"];
|
||||||
|
|
||||||
const navLinkToSlug = (navLink: string) => {
|
const navLinkToSlug = (navLink: string) => {
|
||||||
return navLink.replace(/\s+/g, "-");
|
return navLink.replace(/\s+/g, "-");
|
||||||
};
|
};
|
||||||
|
|
||||||
it("Check navbar links point to correct pathname as a slug", () => {
|
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.viewport(600, 600);
|
||||||
cy.visit("/");
|
cy.visit("/");
|
||||||
pages.forEach((page) => {
|
pages.forEach((page) => {
|
||||||
cy.get("[data-cy='hamburger-button']").click();
|
cy.getByData("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");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Check dead links", () => {
|
// TODO consider doing .each from pages array once links are on each page
|
||||||
pages.forEach((page) => {
|
// TODO at present, the commented out tests have no links so fail
|
||||||
cy.visit(`/${navLinkToSlug(page)}`);
|
it("homepage dead links", () => {
|
||||||
cy.get("a:not([href*='mailto:']").each((link) => {
|
cy.visit("/");
|
||||||
if (
|
testLinks();
|
||||||
!link
|
});
|
||||||
.prop("href")
|
|
||||||
.includes("http://www.echecs.asso.fr/FicheTournoi.aspx") // ignore every external FFE tournament link
|
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({
|
cy.request({
|
||||||
url: link.prop("href"),
|
url: link.prop("href"),
|
||||||
failOnStatusCode: false,
|
failOnStatusCode: false,
|
||||||
});
|
});
|
||||||
cy.log(link.prop("href"));
|
cy.log(link.prop("href"));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ describe("Mobile Navbar", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("hamburger menu on mobile screens", () => {
|
it("hamburger menu on mobile screens", () => {
|
||||||
cy.get("[data-cy='mobile-menu']").should("be.visible");
|
cy.getByData("mobile-menu").should("be.visible");
|
||||||
cy.get("[data-cy='desktop-menu']").should("be.not.visible");
|
cy.getByData("desktop-menu").should("be.not.visible");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hamburger button available", () => {
|
it("hamburger button available", () => {
|
||||||
cy.get("[data-cy='hamburger-button']").should("be.visible");
|
cy.getByData("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("[data-cy='mobile-menu']").should("be.hidden");
|
cy.getByData("mobile-menu").should("be.hidden");
|
||||||
cy.get("[data-cy='desktop-menu']").should("be.not.hidden");
|
cy.getByData("desktop-menu").should("be.not.hidden");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hamburger button hidden", () => {
|
it("hamburger button hidden", () => {
|
||||||
cy.get("[data-cy='hamburger-button']").should("be.not.visible");
|
cy.getByData("hamburger-button").should("be.not.visible");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -5,8 +5,8 @@ describe("Scroll to top button", () => {
|
|||||||
|
|
||||||
it("desktop scroll to top", () => {
|
it("desktop scroll to top", () => {
|
||||||
cy.viewport(1024, 800);
|
cy.viewport(1024, 800);
|
||||||
cy.get("[data-cy='tournament-table-div']").scrollTo("bottom");
|
cy.getByData("tournament-table-div").scrollTo("bottom");
|
||||||
cy.get("[data-cy='scroll-to-top-button']").click();
|
cy.getByData("scroll-to-top-button").click();
|
||||||
// cy.get("[data-cy='tournament-table-div']")
|
// cy.get("[data-cy='tournament-table-div']")
|
||||||
// .invoke("scrollTop")
|
// .invoke("scrollTop")
|
||||||
// .should("equal", 0);
|
// .should("equal", 0);
|
||||||
@@ -20,7 +20,7 @@ describe("Scroll to top button", () => {
|
|||||||
cy.viewport(600, 600);
|
cy.viewport(600, 600);
|
||||||
cy.scrollTo("bottom");
|
cy.scrollTo("bottom");
|
||||||
cy.window().its("scrollY").should("not.equal", 0);
|
cy.window().its("scrollY").should("not.equal", 0);
|
||||||
cy.get("[data-cy='scroll-to-top-button']").click();
|
cy.getByData("scroll-to-top-button").click();
|
||||||
cy.window().its("scrollY").should("equal", 0);
|
cy.window().its("scrollY").should("equal", 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 276 KiB |
@@ -1,3 +1,13 @@
|
|||||||
|
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" />
|
/// <reference types="cypress" />
|
||||||
// ***********************************************
|
// ***********************************************
|
||||||
// This example commands.ts shows you how to
|
// This example commands.ts shows you how to
|
||||||
@@ -34,4 +44,4 @@
|
|||||||
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|||||||
@@ -11,4 +11,4 @@
|
|||||||
<body>
|
<body>
|
||||||
<div data-cy-root></div>
|
<div data-cy-root></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user