import { expect, test } from '@playwright/test'; test.describe('Reproductor', () => { const album = '/albumes/cupido-sin-flechas'; /** El título del tema dentro de la barra, por su enlace exacto. */ const temaEnBarra = (page: import('@playwright/test').Page, slug: string) => page.getByRole('group', { name: 'Sonando ahora' }).locator(`a[href="/canciones/${slug}"]`); test('la escucha pasa por el servidor y admite buscar por tramos', async ({ request }) => { const respuesta = await request.get('/escucha/amame-esta-noche-nada-mas', { headers: { Range: 'bytes=0-31' } }); expect(respuesta.status()).toBe(206); expect(respuesta.headers()['content-range']).toMatch(/^bytes 0-31\/\d+$/); expect((await respuesta.body()).byteLength).toBe(32); }); test('la barra aparece al reproducir un álbum y anuncia el tema', async ({ page }) => { await page.goto(album); const barra = page.getByRole('region', { name: 'Reproductor' }); await expect(barra).toBeHidden(); await page.getByRole('button', { name: 'Reproducir', exact: true }).first().click(); await expect(barra).toBeVisible(); await expect(temaEnBarra(page, 'amame-esta-noche-nada-mas')).toBeVisible(); // Y sigue sonando de verdad, no solo pintada: la posición avanza. Sin esto // el test pasaría igual con una barra congelada. const posicion = page.getByLabel('Posición de reproducción'); const antes = Number(await posicion.inputValue()); await page.waitForTimeout(1500); expect(Number(await posicion.inputValue())).toBeGreaterThan(antes); }); test('la barra aparece al reproducir una canción desde la tabla', async ({ page }) => { await page.goto(album); const logos = page.locator('[data-logo-senza-paura]'); await expect(logos.first()).toHaveCSS('animation-play-state', 'paused'); const fila = page.getByRole('row').filter({ hasText: 'Ton silence me libère' }); const titulo = fila.getByRole('link', { name: 'Ton silence me libère', exact: true }); const estilo = fila.getByRole('link', { name: 'Baladas románticas', exact: true }); const etiquetas = fila.getByRole('list', { name: 'Etiquetas de Ton silence me libère' }); await expect(estilo).toBeVisible(); await expect(etiquetas).toBeVisible(); const alturas = await fila.evaluate((elemento) => { const caja = (selector: string) => elemento.querySelector(selector)!.getBoundingClientRect(); return { titulo: caja('.titulo').top, estilo: caja('.clasificacion').top, etiquetas: caja('.senas').top }; }); expect(alturas.estilo).toBeGreaterThan(alturas.titulo); expect(alturas.etiquetas).toBeGreaterThan(alturas.estilo); await fila.getByRole('button', { name: 'Reproducir Ton silence me libère' }).click(); const barra = page.getByRole('region', { name: 'Reproductor' }); await expect(barra).toBeVisible(); await expect(titulo).toBeVisible(); await expect(temaEnBarra(page, 'ton-silence-me-libere')).toBeVisible(); await expect(fila.getByRole('button', { name: 'Pausar' })).toBeVisible(); await expect(logos.first()).toHaveCSS('animation-play-state', 'running'); await expect(logos.last()).toHaveCSS('animation-play-state', 'running'); const giroInicial = await logos.first().evaluate((logo) => getComputedStyle(logo).transform); await expect .poll(() => logos.first().evaluate((logo) => getComputedStyle(logo).transform)) .not.toBe(giroInicial); await fila.getByRole('button', { name: 'Pausar' }).click(); await expect(logos.first()).toHaveCSS('animation-play-state', 'paused'); await expect(logos.last()).toHaveCSS('animation-play-state', 'paused'); }); test('el paso al tema siguiente carga el orden del disco', async ({ page }) => { await page.goto(album); await page.getByRole('button', { name: 'Reproducir', exact: true }).first().click(); const barra = page.getByRole('region', { name: 'Reproductor' }); await barra.getByRole('button', { name: 'Tema siguiente' }).click(); await expect(temaEnBarra(page, 'cuando-tus-manos-me-tocan')).toBeVisible(); }); test('la reproducción sobrevive al cambiar de página', async ({ page }) => { // Es la razón de que la barra viva en el layout raíz: navegar por la web // no puede cortar lo que se está escuchando. await page.goto(album); await page.getByRole('button', { name: 'Reproducir', exact: true }).first().click(); const barra = page.getByRole('region', { name: 'Reproductor' }); await expect(temaEnBarra(page, 'amame-esta-noche-nada-mas')).toBeVisible(); await page.getByRole('contentinfo').getByRole('link', { name: 'Sobre mí' }).click(); await expect(page).toHaveURL('/bio'); await expect(barra).toBeVisible(); await expect(temaEnBarra(page, 'amame-esta-noche-nada-mas')).toBeVisible(); }); test('la cola muestra los temas pendientes', async ({ page }) => { await page.goto(album); await page.getByRole('button', { name: 'Reproducir', exact: true }).first().click(); const barra = page.getByRole('region', { name: 'Reproductor' }); await barra.getByRole('button', { name: 'Ver la cola de reproducción' }).click(); const cola = page.getByRole('complementary', { name: 'Cola de reproducción' }); await expect(cola).toBeVisible(); await expect(cola.getByRole('button', { name: /Pagué por una noche de amor/ })).toBeVisible(); // Saltar desde la cola cambia lo que suena. await cola.getByRole('button', { name: /Pagué por una noche de amor/ }).click(); await expect(temaEnBarra(page, 'pague-por-una-noche-de-amor')).toBeVisible(); }); });