Files
siftlode/frontend/src/components/ui/BackToTop.dom.test.tsx
T
peter 5ebb4cb506 fix(a11y): chips, grips, the panel tab and Back to top keep the focus somewhere real
- F5: a chip's × pressed from the keyboard hands the focus to the next chip (else the previous one,
  else what follows) before it unmounts — in DismissibleChip, so all five chip rows get it
  (`focusNeighbour` in lib/useFocusKeeper).
- F4: a drag grip names what it lifts (`common.order.dragNamed`: panel groups, personal views);
  the two generic "Drag to reorder" keys are gone.
- F6: the side panel's edge tab is out of the Tab order while the card covers it, names its panel,
  and a keyboard pin moves the focus into the card.
- F7: Back to top is no Tab stop while hidden, and a keyboard press leaves the focus on the page.
2026-09-27 15:01:22 +02:00

40 lines
1.3 KiB
TypeScript

// @vitest-environment jsdom
//
// E28 review F7: while hidden the button only went transparent — a Tab still landed on the invisible
// control. And a keyboard press scrolled to the top and hid it with the focus still on it.
import { afterEach, describe, expect, it, vi } from "vitest";
import { act, cleanup, fireEvent, render, screen } from "@testing-library/react";
vi.mock("react-i18next", async (importOriginal) => ({
...(await importOriginal<typeof import("react-i18next")>()),
useTranslation: () => ({ t: (k: string) => k }),
}));
import BackToTop from "./BackToTop";
afterEach(cleanup);
function scrolled(main: HTMLElement, top: number) {
main.scrollTop = top;
act(() => void main.dispatchEvent(new Event("scroll")));
}
describe("BackToTop", () => {
it("is no Tab stop while hidden; a keyboard press leaves the focus on the page", () => {
const main = document.createElement("main");
main.tabIndex = -1;
main.scrollTo = vi.fn();
document.body.appendChild(main);
render(<BackToTop />);
const btn = screen.getByText("common.backToTop").closest("button")!;
expect(btn.tabIndex).toBe(-1);
scrolled(main, 900);
expect(btn.tabIndex).toBe(0);
btn.focus();
fireEvent.click(btn, { detail: 0 });
expect(main.scrollTo).toHaveBeenCalled();
expect(document.activeElement).toBe(main);
main.remove();
});
});