sasalatart/on-this-day

View on GitHub
packages/client/cypress/integration/episodes-timeline-spec.ts

Summary

Maintainability
A
0 mins
Test Coverage
/// <reference types="cypress" />
import upperFirst from 'lodash/upperFirst';
import { EpisodeKind } from '@on-this-day/shared';

function assertChronologicalEpisodes(): void {
  let firstYear: number;

  cy.get('.vertical-timeline-element-content')
    .first()
    .find('p')
    .should('exist');

  cy.get('.vertical-timeline-element-date')
    .first()
    .then(($year) => {
      firstYear = +$year.text();
      // eslint-disable-next-line @typescript-eslint/no-unused-expressions
      expect($year).not.to.be.NaN;
    });

  cy.scrollTo('bottom');

  cy.get('.vertical-timeline-element-date')
    .last()
    .then(($year) => {
      const lastYear = +$year.text();
      // eslint-disable-next-line @typescript-eslint/no-unused-expressions
      expect($year).not.to.be.NaN;
      expect(firstYear).not.to.equal(lastYear);
      expect(firstYear).to.be.lessThan(lastYear);
    });
}

function assertRootRedirectionWithAlert(query: string): void {
  cy.visit(`/year-date${query}`);
  cy.location('pathname').should('equal', '/');
  cy.get('#swal2-content').should('contain.text', 'Invalid date');
}

describe('Episodes Timeline', () => {
  context('when URL has invalid query params', () => {
    context('when day is not present in the query param', () => {
      it('redirects to the root dir and alerts', () => {
        assertRootRedirectionWithAlert('?month=1');
      });
    });

    context('when month is not present in the query param', () => {
      it('redirects to the root dir and alerts', () => {
        assertRootRedirectionWithAlert('?day=1');
      });
    });

    context('when month nor day are present as query params', () => {
      it('redirects to the root dir and alerts', () => {
        assertRootRedirectionWithAlert('');
      });
    });

    context('when day and month do not form a valid date', () => {
      it('redirects to the root dir and alerts', () => {
        assertRootRedirectionWithAlert('?day=30&month=2');
      });
    });
  });

  context('When URL has a valid date', () => {
    const day = 15;
    const month = 1;

    before(() => {
      cy.visit(`/year-date?day=${day}&month=${month}`);
    });

    it('specifies the selected date', () => {
      cy.get('#timeline-subtitle').should('have.text', 'January 15');
    });

    describe('description', () => {
      it('has a proper name', () => {
        cy.get('#timeline-description').should('have.text', 'Description');
      });

      it('starts as not expanded, but expands when clicked', () => {
        cy.get('#timeline-description')
          .parent()
          .parent()
          .should('have.attr', 'aria-expanded', 'false')
          .click()
          .should('have.attr', 'aria-expanded', 'true');
      });
    });

    describe('initial tab', () => {
      it('corresponds to events', () => {
        cy.get(`button[role="tab"][data-kind=${EpisodeKind.events}]`).should(
          'have.attr',
          'aria-selected',
          'true',
        );
      });

      it("makes the title's text be 'Events'", () => {
        cy.get('#timeline-title').should(
          'have.text',
          upperFirst(EpisodeKind.events),
        );
      });

      it('displays events chronologically sorted', () => {
        assertChronologicalEpisodes();
      });
    });

    describe('clicking tabs', () => {
      Object.values(EpisodeKind).forEach((episodeKind) => {
        context(`when clicking on ${episodeKind}`, () => {
          it('sets it as selected', () => {
            cy.get(`button[role="tab"][data-kind="${episodeKind}"]`)
              .click()
              .should('have.attr', 'aria-selected', 'true');
          });

          it("changes the title's text", () => {
            cy.get('#timeline-title').should(
              'have.text',
              upperFirst(episodeKind),
            );
          });

          it('displays events chronologically sorted', () => {
            assertChronologicalEpisodes();
          });
        });
      });
    });
  });
});