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
@@ -1,6 +1,23 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { fireEvent, render, screen, within } from "@testing-library/react";
|
||||
import About from "./About";
|
||||
|
||||
// o Link do Next, trocado por um <a> que mostra o prefetch recebido: HoverPrefetchLink começa em false
|
||||
jest.mock("next/link", () => ({
|
||||
__esModule: true,
|
||||
default: ({
|
||||
children,
|
||||
prefetch,
|
||||
...props
|
||||
}: { children?: React.ReactNode; prefetch?: boolean | null } & Record<
|
||||
string,
|
||||
unknown
|
||||
>) => (
|
||||
<a data-prefetch={String(prefetch)} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
}));
|
||||
|
||||
/**
|
||||
* Testes de caminhos-base de About: a entrada dos quatro cartões (Reveal, CSS) com atrasos crescentes, o
|
||||
* feedback de toque e de mouse por classes (cv-press, cv-lift; cartões sem foco), o conteúdo e a coluna de
|
||||
@@ -89,24 +106,69 @@ describe("About", () => {
|
||||
expect(cards[3]).toHaveClass("cv-press");
|
||||
});
|
||||
|
||||
it("path: the story, the profile points and the résumé link are all there", () => {
|
||||
render(<About />);
|
||||
it("path: the section has three points, each with the proof that backs it, and the résumé link", () => {
|
||||
const { container } = render(<About />);
|
||||
|
||||
const titles = [
|
||||
"Quem conversa com você escreve o código",
|
||||
"Aproveito o que você já tem",
|
||||
"Do código ao sistema no ar",
|
||||
];
|
||||
for (const name of titles) {
|
||||
expect(
|
||||
screen.getByRole("heading", { level: 3, name }),
|
||||
).toBeInTheDocument();
|
||||
}
|
||||
// no máximo três pontos: os três cartões da história; o cartão do perfil não é um quarto ponto, só diz do que cuido
|
||||
const story = [...container.querySelectorAll("article")].slice(0, 3);
|
||||
expect(story).toHaveLength(3);
|
||||
for (const card of story) {
|
||||
expect(within(card).getAllByText("Na prática:")).toHaveLength(1);
|
||||
}
|
||||
// a prova de cada ponto é concreta: a Apolo desde 2022, a revisão e os cases entregues
|
||||
expect(story[0]).toHaveTextContent(
|
||||
/Na prática: Na Apolo Energia, desde 2022, desenvolvo aplicações web e mobile, APIs e integrações com dispositivos IoT/,
|
||||
);
|
||||
expect(story[1]).toHaveTextContent(
|
||||
/Na prática: Na revisão, você recebe o que dá para aproveitar e o que é melhor refazer/,
|
||||
);
|
||||
expect(story[2]).toHaveTextContent(
|
||||
/Na prática: Já entregue para SEV Moda Íntima, Lavação 047, SC Plus Aquicultura e AS Serviços\./,
|
||||
);
|
||||
expect(
|
||||
screen.getByRole("heading", {
|
||||
level: 3,
|
||||
name: "Sem intermediários entre o pedido e o sistema",
|
||||
within(story[1]).getByRole("link", {
|
||||
name: "Ver como funciona a revisão",
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Solução do tamanho do seu problema"),
|
||||
).toBeInTheDocument();
|
||||
).toHaveAttribute("href", "/ia");
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Ver trajetória completa" }),
|
||||
).toHaveAttribute("href", "/curriculo");
|
||||
});
|
||||
|
||||
it("path: speaks in client benefits, with no technical jargon, and cites the Apolo Energia work", () => {
|
||||
it("path: the idea of talking to whoever develops shows up once, not in five texts", () => {
|
||||
const { container } = render(<About />);
|
||||
|
||||
expect(container.textContent).not.toMatch(
|
||||
/Sem intermediários|Uma pessoa cuida|Quem responde pelo projeto|acompanha as decisões|fala com quem desenvolve|Solução do tamanho|Tudo funcionando junto/,
|
||||
);
|
||||
expect(container.textContent?.match(/mesma pessoa/g)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("path: the résumé and the review links pre-fetch only when the visitor reaches them (HoverPrefetchLink), as in the rest of the home", () => {
|
||||
render(<About />);
|
||||
|
||||
for (const name of [
|
||||
"Ver trajetória completa",
|
||||
"Ver como funciona a revisão",
|
||||
]) {
|
||||
const link = screen.getByRole("link", { name });
|
||||
expect(link).toHaveAttribute("data-prefetch", "false");
|
||||
fireEvent.mouseEnter(link);
|
||||
expect(link).toHaveAttribute("data-prefetch", "null");
|
||||
}
|
||||
});
|
||||
|
||||
it("path: speaks in client benefits, with no technical jargon, and cites the Apolo Energia work once, as the proof of the first point", () => {
|
||||
const { container } = render(<About />);
|
||||
|
||||
expect(container.textContent).not.toMatch(
|
||||
@@ -116,14 +178,14 @@ describe("About", () => {
|
||||
expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent(
|
||||
"Evandro Fonseca Junior",
|
||||
);
|
||||
expect(screen.getByTestId("about-description").textContent).toMatch(
|
||||
/^Engenheiro da computação; desde 2022 desenvolvo aplicações web e mobile, APIs e integrações com dispositivos IoT para as rotinas internas da Apolo Energia\./,
|
||||
expect(screen.getByTestId("about-description").textContent).toBe(
|
||||
"Engenheiro da computação e desenvolvedor de software, com projetos entregues para empresas.",
|
||||
);
|
||||
// só o que o currículo sustenta: nada de "os sistemas internos e a IoT" da empresa inteira
|
||||
expect(container.textContent).not.toMatch(
|
||||
/os sistemas internos e a IoT da Apolo/,
|
||||
);
|
||||
// a frase da Apolo aparece uma só vez
|
||||
// a frase da Apolo aparece uma só vez (na prova do primeiro ponto)
|
||||
expect(container.textContent?.match(/Apolo Energia/g)).toHaveLength(1);
|
||||
});
|
||||
|
||||
@@ -131,7 +193,7 @@ describe("About", () => {
|
||||
const { container } = render(<About />);
|
||||
|
||||
expect(container.textContent).not.toMatch(/Como eu trabalho/);
|
||||
expect(screen.getByText("Acompanhamento")).toBeInTheDocument();
|
||||
expect(screen.getByText("Quem desenvolve")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("path: 'contato direto', 'fala direto' and 'conversa comigo' no longer repeat in the section", () => {
|
||||
@@ -142,13 +204,14 @@ describe("About", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("path: the location label stays on one line and the columns stretch to the same height", () => {
|
||||
it("path: the location label stays on one line and the portrait card keeps its own height next to the text cards", () => {
|
||||
const { container } = render(<About />);
|
||||
|
||||
expect(screen.getByText(/Garuva, SC · Atendimento remoto/)).toHaveClass(
|
||||
"whitespace-nowrap",
|
||||
);
|
||||
expect(container.querySelector(".ds-grid-2")).toHaveClass("items-stretch");
|
||||
// items-start: o retrato tem a altura do próprio conteúdo e acompanha a rolagem; só os cartões de texto se esticam entre si
|
||||
expect(container.querySelector(".ds-grid-2")).toHaveClass("items-start");
|
||||
const story = container.querySelectorAll("article");
|
||||
for (const card of Array.from(story).slice(0, 3)) {
|
||||
expect(card).toHaveClass("flex-1");
|
||||
|
||||
Reference in new issue
Block a user