fix(home): oferta leva ao formulário, ofertas logo depois da vitrine
O botão das ofertas rola até o contato com o tipo marcado e não quebra mais as âncoras; ofertas com o que você recebe e primeiro passo, logo depois da vitrine; bloco de IA fora da home; cartão largo da SEV no hero do celular; separador da faixa de clientes só entre itens; favicon de 13 para 1,8 KB; pré-carregamento só no hover e nunca de /#... fora da home; X do menu e cabeçalho opaco; WhatsApp com "o case"; /ia com 3 passos e modelo de relatório ilustrativo; Sobre alinhado ao currículo; CSP Report-Only com os domínios do Ads.
This commit is contained in:
1 parent
fc44a69fb3
commit
9e2d65a926
51 files changed
+1730
-420
No files matched your search
@@ -33,7 +33,7 @@ function setScrollY(value: number) {
|
||||
}
|
||||
|
||||
const header = () => screen.getByRole("banner");
|
||||
/** Rolada: borda visível e fundo a 95% (sem backdrop-blur: o filtro refazia a pintura a cada quadro da rolagem). */
|
||||
/** Rolada: borda visível e fundo opaco (sem backdrop-blur: o filtro refazia a pintura a cada quadro da rolagem). */
|
||||
const isDark = () => header().className.includes("border-white/12");
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -79,6 +79,20 @@ describe("Header: rolagem", () => {
|
||||
expect(isDark()).toBe(false);
|
||||
});
|
||||
|
||||
it("path: the background is fully opaque at the top and scrolled (no 95% fill: the titles showed through)", () => {
|
||||
render(<Header />);
|
||||
|
||||
expect(header().className).toContain("bg-[var(--ink)]");
|
||||
expect(header().className).not.toContain("bg-[var(--ink)]/");
|
||||
|
||||
setScrollY(120);
|
||||
act(() => {
|
||||
window.dispatchEvent(new Event("scroll"));
|
||||
});
|
||||
expect(header().className).toContain("bg-[var(--ink)]");
|
||||
expect(header().className).not.toContain("bg-[var(--ink)]/");
|
||||
});
|
||||
|
||||
it("path: page already scrolled when the header mounts -> starts with the bordered bar", () => {
|
||||
setScrollY(500);
|
||||
render(<Header />);
|
||||
@@ -96,6 +110,29 @@ describe("Header: rolagem", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Header: ícone do menu", () => {
|
||||
it("path: open -> the outer bars move 10px (2px bar + 8px gap) to the middle and turn into a straight X; closed -> nothing moves", () => {
|
||||
render(<Header />);
|
||||
const button = screen.getByRole("button", { name: "Abrir menu" });
|
||||
const bars = () =>
|
||||
Array.from(button.querySelectorAll("span")) as HTMLElement[];
|
||||
|
||||
// 2 px de altura + 8 px de espaço entre as linhas = 10 px de centro a centro
|
||||
expect(bars()[0]).toHaveClass("h-0.5");
|
||||
expect(button).toHaveClass("gap-sp-2");
|
||||
for (const bar of bars()) expect(bar.className).not.toMatch(/translate-y/);
|
||||
|
||||
fireEvent.click(button);
|
||||
const open = bars();
|
||||
expect(open).toHaveLength(3);
|
||||
expect(open[0]).toHaveClass("translate-y-[10px]", "rotate-45");
|
||||
expect(open[1]).toHaveClass("opacity-0");
|
||||
expect(open[2]).toHaveClass("-translate-y-[10px]", "-rotate-45");
|
||||
expect(open[0].className).not.toContain("6px");
|
||||
expect(open[2].className).not.toContain("6px");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Header: teclado no menu do celular", () => {
|
||||
it("path: a key other than Escape inside the open menu -> the menu stays open and the key is not blocked", () => {
|
||||
render(<Header />);
|
||||
|
||||
Reference in new issue
Block a user