diff --git a/frontend/src/components/plexCards.dom.test.tsx b/frontend/src/components/plexCards.dom.test.tsx new file mode 100644 index 00000000..20261d36 --- /dev/null +++ b/frontend/src/components/plexCards.dom.test.tsx @@ -0,0 +1,82 @@ +// @vitest-environment jsdom +// +// Plex card a11y: locks the accessible names on the icon-only card controls (the E4 a11y sweep). These +// buttons are icon-only (WatchedIcon / Info / ListPlus, no text), so their name comes solely from the +// aria-label — a dropped label silently reintroduces an unnamed button for screen-reader users. i18n is +// key-passthrough, so the asserted names are the i18n keys. +import { describe, it, expect, afterEach, vi } from "vitest"; +import { render, screen, cleanup } from "@testing-library/react"; + +vi.mock("react-i18next", async (importOriginal) => { + const actual = await importOriginal(); + return { ...actual, useTranslation: () => ({ t: (key: string) => key }) }; +}); + +import { PlexPosterCard, SeasonCard, EpisodeCard } from "./plexCards"; +import type { PlexCard, PlexSeasonDetail } from "../lib/api"; + +const movie = (status?: string): PlexCard => ({ + id: "1", + type: "movie", + title: "M", + thumb: "", + status, +}); +const episode = (status?: string): PlexCard => ({ + id: "e1", + type: "episode", + title: "E1", + thumb: "", + status, +}); +const season = (status = "new"): PlexSeasonDetail => ({ + id: "s1", + season_number: 1, + title: "S1", + thumb: "", + episode_count: 3, + status, + episodes: [], +}); + +afterEach(cleanup); + +describe("PlexPosterCard a11y", () => { + it("names the watched-toggle (mark-watched when unwatched) and the info button", () => { + render( + , + ); + expect(screen.getByRole("button", { name: "plex.markWatched" })).toBeTruthy(); + expect(screen.getByRole("button", { name: "plex.info.title" })).toBeTruthy(); + }); + + it("names the watched-toggle as mark-unwatched when the movie is watched", () => { + render( + , + ); + expect(screen.getByRole("button", { name: "plex.markUnwatched" })).toBeTruthy(); + }); +}); + +describe("SeasonCard a11y", () => { + it("names the watched-toggle and the add-season button", () => { + render(); + expect(screen.getByRole("button", { name: "plex.series.markSeasonWatched" })).toBeTruthy(); + expect(screen.getByRole("button", { name: "plex.playlist.addSeason" })).toBeTruthy(); + }); +}); + +describe("EpisodeCard a11y", () => { + it("names the watched-toggle and the add-episode button", () => { + render( + , + ); + expect(screen.getByRole("button", { name: "plex.markWatched" })).toBeTruthy(); + expect(screen.getByRole("button", { name: "plex.playlist.addEpisode" })).toBeTruthy(); + }); +});