Compare commits

...
Author SHA1 Message Date
devopsandClaude Sonnet 5 e6c3e0ed8d docs(adr-0010): resultados de la segunda tanda de pruebas con navegador real
Checkout con carrito vacío, fallback WhatsApp, filtros de catálogo,
búsqueda sin resultados (bug encontrado y corregido en otro commit),
slug de producto inválido (hallazgo pendiente de investigar: responde
200 en vez de 404), zoom interactivo, wishlist, otros viewports,
página 404 genérica, accesibilidad básica del buscador, y registro/
login con email -- todo verificado con Chromium real vía el harness de
.browser-scratch/.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR
2026-09-11 13:12:00 +00:00
devopsandClaude Sonnet 5 35fdea5df5 Merge: mostrar mensaje cuando el buscador no tiene resultados
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (push) Successful in 23s
Build and Push Frontend / Construir y Subir Imagen (push) Successful in 19m18s
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR
2026-09-11 13:08:53 +00:00
devopsandClaude Sonnet 5 8d44f2e771 fix(ecommerce): mostrar mensaje cuando el buscador no tiene resultados
Encontrado probando en vivo con navegador real (Docker + Playwright):
una búsqueda de 2+ caracteres sin coincidencias no mostraba nada -- ni
"Buscando…" ni ningún mensaje. El usuario quedaba sin feedback de que
su búsqueda de verdad corrió. Se agrega un estado vacío con el botón
de buscar en todo el catálogo (esa búsqueda completa puede usar
criterios más amplios que el autocompletado).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR
2026-09-11 13:08:50 +00:00
gitea-actions ef6dc1f6a8 chore(gitops): deploy Docs Portal v1.0.242 [skip ci] 2026-09-10 21:46:38 +00:00
devopsandClaude Sonnet 5 352762b9d2 Merge: ampliar checklist de pruebas reales pendientes (ADR 0010)
Build and Push Docs Portal / Escaneo de Secretos (Gitleaks) (push) Successful in 20s
Build and Push Docs Portal / Construir y publicar Docs Portal (push) Successful in 6m6s
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR
2026-09-10 21:40:11 +00:00
devopsandClaude Sonnet 5 58cc93bb2f docs(adr-0010): ampliar checklist de pruebas reales pendientes
Cubre el resto de la superficie del storefront (checkout edge cases,
filtros de catalogo, variantes de producto, cuenta/wishlist,
accesibilidad, otros viewports) agrupado por riesgo, no solo lo ya
probado.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR
2026-09-10 21:40:09 +00:00
3 changed files with 99 additions and 16 deletions

No files matched your search

@@ -328,7 +328,69 @@ compartido) para que el contenedor vea los archivos de verdad.
`<select>` del checkout. Ningún banco PSE real tiene código "0" —
se filtra explícitamente en `pse-banks/route.ts`.
### Pendiente — checklist ampliado para la próxima sesión con navegador
Ampliado 2026-09-10 con el resto de la superficie real del storefront
(4 páginas + `components/{account,cart,catalog,checkout,home,layout,
product,search,wishlist}`), agrupado por riesgo, y ejecutado el mismo
día contra `shop.cruzcloud.net` con el harness de `.browser-scratch/`.
### RESUELTO (2026-09-11) — segunda tanda con navegador real
Resultados reales, uno por uno (código de cada prueba en
`checks.mjs`):
- **`/checkout` con carrito vacío (ítem 9) — OK.** Muestra "Tu carrito
está vacío" con link a `/catalog`, no rompe.
- **Fallback "Confirmar por WhatsApp" (ítem 10) — OK.** Abre
`api.whatsapp.com/send?phone=...` en pestaña nueva con el mensaje del
pedido armado correctamente.
- **Filtros de `/catalog` (ítem 11) — OK.** Un filtro de categoría real
("Figuras de acción") redujo los productos mostrados de 18 a 4. Nota:
estos filtros (categoría/marca/edad dentro de la barra lateral) son
**estado de cliente, no reflejado en la URL** — distinto de los
filtros por query param (`?category=...`) que sí usa la navegación
del header. Ninguno de los dos es un bug, son dos mecanismos
distintos coexistiendo; queda como nota para no confundirlos.
- **Búsqueda sin resultados (ítem 12) — BUG real encontrado y
corregido.** El dropdown de autocompletado no mostraba absolutamente
nada (ni "Buscando…" ni ningún mensaje) cuando una búsqueda de 2+
caracteres no tenía coincidencias — el usuario se quedaba sin
feedback de que su búsqueda había corrido. Corregido en
`predictive-search.tsx`: ahora muestra "No encontramos resultados
para…" con el botón de buscar en todo el catálogo.
- **Slug de producto inválido (ítem 14) — hallazgo, no corregido
todavía.** La página sí muestra el contenido correcto de "Este tesoro
no existe" (el código ya llama a `notFound()` de
`next/navigation`, como corresponde), **pero la respuesta HTTP real
es `200`, no `404`** — confirmado independientemente con `curl`, no
es un artefacto de Playwright. No se investigó a fondo en qué capa se
pierde el status real (Next.js standalone vs. alguna capa de
Cloudflare/NPM/Traefik en el medio, ver
`incidente-cloudflared-504-quic-2026-08.md` para precedente de
problemas de red en esa cadena) — bajo impacto en la experiencia del
usuario (el contenido es correcto), pero sí afecta SEO/crawlers.
Queda como pendiente de investigar, no de corregir a ciegas.
- **Zoom interactivo del producto (ítem 15) — OK.** Hover-zoom y el
modal de click-to-zoom siguen funcionando igual tras los cambios
recientes al storefront.
- **Wishlist/favoritos (ítem 17) — OK.** Agregar a favoritos +
recargar la página: persiste correctamente vía `localStorage`.
- **Otros viewports, tablet y desktop grande (ítem 19) — OK.**
Capturas guardadas, sin problemas de layout visibles en el banner ni
el header en esos anchos.
- **Página 404 genérica (ítem 20) — OK.** Una ruta que no existe cae en
`not-found.tsx` con status HTTP `404` real (a diferencia del caso de
producto inválido arriba — la diferencia de comportamiento entre
ambos casos es justamente lo que quedó como pendiente de investigar).
- **Accesibilidad básica (ítem 21) — OK, parcial.** El buscador es
alcanzable navegando solo con `Tab` desde el body, sin mouse. Falta
probar el resto del flujo de checkout por teclado.
- **Registro/login con email y contraseña (parte del ítem 16) — OK.**
Crear cuenta con nombre/apellido/email/contraseña funciona y deja la
sesión iniciada. La parte de Google OAuth sigue sin probarse (necesita
una cuenta de Google real, no algo que se pueda automatizar sin
credenciales).
### Pendiente — lo que queda sin probar
3. **Resiliencia del fallback de envío:** forzar una dirección o
producto que haga fallar la cotización real de EnvíoClick (ej. un
@@ -340,17 +402,26 @@ compartido) para que el contenedor vea los archivos de verdad.
conseguir credenciales de prueba reales de PSE (persona/clave de
algún banco del ambiente `desarrollo`), completar el login bancario
de punta a punta, y confirmar que el webhook mueve la orden a
completada sin intervención manual — hoy solo se confirmó que el
endpoint responde `200` a un `POST` sintético y que la redirección
al banco ocurre, no el ciclo completo con notificación real.
7. **Login/registro de cliente real** (Google OAuth y con contraseña) —
nunca ejercitado con un navegador real en ninguna sesión.
8. **Bug conocido de Firefox Android** (ver memoria de proyecto,
`known-bug-firefox-android-layout`): el layout se corta/desplaza
solo en Firefox Android — Playwright puede emular Android/Chrome
pero no Firefox; si se necesita reproducir esto específicamente hace
falta `playwright-firefox` o un dispositivo real.
9. **Otros viewports** (tablet, desktop grande) para el banner y el
buscador — solo se probaron mobile (iPhone 13) y desktop 1280px.
10. **Flujo de wishlist/favoritos y el diálogo de cuenta** — no
ejercitados todavía con navegador real.
completada sin intervención manual.
7. **Pago cancelado o rechazado en el banco PSE:** confirmar que la
orden no queda en un estado ambiguo ("colgada" en
`pending_authorization` para siempre).
8. **Persona jurídica + NIT** en el formulario de PSE — solo se probó
persona natural con cédula.
13. **Selección de variantes** (cuando un producto tiene más de una) y
que el precio/disponibilidad mostrado cambie según la variante
elegida — ningún producto probado hasta ahora tenía más de una
variante real.
14b. **Investigar por qué `/product/<slug-inválido>` responde HTTP 200**
en vez de 404 pese a llamar `notFound()` correctamente (ver
hallazgo arriba) — identificar la capa responsable antes de tocar
código.
16b. **Login con Google (OAuth completo)** incluyendo
`/auth/google/callback` — necesita una cuenta de Google real de
prueba.
18. **Bug conocido de Firefox Android** (ver memoria de proyecto,
`known-bug-firefox-android-layout`) — Playwright puede emular
Android/Chrome pero no Firefox; hace falta `playwright-firefox` o
un dispositivo real.
21b. **Accesibilidad del checkout completo** por teclado (no solo el
buscador) — tab order y foco visible en los 3 pasos.
@@ -25,7 +25,7 @@ spec:
runAsNonRoot: false
containers:
- name: app
image: gitea.cruzcloud.net/devops/docs-portal:v1.0.241
image: gitea.cruzcloud.net/devops/docs-portal:v1.0.242
# El base saca TODAS las capabilities. Probado en vivo y
# revertido: con drop: ALL (aunque se agregue NET_BIND_SERVICE
# de vuelta) el propio entrypoint de nginx:1.27-alpine falla al
@@ -87,6 +87,18 @@ export function PredictiveSearch() {
Buscando…
</div>
)}
{/* Encontrado probando en vivo con navegador real: sin este bloque,
una busqueda de 2+ caracteres sin coincidencias no mostraba nada
(ni "buscando" ni un mensaje) -- el usuario se quedaba sin ningun
feedback de que su busqueda de verdad corrio. Se ofrece igual el
boton de buscar en todo el catalogo porque esa busqueda completa
puede usar criterios mas amplios que el autocompletado. */}
{!loading && normalized.length >= 2 && matches.length === 0 && (
<div className="absolute left-0 right-0 top-[calc(100%+10px)] z-50 rounded-2xl border border-slate-200 bg-white p-2 text-center shadow-2xl">
<p className="p-3 text-sm text-slate-500">No encontramos resultados para “{query.trim()}”.</p>
<button type="submit" className="w-full rounded-xl bg-ari-marino px-4 py-3 text-sm font-black text-white hover:brightness-110">Buscar “{query.trim()}” en todo el catálogo</button>
</div>
)}
{matches.length > 0 && (
<div className="absolute left-0 right-0 top-[calc(100%+10px)] z-50 overflow-hidden rounded-2xl border border-slate-200 bg-white p-2 shadow-2xl">
{matches.map((product) => (