import React, { act } from "react"; import { addDays, addMonths, addWeeks, addYears, endOfWeek, lastDayOfMonth, setDate, startOfWeek } from "date-fns"; import { grid, nextButton, dateButton, activeElement, previousButton } from "@/test/elements"; import { render } from "@/test/render"; import { user } from "@/test/user"; import { Keyboard } from "./Keyboard"; const today = new Date(2022, 5, 10); beforeAll(() => jest.setSystemTime(today)); afterAll(() => jest.useRealTimers()); describe.each(["ltr", "rtl"])("when text direction is %s", (dir: string) => { beforeEach(() => { render(); }); describe("when clicking the previous month button", () => { beforeEach(() => user.click(previousButton())); test("should display the previous month", () => { expect(grid("May 2022")).toBeInTheDocument(); }); }); describe("when clicking the next month button", () => { beforeEach(() => user.click(nextButton())); test("should display the next month", () => { expect(grid("July 2022")).toBeInTheDocument(); }); }); describe("when the first day is focused", () => { const day = setDate(today, 1); const nextDay = addDays(day, 1); const prevDay = addDays(day, -1); const nextMonth = addMonths(day, 1); const prevMonth = addMonths(day, -1); const nextYear = addYears(day, 1); const prevYear = addYears(day, -1); const prevWeekDay = addWeeks(day, -1); const nextWeekDay = addWeeks(day, 1); const startOfWeekDay = startOfWeek(day); const endOfWeekDay = endOfWeek(day); beforeEach(() => act(() => dateButton(day).focus())); test("the day button should be focused", () => { expect(activeElement()).toBe(dateButton(day)); }); describe("when the Arrow Left is pressed", () => { beforeEach(() => user.type(activeElement(), "{arrowleft}")); if (dir === "rtl") { test("should focus the next day", () => { expect(dateButton(nextDay)).toHaveFocus(); }); } else { test("should display the previous month", () => { expect(grid("May 2022")).toBeInTheDocument(); }); test("should focus the previous day", () => { expect(dateButton(prevDay)).toHaveFocus(); }); } }); describe("when the Arrow Right is pressed", () => { beforeEach(() => user.type(activeElement(), "{arrowright}")); if (dir === "rtl") { test("should display the previous month", () => { expect(grid("May 2022")).toBeInTheDocument(); }); test("should focus the previous day", () => { expect(dateButton(prevDay)).toHaveFocus(); }); } else { test("should focus the next day", () => { expect(dateButton(nextDay)).toHaveFocus(); }); } }); describe("when the Arrow Up is pressed", () => { beforeEach(() => user.type(activeElement(), "{arrowup}")); test("should display the previous month", () => { expect(grid("May 2022")).toBeInTheDocument(); }); test("should focus the day in the previous week", () => { expect(dateButton(prevWeekDay)).toHaveFocus(); }); }); describe("when the Arrow Down is pressed", () => { beforeEach(() => user.type(activeElement(), "{arrowdown}")); test("should display the same month", () => { expect(grid("June 2022")).toBeInTheDocument(); }); test("should focus the day in the next week", () => { expect(dateButton(nextWeekDay)).toHaveFocus(); }); }); describe("when Page Up is pressed", () => { beforeEach(() => { return user.type(activeElement(), "{pageup}"); }); it("should display the previous month", () => { expect(grid("May 2022")).toBeInTheDocument(); }); it("should focus the day in the previous month", () => { expect(dateButton(prevMonth)).toHaveFocus(); }); }); describe("when Page Down is pressed", () => { beforeEach(() => user.type(activeElement(), "{pagedown}")); it("should display the next month", () => { expect(grid("July 2022")).toBeInTheDocument(); }); it("should focus the day in the next month", () => { expect(dateButton(nextMonth)).toHaveFocus(); }); }); describe("when Shift + Page Up is pressed", () => { beforeEach(() => user.type(activeElement(), "{shift>}{pageup}")); it("should display the previous year", () => { expect(grid("June 2021")).toBeInTheDocument(); }); it("should focus the day in the previous year", () => { expect(dateButton(prevYear)).toHaveFocus(); }); }); describe("when Shift + Page Down is pressed", () => { beforeEach(() => { return user.type(activeElement(), "{shift>}{pagedown}"); }); it("should display the next year", () => { expect(grid("June 2023")).toBeInTheDocument(); }); it("should focus the day in the next yeaer", () => { expect(dateButton(nextYear)).toHaveFocus(); }); }); describe("when Home is pressed", () => { beforeEach(() => user.type(activeElement(), "{home}")); it("should focus the start of the week", () => { expect(dateButton(startOfWeekDay)).toHaveFocus(); }); }); describe("when End is pressed", () => { beforeEach(() => user.type(activeElement(), "{end}")); it("should focus the end of the week", () => { expect(dateButton(endOfWeekDay)).toHaveFocus(); }); }); }); describe("when the last day is focused", () => { const day = lastDayOfMonth(today); const nextDay = addDays(day, 1); const prevDay = addDays(day, -1); beforeEach(() => { return act(() => dateButton(day).focus()); }); describe("when the Arrow Right is pressed", () => { beforeEach(() => user.type(activeElement(), "{arrowright}")); if (dir === "rtl") { test("should focus the previous day", () => { expect(dateButton(prevDay)).toHaveFocus(); }); } else { test("should display the next month", () => { expect(grid("July 2022")).toBeInTheDocument(); }); test("should focus the next day", () => { const nextDay = addDays(day, 1); expect(dateButton(nextDay)).toHaveFocus(); }); } }); describe("when the Arrow Left is pressed", () => { beforeEach(() => user.type(activeElement(), "{arrowleft}")); if (dir === "rtl") { test("should display the next month", () => { expect(grid("July 2022")).toBeInTheDocument(); }); test("should focus the next day", () => { expect(dateButton(nextDay)).toHaveFocus(); }); } else { test("should display the same month", () => { expect(grid("June 2022")).toBeInTheDocument(); }); test("should focus the previous day", () => { const prevDay = addDays(day, -1); expect(dateButton(prevDay)).toHaveFocus(); }); } }); describe("when the Arrow Up is pressed", () => { beforeEach(() => user.type(activeElement(), "{arrowup}")); test("should display the same month", () => { expect(grid("June 2022")).toBeInTheDocument(); }); test("should focus the day in the previous week", () => { const prevDay = addWeeks(day, -1); expect(dateButton(prevDay)).toHaveFocus(); }); }); describe("when the Arrow Down is pressed", () => { beforeEach(() => user.type(activeElement(), "{arrowdown}")); test("should display the next month", () => { expect(grid("July 2022")).toBeInTheDocument(); }); test("should focus the day in the next week", () => { const nextDay = addWeeks(day, 1); expect(dateButton(nextDay)).toHaveFocus(); }); }); }); }); describe("when week is set to start on a Monday", () => { const day = setDate(today, 10); const startOfWeekDay = startOfWeek(day, { weekStartsOn: 1 }); const endOfWeekDay = endOfWeek(day, { weekStartsOn: 1 }); beforeEach(() => { render(); act(() => dateButton(day).focus()); }); describe("when Home is pressed", () => { beforeEach(() => user.type(activeElement(), "{home}")); it("should focus the start of the week being Monday", () => { expect(dateButton(startOfWeekDay)).toHaveFocus(); }); }); describe("when End is pressed", () => { beforeEach(() => user.type(activeElement(), "{end}")); it("should focus the end of the week being Sunday", () => { expect(dateButton(endOfWeekDay)).toHaveFocus(); }); }); });