You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
4.1 KiB
112 lines
4.1 KiB
import { expect, test } from '@playwright/test';
|
|
|
|
/** Anchos que representan un móvil pequeño, uno normal, una tableta y un panel. */
|
|
const ANCHOS = [320, 375, 768, 1440];
|
|
|
|
const RUTAS = [
|
|
'/',
|
|
'/musica',
|
|
'/musica/baladas-romanticas',
|
|
'/albumes/como-si-nada',
|
|
'/canciones/dorina',
|
|
'/taller/bachata',
|
|
'/blog',
|
|
'/etiquetas',
|
|
'/carrito',
|
|
'/entrar'
|
|
];
|
|
|
|
test.describe('Responsive', () => {
|
|
for (const ancho of ANCHOS) {
|
|
test(`ninguna página desborda a lo ancho a ${ancho}px`, async ({ page }) => {
|
|
// Es el fallo clásico: un elemento se pasa de ancho, aparece una barra
|
|
// horizontal y toda la página se puede arrastrar de lado.
|
|
await page.setViewportSize({ width: ancho, height: 800 });
|
|
|
|
for (const ruta of RUTAS) {
|
|
await page.goto(ruta);
|
|
const desborde = await page.evaluate(
|
|
() => document.documentElement.scrollWidth - window.innerWidth
|
|
);
|
|
expect(desborde, `${ruta} a ${ancho}px`).toBeLessThanOrEqual(1);
|
|
}
|
|
});
|
|
}
|
|
|
|
test('los controles se pueden pulsar con el dedo', async ({ page }) => {
|
|
// 24x24 es el mínimo de la norma. Los enlaces dentro de un texto quedan
|
|
// fuera —los limita la línea—, pero un botón suelto no tiene excusa.
|
|
await page.setViewportSize({ width: 375, height: 800 });
|
|
|
|
for (const ruta of ['/', '/musica', '/carrito', '/canciones/dorina']) {
|
|
await page.goto(ruta);
|
|
const pequenos = await page.evaluate(() => {
|
|
const fuera: string[] = [];
|
|
for (const e of document.querySelectorAll('button, input, select, [role="button"]')) {
|
|
const c = e.getBoundingClientRect();
|
|
if (!c.width || !c.height) continue;
|
|
if (c.width < 24 || c.height < 24) {
|
|
fuera.push(`${e.getAttribute('aria-label') ?? e.textContent?.trim().slice(0, 20)}`);
|
|
}
|
|
}
|
|
return [...new Set(fuera)];
|
|
});
|
|
expect(pequenos, `controles pequeños en ${ruta}`).toEqual([]);
|
|
}
|
|
});
|
|
|
|
test('la barra de reproducción no tapa el final de la página', async ({ page }) => {
|
|
// La barra se apila en un móvil y crece de 97 a 145 píxeles. El hueco que
|
|
// se le reserva sale de medirla, no de un número escrito a mano: con uno
|
|
// fijo, en móvil se comía el pie.
|
|
await page.setViewportSize({ width: 375, height: 800 });
|
|
await page.goto('/albumes/como-si-nada');
|
|
await page.getByRole('button', { name: 'Reproducir', exact: true }).first().click();
|
|
await expect(page.getByRole('region', { name: 'Reproductor' })).toBeVisible();
|
|
|
|
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
|
|
|
|
const solapa = await page.evaluate(() => {
|
|
const barra = document.querySelector('[aria-label="Reproductor"]')!.getBoundingClientRect();
|
|
const pie = document.querySelector('footer')!.getBoundingClientRect();
|
|
return Math.round(pie.bottom - barra.top);
|
|
});
|
|
expect(solapa).toBeLessThanOrEqual(1);
|
|
});
|
|
|
|
test('en móvil la navegación se despliega y sigue completa', async ({ page }) => {
|
|
await page.setViewportSize({ width: 375, height: 800 });
|
|
await page.goto('/');
|
|
|
|
const nav = page.getByRole('navigation', { name: 'Principal' });
|
|
await expect(nav).toBeHidden();
|
|
|
|
await page.getByRole('button', { name: 'Menú' }).click();
|
|
await expect(nav).toBeVisible();
|
|
await expect(nav.getByRole('link')).toHaveCount(5);
|
|
});
|
|
|
|
test('las barras laterales bajan en vez de desaparecer', async ({ page }) => {
|
|
// Son la navegación de su sección: esconderlas deja la página sin salidas.
|
|
await page.setViewportSize({ width: 375, height: 800 });
|
|
|
|
await page.goto('/musica/baladas-romanticas');
|
|
await expect(page.getByRole('navigation', { name: 'Estilos' })).toBeVisible();
|
|
|
|
await page.goto('/taller/bachata');
|
|
await expect(page.getByRole('navigation', { name: 'Contenido del taller' })).toBeVisible();
|
|
});
|
|
|
|
test('la tabla se desplaza dentro de su marco, no arrastra la página', async ({ page }) => {
|
|
await page.setViewportSize({ width: 375, height: 800 });
|
|
await page.goto('/musica');
|
|
await page.getByRole('button', { name: 'Tabla' }).click();
|
|
|
|
const dentro = await page.evaluate(() => {
|
|
const marco = document.querySelector('.marco')!;
|
|
return marco.scrollWidth > marco.clientWidth;
|
|
});
|
|
expect(dentro).toBe(true);
|
|
});
|
|
});
|