feat(home): prova no topo, contato sem atrito e conversão medida

Home mais curta (hero, vitrine de clientes, sobre, serviços, IA resumida, depoimentos e contato), faixa de clientes e telas reais no hero, sem números do GitHub. Barra de cookies fina, WhatsApp fixo no celular, formulário com e-mail opcional e alternativa por e-mail, página /ia, eventos de e-mail, redes e currículo e conversão do Ads opcional por variável. Rodapé em 3 colunas. Remove componentes órfãos (LighthouseMetrics, Skills, Experience, contagem do GitHub).
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 03:32:23 -03:00
1 parent 6e1022b58c
commit 8d07b8c6bb
60 files changed
+4392 -2124

No files matched your search

+77 -37
View File
@@ -1,4 +1,6 @@
import { render, screen } from "@testing-library/react";
import { fireEvent, render, screen, within } from "@testing-library/react";
import { OPEN_COOKIE_PREFERENCES_EVENT } from "@/lib/analytics";
import { serviceHubLinks } from "@/lib/site-content";
import Footer from "./Footer";
describe("Footer contact and navigation", () => {
@@ -20,56 +22,94 @@ describe("Footer contact and navigation", () => {
expect(emailLink).not.toHaveAttribute("target", "_blank");
});
it("renders quick links as same-tab navigation", () => {
render(<Footer />);
it("lists the six services from the services hub as same-tab links", () => {
render(<Footer serviceLinks={serviceHubLinks} />);
const servicesLink = screen.getByRole("link", { name: "Hub de serviços" });
expect(servicesLink).toHaveAttribute("href", "/servicos");
expect(servicesLink).not.toHaveAttribute("target", "_blank");
expect(screen.getByRole("link", { name: "Privacidade" })).toHaveAttribute(
"href",
"/privacidade",
expect(serviceHubLinks).toHaveLength(6);
const services = screen.getByRole("navigation", { name: "Serviços" });
const links = within(services).getAllByRole("link");
expect(links.map((link) => link.getAttribute("href"))).toEqual(
serviceHubLinks.map((service) => service.href),
);
expect(links.map((link) => link.textContent)).toEqual(
serviceHubLinks.map((service) => service.label),
);
for (const link of links) expect(link).not.toHaveAttribute("target");
});
it("keeps the résumé page and PDF download as the final secondary links", () => {
it("links Cases, Privacidade and a discreet Currículo, with no PDF download", () => {
render(<Footer />);
const résuméLink = screen.getByRole("link", { name: "Currículo" });
const downloadLink = screen.getByRole("link", {
name: "Baixar currículo (PDF)",
});
expect(résuméLink).toHaveAttribute("href", "/curriculo");
expect(downloadLink).toHaveAttribute("href", "/Profile.pdf");
expect(downloadLink).toHaveAttribute(
"download",
"Evandro_Fonseca_Junior_CV.pdf",
const more = screen.getByRole("navigation", { name: "Mais" });
expect(within(more).getByRole("link", { name: "Cases" })).toHaveAttribute(
"href",
"/cases",
);
expect(screen.getAllByRole("link").slice(-2)).toEqual([
résuméLink,
downloadLink,
]);
expect(
within(more).getByRole("link", { name: "Privacidade" }),
).toHaveAttribute("href", "/privacidade");
const resume = within(more).getByRole("link", { name: "Currículo" });
expect(resume).toHaveAttribute("href", "/curriculo");
expect(within(more).getAllByRole("link").at(-1)).toBe(resume);
expect(screen.queryByRole("link", { name: /baixar|pdf/i })).toBeNull();
for (const link of screen.getAllByRole("link")) {
expect(link).not.toHaveAttribute("download");
}
});
it("reopens the cookie preferences from a button", () => {
const reopen = jest.fn();
window.addEventListener(OPEN_COOKIE_PREFERENCES_EVENT, reopen);
render(<Footer />);
fireEvent.click(
screen.getByRole("button", { name: "Preferências de cookies" }),
);
expect(reopen).toHaveBeenCalledTimes(1);
window.removeEventListener(OPEN_COOKIE_PREFERENCES_EVENT, reopen);
});
it("states the location and rights in Portuguese", () => {
render(<Footer />);
expect(
screen.getByText("Garuva, SC · Atendimento remoto em todo o Brasil"),
).toBeInTheDocument();
expect(
screen.getByText(/Todos os direitos\s+reservados/),
).toBeInTheDocument();
expect(screen.queryByText(/remote worldwide|all rights/i)).toBeNull();
});
});
describe("Footer social links", () => {
it("opens social links securely in a new tab", () => {
it("keeps one LinkedIn profile in a new tab and no GitHub link", () => {
render(<Footer />);
const socialLinks = screen.getAllByRole("link", { name: /profile/i });
for (const link of socialLinks) {
expect(link).toHaveAttribute("target", "_blank");
expect(link).toHaveAttribute("rel", "noopener noreferrer");
expect(link.querySelector("svg")).toHaveAttribute("aria-hidden", "true");
}
expect(screen.getByLabelText("Visit GitHub profile")).toHaveAttribute(
const linkedin = screen.getByRole("link", { name: "LinkedIn" });
expect(linkedin).toHaveAttribute(
"href",
"https://github.com/evandrodevbr",
"https://www.linkedin.com/in/evandrodevbr/",
);
expect(
screen.getByLabelText("Visit LinkedIn profile").getAttribute("href"),
).toContain("https://www.linkedin.com/in/evandrodevbr/");
expect(linkedin).toHaveAttribute("target", "_blank");
expect(linkedin).toHaveAttribute("rel", "noopener noreferrer");
for (const link of screen.getAllByRole("link")) {
expect(link.getAttribute("href") ?? "").not.toMatch(/github\.com/);
}
expect(screen.queryByRole("link", { name: /github/i })).toBeNull();
});
it("keeps Instagram in the contact column, in a new tab", () => {
render(<Footer />);
const contact = screen.getByRole("region", { name: "Contato" });
const instagram = within(contact).getByRole("link", { name: "Instagram" });
expect(instagram).toHaveAttribute(
"href",
"https://www.instagram.com/evandrodevbr/",
);
expect(instagram).toHaveAttribute("target", "_blank");
expect(instagram).toHaveAttribute("rel", "noopener noreferrer");
});
});