Skip to content

Inventario de data-testid ​

Todos los elementos interactivos de web.theproject.ec tienen un atributo data-testid estable: existe solo para las pruebas y no cambia cuando se retoca el diseño o los textos.

Úsalos siempre en tus pruebas automatizadas:

ts
await page.getByTestId('boton-confirmar').click();

Estructura general ​

testidElementoDónde
cabeceraBarra superiorTodas las pantallas
titulo-appTítulo "ReservaLab"Cabecera
usuario-actualEmail del usuario en sesiónCabecera (autenticado)
boton-cerrar-sesionBotón de salirCabecera (autenticado)
piePie de páginaTodas las pantallas

Pantalla de inicio de sesión ​

testidElementoNotas
pagina-loginContenedor de la pantallaÚtil para comprobar en qué pantalla estás
titulo-loginTítulo "Iniciar sesión"
formulario-loginEl formulario
input-emailCampo de correo
input-passwordCampo de contraseña
boton-entrarBotón de envíoSe deshabilita mientras envía
error-loginMensaje de errorSolo aparece si falla; tiene role="alert"
ts
await page.getByTestId('input-email').fill('student01@theproject.ec');
await page.getByTestId('input-password').fill(password);
await page.getByTestId('boton-entrar').click();
await expect(page.getByTestId('pagina-citas')).toBeVisible();

Pantalla de citas ​

testidElemento
pagina-citasContenedor de la pantalla

Formulario de reserva ​

testidElementoNotas
seccion-nueva-citaBloque de la reserva
titulo-nueva-citaTítulo "Reservar una cita"
formulario-nueva-citaEl formulario
select-servicioDesplegable de serviciosLa primera opción está vacía
opcion-servicio-{id}Cada opción del desplegable{id} es el id real del servicio
input-fechaCampo de fecha y horaTipo datetime-local
input-notasCampo de notasOpcional
boton-confirmarBotón de reservar
mensaje-exitoAviso verderole="status"
mensaje-errorAviso rojorole="alert"

El desplegable de servicios

La opción en el índice 0 es el texto guía ("Elige un servicio…") y no tiene valor. Para seleccionar el primer servicio real usa { index: 1 }, o mejor todavía, pide los servicios a la API y selecciona por su id:

ts
await page.getByTestId('select-servicio').selectOption({ index: 1 });

El campo de fecha

Es datetime-local: espera el formato YYYY-MM-DDTHH:mm en hora local, sin zona y sin segundos.

ts
const fecha = new Date(Date.now() + 30 * 86400000);
fecha.setSeconds(0, 0);
await page.getByTestId('input-fecha').fill(fecha.toISOString().slice(0, 16));

Listado de citas ​

testidElementoNotas
seccion-mis-citasBloque del listado
titulo-mis-citasTítulo "Mis citas"
boton-recargarBotón de recargar
cargando-citasAviso de cargaSolo mientras carga
sin-citasAviso de listado vacíoSolo si no hay citas
tabla-citasLa tablaSolo si hay citas
total-citasResumen "Total: N"

Filas de la tabla ​

Cada fila lleva el id real de la cita en su testid:

testidElemento
fila-cita-{id}La fila completa
servicio-cita-{id}Nombre del servicio
fecha-cita-{id}Fecha formateada
estado-cita-{id}Estado: confirmada, cancelada o completada
boton-cancelar-{id}Botón de cancelar (solo si está confirmada)

Para recorrer todas las filas sin conocer los ids:

ts
// Contar las citas visibles
const filas = page.locator('[data-testid^="fila-cita-"]');
await expect(filas).toHaveCount(5);

// Sacar los ids de las citas que hay ahora
const ids = await filas.evaluateAll((fs) =>
  fs.map((f) => f.getAttribute('data-testid').replace('fila-cita-', '')),
);

// Cancelar la primera cita confirmada
const boton = page.locator('[data-testid^="boton-cancelar-"]').first();
await boton.click();

Buenas prácticas ​

Espera por estado, no por tiempo. Un sleep fijo hace la prueba lenta y frágil a la vez:

ts
// ❌ mal
await page.waitForTimeout(3000);

// ✅ bien
await expect(page.getByTestId('mensaje-exito')).toBeVisible();

Comprueba el efecto, no solo el mensaje. La aplicación puede decir "éxito" sin haber hecho nada:

ts
// Débil: solo mira el cartel
await expect(page.getByTestId('mensaje-exito')).toBeVisible();

// Fuerte: comprueba que el dato cambió de verdad
await expect(page.getByTestId(`estado-cita-${id}`)).toHaveText('cancelada');

Deja el sistema como estaba. Si tu prueba crea una cita, cancélala al final — y espera a que la cancelación se refleje antes de terminar la prueba, o Playwright cierra la página con la petición a medias.

Si falta un testid ​

Si necesitas automatizar algo que no tiene data-testid, avísale al instructor: se puede añadir. Es mejor que recurrir a un selector frágil.

Material del bootcamp de QA. El sistema de práctica contiene defectos a propósito.