Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Giofelix/Proyecto-automatizacion-Empresa/llms.txt

Use this file to discover all available pages before exploring further.

LoginPage encapsula el flujo completo de autenticación del sistema municipal de impuestos. El formulario Angular utiliza un diseño de dos pasos — primero se valida el nombre de usuario (campo #txtU → botón Siguiente) y, sólo si el usuario existe, aparece el campo de contraseña (#txtP → botón Iniciar Sesión). Para absorber inestabilidades de red o sesiones colgadas del pipeline anterior, login() reintenta el paso 1 hasta 3 veces y guarda capturas de pantalla de diagnóstico en playwright/.auth/ ante cualquier fallo.

Importación

LoginPage es consumida desde los archivos de setup/teardown que viven en el directorio playwright/. El import usa una ruta relativa hacia la raíz del proyecto:
// playwright/global-setup.js  y  playwright/global-teardown.js
const { LoginPage } = require('../pages/login/login.page');
La ruta ../pages/login/login.page (sin extensión .js) es la forma que usa el proyecto internamente. Si escribes un script personalizado en la raíz del proyecto, la ruta correcta sería ./pages/login/login.page.

Constructor

El constructor recibe la instancia page de Playwright y registra todos los locators utilizados por los métodos de la clase.
PropiedadLocatorDescripción
usernameInputpage.locator('#txtU')Campo de nombre de usuario (paso 1)
nextButtonpage.getByRole('button', { name: /siguiente|next/i })Botón que avanza al paso de contraseña
passwordInputpage.locator('#txtP')Campo de contraseña (paso 2, aparece tras Siguiente)
loginButtonpage.getByRole('button', { name: /iniciar sesión|sign in|log in/i })Botón que envía las credenciales al servidor
logoutButtonpage.getByRole('menuitem', { name: /cerrar sesión|sign out|log out/i })Ítem de menú para cerrar sesión
userMenuButtonpage.locator('button.mat-menu-trigger.btn-barra')Botón de la barra superior que abre el menú de usuario

Métodos

Navega a la URL base de la aplicación y espera a que Angular haya terminado de inicializar los controles del formulario de login.
await loginPage.navegar();
Comportamiento interno:
  1. Llama a page.goto(process.env.BASE_URL, { waitUntil: 'domcontentloaded', timeout: 120000 }).
  2. Espera con page.waitForFunction a que #txtU tenga la clase ng-pristine, lo que indica que Angular ha completado su ciclo de detección de cambios y el formulario está listo para recibir input.
BASE_URL debe definirse en el archivo .env del proyecto o como variable de entorno del runner de CI. La página no se puede usar antes de que esta variable esté disponible.

login(usuario, password)

Realiza el flujo completo de autenticación de dos pasos con lógica de reintentos automáticos.
usuario
string
required
Nombre de usuario de la aplicación (normalmente leído de process.env.USER_GENERIC).
password
string
required
Contraseña del usuario (normalmente leída de process.env.PASSWORD_UNIVERSAL).
Flujo de ejecución:
1

Paso 1 — Validación de usuario (con reintentos)

El método intenta hasta 3 veces (MAX_INTENTOS = 3) la siguiente secuencia:
  • Hace click() sobre #txtU, llama a fill('') para limpiar, y escribe el usuario con page.keyboard.type(usuario, { delay: 80 }). El despacho a nivel de page.keyboard en lugar de locator.pressSequentially es necesario para que Angular dispare el evento blur en modo headless sobre Linux.
  • Presiona Tab para ejecutar el blur y el ciclo de detección de cambios de Angular que habilita el botón Siguiente.
  • Hace click() sobre nextButton.
  • Espera que passwordInput sea visible (timeout de 20 s por intento).
  • Si el intento falla: guarda un screenshot de diagnóstico, espera 3 s, recarga la página y vuelve a esperar ng-pristine antes del siguiente intento.
  • Tras 3 fallos consecutivos lanza un error descriptivo mencionando la posible sesión colgada.
2

Paso 2 — Autenticación con contraseña

  • Llama a passwordInput.fill(password) y luego loginButton.click().
3

Paso 3 — Espera de redirección con manejo de diálogos intermedios

Entra en un loop que compite con cuatro eventos simultáneos (timeout global de 120 s):
  • okpage.waitForURL('**/modulos**') → login exitoso, rompe el loop.
  • errormat-dialog-container con texto de error de credenciales (/código|no fue posible|credencial|contraseña incorrecta/i) → lanza error con el texto del diálogo.
  • confirm — diálogo de sesión activa previa sin texto de error → acepta el botón Aceptar/Continuar/OK/Sí y reinicia la espera.
  • swal — popup SweetAlert2 (.swal2-popup) → si contiene texto de error cambia a error; si no, cierra con .swal2-confirm y reinicia.
4

Paso 4 — Confirmación de navegación

Espera a que .mat-drawer-inner-container sea visible (hasta 30 s), confirmando que el menú lateral de módulos se ha renderizado correctamente.

logout()

Abre el menú de usuario, hace clic en el ítem de cerrar sesión y espera a que la aplicación regrese a la pantalla de login.
await loginPage.logout();
Comportamiento interno:
  1. Hace click() sobre userMenuButton (con timeout de 10 s) y espera 500 ms para la animación del menú.
  2. Hace click() sobre logoutButton.
  3. Espera que usernameInput (#txtU) vuelva a ser visible, indicando el retorno a la página de login.
logout() está diseñado para tolerar fallos sin romper el pipeline. Si cualquier paso lanza una excepción, el método la captura, emite un console.warn y retorna normalmente. Esto evita que un timeout de red en el teardown marque toda la suite como fallida.

Ejemplo de uso

LoginPage se utiliza exclusivamente en global-setup.js (para autenticarse antes de la suite) y en global-teardown.js (para liberar la sesión del servidor al finalizar).
// playwright/global-setup.js
const { LoginPage } = require('../pages/login/login.page');

// ...
const loginPage = new LoginPage(page);
await loginPage.navegar();
await loginPage.login(process.env.USER_GENERIC, process.env.PASSWORD_UNIVERSAL);
// Guardar estado de autenticación para reutilización en los tests
// (el proyecto persiste sessionStorage manualmente en playwright/.auth/user.json)
// playwright/global-teardown.js
const { LoginPage } = require('../pages/login/login.page');

// ...
const loginPage = new LoginPage(page);
// La sesión se restaura inyectando sessionStorage antes de navegar a la app,
// luego se hace logout para liberar el usuario en el servidor:
await loginPage.logout();
No uses LoginPage dentro de tests individuales. Los tests consumen el estado de autenticación guardado mediante la fixture paginaAutenticada, que restaura el storageState generado por global-setup.js. Esto evita un ciclo de login/logout completo por cada test, reduciendo drásticamente el tiempo de ejecución de la suite.

Screenshots de diagnóstico

Cuando login() necesita registrar un fallo, llama al método interno _guardarScreenshotDiagnostico(nombre).
_guardarScreenshotDiagnostico() es un helper interno de la clase (indicado por el prefijo _). No forma parte de la API pública de LoginPage y no debe llamarse desde los tests. Es invocado automáticamente por login() ante fallos de intento o de credenciales.
Los archivos se guardan en:
playwright/.auth/<nombre>.png
Los nombres posibles son:
Nombre de archivoCuándo se genera
login-intento-1-fallido.pngEl intento 1 de validación de usuario agotó su timeout
login-intento-2-fallido.pngEl intento 2 de validación de usuario agotó su timeout
login-intento-3-fallido.pngEl intento 3 (último) agotó su timeout
login-error-credenciales.pngEl servidor rechazó las credenciales
login-timeout-modulos.pngEl redirect a /modulos no ocurrió en 120 s
Si la suite falla durante global-setup, revisa primero estos screenshots en playwright/.auth/ para distinguir entre un problema de red, credenciales incorrectas o una sesión previa colgada en el servidor.

Build docs developers (and LLMs) love