import { expect, test } from '@playwright/test'; test('las tablas reproducen sobre la miniatura al pasar por la fila y con teclado', async ({ page }) => { await page.setViewportSize({ width: 1440, height: 1000 }); for (const ruta of ['/albumes/cupido-sin-flechas', '/musica?vista=canciones']) { await page.goto(ruta); await page.locator('html[data-hidratado]').waitFor(); if (ruta.startsWith('/musica')) await page.getByRole('button', { name: 'Tabla', exact: true }).click(); const tabla = page.locator('table.tabla-canciones'); const fila = tabla .locator('tbody tr') .filter({ has: page.locator('.mini-control button:enabled') }) .first(); const mini = fila.locator('.mini'); const control = fila.locator('.mini-control'); const play = control.getByRole('button'); await mini.scrollIntoViewIfNeeded(); await page.mouse.move(0, 0); await expect(control).toHaveCSS('opacity', '0'); const antes = await mini.boundingBox(); await fila.locator('.titulo').hover(); await expect(control).toHaveCSS('opacity', '1'); const medidas = await mini.evaluate((el) => { const imagen = el.querySelector('img')!.getBoundingClientRect(); const boton = el.querySelector('button')!.getBoundingClientRect(); return { dx: Math.abs(imagen.x - boton.x), dy: Math.abs(imagen.y - boton.y), ancho: Math.abs(imagen.width - boton.width), alto: Math.abs(imagen.height - boton.height), celdasPrevias: el.closest('td')!.cellIndex }; }); expect(medidas).toEqual({ dx: 0, dy: 0, ancho: 0, alto: 0, celdasPrevias: 0 }); expect(await mini.boundingBox()).toEqual(antes); await page.screenshot({ path: `test-results-publica/tabla-play-${ruta.startsWith('/musica') ? 'catalogo' : 'album'}.png` }); await page.mouse.move(0, 0); await play.focus(); await page.keyboard.press('Tab'); await page.keyboard.press('Shift+Tab'); await expect(play).toBeFocused(); await expect(control).toHaveCSS('opacity', '1'); await expect(play).toHaveAttribute('title', /Reproducir/); await page.keyboard.press('Enter'); await expect(play).toHaveAttribute('aria-label', 'Pausar'); await play.evaluate((b: HTMLButtonElement) => b.blur()); await expect(control).toHaveCSS('opacity', '1'); await expect(page.getByRole('region', { name: 'Reproductor', exact: true })).toBeVisible(); await play.click(); await expect(play).toHaveAttribute('aria-label', /Reproducir/); } }); test('el control sobre la miniatura permanece visible en táctil sin necesitar hover', async ({ browser }) => { const context = await browser.newContext({ viewport: { width: 390, height: 844 }, isMobile: true, hasTouch: true }); try { const page = await context.newPage(); await page.goto('http://127.0.0.1:4180/albumes/cupido-sin-flechas'); await page.locator('html[data-hidratado]').waitFor(); const tabla = page.locator('table.tabla-canciones'); const control = tabla .locator('.mini-control') .filter({ has: page.locator('button:enabled') }) .first(); await control.scrollIntoViewIfNeeded(); await expect(control).toHaveCSS('opacity', '1'); await control.getByRole('button').tap(); await expect(control.getByRole('button')).toHaveAttribute('aria-label', 'Pausar'); expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe( true ); await page.screenshot({ path: 'test-results-publica/tabla-play-tactil.png' }); } finally { await context.close(); } });