perf(movimento): sem tela vazia, passagens em CSS e vitrine leve
Projetos sobem sobre o palco do hero e o celular tem hero de uma tela sem mergulho; passagens com animation-timeline em CSS, sem GSAP nem motion; troca da vitrine sem texto duplicado; moldura de celular só com pôster e scrub reencodado em 960 px (9,4 para 5,2 MB); 3D monta na primeira interação e para quando parado; transição entre páginas do mesmo segmento; foco em anel duplo; texto de 15 px no celular; código morto removido.
This commit is contained in:
1 parent
10f170abf4
commit
318a764190
77 files changed
+4293
-4951
No files matched your search
@@ -0,0 +1,102 @@
|
||||
import { act, render, screen } from "@testing-library/react";
|
||||
import CinematicOverlays from "./CinematicOverlays";
|
||||
|
||||
let mockPathname = "/";
|
||||
jest.mock("next/navigation", () => ({ usePathname: () => mockPathname }));
|
||||
|
||||
// o grão vem por import dinâmico (pacote próprio): aqui ele vira um marcador, e o contador diz se o pacote foi pedido
|
||||
const mockLoaded = jest.fn();
|
||||
jest.mock("./FilmGrain", () => {
|
||||
mockLoaded();
|
||||
return {
|
||||
__esModule: true,
|
||||
default: function MockGrain() {
|
||||
return <div data-testid="grain" />;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
/** O import dinâmico do grão resolve em microtarefas. */
|
||||
const loaded = () =>
|
||||
act(async () => {
|
||||
for (let i = 0; i < 5; i++) await Promise.resolve();
|
||||
});
|
||||
|
||||
const original = window.matchMedia;
|
||||
|
||||
function mockMedia(active: string[] = []) {
|
||||
window.matchMedia = jest.fn().mockImplementation((query: string) => ({
|
||||
matches: active.includes(query),
|
||||
media: query,
|
||||
addEventListener() {},
|
||||
removeEventListener() {},
|
||||
}));
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
mockPathname = "/";
|
||||
mockMedia();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
window.matchMedia = original;
|
||||
});
|
||||
|
||||
/*
|
||||
* Os três primeiros testes vêm antes de qualquer um que carregue o grão: o módulo, depois de pedido uma vez, fica
|
||||
* no registro do Jest, então "o pacote nunca foi pedido" só vale enquanto ninguém o pediu.
|
||||
*/
|
||||
describe("CinematicOverlays: where the grain package is never requested", () => {
|
||||
it("does not request the grain on a touch screen (nothing invisible left measuring the page); the progress bar stays", async () => {
|
||||
mockMedia(["(pointer: coarse)"]);
|
||||
const { container } = render(<CinematicOverlays />);
|
||||
await loaded();
|
||||
|
||||
expect(mockLoaded).not.toHaveBeenCalled();
|
||||
expect(screen.queryByTestId("grain")).toBeNull();
|
||||
// a barra de progresso é CSS puro: continua
|
||||
expect(container.querySelector(".ds-scroll-bar")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not request the grain for users who prefer reduced motion", async () => {
|
||||
mockMedia(["(prefers-reduced-motion: reduce)"]);
|
||||
render(<CinematicOverlays />);
|
||||
await loaded();
|
||||
|
||||
expect(mockLoaded).not.toHaveBeenCalled();
|
||||
expect(screen.queryByTestId("grain")).toBeNull();
|
||||
});
|
||||
|
||||
it("shows nothing, and requests nothing, on the other pages", async () => {
|
||||
mockPathname = "/cases";
|
||||
const { container } = render(<CinematicOverlays />);
|
||||
await loaded();
|
||||
|
||||
expect(mockLoaded).not.toHaveBeenCalled();
|
||||
expect(screen.queryByTestId("grain")).toBeNull();
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
});
|
||||
|
||||
describe("CinematicOverlays: with a mouse", () => {
|
||||
it("shows the scroll progress at once and the film grain as soon as its package arrives", async () => {
|
||||
const { container } = render(<CinematicOverlays />);
|
||||
|
||||
// a barra vem no HTML; o grão só depois do import
|
||||
expect(container.querySelector(".ds-scroll-bar")).toBeInTheDocument();
|
||||
expect(screen.queryByTestId("grain")).toBeNull();
|
||||
|
||||
await loaded();
|
||||
expect(screen.getByTestId("grain")).toBeInTheDocument();
|
||||
expect(mockLoaded).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not mount the grain if the page unmounts while its package loads", async () => {
|
||||
const { unmount } = render(<CinematicOverlays />);
|
||||
unmount();
|
||||
|
||||
await loaded();
|
||||
|
||||
expect(screen.queryByTestId("grain")).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user