Tres camadas de pontos ligadas por colunas de dados, animadas no vertex shader; o hero fica fixo em telas grandes enquanto a camera atravessa as camadas. Secoes sobem como cartoes via animation-timeline: view() (sem JS). Co-Authored-By: Claude Opus 5.5 <[email protected]>
85 lines
2.4 KiB
TypeScript
85 lines
2.4 KiB
TypeScript
import { fireEvent, render, screen } from "@testing-library/react";
|
|
import type { ReactNode } from "react";
|
|
|
|
import Hero from "./Hero";
|
|
|
|
jest.mock("motion/react", () => {
|
|
const React = require("react");
|
|
|
|
const motion = new Proxy(
|
|
{},
|
|
{
|
|
get: (_, tag: string) => {
|
|
const Component = ({
|
|
children,
|
|
initial: _initial,
|
|
animate: _animate,
|
|
transition: _transition,
|
|
...props
|
|
}: { children?: ReactNode } & Record<string, unknown>) =>
|
|
React.createElement(tag, props, children);
|
|
Component.displayName = `motion.${tag}`;
|
|
return Component;
|
|
},
|
|
},
|
|
);
|
|
|
|
return { motion, useReducedMotion: () => false };
|
|
});
|
|
|
|
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(
|
|
"Sistemas sob medida para operações que não cabem em soluções prontas.",
|
|
);
|
|
});
|
|
|
|
it("keeps social destinations with isolated external tabs", () => {
|
|
render(<Hero />);
|
|
|
|
expect(screen.getByRole("link", { name: "GitHub" })).toHaveAttribute(
|
|
"href",
|
|
"https://github.com/evandrodevbr",
|
|
);
|
|
expect(screen.getByRole("link", { name: "LinkedIn" })).toHaveAttribute(
|
|
"href",
|
|
"https://www.linkedin.com/in/evandro-fonseca-junior-0969aa1b0/",
|
|
);
|
|
expect(screen.getByRole("link", { name: "Email" })).toHaveAttribute(
|
|
"href",
|
|
"mailto:[email protected]",
|
|
);
|
|
for (const name of ["GitHub", "LinkedIn"]) {
|
|
const link = screen.getByRole("link", { name });
|
|
expect(link).toHaveAttribute("target", "_blank");
|
|
expect(link).toHaveAttribute("rel", "noopener noreferrer");
|
|
}
|
|
});
|
|
});
|