Files
Creeer-Web/components/sections/__tests__/PuntosInflexion.test.tsx
T
erikghandClaude Opus 5.5 89e54a6e84 feat: rediseño «El documento» en curso, contacto real y enlaces externos
Primitivas y contenido del rediseño (escala tipográfica, Revelar,
MarcaSeccion, Seccion, Antetitulo, SimboloMarca, Resplandor, ClaridadHero,
sección Proceso de ocho etapas, lib/content.ts reestructurado en seis
secciones con alias para las viejas). Mecanismo y FormaTrabajar se retiran.

Encima, lo de esta sesión:
- recorrido: creeer vuelve a responder cada situación en vez de repetirla
  (el alias apuntaba respuesta a situacion); respuestas en plural. Créditos
  de las seis fotos de México.
- contacto: WhatsApp, email (con mailto:) y LinkedIn reales; iconos de las
  redes en el cierre y el footer (IconoRed, trazos de Simple Icons, CC0).
- enlaces: lo externo abre en otra pestaña con noopener y aviso para
  lectores de pantalla (lib/enlaces.ts); mailto y anclas se quedan.
- Proceso: las ocho tarjetas no aparecían nunca en móvil (amount 0.3 sobre
  una lista de ~3000px); ahora cada una se revela sola. El ≡ de la 08 ya no
  tapa un entregable, título equilibrado, etiqueta a 12px, sin elevar al
  hover lo que no es clicable.
- Disciplinas: la frase «No son la promesa — son los medios» gana peso y
  se agrupa con título e ilustración; sin cortes huérfanos en móvil.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:27:20 -06:00

78 lines
3.8 KiB
TypeScript

import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { PuntosInflexion } from '../PuntosInflexion';
import { puntosInflexion } from '@/lib/content';
describe('<PuntosInflexion />', () => {
it('still has a heading after losing its header block', () => {
render(<PuntosInflexion />);
// The eyebrow and the deck's title used to sit in a light strip above the
// pinned stage; with them gone the lead carries the heading level. A
// section this long with no heading at all is a hole in the outline —
// for a screen reader the six exchanges would hang off nothing.
const encabezado = screen.getByRole('heading', { name: /te reconoces/i });
expect(encabezado.tagName).toBe('H2');
});
it('labels both halves of every exchange with its inflection point', () => {
render(<PuntosInflexion />);
// Twice per point, once on each frame. The pinned sequence shows one thing
// at a time, so when creeer's answer is on screen the question that
// prompted it is gone — the repeated label is the only thing left tying the
// two together. Dropping it from the answer would leave six statements
// floating with nothing to answer.
for (const name of ['Crecer', 'Consolidarse', 'Recuperar rentabilidad', 'Simplificar', 'Expandirse', 'Replantear el portafolio']) {
expect(screen.getAllByText(new RegExp(name))).toHaveLength(2);
}
expect(screen.getAllByRole('listitem')).toHaveLength(6);
});
it('answers every situation instead of only naming it', () => {
render(<PuntosInflexion />);
// The whole point of the section, and the one thing that would silently
// regress back into the old mute grid: six situations, six answers, each
// spoken by creeer.
expect(screen.getAllByLabelText('creeer')).toHaveLength(6);
for (const { respuesta } of puntosInflexion.items) {
expect(screen.getByText(respuesta)).toBeInTheDocument();
}
});
it('never lets creeer answer by repeating the situation back', () => {
// The restructure of lib/content.ts once aliased `respuesta` to
// `situacion`: problem and answer read the same, and the test above still
// passed because the situation renders inside «».
for (const { situacion, respuesta } of puntosInflexion.items) {
expect(respuesta).not.toBe(situacion);
}
});
it('states each situation in the second person, as the dueña reads them', () => {
// Her own phrasing in the 31/jul call: "estás atrapado en tu compañía",
// "creciste muy rápido pero quieres expandirte". The deck's infinitives
// ("Dar el siguiente salto") would put the reader outside their own story.
//
// Only real second-person markers count here. The first draft of this
// pattern also accepted `dejó|volvió|abiertos|mismo`, which let four
// impersonal lines through — "El esfuerzo dejó de traducirse en resultado"
// never addresses anyone. That was the test being bent to fit the copy.
for (const { situacion } of puntosInflexion.items) {
expect(situacion).toMatch(/\b(tu|tus|te|ti|tienes|vas|sabes|quieres|puedes|demostraste|construiste|creciste)\b/i);
}
});
it('keeps the situations about the business, not about how it feels', () => {
// `dolores` is four sections down and owns the feelings, in the client's
// own first-person words. If a situation starts saying "siento" or "estoy
// agotado", the two sections collapse into each other.
for (const { situacion } of puntosInflexion.items) {
expect(situacion).not.toMatch(/\b(siento|me siento|estoy|agotad|frustrad|harto)\b/i);
}
});
it('does NOT introduce scarcity', () => {
const { container } = render(<PuntosInflexion />);
expect(container.textContent).not.toMatch(/cupos|cohorte|generación fundadora/i);
});
});