|
|
|
@@ -0,0 +1,204 @@
|
|
|
|
|
/**
|
|
|
|
|
* shot_search_advanced.cjs — Verificación del buscador avanzado (#8)
|
|
|
|
|
* Comprueba: FULLTEXT, filtro autor, filtro tema, filtro cita bíblica,
|
|
|
|
|
* filtro fecha, combinado palabra+autor, multiidioma, formulario desktop/móvil.
|
|
|
|
|
*
|
|
|
|
|
* Uso: NODE_PATH=/home/rafa/joomla-migration/tools/e2e/node_modules node tools/e2e/shot_search_advanced.cjs
|
|
|
|
|
*/
|
|
|
|
|
const { chromium } = require('playwright');
|
|
|
|
|
const path = require('path');
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
|
|
|
|
const BASE = 'http://localhost:8081';
|
|
|
|
|
const OUT = '/tmp/claude-1000/-mnt-c-Users-Chia/2802dab4-7a28-4ab7-ad16-457debcccc00/scratchpad';
|
|
|
|
|
|
|
|
|
|
// Ensure output dir
|
|
|
|
|
fs.mkdirSync(OUT, { recursive: true });
|
|
|
|
|
|
|
|
|
|
function shotPath(name) {
|
|
|
|
|
return path.join(OUT, name + '.png');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function check(page, label, fn) {
|
|
|
|
|
try {
|
|
|
|
|
const result = await fn(page);
|
|
|
|
|
console.log(`✓ ${label}:`, result);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error(`✗ ${label}: ERROR`, e.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(async () => {
|
|
|
|
|
const b = await chromium.launch({ headless: true });
|
|
|
|
|
|
|
|
|
|
// ── 1. FULLTEXT por relevancia ──────────────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/?s=oraci%C3%B3n`, { waitUntil: 'networkidle' });
|
|
|
|
|
// Comprueba que hay resultados
|
|
|
|
|
const cards = await p.$$('.fea-archive-card');
|
|
|
|
|
console.log(`✓ FULLTEXT /?s=oración: ${cards.length} tarjetas`);
|
|
|
|
|
// Comprueba que el formulario avanzado está presente
|
|
|
|
|
const form = await p.$('.fea-adv-form');
|
|
|
|
|
console.log(` formulario avanzado en resultados: ${!!form}`);
|
|
|
|
|
const counter = await p.$('.fea-adv-count');
|
|
|
|
|
const countText = counter ? await counter.textContent() : 'no counter';
|
|
|
|
|
console.log(` contador: ${countText}`);
|
|
|
|
|
await p.screenshot({ path: shotPath('1_fulltext_oración'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 2. Filtro autor ─────────────────────────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
// Fray Marcos = 382, Florentino Ulibarri = 395
|
|
|
|
|
await p.goto(`${BASE}/?s=&fea_author=382`, { waitUntil: 'networkidle' });
|
|
|
|
|
const cards = await p.$$('.fea-archive-card');
|
|
|
|
|
console.log(`✓ Filtro autor (fea_author=382 Fray Marcos): ${cards.length} tarjetas`);
|
|
|
|
|
// Verify selected value in form
|
|
|
|
|
const selVal = await p.$eval('#fea-author', el => el.value).catch(() => 'n/a');
|
|
|
|
|
console.log(` select author value: ${selVal}`);
|
|
|
|
|
await p.screenshot({ path: shotPath('2_filtro_autor'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 3. Filtro categoría + verificación del desplegable ───────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/?fea_cat=1650`, { waitUntil: 'networkidle' });
|
|
|
|
|
const cards = await p.$$('.fea-archive-card');
|
|
|
|
|
console.log(`✓ Filtro categoría (fea_cat=1650 Artículos): ${cards.length} tarjetas`);
|
|
|
|
|
const selVal = await p.$eval('#fea-cat', el => el.value).catch(() => 'n/a');
|
|
|
|
|
console.log(` select cat value: ${selVal}`);
|
|
|
|
|
// Label debe decir "Categoría"
|
|
|
|
|
const catLabel = await p.$eval('label[for="fea-cat"]', el => el.textContent).catch(() => 'n/a');
|
|
|
|
|
console.log(` label categoría: "${catLabel}"`);
|
|
|
|
|
// Contar y listar opciones de categoría (idioma ES)
|
|
|
|
|
const catOpts = await p.$$eval('#fea-cat option', els => els.map(e => e.textContent));
|
|
|
|
|
console.log(` nº opciones categoría: ${catOpts.length}`);
|
|
|
|
|
console.log(` opciones: ${catOpts.join(' | ')}`);
|
|
|
|
|
// No debe contener categorías de carta ni "Testament"
|
|
|
|
|
const badCat = catOpts.filter(t => /Testament/i.test(t));
|
|
|
|
|
console.log(` opciones con 'Testament': ${badCat.length}`);
|
|
|
|
|
await p.screenshot({ path: shotPath('3_filtro_categoria'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 3b. Desplegable de AUTOR: sin "Testamento" ───────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/?s=fe`, { waitUntil: 'networkidle' });
|
|
|
|
|
const autOpts = await p.$$eval('#fea-author option', els => els.map(e => e.textContent));
|
|
|
|
|
console.log(`✓ Desplegable autor: ${autOpts.length} opciones`);
|
|
|
|
|
const badAut = autOpts.filter(t => /Testament/i.test(t));
|
|
|
|
|
console.log(` opciones autor con 'Testament': ${badAut.length} ${badAut.length ? '→ ' + badAut.join(', ') : ''}`);
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 4. Filtro cita bíblica (PREFIJO) ─────────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/?fea_cita=Jn`, { waitUntil: 'networkidle' });
|
|
|
|
|
const cards = await p.$$('.fea-archive-card');
|
|
|
|
|
console.log(`✓ Filtro cita PREFIJO (fea_cita=Jn): ${cards.length} tarjetas`);
|
|
|
|
|
const citaVal = await p.$eval('#fea-cita', el => el.value).catch(() => 'n/a');
|
|
|
|
|
console.log(` input cita value: ${citaVal}`);
|
|
|
|
|
const chip = await p.$('.fea-adv-chip');
|
|
|
|
|
const chipText = chip ? await chip.textContent() : 'no chip';
|
|
|
|
|
console.log(` chip activo: ${chipText}`);
|
|
|
|
|
// Placeholder corto + foco para ver que NO se corta
|
|
|
|
|
const ph = await p.$eval('#fea-cita', el => el.placeholder).catch(() => 'n/a');
|
|
|
|
|
console.log(` placeholder cita: "${ph}"`);
|
|
|
|
|
await p.screenshot({ path: shotPath('4_filtro_cita'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 4b. Cita bíblica con valor largo: comprobar que no desborda ──────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/?fea_cita=Jn%2020%2C%2019-31`, { waitUntil: 'networkidle' });
|
|
|
|
|
// Medir overflow: scrollWidth vs clientWidth del input y de su fila
|
|
|
|
|
const metrics = await p.$eval('#fea-cita', el => ({
|
|
|
|
|
scrollW: el.scrollWidth, clientW: el.clientWidth,
|
|
|
|
|
offsetW: el.offsetWidth, parentW: el.parentElement.clientWidth,
|
|
|
|
|
})).catch(() => null);
|
|
|
|
|
console.log(`✓ Cita valor largo (Jn 20, 19-31): ${JSON.stringify(metrics)}`);
|
|
|
|
|
const overflow = metrics ? (metrics.offsetW > metrics.parentW + 1) : 'n/a';
|
|
|
|
|
console.log(` input desborda su celda: ${overflow}`);
|
|
|
|
|
await p.screenshot({ path: shotPath('4b_cita_largo_nocorta'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 5. Filtro fecha ─────────────────────────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/?fea_date_from=2020-01-01&fea_date_to=2020-12-31`, { waitUntil: 'networkidle' });
|
|
|
|
|
const cards = await p.$$('.fea-archive-card');
|
|
|
|
|
console.log(`✓ Filtro fecha (2020): ${cards.length} tarjetas`);
|
|
|
|
|
await p.screenshot({ path: shotPath('5_filtro_fecha'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 6. Combinado palabra + autor ────────────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/?s=amor&fea_author=384`, { waitUntil: 'networkidle' }); // Enrique Martínez Lozano
|
|
|
|
|
const cards = await p.$$('.fea-archive-card');
|
|
|
|
|
console.log(`✓ Combinado s=amor + fea_author=384 (Enrique M.L.): ${cards.length} tarjetas`);
|
|
|
|
|
await p.screenshot({ path: shotPath('6_combinado_palabra_autor'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 7. Multiidioma /en/?s=love ──────────────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/en/?s=love`, { waitUntil: 'networkidle' });
|
|
|
|
|
const cards = await p.$$('.fea-archive-card');
|
|
|
|
|
// Check form action points to /en/
|
|
|
|
|
const formAction = await p.$eval('.fea-adv-form', el => el.action).catch(() => 'n/a');
|
|
|
|
|
console.log(`✓ Multiidioma /en/?s=love: ${cards.length} tarjetas, form action: ${formAction}`);
|
|
|
|
|
// Check if labels are in English
|
|
|
|
|
const firstLabel = await p.$eval('.fea-adv-label', el => el.textContent).catch(() => 'n/a');
|
|
|
|
|
console.log(` primer label: ${firstLabel}`);
|
|
|
|
|
await p.screenshot({ path: shotPath('7_multiidioma_en'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 8a. Formulario visible en desktop ───────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/?s=fe`, { waitUntil: 'networkidle' });
|
|
|
|
|
const formVisible = await p.isVisible('.fea-adv-form');
|
|
|
|
|
console.log(`✓ Formulario desktop (1280px): visible=${formVisible}`);
|
|
|
|
|
await p.screenshot({ path: shotPath('8a_form_desktop'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 8b. Formulario visible en móvil ────────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 390, height: 844 } });
|
|
|
|
|
await p.goto(`${BASE}/?s=fe`, { waitUntil: 'networkidle' });
|
|
|
|
|
const formVisible = await p.isVisible('.fea-adv-form');
|
|
|
|
|
console.log(`✓ Formulario móvil (390px): visible=${formVisible}`);
|
|
|
|
|
// Check advanced link in mobile header
|
|
|
|
|
const advLink = await p.$('.fea-adv-link');
|
|
|
|
|
const advLinkVisible = advLink ? await advLink.isVisible() : false;
|
|
|
|
|
console.log(` enlace búsqueda avanzada móvil: visible=${advLinkVisible}`);
|
|
|
|
|
await p.screenshot({ path: shotPath('8b_form_mobile'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 9. Página /buscar ────────────────────────────────────────────────────
|
|
|
|
|
{
|
|
|
|
|
const p = await b.newPage({ viewport: { width: 1280, height: 900 } });
|
|
|
|
|
await p.goto(`${BASE}/buscar/`, { waitUntil: 'networkidle' });
|
|
|
|
|
const status = p.url();
|
|
|
|
|
const form = await p.$('.fea-adv-form');
|
|
|
|
|
console.log(`✓ Página /buscar: url=${status}, form=${!!form}`);
|
|
|
|
|
await p.screenshot({ path: shotPath('9_pagina_buscar'), fullPage: false });
|
|
|
|
|
await p.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await b.close();
|
|
|
|
|
console.log(`\nCapturas guardadas en: ${OUT}`);
|
|
|
|
|
})();
|