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.
senzapaura_es/e2e/albumes-tabla.e2e.ts

213 lines
9.9 KiB

import { expect, test } from '@playwright/test';
test('Tabla y Tarjetas cambian a la vez álbumes y canciones', async ({ page }) => {
await page.goto('/musica');
await page.waitForSelector('html[data-hidratado]');
const albumes = page.getByRole('region', { name: 'Álbumes' });
const canciones = page.getByRole('region', { name: 'Canciones', exact: true });
const cantidadAlbumes = await albumes.locator('.tarjeta').count();
const cantidadCanciones = await canciones.locator('.tarjeta').count();
expect(cantidadAlbumes).toBeGreaterThan(0);
await page.getByRole('button', { name: 'Tabla', exact: true }).click();
await expect(albumes.getByRole('table')).toBeVisible();
await expect(albumes.locator('tbody tr')).toHaveCount(cantidadAlbumes);
await expect(canciones.locator('tbody tr')).toHaveCount(cantidadCanciones);
await expect(page.locator('.tarjeta')).toHaveCount(0);
const bordes = await page.evaluate(() => {
const filas = [...document.querySelectorAll('section.albumes tbody tr')];
return {
filas: filas.map((fila) => getComputedStyle(fila.querySelector('th, td')!).borderBottomWidth),
cancionero: getComputedStyle(document.querySelector('section.canciones')!).borderTopWidth
};
});
expect(bordes.filas.slice(0, -1).every((borde) => borde === '1px')).toBe(true);
expect(bordes.filas.at(-1)).toBe('0px');
expect(bordes.cancionero).toBe('0px');
await page
.getByRole('navigation', { name: 'Ver catálogo' })
.getByRole('link', { name: 'Todos los álbumes' })
.click();
await expect(albumes.getByRole('table')).toBeVisible();
await expect(canciones).toHaveCount(0);
await page.getByRole('button', { name: 'Tarjetas', exact: true }).click();
await expect(albumes.locator('.tarjeta')).toHaveCount(cantidadAlbumes);
await expect(albumes.getByRole('table')).toHaveCount(0);
await page
.getByRole('navigation', { name: 'Ver catálogo' })
.getByRole('link', { name: 'Todo el catálogo' })
.click();
await expect(canciones.locator('.tarjeta')).toHaveCount(cantidadCanciones);
});
test('Todos los álbumes permite elegir tabla, filtrar y abrir la ficha', async ({ page }) => {
await page.goto('/musica?vista=albumes&estilo=baladas-romanticas');
await page.waitForSelector('html[data-hidratado]');
await page.getByRole('button', { name: 'Tabla', exact: true }).click();
await page.getByLabel('Buscar en el catálogo').fill('cupido');
const tabla = page.getByRole('table', { name: 'Álbumes' });
await expect(tabla.locator('tbody tr')).toHaveCount(1);
await expect(tabla.getByRole('link', { name: 'Cupido sin flechas', exact: true })).toBeVisible();
await page.getByLabel('Buscar en el catálogo').fill('zzzinexistentezzz');
await expect(page.getByText('No hay álbumes que coincidan.')).toBeVisible();
await page.getByLabel('Buscar en el catálogo').fill('cupido');
await page.getByRole('button', { name: 'Tarjetas', exact: true }).click();
await expect(page.locator('section.albumes .tarjeta')).toHaveCount(1);
await page.getByRole('button', { name: 'Tabla', exact: true }).click();
await tabla.getByRole('link', { name: 'Cupido sin flechas', exact: true }).click();
await expect(page).toHaveURL('/albumes/cupido-sin-flechas');
});
test('el álbum mantiene su reproducción al alternar tabla y tarjetas', async ({ page }) => {
await page.goto('/musica?vista=albumes');
await page.waitForSelector('html[data-hidratado]');
await page
.locator('audio')
.evaluateAll((audios) => audios.forEach((audio) => (audio.muted = true)));
await page.getByRole('button', { name: 'Tabla', exact: true }).click();
const fila = page.getByRole('row').filter({ hasText: 'Cupido sin flechas' });
await fila.getByRole('button', { name: 'Reproducir todo' }).click();
await expect(fila.getByRole('button', { name: 'Pausar', exact: true })).toBeVisible();
const barra = page.getByRole('region', { name: 'Reproductor', exact: true });
await expect(barra).toBeVisible();
await expect
.poll(async () => Number(await page.getByLabel('Posición de reproducción').inputValue()))
.toBeGreaterThan(0);
const tema = await page
.getByRole('group', { name: 'Sonando ahora' })
.locator('a')
.first()
.getAttribute('href');
await page.getByRole('button', { name: 'Tarjetas', exact: true }).click();
const tarjeta = page
.locator('section.albumes .tarjeta')
.filter({ hasText: 'Cupido sin flechas' });
await expect(tarjeta.getByRole('button', { name: 'Pausar', exact: true })).toBeVisible();
await page.getByRole('button', { name: 'Tabla', exact: true }).click();
await expect(fila.getByRole('button', { name: 'Pausar', exact: true })).toBeVisible();
await expect(
page.getByRole('group', { name: 'Sonando ahora' }).locator('a').first()
).toHaveAttribute('href', tema!);
await fila.getByRole('button', { name: 'Pausar', exact: true }).click();
await expect(barra.getByRole('button', { name: 'Reproducir', exact: true })).toBeVisible();
});
test('las tablas comparten ancho sin partir los títulos ni alterar la jerarquía tipográfica', async ({
page
}) => {
await page.setViewportSize({ width: 1536, height: 1000 });
await page.goto('/musica');
await page.waitForSelector('html[data-hidratado]');
await page.getByRole('button', { name: 'Tabla', exact: true }).click();
const tablaAlbumes = page.getByRole('table', { name: 'Álbumes' });
const tablaCanciones = page.getByRole('table', {
name: 'Los temas. Cada encabezado ordena por su columna.'
});
const titulo = tablaCanciones.getByRole('link', {
name: 'Ámame esta noche, nada más',
exact: true
});
const fila = tablaCanciones.getByRole('row', { name: /Ámame esta noche, nada más/ });
await expect(tablaCanciones.getByRole('columnheader', { name: 'Año' })).toBeVisible();
const aspecto = await page.evaluate(() => {
const albumes = document.querySelector<HTMLElement>('section.albumes table')!;
const canciones = document.querySelector<HTMLElement>('section.canciones table')!;
const enlaceTituloAlbum = albumes.querySelector<HTMLAnchorElement>('a.titulo')!;
const enlaceTitulo = [...canciones.querySelectorAll<HTMLAnchorElement>('a.titulo')].find(
(enlace) => enlace.textContent?.trim() === 'Ámame esta noche, nada más'
)!;
const celdaTitulo = enlaceTitulo.closest<HTMLElement>('th')!;
const enlaceAlbum = celdaTitulo.parentElement!.querySelector<HTMLAnchorElement>(
'td.columna-album a'
)!;
return {
anchos: [albumes.getBoundingClientRect().width, canciones.getBoundingClientRect().width],
album: {
tamano: getComputedStyle(enlaceTituloAlbum).fontSize,
peso: getComputedStyle(enlaceTituloAlbum).fontWeight
},
titulo: {
alto: enlaceTitulo.getBoundingClientRect().height,
linea: Number.parseFloat(getComputedStyle(enlaceTitulo).lineHeight),
tamano: getComputedStyle(enlaceTitulo).fontSize,
whiteSpace: getComputedStyle(enlaceTitulo).whiteSpace,
vertical: getComputedStyle(celdaTitulo).verticalAlign
},
pesoAlbum: getComputedStyle(enlaceAlbum).fontWeight,
marco: {
overflow: getComputedStyle(canciones.closest('.tabla-catalogo-marco')!).overflowX,
cabecera: getComputedStyle(canciones.querySelector('thead th')!).position
}
};
});
expect(Math.abs(aspecto.anchos[0] - aspecto.anchos[1])).toBeLessThanOrEqual(1);
expect(aspecto.album).toEqual({ tamano: '16px', peso: '400' });
expect(aspecto.titulo.alto).toBeLessThanOrEqual(aspecto.titulo.linea + 1);
expect(aspecto.titulo.tamano).toBe('16px');
expect(aspecto.titulo.whiteSpace).toBe('nowrap');
expect(aspecto.titulo.vertical).toBe('top');
expect(aspecto.pesoAlbum).toBe('400');
expect(aspecto.marco).toEqual({ overflow: 'auto', cabecera: 'static' });
await expect(titulo).toBeVisible();
await expect(fila).toBeVisible();
const catalogo = page
.getByRole('navigation', { name: 'Ver catálogo' })
.getByRole('link', { name: 'Todo el catálogo' });
const idiomas = page
.getByRole('navigation', { name: 'Idiomas' })
.getByRole('link', { name: 'Todos los idiomas' });
const estilosActivos = await Promise.all(
[catalogo, idiomas].map((enlace) =>
enlace.evaluate((elemento) => ({
color: getComputedStyle(elemento).color,
peso: getComputedStyle(elemento).fontWeight
}))
)
);
expect(estilosActivos[0]).toEqual(estilosActivos[1]);
await page.screenshot({ path: 'test-results/catalogo-tablas-1536.png', fullPage: true });
});
for (const tema of ['claro', 'oscuro']) {
test(`la tabla de álbumes se adapta a escritorio y móvil en ${tema}`, async ({ page }) => {
await page.addInitScript((valor) => localStorage.setItem('senzapaura:tema', valor), tema);
for (const ancho of [1920, 768, 390, 320]) {
await page.setViewportSize({ width: ancho, height: 1000 });
await page.goto('/musica?vista=albumes');
await page.waitForSelector('html[data-hidratado]');
await page.getByRole('button', { name: 'Tabla', exact: true }).click();
const tabla = page.getByRole('table', { name: 'Álbumes' });
await expect(tabla).toBeVisible();
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(
true
);
const medidas = await tabla.evaluate((el) => ({
izquierda: el.getBoundingClientRect().left,
derecha: el.getBoundingClientRect().right,
ancho: innerWidth
}));
expect(medidas.izquierda).toBeGreaterThanOrEqual(0);
expect(medidas.derecha).toBeLessThanOrEqual(medidas.ancho);
const portada = tabla.locator('img').first();
await portada.scrollIntoViewIfNeeded();
await expect
.poll(() =>
portada.evaluate((img: HTMLImageElement) => img.complete && img.naturalWidth > 0)
)
.toBe(true);
await page.evaluate(() => {
const seccion = document.querySelector('section.albumes')!.getBoundingClientRect();
const altoMenu = document.querySelector('.cabecera')!.getBoundingClientRect().height;
const altoBuscador = document
.querySelector('.controles-catalogo')!
.getBoundingClientRect().height;
window.scrollTo(0, scrollY + seccion.top - altoMenu - altoBuscador - 16);
});
await page.screenshot({ path: `test-results/albumes-tabla-${tema}-${ancho}.png` });
}
});
}

Powered by TurnKey Linux.