fix(navegacao): foco em âncora de outra página, vitrine acessível e 3D mais leve
Foco cai no destino ao chegar de outra página; âncoras ignoram ?tipo=; movimento reduzido salta em todos os cliques; cronômetro da janela ampliada; degradê no topo de Projetos e legendas do mergulho com intervalos testados; vitrine acima da barra de cookies e com 2 paradas por projeto; reel-list.css no global; 3D montado em tarefas curtas, limitado a ~30 qps e estático com WebGL por software; pôsteres da vitrine de 330 para 158 KB; SC Plus regravado; scripts sem funções acima de complexidade 10.
This commit is contained in:
1 parent
9e2d65a926
commit
204ebd5fa5
49 files changed
+2197
-606
No files matched your search
@@ -0,0 +1,99 @@
|
||||
import { act, render } from "@testing-library/react";
|
||||
import HeroFieldScene from "./HeroFieldScene";
|
||||
|
||||
/**
|
||||
* Caminho-base de mountField que HeroFieldScene.test.tsx não exerce: o erro que vem ANTES de as peças existirem
|
||||
* (a nuvem de pontos ou a câmera não se criam). O renderizador já abriu o contexto WebGL, então precisa ser solto
|
||||
* (`disposeRenderer`, o `else` do `catch`), o canvas sai da página e a página é avisada. Os outros caminhos de
|
||||
* mountField (desmontada antes da 1ª tarefa, entre o renderizador e as peças, durante a compilação, shader que não
|
||||
* compila, sucesso) estão em HeroFieldScene.test.tsx.
|
||||
*/
|
||||
|
||||
const mockRenderers: MockRenderer[] = [];
|
||||
let mockBuildThrows = false;
|
||||
|
||||
class MockRenderer {
|
||||
domElement = document.createElement("canvas");
|
||||
render = jest.fn();
|
||||
compileAsync = jest.fn(() => Promise.resolve());
|
||||
dispose = jest.fn();
|
||||
forceContextLoss = jest.fn();
|
||||
setSize = jest.fn();
|
||||
setPixelRatio = jest.fn();
|
||||
getPixelRatio = () => 1;
|
||||
constructor() {
|
||||
mockRenderers.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
jest.mock("three", () => {
|
||||
const actual = jest.requireActual("three");
|
||||
class FailingCamera extends actual.PerspectiveCamera {
|
||||
constructor(...args: unknown[]) {
|
||||
if (mockBuildThrows) throw new Error("sem memória para a cena");
|
||||
super(...args);
|
||||
}
|
||||
}
|
||||
return {
|
||||
...actual,
|
||||
PerspectiveCamera: FailingCamera,
|
||||
WebGLRenderer: jest.fn(() => new MockRenderer()),
|
||||
};
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
mockRenderers.length = 0;
|
||||
mockBuildThrows = false;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
const props = () => ({
|
||||
progressRef: { current: 0 },
|
||||
visible: false,
|
||||
onReady: jest.fn(),
|
||||
onError: jest.fn(),
|
||||
});
|
||||
|
||||
const buildScene = () =>
|
||||
act(async () => {
|
||||
await jest.advanceTimersByTimeAsync(10);
|
||||
});
|
||||
|
||||
describe("mountField: erro antes de as peças existirem", () => {
|
||||
it("path: the scene parts fail to build -> the renderer opened a moment ago is released, the canvas leaves and the page is told once", async () => {
|
||||
mockBuildThrows = true;
|
||||
const scene = props();
|
||||
|
||||
const { container } = render(<HeroFieldScene {...scene} />);
|
||||
await buildScene();
|
||||
|
||||
expect(mockRenderers).toHaveLength(1);
|
||||
expect(mockRenderers[0].compileAsync).not.toHaveBeenCalled();
|
||||
expect(mockRenderers[0].dispose).toHaveBeenCalledTimes(1);
|
||||
expect(mockRenderers[0].forceContextLoss).toHaveBeenCalledTimes(1);
|
||||
expect(mockRenderers[0].domElement.isConnected).toBe(false);
|
||||
expect(container.querySelector("canvas")).toBeNull();
|
||||
expect(scene.onError).toHaveBeenCalledTimes(1);
|
||||
expect(scene.onReady).not.toHaveBeenCalled();
|
||||
expect(jest.getTimerCount()).toBe(0);
|
||||
});
|
||||
|
||||
it("path: nothing fails -> the same setup mounts, draws and is released only on unmount (the control for the case above)", async () => {
|
||||
const scene = props();
|
||||
|
||||
const { container, unmount } = render(<HeroFieldScene {...scene} />);
|
||||
await buildScene();
|
||||
|
||||
expect(mockRenderers[0].compileAsync).toHaveBeenCalledTimes(1);
|
||||
expect(mockRenderers[0].dispose).not.toHaveBeenCalled();
|
||||
expect(container.querySelector("canvas")).not.toBeNull();
|
||||
expect(scene.onError).not.toHaveBeenCalled();
|
||||
|
||||
unmount();
|
||||
expect(mockRenderers[0].dispose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user