diff options
Diffstat (limited to 'tests/cypress/e2e')
| -rw-r--r-- | tests/cypress/e2e/back-to-top.cy.ts | 14 | ||||
| -rw-r--r-- | tests/cypress/e2e/nav.cy.ts | 74 | ||||
| -rw-r--r-- | tests/cypress/e2e/pages/blog.cy.ts | 44 | ||||
| -rw-r--r-- | tests/cypress/e2e/pages/contact.cy.ts | 41 | ||||
| -rw-r--r-- | tests/cypress/e2e/pages/cv.cy.ts | 6 | ||||
| -rw-r--r-- | tests/cypress/e2e/pages/homepage.cy.ts | 9 | ||||
| -rw-r--r-- | tests/cypress/e2e/pages/legal-notice.cy.ts | 6 | ||||
| -rw-r--r-- | tests/cypress/e2e/pages/projects.cy.ts | 6 | ||||
| -rw-r--r-- | tests/cypress/e2e/search.cy.ts | 41 | ||||
| -rw-r--r-- | tests/cypress/e2e/settings.cy.ts | 177 | 
10 files changed, 418 insertions, 0 deletions
| diff --git a/tests/cypress/e2e/back-to-top.cy.ts b/tests/cypress/e2e/back-to-top.cy.ts new file mode 100644 index 0000000..06ac3e6 --- /dev/null +++ b/tests/cypress/e2e/back-to-top.cy.ts @@ -0,0 +1,14 @@ +describe('Back to top', () => { +  it('show a back to top button when scrolling', async () => { +    cy.visit('/'); +    cy.findByRole('link', { name: /Retour en haut de page/i }).should( +      'not.be.visible' +    ); + +    // See @components/templates/layout/layout.tsx for scroll position. +    cy.scrollTo(0, 300); +    cy.findByRole('link', { name: /Retour en haut de page/i }).should( +      'be.visible' +    ); +  }); +}); diff --git a/tests/cypress/e2e/nav.cy.ts b/tests/cypress/e2e/nav.cy.ts new file mode 100644 index 0000000..5851058 --- /dev/null +++ b/tests/cypress/e2e/nav.cy.ts @@ -0,0 +1,74 @@ +describe( +  'Main navigation', +  { viewportWidth: 1280, viewportHeight: 720 }, +  () => { +    beforeEach(() => { +      cy.visit('/'); +    }); + +    it( +      'should show hamburger button on small devices', +      { viewportWidth: 810, viewportHeight: 1080 }, +      () => { +        cy.findByLabelText(/Ouvrir le menu/i).should('exist'); +      } +    ); + +    it( +      'should open and close main nav menu by clicking on hamburger button', +      { viewportWidth: 810, viewportHeight: 1080 }, +      () => { +        cy.findByLabelText(/Fermer le menu/i).should('not.exist'); +        cy.findByRole('link', { name: /Blog/i }).should('not.exist'); +        cy.findByLabelText(/Ouvrir le menu/i).click(); +        cy.findByLabelText(/Ouvrir le menu/i).should('not.exist'); +        cy.findByLabelText(/Fermer le menu/i).should('exist'); +        cy.findByRole('link', { name: /Blog/i }).should('exist'); +        cy.findByLabelText(/Fermer le menu/i).click(); +        cy.findByLabelText(/Fermer le menu/i).should('not.exist'); +        cy.findByRole('link', { name: /Blog/i }).should('not.exist'); +        cy.findByLabelText(/Ouvrir le menu/i).should('exist'); +      } +    ); + +    it('should hide hamburger button on large devices', () => { +      cy.findByLabelText(/Ouvrir le menu/i).should('be.hidden'); +    }); + +    it('should navigate to the blog page', async () => { +      cy.findByRole('link', { name: /Blog/i }).click(); +      cy.url().should('include', '/blog'); +      cy.findByRole('heading', { level: 1 }).contains('Blog'); +    }); + +    it('should navigate to the CV page', async () => { +      cy.findByRole('link', { name: /CV/i }).click(); +      cy.url().should('include', '/cv'); +      cy.findByRole('heading', { level: 1 }).contains('CV'); +    }); + +    it('should navigate to the projects page', async () => { +      cy.findByRole('link', { name: /Projects/i }).click(); +      cy.url().should('include', '/projets'); +      cy.findByRole('heading', { level: 1 }).contains('Projets'); +    }); + +    it('should navigate to the contact page', async () => { +      cy.findByRole('link', { name: /Contact/i }).click(); +      cy.url().should('include', '/contact'); +      cy.findByRole('heading', { level: 1 }).contains('Contact'); +    }); +  } +); + +describe('Footer navigation', () => { +  beforeEach(() => { +    cy.visit('/'); +  }); + +  it('should navigate to the legal notice page', async () => { +    cy.findByRole('link', { name: /Mentions légales/i }).click(); +    cy.url().should('include', '/mentions-legales'); +    cy.findByRole('heading', { level: 1 }).contains('Mentions légales'); +  }); +}); diff --git a/tests/cypress/e2e/pages/blog.cy.ts b/tests/cypress/e2e/pages/blog.cy.ts new file mode 100644 index 0000000..dedc0e4 --- /dev/null +++ b/tests/cypress/e2e/pages/blog.cy.ts @@ -0,0 +1,44 @@ +import { settings } from '@utils/config'; + +describe('Blog Page', () => { +  beforeEach(() => { +    cy.visit('/blog'); +  }); + +  it('loads the correct number of pages', () => { +    cy.findByText(/(\d+) articles chargés sur un total de (\d+)/i) +      .then(($div) => { +        type ArticlesGroup = { +          first: string; +          total: string; +        }; + +        const firstLastNumbers = /(?<first>\d+).*[\D](?<total>\d+)/; +        const result = $div.text().match(firstLastNumbers); +        expect(result).to.not.be.null; + +        const { first, total } = result!.groups as ArticlesGroup; +        const firstArticles = parseInt(first, 10); +        const totalArticles = parseInt(total, 10); +        expect(firstArticles).to.be.within(1, settings.postsPerPage); +        expect(totalArticles).to.be.at.least(1); + +        const totalPages = Math.ceil(totalArticles / settings.postsPerPage); +        const remainingPages = totalPages - 1; +        return Array.from({ length: remainingPages }, (_, i) => i + 1); +      }) +      .then((remainingPages) => { +        if (remainingPages.length >= 1) { +          cy.wrap(remainingPages).each(() => { +            cy.findByRole('button', { +              name: /Charger plus d’articles/i, +            }).click(); +          }); +        } + +        cy.findByRole('button', { name: /Charger plus d’articles/i }).should( +          'not.exist' +        ); +      }); +  }); +}); diff --git a/tests/cypress/e2e/pages/contact.cy.ts b/tests/cypress/e2e/pages/contact.cy.ts new file mode 100644 index 0000000..6e1cdb6 --- /dev/null +++ b/tests/cypress/e2e/pages/contact.cy.ts @@ -0,0 +1,41 @@ +const userName = 'Cypress Test'; +const userEmail = 'cypress@testing.com'; +const object = '[Cypress] quos aperiam culpa'; +const message = +  'Asperiores ea nihil. Nam ipsam est sunt porro. Ratione in facilis cum. Voluptatem pariatur rerum.'; + +describe('Contact Page', () => { +  beforeEach(() => { +    cy.visit('/contact'); +  }); + +  it('shows a heading and a contact form', () => { +    cy.findByRole('heading', { level: 1 }).contains(/Contact/i); +    cy.findByRole('form', { name: /Formulaire de contact/i }); +  }); + +  it('submits the form', async () => { +    cy.findByRole('textbox', { name: /Nom/i }) +      .type(userName) +      .should('have.value', userName); +    cy.findByRole('textbox', { name: /E-mail/i }) +      .type(userEmail) +      .should('have.value', userEmail); +    cy.findByRole('textbox', { name: /Sujet/i }) +      .type(object) +      .should('have.value', object); +    cy.findByRole('textbox', { name: /Message/i }) +      .type(message) +      .should('have.value', message); +    cy.findByRole('button', { name: /Envoyer/i }).click(); +    cy.findByText(/E-mail en cours d'envoi/i).should('be.visible'); +  }); + +  it('prevents the form to submit if some fields are missing', async () => { +    cy.findByRole('textbox', { name: /E-mail/i }) +      .type(userEmail) +      .should('have.value', userEmail); +    cy.findByRole('button', { name: /Envoyer/i }).click(); +    cy.findByText(/E-mail en cours d'envoi/i).should('not.be.visible'); +  }); +}); diff --git a/tests/cypress/e2e/pages/cv.cy.ts b/tests/cypress/e2e/pages/cv.cy.ts new file mode 100644 index 0000000..419a098 --- /dev/null +++ b/tests/cypress/e2e/pages/cv.cy.ts @@ -0,0 +1,6 @@ +describe('CV Page', () => { +  it('successfully loads', () => { +    cy.visit('/cv'); +    cy.findByRole('heading', { level: 1 }).contains('CV'); +  }); +}); diff --git a/tests/cypress/e2e/pages/homepage.cy.ts b/tests/cypress/e2e/pages/homepage.cy.ts new file mode 100644 index 0000000..52bfbc7 --- /dev/null +++ b/tests/cypress/e2e/pages/homepage.cy.ts @@ -0,0 +1,9 @@ +import { settings } from '@utils/config'; + +describe('HomePage', () => { +  it('successfully loads', () => { +    cy.visit('/'); +    cy.findByRole('heading', { level: 1 }).contains(settings.name); +    cy.findByText(settings.baseline.fr).should('exist'); +  }); +}); diff --git a/tests/cypress/e2e/pages/legal-notice.cy.ts b/tests/cypress/e2e/pages/legal-notice.cy.ts new file mode 100644 index 0000000..f338a7a --- /dev/null +++ b/tests/cypress/e2e/pages/legal-notice.cy.ts @@ -0,0 +1,6 @@ +describe('Legal Notice Page', () => { +  it('successfully loads', () => { +    cy.visit('/mentions-legales'); +    cy.findByRole('heading', { level: 1 }).contains('Mentions légales'); +  }); +}); diff --git a/tests/cypress/e2e/pages/projects.cy.ts b/tests/cypress/e2e/pages/projects.cy.ts new file mode 100644 index 0000000..b477400 --- /dev/null +++ b/tests/cypress/e2e/pages/projects.cy.ts @@ -0,0 +1,6 @@ +describe('Projects Page', () => { +  it('successfully loads', () => { +    cy.visit('/projets'); +    cy.findByRole('heading', { level: 1 }).contains('Projets'); +  }); +}); diff --git a/tests/cypress/e2e/search.cy.ts b/tests/cypress/e2e/search.cy.ts new file mode 100644 index 0000000..f105a5c --- /dev/null +++ b/tests/cypress/e2e/search.cy.ts @@ -0,0 +1,41 @@ +const queryWithArticles = 'Coldark'; +const queryWithoutArticles = 'etEtRerum'; + +describe('Search', () => { +  it('should open and close search form by clicking on search button', () => { +    cy.visit('/'); +    cy.findByLabelText(/Fermer la recherche/i).should('not.exist'); +    cy.findByRole('searchbox', { name: /Rechercher/i }).should('not.exist'); +    cy.findByLabelText(/Ouvrir la recherche/i).click(); +    cy.findByLabelText(/Ouvrir la recherche/i).should('not.exist'); +    cy.findByLabelText(/Fermer la recherche/i).should('exist'); +    cy.findByRole('searchbox', { name: /Rechercher/i }).should('exist'); +    cy.findByLabelText(/Fermer la recherche/i).click(); +    cy.findByLabelText(/Fermer la recherche/i).should('not.exist'); +    cy.findByRole('searchbox', { name: /Rechercher/i }).should('not.exist'); +    cy.findByLabelText(/Ouvrir la recherche/i).should('exist'); +  }); + +  it('should navigate the search page', async () => { +    cy.visit('/'); +    cy.findByLabelText(/Ouvrir la recherche/i).click(); +    cy.findByRole('searchbox', { name: /Rechercher/i }).type( +      `${queryWithArticles}{enter}` +    ); +    cy.url().should('include', '/blog'); +    cy.findByRole('heading', { level: 1 }).contains( +      /Résultats de la recherche pour/i +    ); +  }); + +  it('should display the total of articles if successful', async () => { +    cy.visit(`/recherche?s=${encodeURIComponent(queryWithArticles)}`); +    const dtSiblings = cy.findByRole('term', { name: /Total/i }).siblings(); +    dtSiblings.findByRole('definition').contains(/article/i); +  }); + +  it('should display a search form if unsuccessful', () => { +    cy.visit(`/recherche?s=${encodeURIComponent(queryWithoutArticles)}`); +    cy.findByRole('searchbox', { name: /Rechercher/i }).should('exist'); +  }); +}); diff --git a/tests/cypress/e2e/settings.cy.ts b/tests/cypress/e2e/settings.cy.ts new file mode 100644 index 0000000..abdbcdf --- /dev/null +++ b/tests/cypress/e2e/settings.cy.ts @@ -0,0 +1,177 @@ +describe('Settings', () => { +  beforeEach(() => { +    cy.visit('/'); +  }); + +  it('should open and close a settings menu by clicking on a button', () => { +    cy.findByLabelText(/Fermer les réglages/i).should('not.exist'); +    cy.findByLabelText(/Ouvrir les réglages/i).click(); +    cy.findByLabelText(/Ouvrir les réglages/i).should('not.exist'); +    cy.findByLabelText(/Fermer les réglages/i).click(); +    cy.findByLabelText(/Fermer les réglages/i).should('not.exist'); +    cy.findByLabelText(/Ouvrir les réglages/i).should('exist'); +  }); + +  it('should open and close a tooltip by clicking on a button', () => { +    cy.findByLabelText(/Ouvrir les réglages/i).click(); +    cy.findByText(/Ackee/).should('not.be.visible'); +    cy.findByRole('button', { name: /Aide/i }).click(); +    cy.findByText(/Ackee/).should('be.visible'); +    cy.findByRole('button', { name: /Aide/i }).click(); +    cy.findByText(/Ackee/).should('not.be.visible'); +  }); + +  it('should change the current theme', () => { +    cy.findByLabelText(/Ouvrir les réglages/i).click(); +    cy.findByRole('document') +      .parent() +      .then(($html) => { +        const initialTheme = $html.attr('data-theme'); + +        if (initialTheme === 'light') { +          cy.findByRole('radiogroup', { name: /Thème/i }) +            .findByRole('radio', { name: /Thème clair/i }) +            .should('be.checked'); +          cy.findByRole('radiogroup', { name: /Thème/i }) +            .findByRole('radio', { name: /Thème sombre/i }) +            .should('not.be.checked') +            .check({ force: true }) // because of label +            .should('be.checked'); +          cy.findByRole('radiogroup', { name: /Thème/i }) +            .findByRole('radio', { name: /Thème clair/i }) +            .should('not.be.checked'); +          cy.findByRole('document') +            .parent() +            .should('have.attr', 'data-theme', 'dark') +            .then(() => { +              expect(localStorage.getItem('theme')).to.eq('dark'); +            }); +        } else { +          cy.findByRole('radiogroup', { name: /Thème/i }) +            .findByRole('radio', { name: /Thème sombre/i }) +            .should('be.checked'); +          cy.findByRole('radiogroup', { name: /Thème/i }) +            .findByRole('radio', { name: /Thème clair/i }) +            .should('not.be.checked') +            .check({ force: true }) // because of label +            .should('be.checked'); +          cy.findByRole('radiogroup', { name: /Thème/i }) +            .findByRole('radio', { name: /Thème sombre/i }) +            .should('not.be.checked'); +          cy.findByRole('document') +            .parent() +            .should('have.attr', 'data-theme', 'light') +            .then(() => { +              expect(localStorage.getItem('theme')).to.eq('light'); +            }); +        } +      }); +  }); + +  it('should change the Prism theme', () => { +    cy.findByLabelText(/Ouvrir les réglages/i).click(); +    // We assume that the default theme is light theme. +    cy.findByRole('radiogroup', { name: /Blocs de code/i }) +      .findByRole('radio', { name: /Thème sombre/i }) +      .check({ force: true }) // because of label +      .should('be.checked') +      .then(() => { +        expect(localStorage.getItem('prismjs-color-scheme')).to.eq('"dark"'); +      }); +    cy.findByRole('radiogroup', { name: /Blocs de code/i }) +      .findByRole('radio', { name: /Thème clair/i }) +      .check({ force: true }) // because of label +      .should('be.checked') +      .then(() => { +        expect(localStorage.getItem('prismjs-color-scheme')).to.eq('"light"'); +      }); +  }); + +  it('should change the motion setting', () => { +    cy.findByLabelText(/Ouvrir les réglages/i).click(); +    cy.findByRole('document') +      .parent() +      .then(($html) => { +        const initialValue = $html.attr('data-reduced-motion'); + +        if (initialValue === 'false') { +          cy.findByRole('radiogroup', { name: /Animations/i }) +            .findByRole('radio', { name: /Marche/i }) +            .should('be.checked'); +          cy.findByRole('radiogroup', { name: /Animations/i }) +            .findByRole('radio', { name: /Arrêt/i }) +            .should('not.be.checked') +            .check({ force: true }) // because of label +            .should('be.checked'); +          cy.findByRole('radiogroup', { name: /Animations/i }) +            .findByRole('radio', { name: /Marche/i }) +            .should('not.be.checked'); +          cy.findByRole('document') +            .parent() +            .should('have.attr', 'data-reduced-motion', 'true') +            .then(() => { +              expect(localStorage.getItem('reduced-motion')).to.eq('true'); +            }); +        } else { +          cy.findByRole('radiogroup', { name: /Animations/i }) +            .findByRole('radio', { name: /Arrêt/i }) +            .should('be.checked'); +          cy.findByRole('radiogroup', { name: /Animations/i }) +            .findByRole('radio', { name: /Marche/i }) +            .should('not.be.checked') +            .check({ force: true }) // because of label +            .should('be.checked'); +          cy.findByRole('radiogroup', { name: /Animations/i }) +            .findByRole('radio', { name: /Arrêt/i }) +            .should('not.be.checked'); +          cy.findByRole('document') +            .parent() +            .should('have.attr', 'data-reduced-motion', 'true') +            .then(() => { +              expect(localStorage.getItem('reduced-motion')).to.eq('true'); +            }); +        } +      }); +  }); + +  it('should change the Ackee setting', () => { +    cy.findByLabelText(/Ouvrir les réglages/i) +      .click() +      .then(() => { +        const storedValue = localStorage.getItem('ackee-tracking'); +        const parsedStoredValue = storedValue ? JSON.parse(storedValue) : ''; + +        if (parsedStoredValue === 'full') { +          cy.findByRole('radio', { name: /Complet/i }).should('be.checked'); +          cy.findByRole('radio', { name: /Partiel/i }) +            .should('not.be.checked') +            .check({ force: true }) // because of label +            .should('be.checked'); +          cy.findByRole('radio', { name: /Complet/i }) +            .should('not.be.checked') +            .then(() => { +              const newStoredValue = localStorage.getItem('ackee-tracking'); +              const parsedNewStoredValue = newStoredValue +                ? JSON.parse(newStoredValue) +                : ''; +              expect(parsedNewStoredValue).to.eq('partial'); +            }); +        } else { +          cy.findByRole('radio', { name: /Partiel/i }).should('be.checked'); +          cy.findByRole('radio', { name: /Complet/i }) +            .should('not.be.checked') +            .check({ force: true }) // because of label +            .should('be.checked'); +          cy.findByRole('radio', { name: /Partiel/i }) +            .should('not.be.checked') +            .then(() => { +              const newStoredValue = localStorage.getItem('ackee-tracking'); +              const parsedNewStoredValue = newStoredValue +                ? JSON.parse(newStoredValue) +                : ''; +              expect(parsedNewStoredValue).to.eq('full'); +            }); +        } +      }); +  }); +}); | 
