feat(cases): mídia no topo, títulos de busca curtos e CreativeWork

Case com mídia ao lado do título e play acessível; problema de cada cliente reescrito com base nos dados; serviços relacionados em 2 cards; FAQ antes do próximo passo e bloco 'Onde já apliquei isso'; Apolo citada em IoT e arquitetura. metaTitle até 43 caracteres e descrições até 155 com teste; JSON-LD CreativeWork; imagens de compartilhamento abaixo de 100 KB; 404 e robots corrigidos; server-only nos módulos com node:.
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 14:15:25 -03:00
1 parent c9a0b80656
commit e80f73d075
52 files changed
+2593 -439

No files matched your search

+48 -9
View File
@@ -1,10 +1,11 @@
import { render, screen } from "@testing-library/react";
import { fireEvent, render, screen } from "@testing-library/react";
import { getShowcaseAssets } from "@/lib/project-showcase";
import { CaseMedia } from "./CaseMedia";
import { getCaseMedia } from "./case-media";
/**
* Testes de caminhos-base de CaseMedia: com computador e celular, só um dos dois, ou nenhum.
* Cada quadro mostra o pôster com um botão de play; o vídeo só aparece depois do clique.
* A existência dos arquivos em disco é simulada em getCaseMedia, para o teste não depender de public/.
*/
@@ -23,8 +24,10 @@ const props = {
title: "SEV Moda Íntima",
demoUrl: "https://sevmodaintima.com.br",
};
const desktopLabel = `Vídeo do site ${props.title} no computador`;
const mobileLabel = `Vídeo do site ${props.title} no celular`;
const desktopPlay = `Reproduzir o vídeo do site ${props.title} no computador`;
const mobilePlay = `Reproduzir o vídeo do site ${props.title} no celular`;
const desktopVideo = `Vídeo do site ${props.title} no computador`;
const mobileVideo = `Vídeo do site ${props.title} no celular`;
afterEach(() => {
mockedGetCaseMedia.mockReset();
@@ -36,10 +39,10 @@ describe("CaseMedia", () => {
const { container } = render(<CaseMedia {...props} />);
expect(container.querySelector(".ds-bframe")).toContainElement(
screen.getByLabelText(desktopLabel),
screen.getByRole("button", { name: desktopPlay }),
);
expect(container.querySelector(".ds-phone")).toContainElement(
screen.getByLabelText(mobileLabel),
screen.getByRole("button", { name: mobilePlay }),
);
expect(container.querySelector(".ds-bframe-url")).toHaveTextContent(
"sevmodaintima.com.br",
@@ -63,8 +66,10 @@ describe("CaseMedia", () => {
withCaptures(["mobile"]);
const { container } = render(<CaseMedia {...props} />);
expect(screen.getByLabelText(mobileLabel)).toBeInTheDocument();
expect(screen.queryByLabelText(desktopLabel)).toBeNull();
expect(
screen.getByRole("button", { name: mobilePlay }),
).toBeInTheDocument();
expect(screen.queryByRole("button", { name: desktopPlay })).toBeNull();
expect(container.querySelector(".ds-bframe")).toBeNull();
expect(container.querySelector(".ds-phone")).not.toBeNull();
expect(screen.queryByText(/no computador\./)).toBeNull();
@@ -74,13 +79,47 @@ describe("CaseMedia", () => {
withCaptures(["desktop"]);
const { container } = render(<CaseMedia {...props} />);
expect(screen.getByLabelText(desktopLabel)).toBeInTheDocument();
expect(screen.queryByLabelText(mobileLabel)).toBeNull();
expect(
screen.getByRole("button", { name: desktopPlay }),
).toBeInTheDocument();
expect(screen.queryByRole("button", { name: mobilePlay })).toBeNull();
expect(container.querySelector(".ds-phone")).toBeNull();
expect(container.querySelector(".ds-bframe")).not.toBeNull();
expect(screen.queryByText("No celular.")).toBeNull();
});
it("path: both captures -> no video until play, then only the pressed frame plays", () => {
withCaptures(["desktop", "mobile"]);
const { container } = render(<CaseMedia {...props} />);
expect(container.querySelector("video")).toBeNull();
// o pôster do computador vem com texto alternativo vazio: o botão já descreve o quadro
expect(container.querySelector(".ds-bframe img")).toHaveAttribute(
"alt",
"",
);
fireEvent.click(screen.getByRole("button", { name: mobilePlay }));
const phone = screen.getByLabelText(mobileVideo);
expect(container.querySelector(".ds-phone")).toContainElement(phone);
expect(phone).toHaveAttribute("poster", `/videos/${props.id}/mobile.webp`);
expect(phone.querySelectorAll("source")).toHaveLength(2);
expect(screen.queryByLabelText(desktopVideo)).toBeNull();
expect(
screen.getByRole("button", { name: desktopPlay }),
).toBeInTheDocument();
expect(container.querySelectorAll("video")).toHaveLength(1);
fireEvent.click(screen.getByRole("button", { name: desktopPlay }));
expect(screen.getByLabelText(desktopVideo)).toHaveAttribute(
"poster",
`/videos/${props.id}/desktop.webp`,
);
expect(container.querySelectorAll("video")).toHaveLength(2);
expect(screen.queryByRole("button")).toBeNull();
});
it("path: no demo address -> the browser bar falls back to the project title", () => {
withCaptures(["desktop"]);
const { container } = render(