CI / verify (push) Failing after 5m29s
Estado do disco em 14/10/2026, sem filtrar. Inclui as copias .sync-conflict-* do Syncthing de 07/10 e os 15 arquivos que o Syncthing apagou; todo esse conteudo ja existia em outros commits. So havia fora do Git: AGENTS.md, CLAUDE.md e a alteracao em data/project-health.json.
104 lines
3.5 KiB
TypeScript
104 lines
3.5 KiB
TypeScript
import { fireEvent, render, screen } from "@testing-library/react";
|
|
import FilmGrain from "./FilmGrain";
|
|
import ScrollVelocityText from "./ScrollVelocityText";
|
|
import SectionDivider from "./SectionDivider";
|
|
|
|
function mockReducedMotion(matches: boolean) {
|
|
Object.defineProperty(window, "matchMedia", {
|
|
writable: true,
|
|
value: jest.fn().mockImplementation((query: string) => ({
|
|
matches: query.includes("prefers-reduced-motion") ? matches : false,
|
|
media: query,
|
|
onchange: null,
|
|
addListener: jest.fn(),
|
|
removeListener: jest.fn(),
|
|
addEventListener: jest.fn(),
|
|
removeEventListener: jest.fn(),
|
|
dispatchEvent: jest.fn(),
|
|
})),
|
|
});
|
|
}
|
|
|
|
describe("static cinematic effects", () => {
|
|
beforeEach(() => mockReducedMotion(false));
|
|
|
|
it("renders grain and every divider without a canvas", () => {
|
|
const grain = render(<FilmGrain />);
|
|
expect(grain.container.firstElementChild).toHaveAttribute(
|
|
"aria-hidden",
|
|
"true",
|
|
);
|
|
expect(grain.container.querySelector("canvas")).not.toBeInTheDocument();
|
|
grain.unmount();
|
|
|
|
for (const variant of ["gradient", "pulse", "waveform"] as const) {
|
|
const divider = render(<SectionDivider variant={variant} />);
|
|
expect(divider.container.firstElementChild).toHaveAttribute(
|
|
"aria-hidden",
|
|
"true",
|
|
);
|
|
expect(divider.container.querySelector("canvas")).not.toBeInTheDocument();
|
|
expect(divider.container.firstElementChild).not.toHaveAttribute(
|
|
"tabindex",
|
|
);
|
|
divider.unmount();
|
|
}
|
|
});
|
|
|
|
it("exposes a persistent pause control for an automatic marquee", () => {
|
|
render(<ScrollVelocityText text="SOFTWARE ENGINEERING" direction="left" />);
|
|
|
|
const pause = screen.getByRole("button", { name: "Pausar animação" });
|
|
const track = document.getElementById(
|
|
pause.getAttribute("aria-controls") ?? "",
|
|
);
|
|
expect(pause).toHaveAttribute("aria-pressed", "false");
|
|
expect(track).not.toHaveStyle({ animationPlayState: "paused" });
|
|
expect(
|
|
screen.getByText("SOFTWARE ENGINEERING", {
|
|
selector: '[aria-hidden="false"]',
|
|
}),
|
|
).toBeVisible();
|
|
expect(screen.getAllByText("SOFTWARE ENGINEERING")).toHaveLength(2);
|
|
expect(
|
|
screen
|
|
.getAllByText("SOFTWARE ENGINEERING")
|
|
.slice(1)
|
|
.every((copy) => copy.getAttribute("aria-hidden") === "true"),
|
|
).toBe(true);
|
|
|
|
fireEvent.click(pause);
|
|
|
|
const resume = screen.getByRole("button", { name: "Retomar animação" });
|
|
expect(resume).toHaveAttribute("aria-pressed", "true");
|
|
expect(track).toHaveStyle({ animationPlayState: "paused" });
|
|
|
|
fireEvent.click(resume);
|
|
expect(
|
|
screen.getByRole("button", { name: "Pausar animação" }),
|
|
).toHaveAttribute("aria-pressed", "false");
|
|
expect(track).not.toHaveStyle({ animationPlayState: "paused" });
|
|
});
|
|
|
|
it("starts static under reduced motion without a redundant control", () => {
|
|
mockReducedMotion(true);
|
|
render(<ScrollVelocityText text="VAMOS CONVERSAR" direction="right" />);
|
|
|
|
expect(
|
|
screen.queryByRole("button", { name: /animação/i }),
|
|
).not.toBeInTheDocument();
|
|
const copies = screen.getAllByText("VAMOS CONVERSAR");
|
|
expect(copies).toHaveLength(2);
|
|
expect(copies[0]).toBeVisible();
|
|
expect(copies[0]).toHaveAttribute("aria-hidden", "false");
|
|
expect(copies[0].closest("[style]")).toHaveStyle({
|
|
animationPlayState: "paused",
|
|
});
|
|
expect(
|
|
copies
|
|
.slice(1)
|
|
.every((copy) => copy.getAttribute("aria-hidden") === "true"),
|
|
).toBe(true);
|
|
});
|
|
});
|