feat(home): posicionamento com prova, menu sem recarregar e WhatsApp em todo o site
H1 'Sites e sistemas que trazem pedidos pelo WhatsApp e tiram sua operação da planilha.'; HeroWork maior com a SEV; menu Cases, Serviços, Como trabalho, Sobre e IA com next/link e pré-carregamento no hover; menu do celular em tela cheia; WhatsApp flutuante e no rodapé com a mensagem da rota; rodapé em todas as páginas; FAQ da home; /ia como oferta de revisão de app feito com IA; formulário com noscript, validação do mailto e plano B do pop-up; cartões sem foco indevido; sem a fonte Monument.
This commit is contained in:
1 parent
e80f73d075
commit
10f170abf4
56 files changed
+3099
-906
No files matched your search
@@ -12,7 +12,10 @@ beforeEach(() => {
|
||||
localStorage.setItem("evandro.analytics-consent.v1", "granted");
|
||||
delete window["ga-disable-G-QTT9QT0T3S"];
|
||||
window.gtag = jest.fn();
|
||||
jest.spyOn(window, "open").mockImplementation(() => null);
|
||||
// uma aba aberta de verdade: se devolver null, o Contact cai para location.href
|
||||
jest
|
||||
.spyOn(window, "open")
|
||||
.mockImplementation(() => ({ opener: {} }) as unknown as Window);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -48,7 +51,7 @@ function sentMessage() {
|
||||
|
||||
describe("Contact: validate()", () => {
|
||||
it("path: only the name is missing -> only the name is flagged and gets the focus", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await fill(user, {
|
||||
email: "[email protected]",
|
||||
@@ -69,7 +72,7 @@ describe("Contact: validate()", () => {
|
||||
});
|
||||
|
||||
it("path: only the e-mail is malformed -> only the e-mail is flagged and gets the focus (not the name)", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await fill(user, {
|
||||
name: "Ana",
|
||||
@@ -88,7 +91,7 @@ describe("Contact: validate()", () => {
|
||||
});
|
||||
|
||||
it("path: only the message is missing -> only the message is flagged and gets the focus", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await fill(user, { name: "Ana" });
|
||||
|
||||
@@ -105,7 +108,7 @@ describe("Contact: validate()", () => {
|
||||
});
|
||||
|
||||
it("path: name and message made only of spaces -> both rejected", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await fill(user, { name: " ", message: " " });
|
||||
|
||||
@@ -118,7 +121,7 @@ describe("Contact: validate()", () => {
|
||||
});
|
||||
|
||||
it("path: e-mail made only of spaces -> counts as omitted: no error and no e-mail line", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await fill(user, {
|
||||
name: "Ana",
|
||||
@@ -136,7 +139,7 @@ describe("Contact: validate()", () => {
|
||||
it.each(["a@b", "a@c.", "@c.com", "a@@c.com", "a [email protected]", "sem-arroba.com"])(
|
||||
"path: e-mail %j -> invalid format is blocked",
|
||||
async (email) => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await fill(user, { name: "Ana", email, message: "Organizar pedidos" });
|
||||
|
||||
@@ -150,7 +153,7 @@ describe("Contact: validate()", () => {
|
||||
it.each(["[email protected]", "[email protected]"])(
|
||||
"path: e-mail %j -> valid format is accepted and sent",
|
||||
async (email) => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await fill(user, { name: "Ana", email, message: "Organizar pedidos" });
|
||||
|
||||
@@ -165,7 +168,7 @@ describe("Contact: validate()", () => {
|
||||
|
||||
describe("Contact: updateField() and the error state", () => {
|
||||
it("path: typing in one field clears only that field's error", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await user.click(submitButton());
|
||||
expect(screen.getByText(NAME_ERROR)).toBeVisible();
|
||||
@@ -180,7 +183,7 @@ describe("Contact: updateField() and the error state", () => {
|
||||
});
|
||||
|
||||
it("path: changing the project type keeps the other fields' errors untouched", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await user.click(submitButton());
|
||||
|
||||
@@ -197,7 +200,7 @@ describe("Contact: updateField() and the error state", () => {
|
||||
});
|
||||
|
||||
it("path: fixing every error and submitting again -> errors gone, WhatsApp opens once", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await user.click(submitButton());
|
||||
expect(window.open).not.toHaveBeenCalled();
|
||||
@@ -214,7 +217,7 @@ describe("Contact: updateField() and the error state", () => {
|
||||
|
||||
describe("Contact: mensagem montada", () => {
|
||||
it("path: surrounding spaces are trimmed in name, e-mail and message", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await fill(user, {
|
||||
name: " Ana ",
|
||||
@@ -233,7 +236,7 @@ describe("Contact: mensagem montada", () => {
|
||||
});
|
||||
|
||||
it("path: the chosen project type and the e-mail line reach the mailto draft, and the e-mail line is omitted when blank", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
await user.selectOptions(
|
||||
screen.getByRole("combobox", { name: /tipo de projeto/i }),
|
||||
@@ -260,7 +263,7 @@ describe("Contact: mensagem montada", () => {
|
||||
});
|
||||
|
||||
it("path: the direct e-mail row reports its own placement", async () => {
|
||||
const user = userEvent.setup();
|
||||
const user = userEvent.setup({ delay: null });
|
||||
render(<Contact />);
|
||||
|
||||
const direct = screen.getByRole("link", {
|
||||
|
||||
Reference in new issue
Block a user