Files
Creeer-Web/components/sections/__tests__/Dolores.test.tsx
T
erikghandClaude Opus 5 99c9f77547 feat(dolores): las cuatro frases se apilan en vez de desfilar
El rótulo en bucle era idea mía y era peor que las tarjetas que sustituía.
Medido contra el tono bloqueado de la marca —«seguridad + cercanía»,
«simple, directo, limpio»— un marquee es lo contrario de los tres:
arrastra la asociación con banner de rebajas y teletipo. Y cortaba cada
frase por los dos bordes, así que ninguna llegaba entera.

Ahora entran de una en una al bajar y se quedan. El peso lo da el montón,
no el recorrido: cada una cae con una sangría distinta —irregular a
propósito, una regular se lee como lista y una irregular como cuatro
voces en la misma habitación— y al llegar la cuarta el lector las ve
todas juntas. Debajo, el remate alineado a la izquierda y quieto.

Se acabó la duplicación: el bucle necesitaba pintar cada frase cuatro
veces y esconder tres de los lectores de pantalla. Una frase, una vez.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 15:50:17 -06:00

51 lines
2.4 KiB
TypeScript

import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { Dolores } from '../Dolores';
import { dolores } from '@/lib/content';
describe('<Dolores />', () => {
it('renders the four pains verbatim, in the client\'s first person', () => {
render(<Dolores />);
for (const dolor of dolores.quotes) {
expect(screen.getAllByText(new RegExp(dolor.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))).length).toBeGreaterThan(0);
}
});
it('says each pain exactly once', () => {
const { container } = render(<Dolores />);
// A marquee needed the four sentences painted four times over — twice per
// row for a seamless loop, twice again for the second row — and three of
// those runs had to be hidden from assistive tech or a screen reader would
// recite the whole list twice. Stacked, there is nothing to hide: one
// sentence, once, said once.
for (const dolor of dolores.quotes) {
const apariciones = Array.from(container.querySelectorAll('blockquote')).filter(
(el) => el.textContent?.includes(dolor),
);
expect(apariciones).toHaveLength(1);
expect(apariciones[0].closest('[aria-hidden="true"]')).toBeNull();
}
expect(container.querySelectorAll('li')).toHaveLength(dolores.quotes.length);
});
it('closes with the resolution, not with more effort', () => {
const { container } = render(<Dolores />);
expect(container.textContent).toContain('Esto no se resuelve con más esfuerzo.');
expect(container.textContent).toContain('Se resuelve con una estrategia clara.');
});
it('centres the knot so the conductor thread runs through it', () => {
const { container } = render(<Dolores />);
// The knot is the centred decorative svg of the section; the conductor
// thread runs down the centre, so only a centred knot gets traversed by
// it — stitching the pain to the resolution below.
const centrados = Array.from(container.querySelectorAll('svg')).filter((s) => {
const cls = s.getAttribute('class') ?? '';
return cls.includes('left-1/2') && cls.includes('-translate-x-1/2');
});
expect(centrados.length).toBeGreaterThanOrEqual(1);
});
it('does NOT introduce scarcity', () => {
const { container } = render(<Dolores />);
expect(container.textContent).not.toMatch(/cupos|cohorte|generación fundadora/i);
});
});