Files
portifolio-evandrodevbr/app/components/Hero.test.tsx
T
Evandro Fonseca Junior 10f170abf4 feat(home): posicionamento com prova, menu sem recarregar e WhatsApp em todo o site
H1 'Sites e sistemas que trazem pedidos pelo WhatsApp e tiram sua operação da planilha.'; HeroWork maior com a SEV; menu Cases, Serviços, Como trabalho, Sobre e IA com next/link e pré-carregamento no hover; menu do celular em tela cheia; WhatsApp flutuante e no rodapé com a mensagem da rota; rodapé em todas as páginas; FAQ da home; /ia como oferta de revisão de app feito com IA; formulário com noscript, validação do mailto e plano B do pop-up; cartões sem foco indevido; sem a fonte Monument.
2026-10-14 14:15:25 -03:00

132 lines
4.4 KiB
TypeScript

import { fireEvent, render, screen } from "@testing-library/react";
import Hero from "./Hero";
const clients = [
{ id: "sev-modaintima", name: "SEV Moda Íntima" },
{ id: "lavacao-047", name: "Lavação 047" },
{ id: "sc-plus", name: "SC Plus Aquicultura" },
{ id: "as-servicos", name: "AS Serviços" },
];
describe("Hero", () => {
beforeEach(() => {
jest.spyOn(window, "open").mockImplementation(() => null);
});
afterEach(() => {
jest.restoreAllMocks();
});
it("routes project conversations to contact without opening an external service", () => {
render(<Hero />);
const contactLink = screen.getByRole("link", {
name: /conversar/i,
});
expect(contactLink).toHaveAttribute("href", "/#contact");
expect(contactLink).not.toHaveAttribute("target", "_blank");
fireEvent.click(contactLink);
expect(window.open).not.toHaveBeenCalled();
expect(screen.getByRole("link", { name: /ver projetos/i })).toHaveAttribute(
"href",
"/cases",
);
});
it("keeps the headline as one readable sentence despite the per-word animation", () => {
render(<Hero />);
expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent(
"Sites e sistemas que trazem pedidos pelo WhatsApp e tiram sua operação da planilha.",
);
});
it("highlights only the short stretch 'pedidos pelo WhatsApp' in lime", () => {
render(<Hero />);
const highlighted = Array.from(
screen.getByRole("heading", { level: 1 }).querySelectorAll(".hero-word"),
)
.filter((word) => word.className.includes("text-[var(--slash)]"))
.map((word) => word.textContent);
expect(highlighted).toEqual(["pedidos", "pelo", "WhatsApp"]);
});
it("keeps the single LinkedIn profile and the e-mail, with no GitHub link", () => {
render(<Hero />);
expect(screen.getByRole("link", { name: "LinkedIn" })).toHaveAttribute(
"href",
"https://www.linkedin.com/in/evandrodevbr/",
);
expect(screen.getByRole("link", { name: "Email" })).toHaveAttribute(
"href",
"mailto:[email protected]",
);
const linkedin = screen.getByRole("link", { name: "LinkedIn" });
expect(linkedin).toHaveAttribute("target", "_blank");
expect(linkedin).toHaveAttribute("rel", "noopener noreferrer");
expect(screen.queryByRole("link", { name: "GitHub" })).toBeNull();
for (const link of screen.getAllByRole("link")) {
expect(link.getAttribute("href") ?? "").not.toMatch(/github\.com/);
}
});
it("states who the work is for and how the contact works", () => {
render(<Hero />);
expect(
screen.getByText(
"Do catálogo com pedido no WhatsApp ao painel da sua equipe. Você fala direto com quem desenvolve.",
),
).toBeInTheDocument();
expect(screen.getByRole("link", { name: /conversar/i })).toHaveAttribute(
"id",
"hero-contact-cta",
);
});
it("shows only the years of experience, with no repository numbers", () => {
render(<Hero stats={{ years: 5 }} />);
expect(screen.getByText("anos de experiência")).toBeInTheDocument();
expect(screen.getByText("5")).toBeInTheDocument();
expect(screen.queryByRole("term")).toBeNull();
expect(screen.queryByText(/projetos desenvolvidos/i)).toBeNull();
expect(screen.queryByText(/públicos|privados|mais de/i)).toBeNull();
});
it("lists the delivered clients, each linking to its case", () => {
render(<Hero clients={clients} />);
expect(screen.getByText("Já entregue para:")).toBeInTheDocument();
for (const { id, name } of clients) {
expect(screen.getByRole("link", { name })).toHaveAttribute(
"href",
`/cases/${id}`,
);
}
});
it("renders the work column with lazy posters that stay out of small screens", () => {
render(<Hero clients={clients} />);
const work = screen.getByTestId("hero-work");
expect(work).toHaveClass("hidden", "lg:block");
const images = work.querySelectorAll("img");
expect(images).toHaveLength(2);
for (const image of images) {
expect(image).toHaveAttribute("loading", "lazy");
}
expect(images[0]).toHaveAttribute(
"src",
"/videos/sev-modaintima/desktop.webp",
);
expect(images[0]).toHaveAccessibleName(
"Site da SEV Moda Íntima aberto no computador",
);
expect(images[1]).toHaveAttribute("src", "/videos/as-servicos/mobile.webp");
});
});