GUÍA DE APIs Y SERVICIOS WEB - HAKALAB FRAMEWORK
================================================

Esta guía explica cómo realizar testing completo de APIs REST usando el Hakalab Framework.
Incluye validación avanzada de JSON, comparación con archivos, esquemas JSON Schema, y más.

ÍNDICE
======
1. Requests HTTP Básicos
2. Autenticación
3. Headers y Parámetros
4. Validación de Respuestas
5. JSON y Datos
6. Códigos de Estado
7. Validación Avanzada de JSON
8. Comparación con Archivos
9. Validación de Esquemas JSON Schema
10. Validación de Tipos y Patrones
11. Validación de Arrays
12. APIs REST Completas
13. Ejemplos Prácticos Avanzados
14. Configuración Avanzada
15. Troubleshooting

================================================

1. REQUESTS HTTP BÁSICOS
========================

GET Requests:
- envío una petición GET a "/api/usuarios"
- I send GET request to "/api/users"
- envío una petición GET a "https://api.mi-app.com/v1/productos"
- I send GET request to "https://api.my-app.com/v1/products"
- envío una petición GET a la variable "api_endpoint" + "/datos"
- I send GET request to variable "api_endpoint" + "/data"

POST Requests:
- envío una petición POST a "/api/usuarios" con el JSON:
  {
    "nombre": "Juan Pérez",
    "email": "juan@test.com",
    "rol": "usuario"
  }
- I send POST request to "/api/users" with JSON:
  {
    "name": "Juan Pérez",
    "email": "juan@test.com",
    "role": "user"
  }
- envío una petición POST a "/api/productos" con los datos de la variable "nuevo_producto"
- I send POST request to "/api/products" with data from variable "new_product"

PUT y PATCH Requests:
- envío una petición PUT a "/api/usuarios/123" con el JSON:
  {
    "nombre": "Juan Carlos Pérez",
    "email": "juan.carlos@test.com",
    "rol": "admin"
  }
- envío una petición PATCH a "/api/usuarios/123" con el JSON:
  {
    "rol": "admin"
  }

DELETE Requests:
- envío una petición DELETE a "/api/usuarios/123"
- I send DELETE request to "/api/users/123"
- envío una petición DELETE a "/api/productos/456" con el header "X-Confirm" con valor "true"
- I send DELETE request to "/api/products/456" with header "X-Confirm" with value "true"

================================================

2. AUTENTICACIÓN
================

Autenticación Básica:
- establezco autenticación básica con usuario "admin" y contraseña "password123"
- I set basic authentication with user "admin" and password "password123"

Bearer Token:
- establezco el token de autorización "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
- I set authorization token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

API Key:
- establezco el header "X-API-Key" con valor "mi-api-key-secreta"
- I set header "X-API-Key" with value "my-secret-api-key"

Obtener Token de Autenticación:
- envío una petición POST a "/api/auth/login" con el JSON:
  {
    "email": "admin@test.com",
    "password": "admin123"
  }
- extraigo el campo "access_token" de la respuesta y lo guardo en la variable "auth_token"
- establezco el token de autorización de la variable "auth_token"

================================================

3. HEADERS Y PARÁMETROS
=======================

Headers HTTP:
- establezco el header "Content-Type" con valor "application/json"
- I set header "Content-Type" with value "application/json"
- establezco los headers:
  | nombre | valor |
  | Accept | application/json |
  | User-Agent | TestFramework/1.0 |
  | X-Request-ID | test-123 |
- establezco el header "Authorization" con el valor de la variable "auth_header"
- I set header "Authorization" with value from variable "auth_header"

Parámetros de Query:
- envío una petición GET a "/api/productos" con los parámetros:
  | nombre | valor |
  | page | 1 |
  | limit | 10 |
  | category | electronics |
- envío una petición GET a "/api/usuarios" con el parámetro "search" con valor de la variable "busqueda"
- I send GET request to "/api/users" with parameter "search" with value from variable "search_term"

================================================

4. VALIDACIÓN DE RESPUESTAS
===========================

Códigos de Estado:
- la respuesta debería tener código de estado 200
- response should have status code 200
- la respuesta debería tener un código de estado exitoso (2xx)
- response should have successful status code (2xx)
- la respuesta debería tener código de estado 404
- la respuesta debería contener el mensaje "Usuario no encontrado"

Headers de Respuesta:
- la respuesta debería tener el header "Content-Type" con valor "application/json"
- response should have header "Content-Type" with value "application/json"
- la respuesta debería tener el header "X-Rate-Limit"
- response should have header "X-Rate-Limit"
- extraigo el header "Location" de la respuesta y lo guardo en la variable "nueva_ubicacion"
- I extract header "Location" from response and store it in variable "new_location"

Tiempo de Respuesta:
- la respuesta debería llegar en menos de 2000 milisegundos
- response should arrive in less than 2000 milliseconds
- mido el tiempo de respuesta y lo guardo en la variable "response_time"
- la variable "response_time" debería ser menor que 1000

================================================

5. JSON Y DATOS
===============

Validar Estructura JSON:
- la respuesta debería ser JSON válido
- response should be valid JSON
- la respuesta JSON debería tener el campo "id"
- JSON response should have field "id"
- el campo "edad" de la respuesta debería ser un número
- field "age" in response should be a number
- el campo "status" de la respuesta debería ser "active"
- field "status" in response should be "active"

Extraer Datos de JSON:
- extraigo el campo "user_id" de la respuesta y lo guardo en la variable "id_usuario"
- I extract field "user_id" from response and store it in variable "user_id"
- extraigo el campo "user.profile.name" de la respuesta y lo guardo en la variable "nombre_usuario"
- I extract field "user.profile.name" from response and store it in variable "username"
- extraigo el elemento 0 del array "productos" de la respuesta y lo guardo en la variable "primer_producto"
- I extract element 0 from array "products" in response and store it in variable "first_product"

Validar Arrays:
- el array "usuarios" en la respuesta debería tener 5 elementos
- array "users" in response should have 5 elements
- el array "categorías" debería contener "electrónicos"
- array "categories" should contain "electronics"
- el array "resultados" no debería estar vacío
- array "results" should not be empty

================================================

6. CÓDIGOS DE ESTADO
====================

Respuestas Exitosas (2xx):
- 200 OK: la respuesta debería tener código 200
- 201 Created: la respuesta debería tener código 201 y debería tener el header "Location"
- 204 No Content: la respuesta debería tener código 204 y no debería tener contenido

Errores del Cliente (4xx):
- 400 Bad Request: la respuesta debería tener código 400 y debería contener detalles del error
- 401 Unauthorized: la respuesta debería tener código 401 y debería contener "Token inválido"
- 404 Not Found: la respuesta debería tener código 404 y debería contener "Recurso no encontrado"

Errores del Servidor (5xx):
- 500 Internal Server Error: la respuesta debería tener código 500
- 503 Service Unavailable: la respuesta debería tener código 503 y debería tener "Retry-After"

================================================

7. VALIDACIÓN AVANZADA DE JSON
==============================

Validación de Esquemas JSON Schema (Draft 7):
- verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/user_schema.json"
- I verify API response JSON matches schema file "schemas/user_schema.json"

Ejemplo de esquema JSON Schema:
{
  "type": "object",
  "required": ["id", "name", "email"],
  "properties": {
    "id": {"type": "integer"},
    "name": {"type": "string", "minLength": 1},
    "email": {"type": "string", "format": "email"},
    "age": {"type": "integer", "minimum": 0, "maximum": 150},
    "roles": {
      "type": "array",
      "items": {"type": "string"}
    }
  }
}

Validación de Tipos de Campos:
- verifico que el JSON de respuesta API tiene el campo "user.age" con tipo "integer"
- verifico que el JSON de respuesta API tiene el campo "user.email" con tipo "string"
- verifico que el JSON de respuesta API tiene el campo "user.active" con tipo "boolean"
- verifico que el JSON de respuesta API tiene el campo "user.roles" con tipo "array"
- verifico que el JSON de respuesta API tiene el campo "user.profile" con tipo "object"

Tipos soportados:
- string: Cadenas de texto
- number: Números (enteros o decimales)
- integer: Números enteros
- boolean: true/false
- array: Arrays/listas
- object: Objetos/diccionarios
- null: Valores nulos

Validación con Expresiones Regulares:
- verifico que el campo "email" del JSON de respuesta API coincide con el patrón "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
- verifico que el campo "phone" del JSON de respuesta API coincide con el patrón "^\\+?[1-9]\\d{1,14}$"
- verifico que el campo "uuid" del JSON de respuesta API coincide con el patrón "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"

Validación de Rangos Numéricos:
- verifico que el campo "age" del JSON de respuesta API está en el rango 18 a 65
- verifico que el campo "price" del JSON de respuesta API está en el rango 0 a 9999.99
- verifico que el campo "rating" del JSON de respuesta API está en el rango 1 a 5

Validación de Valores Nulos:
- verifico que el JSON de respuesta API no tiene valores nulos
- Busca recursivamente en todo el JSON y falla si encuentra algún null

================================================

8. COMPARACIÓN CON ARCHIVOS
===========================

Comparación Exacta:
- verifico que el JSON de respuesta API coincide exactamente con el archivo "expected/user_response.json"
- I verify API response JSON exactly matches file "expected/user_response.json"
- Compara byte por byte, cualquier diferencia causa fallo

Comparación Ignorando Orden de Arrays:
- verifico que el JSON de respuesta API coincide con el archivo "expected/users.json" ignorando orden
- I verify API response JSON matches file "expected/users.json" ignoring order
- Útil cuando el orden de elementos en arrays no importa

Comparación Ignorando Campos Específicos:
- verifico que el JSON de respuesta API coincide con el archivo "expected/user.json" ignorando campos "id,created_at,updated_at"
- I verify API response JSON matches file "expected/user.json" ignoring fields "id,created_at,updated_at"
- Útil para ignorar timestamps, IDs autogenerados, etc.

Guardar Respuesta en Archivo:
- guardo el JSON de respuesta API en el archivo "responses/actual_response.json"
- I save API response JSON to file "responses/actual_response.json"
- Útil para crear archivos de referencia o debugging

Cargar JSON desde Archivo y Enviar:
- cargo JSON del archivo "payloads/create_user.json" y envío POST a "/api/users" guardando respuesta en variable "response"
- I load JSON from file "payloads/create_user.json" and send POST to "/api/users" storing response in variable "response"
- Útil para mantener payloads complejos en archivos separados

Estructura de Directorios Recomendada:
project/
├── schemas/              # Esquemas JSON Schema
│   ├── user_schema.json
│   ├── product_schema.json
│   └── order_schema.json
├── expected/             # Respuestas esperadas
│   ├── user_response.json
│   └── users_list.json
├── payloads/             # Cuerpos de peticiones
│   ├── create_user.json
│   ├── update_user.json
│   └── create_order.json
└── responses/            # Respuestas guardadas (para debugging)
    └── actual_response.json

================================================

9. VALIDACIÓN DE ESQUEMAS JSON SCHEMA
=====================================

JSON Schema es un estándar para validar la estructura de documentos JSON.
El framework soporta JSON Schema Draft 7.

Ejemplo Completo de Esquema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "User",
  "description": "Schema for user object",
  "type": "object",
  "required": ["id", "name", "email"],
  "properties": {
    "id": {
      "type": "integer",
      "description": "User ID"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "User full name"
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "User email address"
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150
    },
    "roles": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": ["admin", "user", "guest"]
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "profile": {
      "type": "object",
      "properties": {
        "bio": {"type": "string"},
        "avatar": {"type": "string", "format": "uri"}
      }
    },
    "active": {
      "type": "boolean",
      "default": true
    }
  },
  "additionalProperties": false
}

Uso en Tests:

Scenario: Validar estructura de usuario
  When envío petición GET a "/api/users/123"
  Then la respuesta debería tener código 200
  And verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/user_schema.json"

Ventajas de JSON Schema:
✅ Validación completa de estructura
✅ Validación de tipos de datos
✅ Validación de formatos (email, uri, date, etc.)
✅ Validación de rangos y longitudes
✅ Validación de valores permitidos (enum)
✅ Validación de campos requeridos
✅ Validación de propiedades adicionales

================================================

10. VALIDACIÓN DE TIPOS Y PATRONES
==================================

Validación de Tipos de Datos:

Tipos Primitivos:
- verifico que el JSON de respuesta API tiene el campo "name" con tipo "string"
- verifico que el JSON de respuesta API tiene el campo "age" con tipo "integer"
- verifico que el JSON de respuesta API tiene el campo "price" con tipo "number"
- verifico que el JSON de respuesta API tiene el campo "active" con tipo "boolean"

Tipos Complejos:
- verifico que el JSON de respuesta API tiene el campo "tags" con tipo "array"
- verifico que el JSON de respuesta API tiene el campo "metadata" con tipo "object"
- verifico que el JSON de respuesta API tiene el campo "deleted_at" con tipo "null"

Validación con Patrones Regex:

Email:
- verifico que el campo "email" del JSON de respuesta API coincide con el patrón "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"

Teléfono (formato internacional):
- verifico que el campo "phone" del JSON de respuesta API coincide con el patrón "^\\+?[1-9]\\d{1,14}$"

UUID:
- verifico que el campo "uuid" del JSON de respuesta API coincide con el patrón "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"

Fecha ISO 8601:
- verifico que el campo "created_at" del JSON de respuesta API coincide con el patrón "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"

URL:
- verifico que el campo "website" del JSON de respuesta API coincide con el patrón "^https?://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"

Código Postal (España):
- verifico que el campo "postal_code" del JSON de respuesta API coincide con el patrón "^\\d{5}$"

Validación de Rangos:

Edad:
- verifico que el campo "age" del JSON de respuesta API está en el rango 0 a 150

Precio:
- verifico que el campo "price" del JSON de respuesta API está en el rango 0 a 999999.99

Rating:
- verifico que el campo "rating" del JSON de respuesta API está en el rango 1 a 5

Porcentaje:
- verifico que el campo "discount" del JSON de respuesta API está en el rango 0 a 100

================================================

11. VALIDACIÓN DE ARRAYS
========================

Validación de Longitud:
- el array "usuarios" en la respuesta debería tener 5 elementos
- array "users" in response should have 5 elements

Validación de Contenido:
- verifico que el array "users" del JSON de respuesta API contiene un elemento con "name" igual a "Juan"
- I verify API response JSON array "users" contains item with "name" equals "Juan"
- Busca en el array un elemento que tenga el campo especificado con el valor dado

Validación de Campos en Todos los Elementos:
- verifico que todos los elementos del array "users" del JSON de respuesta API tienen el campo "id"
- I verify API response JSON array "users" all items have field "id"
- Verifica que TODOS los elementos del array tienen un campo específico

Validación de Elemento Específico:
- el elemento 0 del array "productos" debería tener el campo "name" con valor "Laptop"
- element 0 of array "products" should have field "name" with value "Laptop"

Validación de Array Vacío:
- el array "resultados" no debería estar vacío
- array "results" should not be empty

Ejemplos Prácticos:

Scenario: Validar lista de usuarios
  When envío petición GET a "/api/users"
  Then la respuesta debería tener código 200
  # Validar longitud
  And el array "data" en la respuesta debería tener 10 elementos
  # Validar que todos tienen ID
  And verifico que todos los elementos del array "data" del JSON de respuesta API tienen el campo "id"
  # Validar que todos tienen email
  And verifico que todos los elementos del array "data" del JSON de respuesta API tienen el campo "email"
  # Validar que existe un usuario específico
  And verifico que el array "data" del JSON de respuesta API contiene un elemento con "email" igual a "admin@test.com"

Scenario: Validar productos con precios válidos
  When envío petición GET a "/api/products"
  Then la respuesta debería tener código 200
  # Validar que todos tienen precio
  And verifico que todos los elementos del array "products" del JSON de respuesta API tienen el campo "price"
  # Validar primer producto
  And el elemento 0 del array "products" debería tener el campo "price" con tipo "number"
  And verifico que el campo "products.0.price" del JSON de respuesta API está en el rango 0 a 999999

================================================

12. APIs REST COMPLETAS
======================

CRUD Completo:

Create (POST):
- envío una petición POST a "/api/productos" con el JSON:
  {
    "nombre": "Laptop Gaming",
    "precio": 1500.00,
    "categoria": "electrónicos"
  }
- la respuesta debería tener código 201
- extraigo el campo "id" de la respuesta y lo guardo en la variable "producto_id"

Read (GET):
- envío una petición GET a "/api/productos/" + la variable "producto_id"
- la respuesta debería tener código 200
- el campo "nombre" debería ser "Laptop Gaming"

Update (PUT):
- envío una petición PUT a "/api/productos/" + la variable "producto_id" con el JSON:
  {
    "nombre": "Laptop Gaming Pro",
    "precio": 1800.00,
    "categoria": "electrónicos"
  }
- la respuesta debería tener código 200

Delete (DELETE):
- envío una petición DELETE a "/api/productos/" + la variable "producto_id"
- la respuesta debería tener código 204

================================================

8. EJEMPLOS PRÁCTICOS
=====================

Ejemplo 1: API de Autenticación Completa

Feature: Sistema de autenticación API

  Scenario: Flujo completo de autenticación
    # Registro de usuario
    When envío una petición POST a "/api/auth/register" con el JSON:
      {
        "name": "Usuario Test",
        "email": "test@example.com",
        "password": "password123"
      }
    Then la respuesta debería tener código 201
    And el campo "message" debería contener "Usuario registrado"
    
    # Login
    When envío una petición POST a "/api/auth/login" con el JSON:
      {
        "email": "test@example.com",
        "password": "password123"
      }
    Then la respuesta debería tener código 200
    And la respuesta debería tener el campo "access_token"
    And la respuesta debería tener el campo "refresh_token"
    
    # Guardar tokens
    When extraigo el campo "access_token" de la respuesta y lo guardo en la variable "access_token"
    And extraigo el campo "refresh_token" de la respuesta y lo guardo en la variable "refresh_token"
    
    # Acceder a recurso protegido
    When establezco el token de autorización de la variable "access_token"
    And envío una petición GET a "/api/user/profile"
    Then la respuesta debería tener código 200
    And el campo "email" debería ser "test@example.com"
    
    # Refresh token
    When envío una petición POST a "/api/auth/refresh" con el JSON:
      {
        "refresh_token": "${refresh_token}"
      }
    Then la respuesta debería tener código 200
    And debería tener un nuevo "access_token"
    
    # Logout
    When envío una petición POST a "/api/auth/logout"
    Then la respuesta debería tener código 200
    And el campo "message" debería ser "Logout exitoso"

Ejemplo 2: API de E-commerce con Validaciones

Feature: API de tienda online

  Background:
    # Autenticación como admin
    Given envío una petición POST a "/api/auth/login" con credenciales de admin
    And extraigo el token y lo establezco para las siguientes peticiones

  Scenario: Gestión completa de productos
    # Crear categoría
    When envío una petición POST a "/api/categories" con el JSON:
      {
        "name": "Electrónicos",
        "description": "Productos electrónicos"
      }
    Then la respuesta debería tener código 201
    And extraigo el campo "id" y lo guardo en la variable "categoria_id"
    
    # Crear producto
    When envío una petición POST a "/api/products" con el JSON:
      {
        "name": "Smartphone XYZ",
        "description": "Teléfono inteligente de última generación",
        "price": 599.99,
        "category_id": ${categoria_id},
        "stock": 50
      }
    Then la respuesta debería tener código 201
    And extraigo el campo "id" y lo guardo en la variable "producto_id"
    
    # Validar producto creado
    When envío una petición GET a "/api/products/" + la variable "producto_id"
    Then la respuesta debería tener código 200
    And el campo "name" debería ser "Smartphone XYZ"
    And el campo "price" debería ser 599.99
    And el campo "stock" debería ser 50
    
    # Actualizar stock
    When envío una petición PATCH a "/api/products/" + la variable "producto_id" con el JSON:
      {
        "stock": 45
      }
    Then la respuesta debería tener código 200
    And el campo "stock" debería ser 45
    
    # Buscar productos
    When envío una petición GET a "/api/products" con los parámetros:
      | nombre | valor |
      | search | Smartphone |
      | category | ${categoria_id} |
      | min_price | 500 |
    Then la respuesta debería tener código 200
    And el array "data" debería tener al menos 1 elemento
    And el primer elemento del array "data" debería tener el campo "name" con "Smartphone XYZ"

Ejemplo 3: Integración con API Externa

Feature: Integración con API de pagos

  Scenario: Procesar pago completo
    # Crear orden
    When envío una petición POST a "/api/orders" con el JSON:
      {
        "customer_id": 123,
        "items": [
          {
            "product_id": 456,
            "quantity": 2,
            "price": 29.99
          }
        ],
        "total": 59.98
      }
    Then la respuesta debería tener código 201
    And extraigo el campo "id" y lo guardo en la variable "order_id"
    And extraigo el campo "total" y lo guardo en la variable "order_total"
    
    # Procesar pago con API externa
    When establezco el header "X-Payment-API-Key" con valor "${PAYMENT_API_KEY}"
    And envío una petición POST a "https://api.payments.com/v1/charges" con el JSON:
      {
        "amount": ${order_total},
        "currency": "USD",
        "source": "tok_visa",
        "description": "Orden #${order_id}"
      }
    Then la respuesta debería tener código 200
    And el campo "status" debería ser "succeeded"
    And extraigo el campo "id" y lo guardo en la variable "payment_id"
    
    # Actualizar orden con información de pago
    When envío una petición PATCH a "/api/orders/" + la variable "order_id" con el JSON:
      {
        "payment_id": "${payment_id}",
        "status": "paid"
      }
    Then la respuesta debería tener código 200
    And el campo "status" debería ser "paid"
    
    # Verificar pago en API externa
    When envío una petición GET a "https://api.payments.com/v1/charges/" + la variable "payment_id"
    Then la respuesta debería tener código 200
    And el campo "status" debería ser "succeeded"
    And el campo "amount" debería ser igual a la variable "order_total"

Ejemplo 4: Testing de Performance y Carga

Feature: Performance de API

  Scenario: Test de carga en endpoint de productos
    # Medir tiempo de respuesta individual
    When mido el tiempo de inicio
    And envío una petición GET a "/api/products"
    And mido el tiempo de fin
    Then el tiempo transcurrido debería ser menor que 500 milisegundos
    
    # Test de múltiples requests
    When ejecuto 10 peticiones GET concurrentes a "/api/products"
    Then todas las respuestas deberían tener código 200
    And el tiempo promedio de respuesta debería ser menor que 1000 milisegundos
    And no debería haber errores de timeout
    
    # Test de carga con datos
    When para cada elemento del 1 al 50 ejecuto:
      | envío petición POST a "/api/products" con datos aleatorios |
      | verifico que la respuesta sea exitosa |
      | guardo el tiempo de respuesta |
    
    Then el 95% de las respuestas deberían ser menores que 2000 milisegundos
    And no debería haber errores 5xx
    
    # Verificar estado del sistema después de la carga
    When envío una petición GET a "/api/health"
    Then la respuesta debería tener código 200
    And el campo "status" debería ser "healthy"
    And el campo "database" debería ser "connected"

================================================

13. EJEMPLOS PRÁCTICOS AVANZADOS
================================

Ejemplo 1: Validación Completa con Esquema y Archivo

Feature: Validación robusta de API de usuarios

  Scenario: Crear y validar usuario con esquema
    # Crear usuario desde archivo
    When cargo JSON del archivo "payloads/create_user.json" y envío POST a "/api/users" guardando respuesta en variable "response"
    Then la respuesta debería tener código 201
    
    # Validar con esquema JSON Schema
    And verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/user_schema.json"
    
    # Validar tipos específicos
    And verifico que el JSON de respuesta API tiene el campo "id" con tipo "integer"
    And verifico que el JSON de respuesta API tiene el campo "email" con tipo "string"
    And verifico que el JSON de respuesta API tiene el campo "active" con tipo "boolean"
    
    # Validar patrones
    And verifico que el campo "email" del JSON de respuesta API coincide con el patrón "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
    
    # Validar rangos
    And verifico que el campo "age" del JSON de respuesta API está en el rango 18 a 100
    
    # Guardar para comparación futura
    And guardo el JSON de respuesta API en el archivo "responses/user_created.json"
    
    # Extraer ID para siguientes tests
    And extraigo el campo "id" de la respuesta y lo guardo en la variable "user_id"

Ejemplo 2: Comparación con Archivo Ignorando Campos Dinámicos

Feature: Testing de API con timestamps

  Scenario: Validar respuesta ignorando campos dinámicos
    When envío petición GET a "/api/users/123"
    Then la respuesta debería tener código 200
    
    # Comparar con archivo esperado ignorando campos que cambian
    And verifico que el JSON de respuesta API coincide con el archivo "expected/user_123.json" ignorando campos "created_at,updated_at,last_login"
    
    # Validar que los campos ignorados existen y tienen formato correcto
    And verifico que el campo "created_at" del JSON de respuesta API coincide con el patrón "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"
    And verifico que el campo "updated_at" del JSON de respuesta API coincide con el patrón "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"

Ejemplo 3: Validación de Arrays Complejos

Feature: API de productos con categorías

  Scenario: Validar lista de productos
    When envío petición GET a "/api/products?category=electronics"
    Then la respuesta debería tener código 200
    
    # Validar estructura del array
    And el array "products" en la respuesta debería tener al menos 1 elemento
    And verifico que todos los elementos del array "products" del JSON de respuesta API tienen el campo "id"
    And verifico que todos los elementos del array "products" del JSON de respuesta API tienen el campo "name"
    And verifico que todos los elementos del array "products" del JSON de respuesta API tienen el campo "price"
    
    # Validar que existe un producto específico
    And verifico que el array "products" del JSON de respuesta API contiene un elemento con "name" igual a "Laptop Gaming"
    
    # Validar tipos en el primer elemento
    And verifico que el JSON de respuesta API tiene el campo "products.0.id" con tipo "integer"
    And verifico que el JSON de respuesta API tiene el campo "products.0.price" con tipo "number"
    And verifico que el JSON de respuesta API tiene el campo "products.0.tags" con tipo "array"
    
    # Validar rangos de precios
    And verifico que el campo "products.0.price" del JSON de respuesta API está en el rango 0 a 999999

Ejemplo 4: Testing de API con Múltiples Esquemas

Feature: API de e-commerce con validación de esquemas

  Background:
    Given establezco el token de autorización "${API_TOKEN}"

  Scenario: Flujo completo de orden con validación de esquemas
    # Crear orden
    When cargo JSON del archivo "payloads/create_order.json" y envío POST a "/api/orders" guardando respuesta en variable "order_response"
    Then la respuesta debería tener código 201
    And verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/order_schema.json"
    And extraigo el campo "id" de la respuesta y lo guardo en la variable "order_id"
    
    # Obtener orden
    When envío petición GET a "/api/orders/${order_id}"
    Then la respuesta debería tener código 200
    And verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/order_schema.json"
    
    # Validar items de la orden
    And verifico que todos los elementos del array "items" del JSON de respuesta API tienen el campo "product_id"
    And verifico que todos los elementos del array "items" del JSON de respuesta API tienen el campo "quantity"
    And verifico que todos los elementos del array "items" del JSON de respuesta API tienen el campo "price"
    
    # Actualizar orden
    When cargo JSON del archivo "payloads/update_order.json" y envío PUT a "/api/orders/${order_id}" guardando respuesta en variable "update_response"
    Then la respuesta debería tener código 200
    And verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/order_schema.json"
    
    # Validar estado actualizado
    And el campo "status" debería ser "processing"

Ejemplo 5: Validación de Respuestas Sin Valores Nulos

Feature: API con validación estricta

  Scenario: Validar que no hay valores nulos
    When envío petición GET a "/api/users/123"
    Then la respuesta debería tener código 200
    
    # Validar que no hay nulls en toda la respuesta
    And verifico que el JSON de respuesta API no tiene valores nulos
    
    # Validar estructura completa
    And verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/user_complete_schema.json"

Ejemplo 6: Testing de Paginación con Validación

Feature: API con paginación

  Scenario: Validar paginación de usuarios
    When envío petición GET a "/api/users?page=1&limit=10"
    Then la respuesta debería tener código 200
    
    # Validar estructura de paginación
    And verifico que el JSON de respuesta API tiene el campo "data" con tipo "array"
    And verifico que el JSON de respuesta API tiene el campo "total" con tipo "integer"
    And verifico que el JSON de respuesta API tiene el campo "page" con tipo "integer"
    And verifico que el JSON de respuesta API tiene el campo "limit" con tipo "integer"
    
    # Validar valores de paginación
    And el campo "page" debería ser 1
    And el campo "limit" debería ser 10
    And el array "data" en la respuesta debería tener 10 elementos
    
    # Validar que todos los usuarios tienen estructura correcta
    And verifico que todos los elementos del array "data" del JSON de respuesta API tienen el campo "id"
    And verifico que todos los elementos del array "data" del JSON de respuesta API tienen el campo "email"

Ejemplo 7: Comparación de Respuestas Ignorando Orden

Feature: API de búsqueda

  Scenario: Validar resultados de búsqueda
    When envío petición GET a "/api/search?q=laptop"
    Then la respuesta debería tener código 200
    
    # Comparar con archivo esperado ignorando orden de resultados
    And verifico que el JSON de respuesta API coincide con el archivo "expected/search_laptop.json" ignorando orden
    
    # Validar que todos los resultados tienen los campos necesarios
    And verifico que todos los elementos del array "results" del JSON de respuesta API tienen el campo "id"
    And verifico que todos los elementos del array "results" del JSON de respuesta API tienen el campo "title"
    And verifico que todos los elementos del array "results" del JSON de respuesta API tienen el campo "relevance"

================================================

14. CONFIGURACIÓN AVANZADA
=========================

Variables de Entorno Relacionadas:

# Configuración de API
API_BASE_URL=https://api.mi-app.com/v1    # URL base de la API
API_TIMEOUT=30000                         # Timeout para requests
API_RETRY_COUNT=3                         # Número de reintentos

# Autenticación
API_KEY=mi-api-key-secreta               # API Key
BEARER_TOKEN=eyJhbGciOiJIUzI1NiIs...     # Token Bearer
BASIC_AUTH_USER=admin                     # Usuario para Basic Auth
BASIC_AUTH_PASS=password123               # Contraseña para Basic Auth

# Headers por defecto
DEFAULT_CONTENT_TYPE=application/json     # Content-Type por defecto
DEFAULT_ACCEPT=application/json           # Accept por defecto
DEFAULT_USER_AGENT=TestFramework/1.0      # User-Agent por defecto

Tips y Mejores Prácticas:

1. Usa variables para URLs: Facilita cambios entre entornos
2. Valida siempre el código de estado: No asumas que será 200
3. Extrae datos importantes: Guarda IDs y tokens para uso posterior
4. Maneja la autenticación: Renueva tokens cuando sea necesario
5. Valida la estructura JSON: Verifica campos requeridos
6. Mide performance: Incluye validaciones de tiempo de respuesta

================================================

15. TROUBLESHOOTING
===================

Problemas Comunes:

Error: "Connection timeout"
- Verifica la URL de la API
- Aumenta el timeout de conexión
- Revisa la conectividad de red

Error: "401 Unauthorized"
- Verifica el token de autenticación
- Renueva el token si ha expirado
- Revisa los headers de autorización

Error: "JSON decode error"
- Verifica que la respuesta sea JSON válido
- Revisa el Content-Type de la respuesta
- Valida la estructura de datos enviada

Error: "Field not found in response"
- Verifica la estructura de la respuesta JSON
- Usa rutas correctas para campos anidados
- Valida que el campo existe antes de extraerlo

Error: "JSON Schema validation failed"
- Revisa el esquema JSON Schema (debe ser Draft 7)
- Verifica que el esquema tiene la estructura correcta
- Usa herramientas online para validar el esquema
- Compara la respuesta actual con el esquema esperado

Error: "File not found" (esquemas o archivos esperados)
- Verifica que la ruta del archivo es correcta
- Usa rutas relativas desde la raíz del proyecto
- Crea los directorios necesarios (schemas/, expected/, payloads/)
- Verifica permisos de lectura del archivo

Error: "Regex pattern does not match"
- Escapa correctamente los caracteres especiales (\\d, \\., etc.)
- Usa herramientas online para probar el regex
- Verifica que el patrón es compatible con Python re
- Recuerda usar doble backslash en strings (\\d en lugar de \d)

Error: "Type mismatch" en validación de tipos
- Verifica que el tipo esperado es correcto
- Tipos soportados: string, number, integer, boolean, array, object, null
- Recuerda que JSON no distingue entre int y float (ambos son number)
- Para enteros específicos usa "integer", para cualquier número usa "number"

Error: "Array item not found"
- Verifica que el array existe en la respuesta
- Usa la ruta correcta para arrays anidados
- Verifica que el campo y valor buscados son correctos
- Recuerda que la búsqueda es case-sensitive

Error: "DeepDiff comparison failed"
- Instala deepdiff: pip install deepdiff>=6.7.0
- Verifica que ambos JSONs tienen la estructura esperada
- Usa "ignorando orden" si el orden de arrays no importa
- Usa "ignorando campos" para timestamps y IDs autogenerados

Tips para Debugging:

1. Guardar Respuestas Actuales:
   And guardo el JSON de respuesta API en el archivo "debug/actual_response.json"
   - Útil para ver qué está devolviendo realmente la API

2. Comparar con Archivo Esperado:
   - Usa herramientas de diff para comparar archivos JSON
   - Formatea ambos JSONs con la misma indentación
   - Usa herramientas online como jsondiff.com

3. Validar Esquemas Paso a Paso:
   - Valida primero el tipo del objeto raíz
   - Luego valida campos requeridos uno por uno
   - Finalmente valida el esquema completo

4. Usar Validaciones Incrementales:
   - Empieza con validaciones simples (código de estado)
   - Luego valida tipos de campos
   - Finalmente valida esquemas completos

5. Logging de Respuestas:
   - Activa logging detallado en behave
   - Revisa los logs para ver respuestas completas
   - Usa print() en steps personalizados para debugging

Mejores Prácticas:

1. Organización de Archivos:
   ✅ Mantén esquemas en schemas/
   ✅ Mantén respuestas esperadas en expected/
   ✅ Mantén payloads en payloads/
   ✅ Usa nombres descriptivos para archivos

2. Versionado de Esquemas:
   ✅ Versiona tus esquemas (user_schema_v1.json, user_schema_v2.json)
   ✅ Documenta cambios en esquemas
   ✅ Mantén compatibilidad hacia atrás cuando sea posible

3. Reutilización de Esquemas:
   ✅ Crea esquemas base y extiéndelos
   ✅ Usa $ref para referenciar esquemas comunes
   ✅ Mantén esquemas DRY (Don't Repeat Yourself)

4. Testing de Esquemas:
   ✅ Valida tus esquemas con herramientas online
   ✅ Prueba esquemas con datos válidos e inválidos
   ✅ Documenta restricciones en el esquema

5. Comparación con Archivos:
   ✅ Usa "ignorando orden" para arrays sin orden específico
   ✅ Usa "ignorando campos" para timestamps y IDs
   ✅ Mantén archivos esperados actualizados
   ✅ Versiona archivos esperados junto con el código

================================================

CONCLUSIÓN

Con estos steps puedes probar cualquier API REST de forma completa y robusta:

✅ Validación de esquemas JSON Schema (Draft 7)
✅ Comparación exacta con archivos esperados
✅ Comparación ignorando orden de arrays
✅ Comparación ignorando campos dinámicos
✅ Validación de tipos de datos
✅ Validación con expresiones regulares
✅ Validación de rangos numéricos
✅ Validación de arrays complejos
✅ Validación de valores nulos
✅ Carga de payloads desde archivos
✅ Guardado de respuestas para debugging

El framework proporciona todas las herramientas necesarias para validar APIs 
modernas con seguridad, confiabilidad y facilidad, desde autenticación básica 
hasta validación avanzada de estructuras JSON complejas.

================================================
Documento generado automáticamente - Hakalab Framework v1.3.0
Guía de APIs y Servicios Web - Validación Avanzada
Fecha: Febrero 2026
================================================
