feat(home): seção Sobre com prova por ponto, contato por oferta e hero com a Lavação 047 na tela larga
This commit is contained in:
1 parent
d356c364e0
commit
9fd1570426
33 files changed
+1128
-369
No files matched your search
@@ -0,0 +1,145 @@
|
||||
import { act, render, screen } from "@testing-library/react";
|
||||
import type { ReactNode } from "react";
|
||||
import Projects from "./Projects";
|
||||
|
||||
/**
|
||||
* "Ver os cases" na coluna dos botões da vitrine: na vitrine fixa o conjunto de aparelhos (`.ds-reel-set`, com a legenda
|
||||
* e os botões no canto esquerdo dele) fica centrado no palco, e esse canto muda com a altura da janela. Projects mede o
|
||||
* canto e dá ao bloco do link o mesmo recuo; sem vitrine fixa (celular, movimento reduzido) o recuo é zero.
|
||||
*/
|
||||
|
||||
jest.mock("next/link", () => ({
|
||||
__esModule: true,
|
||||
default: ({
|
||||
children,
|
||||
prefetch: _prefetch,
|
||||
...props
|
||||
}: { children?: ReactNode; prefetch?: boolean | null } & Record<
|
||||
string,
|
||||
unknown
|
||||
>) => <a {...props}>{children}</a>,
|
||||
}));
|
||||
|
||||
jest.mock("./Section", () => ({
|
||||
Section: ({ children, title }: { children: ReactNode; title: string }) => (
|
||||
<section>
|
||||
<h2>{title}</h2>
|
||||
{children}
|
||||
</section>
|
||||
),
|
||||
}));
|
||||
|
||||
jest.mock("./showcase/ShowcaseProvider", () => ({
|
||||
ShowcaseProvider: ({ children }: { children: ReactNode }) => <>{children}</>,
|
||||
}));
|
||||
|
||||
let pinned = true;
|
||||
jest.mock("./showcase/ProjectReel", () => ({
|
||||
ProjectReel: () => (pinned ? <div className="ds-reel-set" /> : <ul />),
|
||||
}));
|
||||
|
||||
/** Os cantos esquerdos que a página teria: o do bloco do link e o do conjunto de aparelhos. */
|
||||
const lefts = { exit: 100, set: 503 };
|
||||
|
||||
class FakeResizeObserver {
|
||||
static instances: FakeResizeObserver[] = [];
|
||||
observed = new Set<Element>();
|
||||
constructor(private readonly callback: () => void) {
|
||||
FakeResizeObserver.instances.push(this);
|
||||
}
|
||||
observe(target: Element) {
|
||||
this.observed.add(target);
|
||||
}
|
||||
unobserve(target: Element) {
|
||||
this.observed.delete(target);
|
||||
}
|
||||
disconnect() {
|
||||
this.observed.clear();
|
||||
}
|
||||
fire() {
|
||||
this.callback();
|
||||
}
|
||||
}
|
||||
|
||||
const originalRect = Element.prototype.getBoundingClientRect;
|
||||
const originalObserver = global.ResizeObserver;
|
||||
|
||||
beforeEach(() => {
|
||||
pinned = true;
|
||||
lefts.exit = 100;
|
||||
lefts.set = 503;
|
||||
FakeResizeObserver.instances = [];
|
||||
global.ResizeObserver =
|
||||
FakeResizeObserver as unknown as typeof ResizeObserver;
|
||||
Element.prototype.getBoundingClientRect = function rect(this: Element) {
|
||||
const left = this.classList.contains("ds-reel-set")
|
||||
? lefts.set
|
||||
: this.getAttribute("data-reel-stagger") === "left"
|
||||
? lefts.exit
|
||||
: 0;
|
||||
return {
|
||||
left,
|
||||
right: left,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
} as DOMRect;
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Element.prototype.getBoundingClientRect = originalRect;
|
||||
global.ResizeObserver = originalObserver;
|
||||
});
|
||||
|
||||
const exitBlock = () =>
|
||||
screen.getByRole("link", { name: "Ver os cases" })
|
||||
.parentElement as HTMLElement;
|
||||
|
||||
describe("Projects: saída da vitrine", () => {
|
||||
it("indents the link to the left corner of the pinned reel, where the caption and the buttons start", () => {
|
||||
render(<Projects projects={[]} />);
|
||||
|
||||
expect(exitBlock().style.paddingLeft).toBe("403px");
|
||||
});
|
||||
|
||||
it("follows the reel when the window changes size (the stage measures itself), and when the reel is observed", () => {
|
||||
render(<Projects projects={[]} />);
|
||||
expect(exitBlock().style.paddingLeft).toBe("403px");
|
||||
|
||||
lefts.set = 567;
|
||||
act(() => {
|
||||
for (const observer of FakeResizeObserver.instances) observer.fire();
|
||||
});
|
||||
|
||||
expect(exitBlock().style.paddingLeft).toBe("467px");
|
||||
// observa a seção (largura da janela) e o conjunto de aparelhos (a barra de cookies muda a altura do palco)
|
||||
const observed = FakeResizeObserver.instances.flatMap((observer) => [
|
||||
...observer.observed,
|
||||
]);
|
||||
expect(observed.some((element) => element.tagName === "SECTION")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
observed.some((element) => element.classList.contains("ds-reel-set")),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps the link at the start of the column without a pinned reel (phone, reduced motion, short window)", () => {
|
||||
pinned = false;
|
||||
|
||||
render(<Projects projects={[]} />);
|
||||
|
||||
expect(exitBlock().style.paddingLeft).toBe("");
|
||||
});
|
||||
|
||||
it("never indents to the left of its own column, and works where there is no ResizeObserver", () => {
|
||||
lefts.set = 40;
|
||||
global.ResizeObserver = undefined as unknown as typeof ResizeObserver;
|
||||
|
||||
render(<Projects projects={[]} />);
|
||||
|
||||
expect(exitBlock().style.paddingLeft).toBe("");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user