Skip to content

Repository files navigation


🧠 Por qué construí esto

Terminé el curso de Cypress de Free Range Testers y quise llevar los ejercicios a algo más cercano a un entorno real de QA. En lugar de dejar tests sueltos por carpeta, armé una suite organizada con pipeline automático y reporte publicado en cada ejecución.

El objetivo no era acumular tests — era entender cómo se construye una suite que un equipo real pueda confiar.


📊 Resultados

Getting Started Advanced Examples FreeRange + POM API Tests TOTAL
🧪 Specs 1 16 6 7 34
✅ Tests 6 118 13 7 146
⏱ Duración ~0:05 ~1:45 ~1:10 ~0:30 ~4:30
Estado

🔍 Lo que realmente aprendí sobre QA

Más allá de las herramientas, esto es lo que cambió en cómo pienso sobre testing.


☑️ La estabilidad importa más que la cantidad de tests

Al principio mi instinto era agregar más tests para "cubrir más". Pero algunos fallaban una vez sí y una vez no, sin que el sistema hubiera cambiado. Eso es peor que no tener el test: un test intermitente genera desconfianza en toda la suite. Si el equipo aprende a ignorar los fallos porque "a veces pasa", también va a ignorar el fallo real cuando aparezca.

Entendí que un test confiable que corre siempre igual vale más que cinco tests que pasan la mayoría de las veces. La cobertura no se mide en cantidad — se mide en cuánto puedes confiar en lo que el resultado te dice.

Eso me llevó a revisar cada test y preguntarme: ¿este test falla solo cuando el sistema tiene un problema real, o también puede fallar por otras razones? Esa pregunta cambió cómo diseño los assertions.


☑️ Entender bien el flujo antes de automatizar

Mi proceso en este proyecto fue siempre el mismo: primero ejecutaba el caso manualmente, observaba qué pasaba en cada paso, identificaba qué era lo que realmente importaba validar. Recién después automatizaba.

Eso parece obvio, pero no lo es. Es fácil empezar a escribir código sin tener claro qué está probando. El resultado son tests llenos de assertions que validan cosas irrelevantes y no validan lo que importa. O peor: tests que pasan aunque el sistema esté roto porque el assertion no apunta al lugar correcto.

Ejecutar manualmente primero me obligó a hacerme la pregunta correcta antes de escribir: ¿qué comportamiento del sistema estoy garantizando con este test? No qué código voy a escribir, sino qué promesa está haciendo el test sobre el sistema.


☑️ Separar lo que es comportamiento de lo que es contenido

Cuando empecé a testear el sitio de Free Range Testers, validaba texto exacto: el nombre de un enlace, el título de una página. El sitio actualizó su contenido y mis tests fallaron. Pero el sistema no estaba roto — el sitio simplemente cambió un texto.

Eso me enseñó una distinción que aplico en todos los tests ahora: comportamiento es lo que el sistema hace (¿la página responde?, ¿la navegación funciona?, ¿el endpoint devuelve datos?). Contenido es lo que dice (¿el botón dice exactamente "Talleres"?). El comportamiento es responsabilidad del sistema y debo validarlo. El contenido puede cambiar sin que eso sea un bug.

Un test que falla cuando el sistema está funcionando bien genera trabajo innecesario y erosiona la confianza del equipo en la suite.


☑️ Organizar el código de pruebas como si alguien más lo fuera a leer

Al inicio tenía tests largos donde todo estaba junto: los datos, los selectores, la lógica. Funcionaban, pero eran difíciles de entender de un vistazo y más difíciles de mantener.

Empecé a separar responsabilidades: los datos van en fixtures JSON, los selectores y acciones van en Page Objects, las secuencias repetidas van en custom commands. Cada archivo tiene una sola responsabilidad.

Esto no es solo una buena práctica de código — es una decisión de calidad. Un test que nadie entiende es un test que nadie va a mantener. Y un test que no se mantiene se convierte en ruido: falla, alguien lo desactiva "temporalmente", y esa cobertura desaparece sin que nadie lo note.

Cuando el código de pruebas es claro, el equipo puede leer el test y entender qué garantía está dando sobre el sistema. Eso convierte los tests en documentación viva.


☑️ Los reportes son para tomar decisiones, no para registrar ejecuciones

Integrar Allure al pipeline me hizo ver los reportes de una manera diferente. Un reporte no es solo "cuántos tests pasaron". Es la respuesta a la pregunta que el equipo necesita responder después de un deploy: ¿podemos confiar en que el sistema está funcionando?

Para que esa respuesta sea útil, el reporte tiene que ser claro. Tiene que mostrar qué se probó, qué falló y con suficiente contexto para entender por qué. Un reporte con 145 tests en verde da confianza. Un reporte con 3 tests en rojo con screenshots y nombre descriptivo da dirección.

Publicar el reporte automáticamente en cada push —disponible para cualquier persona del equipo sin tener que ejecutar nada— es parte de hacer que la suite sea útil más allá de mi máquina local.


☑️ El aislamiento entre tests no es un detalle técnico — es una decisión de diseño

Cuando los tests comparten estado —cookies de una sesión anterior, datos en localStorage, variables que un test modifica y el siguiente hereda— el orden de ejecución empieza a importar. Y en automatización, el orden no debería importar nunca.

Si el orden importa, significa que los tests tienen dependencias ocultas entre sí. Eso hace que los fallos sean difíciles de reproducir: el test pasa si corre solo, falla si corre después de otro. Ese tipo de fallo es el más costoso porque nadie sabe con certeza qué está causando el problema.

Diseñar cada test para que empiece desde cero —sin asumir nada del estado que dejó el test anterior— es lo que hace que los resultados sean predecibles y que los fallos sean accionables.


🗂️ Cobertura del framework

🖥️ UI Testing — interacciones, DOM y responsive
Técnica Spec Descripción
Acciones de usuario actions.cy.js Click, type, drag & drop, scroll, select, check
DOM traversal traversal.cy.js 18 comandos para navegar entre elementos
Responsive viewport.cy.js cy.viewport() con presets de dispositivos reales
Querying querying.cy.js cy.get(), cy.contains(), .within(), cy.root()
Navegación navigation.cy.js cy.go() (historial), cy.reload() con opciones
Window window.cy.js cy.window(), cy.document(), cy.title()
Page Object Model PageObjet.cy.js Clase FreeRangeHome que encapsula selectores
🔌 API Testing — requests, intercept y datos
Técnica Spec Descripción
HTTP directo Api.cy.js PUT y DELETE con validación de status y body
Intercept + Stub Intercet.cy.js Mock de requests antes de llegar al servidor
Network requests network_requests.cy.js cy.request() con BDD syntax y query params
Login bypass Login-Db-Seeding.cy.js Autenticación vía API sin pasar por UI
Data-driven Ejemplos-TetsData-feature.cy.js forEach genera un it() por cada dataset
⚡ Testing avanzado
Técnica Spec Descripción
Accessibility WCAG Accessibilidad.cy.js cypress-axe — impacto, regla y selector por violación
Sesiones y cookies SessionYCookis.cy.js cy.session(), setCookie, clearCookies
Control de tiempo spies_stubs_clocks.cy.js cy.clock(), cy.tick(), cy.spy(), cy.stub()
iFrame testing iFrameTesting.cy.js Acceso a contenido dentro de iframes
Promises en Cypress PromesasCypress.cy.js Cypress.Promise, fetch, manejo de errores async
Tablas HTML Tablas.cy.js Validación estructural y ordenamiento por columna
Popups TestPopup.cy.js Manejo de ventanas emergentes del mismo origen
🏗️ Arquitectura y patrones
Patrón Implementación Por qué importa
Page Object Model cypress/Pages/FreeRangeHome.js Un selector cambia → se actualiza en un lugar
Custom commands cypress/support/commands.js cy.login() — legible y reutilizable en toda la suite
Fixtures JSON cypress/fixtures/ Datos de test separados de la lógica del test
Data-driven forEach sobre arrays Un dataset más → un test más, sin duplicar código
Aliasing .as() Reutilizar elementos y requests sin queries redundantes

🏗️ Estructura del proyecto

Cypress-E2E-Automation/
│
├── .github/
│   └── workflows/
│       └── cypress.yml          ← 4 jobs paralelos + deploy Allure Pages
│
├── cypress/
│   ├── e2e/
│   │   ├── 1-getting-started/   ← 1 spec  │  6 tests
│   │   ├── 2-advanced-examples/ ← 16 specs │ 118 tests
│   │   ├── 3-freeRangeTest/     ← 6 specs  │  13 tests
│   │   ├── Apis-Test/           ← 7 specs  │   7 tests
│   │   └── PageObjetModel/      ← 1 spec   │   1 test
│   │
│   ├── fixtures/                ← profile.json · users.json · titulos.json
│   ├── Pages/                   ← FreeRangeHome.js (Page Object)
│   └── support/
│       ├── commands.js          ← cy.login() y otros custom commands
│       └── e2e.js               ← allure-cypress · cypress-axe
│
├── cypress.config.js
└── package.json

🔄 Pipeline CI/CD

Push a main  /  Pull Request
         │
    ┌────┴──────────────────────────────────┐
    │            │            │             │
Getting      Advanced     FreeRange      API
Started      Examples     + POM         Tests
 6 tests     118 tests    13 tests      7 tests
    │            │            │             │
    └────────────┴────────────┴─────────────┘
                       │
              allure-report  (job final)
                       │
           ┌───────────┴───────────┐
       Merge de los            GitHub Pages
       4 resultados      →    ipanaque94.github.io/
                              Cypress-E2E-Automation/

Videos y screenshots disponibles en Actions → Artifacts por 7 días.


⚙️ Ejecución local

git clone https://github.com/ipanaque94/Cypress-E2E-Automation.git
cd Cypress-E2E-Automation
npm install

# Modo interactivo
npx cypress open

# Headless Chrome
npx cypress run --browser chrome

# Suite específica
npx cypress run --spec "cypress/e2e/Apis-Test/**/*.cy.js"

# Reporte Allure local
npx allure generate allure-results --clean -o allure-report
npx allure open allure-report

🛠️ Stack

Herramienta Versión Uso
🎯 Cypress 14 Framework E2E principal
🟨 JavaScript ES2020 Lenguaje de los tests
📊 allure-cypress 3.x Reporte con trazabilidad por test
cypress-axe 1.x Accessibility testing WCAG
⚙️ GitHub Actions CI/CD paralelo en cada push
🌐 GitHub Pages Publicación automática del reporte

👨‍💻 Autor

Enoc Ipanaque QA Automation Engineer · Lima, Perú

LinkedIn GitHub Email


Selenium · Playwright · Cypress · Rest Assured · Postman · AWS · Jenkins · Docker


About

End-to-end testing project using Cypress for web applications, featuring test scripts for UI interactions, assertions, and integration with CI/CD pipelines for continuous testing.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages