/servicos abre com as 3 ofertas e depois outros serviços; H1 de criação de sites e de engenharia com o nome da oferta; capa de cada serviço pelo assunto (SEV fora do próprio case cai de ~11 para 2 imagens); diagrama de fluxo em SVG nos serviços sem case; cases com o que o cliente passou a poder fazer e contato logo depois de Como ficou; FAQ num componente só; lastmod por rota; ProfessionalService com areaServed.
71 lines
3.1 KiB
TypeScript
71 lines
3.1 KiB
TypeScript
import { render, screen } from "@testing-library/react";
|
|
import type { ServiceDiagramKind } from "@/lib/site-content";
|
|
import { ServiceDiagram } from "./ServiceDiagram";
|
|
|
|
/** Esquema de fluxo do topo dos serviços sem case com captura: SVG em linha, acessível, sem dado real nem logo de cliente. */
|
|
|
|
const expected: Record<ServiceDiagramKind, string[]> = {
|
|
iot: ["Dispositivo ou sensor", "Gateway", "API", "Painel"],
|
|
arquitetura: ["Interface", "API", "Serviços", "Banco de dados"],
|
|
desktop: ["Aplicativo no computador", "Arquivos", "Sistemas locais"],
|
|
};
|
|
|
|
describe("ServiceDiagram", () => {
|
|
for (const kind of Object.keys(expected) as ServiceDiagramKind[]) {
|
|
it(`path: ${kind} -> an inline SVG image with the flow in its label and the steps in order`, () => {
|
|
const { container } = render(<ServiceDiagram kind={kind} />);
|
|
|
|
const svg = screen.getByRole("img");
|
|
expect(svg.tagName.toLowerCase()).toBe("svg");
|
|
expect(svg).toHaveAttribute("aria-label");
|
|
expect(svg.getAttribute("aria-label")?.length).toBeGreaterThan(60);
|
|
const labels = Array.from(container.querySelectorAll("svg text")).map(
|
|
(text) => text.textContent,
|
|
);
|
|
expect(labels).toEqual(expected[kind]);
|
|
// o texto do desenho está no rótulo da imagem: quem lê a tela ouve o fluxo inteiro
|
|
for (const label of expected[kind]) {
|
|
expect(svg.getAttribute("aria-label")?.toLowerCase()).toContain(
|
|
label.toLowerCase().replace("dispositivo ou sensor", "dispositivo"),
|
|
);
|
|
}
|
|
expect(container.querySelectorAll("svg img, svg image")).toHaveLength(0);
|
|
});
|
|
}
|
|
|
|
it("path: IoT and architecture -> three arrows between four steps; desktop -> two arrows, both ways", () => {
|
|
const iot = render(<ServiceDiagram kind="iot" />);
|
|
expect(iot.container.querySelectorAll("svg line")).toHaveLength(3);
|
|
// uma ponta por seta
|
|
expect(iot.container.querySelectorAll("svg polygon")).toHaveLength(3);
|
|
iot.unmount();
|
|
|
|
const arquitetura = render(<ServiceDiagram kind="arquitetura" />);
|
|
expect(arquitetura.container.querySelectorAll("svg line")).toHaveLength(3);
|
|
arquitetura.unmount();
|
|
|
|
const desktop = render(<ServiceDiagram kind="desktop" />);
|
|
expect(desktop.container.querySelectorAll("svg line")).toHaveLength(2);
|
|
// duas pontas por seta: a informação vai e volta
|
|
expect(desktop.container.querySelectorAll("svg polygon")).toHaveLength(4);
|
|
});
|
|
|
|
it("path: colors -> only site tokens (paper and white), never the lime that belongs to contact, never a client logo", () => {
|
|
const { container } = render(<ServiceDiagram kind="iot" />);
|
|
|
|
const html = container.innerHTML;
|
|
expect(html).toMatch(/var\(--paper\)/);
|
|
expect(html).toMatch(/var\(--white\)/);
|
|
expect(html).not.toMatch(/--slash|#ccff00|ccff00/i);
|
|
expect(html).not.toMatch(/<image|<img|href=/i);
|
|
});
|
|
|
|
it("path: caption -> says it is an illustration, with no client data", () => {
|
|
render(<ServiceDiagram kind="arquitetura" />);
|
|
|
|
expect(
|
|
screen.getByText("Esquema ilustrativo, sem dados de clientes."),
|
|
).toBeVisible();
|
|
});
|
|
});
|