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.
123 lines
5.2 KiB
123 lines
5.2 KiB
import { expect, test, type Page } from '@playwright/test';
|
|
|
|
/**
|
|
* Abre el formulario y espera a que la página sea interactiva.
|
|
*
|
|
* La espera no es adorno. `page.goto` vuelve cuando la página ha cargado, no
|
|
* cuando Svelte ha tomado el control, y al tomarlo reescribe el valor de cada
|
|
* `input` con el del componente, que está vacío: lo que se teclee antes de ese
|
|
* instante desaparece. Fallaba solo con la máquina cargada, así que se caía en
|
|
* la tanda completa y pasaba al repetir la prueba a solas.
|
|
*
|
|
* Un reintento no lo arregla —comprobar que el texto está puesto no impide que
|
|
* lo borren un instante después—, así que el layout marca el momento con
|
|
* `data-hidratado` y aquí se espera a él.
|
|
*/
|
|
async function abrirFormulario(page: Page) {
|
|
await page.goto('/contacto');
|
|
await page.locator('html[data-hidratado]').waitFor();
|
|
}
|
|
|
|
/** Rellena el formulario con datos válidos, salvo lo que se sobrescriba. */
|
|
async function rellenar(
|
|
page: Page,
|
|
campos: Partial<{ nombre: string; email: string; motivo: string; mensaje: string }> = {}
|
|
) {
|
|
await page.getByLabel('Nombre').fill(campos.nombre ?? 'Ana Ruiz');
|
|
await page.getByLabel('Correo electrónico').fill(campos.email ?? 'ana@example.com');
|
|
await page.getByLabel('Motivo').selectOption(campos.motivo ?? 'colaboracion');
|
|
await page
|
|
.getByLabel('Mensaje')
|
|
.fill(campos.mensaje ?? 'Me gustaría hablar contigo sobre una colaboración para un disco.');
|
|
}
|
|
|
|
test.describe('Formulario de contacto', () => {
|
|
test('el pie lo abre como diálogo sin abandonar la página', async ({ page }) => {
|
|
await page.goto('/interpretes/pilar-na-rua');
|
|
await page.locator('html[data-hidratado]').waitFor();
|
|
const enlace = page
|
|
.getByRole('contentinfo')
|
|
.getByRole('link', { name: 'Formulario de contacto' });
|
|
|
|
await enlace.click();
|
|
const dialogo = page.getByRole('dialog', { name: 'Contacto' });
|
|
await expect(dialogo).toBeVisible();
|
|
await expect(dialogo.getByLabel('Nombre')).toBeFocused();
|
|
await expect(page).toHaveURL('/interpretes/pilar-na-rua');
|
|
|
|
await dialogo.getByRole('button', { name: 'Cerrar contacto' }).click();
|
|
await expect(dialogo).toBeHidden();
|
|
await expect(enlace).toBeFocused();
|
|
});
|
|
|
|
test('el diálogo muestra los errores del servidor y conserva lo escrito', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.locator('html[data-hidratado]').waitFor();
|
|
await page
|
|
.getByRole('contentinfo')
|
|
.getByRole('link', { name: 'Formulario de contacto' })
|
|
.click();
|
|
const dialogo = page.getByRole('dialog', { name: 'Contacto' });
|
|
|
|
await dialogo.getByLabel('Nombre').fill('A');
|
|
await dialogo.getByLabel('Correo electrónico').fill('ana@example.com');
|
|
await dialogo.getByLabel('Motivo').selectOption('colaboracion');
|
|
await dialogo.getByLabel('Mensaje').fill('Hola');
|
|
await dialogo.getByRole('button', { name: 'Enviar mensaje' }).click();
|
|
|
|
await expect(dialogo.getByText('Indica tu nombre.')).toBeVisible();
|
|
await expect(dialogo.getByText(/Cuenta un poco más/)).toBeVisible();
|
|
await expect(dialogo.getByLabel('Correo electrónico')).toHaveValue('ana@example.com');
|
|
});
|
|
|
|
test('la validación del servidor devuelve los errores por campo', async ({ page }) => {
|
|
await abrirFormulario(page);
|
|
// "A" y "Hola" pasan la validación del navegador y fallan en el servidor,
|
|
// que es justo lo que interesa comprobar aquí.
|
|
await rellenar(page, { nombre: 'A', mensaje: 'Hola' });
|
|
await page.getByRole('button', { name: 'Enviar mensaje' }).click();
|
|
|
|
await expect(page.getByText('Indica tu nombre.')).toBeVisible();
|
|
await expect(page.getByText(/Cuenta un poco más/)).toBeVisible();
|
|
});
|
|
|
|
test('lo escrito no se pierde cuando la validación falla', async ({ page }) => {
|
|
await abrirFormulario(page);
|
|
await rellenar(page, { nombre: 'A' });
|
|
await page.getByRole('button', { name: 'Enviar mensaje' }).click();
|
|
|
|
await expect(page.getByText('Indica tu nombre.')).toBeVisible();
|
|
await expect(page.getByLabel('Correo electrónico')).toHaveValue('ana@example.com');
|
|
await expect(page.getByLabel('Motivo')).toHaveValue('colaboracion');
|
|
await expect(page.getByLabel('Mensaje')).not.toBeEmpty();
|
|
});
|
|
|
|
test('el campo trampa descarta los envíos automáticos', async ({ page }) => {
|
|
await abrirFormulario(page);
|
|
await rellenar(page);
|
|
|
|
// Solo un cliente automático rellena este campo: está fuera de la vista
|
|
// y fuera del recorrido de tabulación.
|
|
await page.evaluate(() => {
|
|
const trampa = document.querySelector('#companiaWeb');
|
|
if (trampa instanceof HTMLInputElement) trampa.value = 'https://spam.example';
|
|
});
|
|
await page.getByRole('button', { name: 'Enviar mensaje' }).click();
|
|
|
|
await expect(page.getByText('No se ha podido enviar el mensaje.')).toBeVisible();
|
|
});
|
|
|
|
test('un envío válido no muestra errores de campo', async ({ page }) => {
|
|
await abrirFormulario(page);
|
|
await rellenar(page);
|
|
await page.getByRole('button', { name: 'Enviar mensaje' }).click();
|
|
|
|
// El resultado final depende de si hay proveedor de correo configurado
|
|
// (ver src/lib/server/correo.ts), así que solo se comprueba que la
|
|
// validación ha quedado atrás.
|
|
await expect(page.getByText('Indica tu nombre.')).toHaveCount(0);
|
|
await expect(page.getByText(/Cuenta un poco más/)).toHaveCount(0);
|
|
await expect(page.getByText('Ese correo no parece válido.')).toHaveCount(0);
|
|
});
|
|
});
|