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:
1 parent
6e1022b58c
commit
8d07b8c6bb
60 files changed
+4392
-2124
No files matched your search
@@ -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");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user