feat(home): ofertas que vendem o título, WhatsApp no hero e menu do celular acessível
Três ofertas (site que traz pedidos pelo WhatsApp, sistema para tirar a operação da planilha, revisão de sistema existente) com miniatura e formulário com o tipo escolhido; botão principal do hero abre o WhatsApp; moldura da SEV no hero do celular; menu fecha ao navegar, Esc, foco preso incluindo a barra de cookies e espaço para ela; CinematicHome como componente de servidor com ilha cliente; /ia com H1 de oferta e cartão do que você recebe; botão flutuante em aside com transform; AVIF antes de WebP; copy sem repetir contato direto.
This commit is contained in:
1 parent
de6af74a0c
commit
f8545cd442
44 files changed
+2286
-571
No files matched your search
@@ -0,0 +1,74 @@
|
||||
import { act, render, screen } from "@testing-library/react";
|
||||
import Contact from "./Contact";
|
||||
import { CONTACT_KIND_EVENT, DEFAULT_CONTACT_SUBJECT } from "./contact-subject";
|
||||
|
||||
/**
|
||||
* Testes de caminhos-base da leitura do tipo da oferta em Contact (`/?tipo=…#contact`), complemento de
|
||||
* Contact.offer.test.tsx: tipo válido, inválido e ausente no endereço, e a ordem entre o endereço e o evento.
|
||||
*/
|
||||
|
||||
const subjectSelect = () =>
|
||||
screen.getByRole("combobox", {
|
||||
name: /tipo de projeto/i,
|
||||
}) as HTMLSelectElement;
|
||||
|
||||
const choose = (kind: unknown) =>
|
||||
act(() => {
|
||||
window.dispatchEvent(new CustomEvent(CONTACT_KIND_EVENT, { detail: kind }));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
window.history.replaceState(null, "", "/");
|
||||
});
|
||||
|
||||
describe("Contact: tipo no endereço", () => {
|
||||
it.each([
|
||||
["/", "sem busca nenhuma (tipo ausente)"],
|
||||
["/?utm_source=instagram#contact", "só outros parâmetros (tipo ausente)"],
|
||||
["/?tipo=#contact", "tipo vazio"],
|
||||
["/?tipo=SITE#contact", "tipo com outra caixa (só vale em minúsculas)"],
|
||||
["/?tipo=constructor#contact", "nome herdado de todo objeto"],
|
||||
["/?tipo=outra-coisa#contact", "tipo desconhecido"],
|
||||
])("path: %s (%s) -> keeps the default option", (address) => {
|
||||
window.history.replaceState(null, "", address);
|
||||
|
||||
render(<Contact />);
|
||||
|
||||
expect(subjectSelect()).toHaveValue(DEFAULT_CONTACT_SUBJECT);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["/?tipo=site#contact", "Site para empresa"],
|
||||
["/?tipo=sistema#contact", "Sistemas web sob medida"],
|
||||
[
|
||||
"/?utm_source=x&tipo=revisao#contact",
|
||||
"Revisão ou diagnóstico de sistema",
|
||||
],
|
||||
// com o parâmetro repetido vale o primeiro
|
||||
["/?tipo=site&tipo=revisao#contact", "Site para empresa"],
|
||||
])("path: %s (valid type) -> selects %s", (address, option) => {
|
||||
window.history.replaceState(null, "", address);
|
||||
|
||||
render(<Contact />);
|
||||
|
||||
expect(subjectSelect()).toHaveValue(option);
|
||||
});
|
||||
|
||||
it("path: valid type in the address, then an unknown one from the event -> the address choice stays", () => {
|
||||
window.history.replaceState(null, "", "/?tipo=sistema#contact");
|
||||
render(<Contact />);
|
||||
|
||||
choose("desconhecido");
|
||||
|
||||
expect(subjectSelect()).toHaveValue("Sistemas web sob medida");
|
||||
});
|
||||
|
||||
it("path: valid type in the address, then a valid one from the event -> the later choice wins", () => {
|
||||
window.history.replaceState(null, "", "/?tipo=sistema#contact");
|
||||
render(<Contact />);
|
||||
|
||||
choose("revisao");
|
||||
|
||||
expect(subjectSelect()).toHaveValue("Revisão ou diagnóstico de sistema");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user