================================================================================
                    GUÍA DE PASOS NUEVOS - HAKALAB FRAMEWORK
                              Versión 1.0
================================================================================

CONTENIDO:
1. PASOS NUEVOS AGREGADOS
2. CORRECCIONES REALIZADAS
3. EJEMPLOS DE USO
4. RESPUESTAS A PREGUNTAS FRECUENTES
5. ERRORES COMUNES Y SOLUCIONES

================================================================================
                        1. PASOS NUEVOS AGREGADOS
================================================================================

Se han agregado 5 pasos nuevos para trabajar con atributos HTML:

1.1 VALIDACIÓN DE CAMPOS VACÍOS
────────────────────────────────

Paso 1: Verificar que un campo ESTÁ VACÍO
Sintaxis:
  el campo "{field_name}" debería estar vacío con identificador "{identifier}"

Ejemplo:
  el campo "Email" debería estar vacío con identificador "$.FORM.email"

Ubicación: hakalab_framework/steps/assertion_steps.py (línea ~95)

Descripción:
  Verifica que un campo de entrada no tiene valor (está vacío).
  Útil para validar que un campo se limpió correctamente.

---

Paso 2: Verificar que un campo NO ESTÁ VACÍO
Sintaxis:
  el campo "{field_name}" no debería estar vacío con identificador "{identifier}"

Ejemplo:
  el campo "Nombre" no debería estar vacío con identificador "$.FORM.nombre"

Ubicación: hakalab_framework/steps/assertion_steps.py (línea ~110)

Descripción:
  Verifica que un campo tiene algún valor (no está vacío).
  Útil para validar que un campo fue rellenado correctamente.

---

1.2 REMOVER ATRIBUTOS HTML
──────────────────────────

Paso 3: Remover un atributo de un elemento
Sintaxis:
  remuevo el atributo "{attribute_name}" del elemento "{element_name}" con identificador "{identifier}"

Ejemplo:
  remuevo el atributo "readonly" del elemento "Total Días" con identificador "$.KIBERPRO_SOLICITUD.input_total_dias"

Ubicación: hakalab_framework/steps/interaction_steps.py (línea ~161)

Descripción:
  Remueve un atributo HTML de un elemento usando JavaScript.
  Útil para editar campos protegidos con readonly, habilitar botones disabled, etc.

Casos de uso:
  - Editar campos readonly
  - Habilitar botones disabled
  - Remover validaciones HTML (required, pattern, etc.)

---

1.3 ESTABLECER ATRIBUTOS HTML
─────────────────────────────

Paso 4: Establecer o modificar un atributo
Sintaxis:
  establezco el atributo "{attribute_name}" a "{attribute_value}" en el elemento "{element_name}" con identificador "{identifier}"

Ejemplo:
  establezco el atributo "placeholder" a "Ingrese su nombre" en el elemento "Input" con identificador "$.FORM.nombre"

Ubicación: hakalab_framework/steps/interaction_steps.py (línea ~195)

Descripción:
  Establece o modifica un atributo HTML de un elemento usando JavaScript.
  Útil para cambiar atributos dinámicamente durante los tests.

---

1.4 VERIFICAR ATRIBUTOS HTML
────────────────────────────

Paso 5a: Verificar que un elemento TIENE un atributo
Sintaxis:
  verifico que el elemento "{element_name}" con identificador "{identifier}" tiene el atributo "{attribute_name}"

Ejemplo:
  verifico que el elemento "Input" con identificador "$.FORM.input" tiene el atributo "readonly"

Ubicación: hakalab_framework/steps/interaction_steps.py (línea ~220)

Descripción:
  Verifica que un elemento tiene un atributo específico.

---

Paso 5b: Verificar que un elemento NO TIENE un atributo
Sintaxis:
  verifico que el elemento "{element_name}" con identificador "{identifier}" no tiene el atributo "{attribute_name}"

Ejemplo:
  verifico que el elemento "Botón" con identificador "$.FORM.button" no tiene el atributo "disabled"

Ubicación: hakalab_framework/steps/interaction_steps.py (línea ~240)

Descripción:
  Verifica que un elemento NO tiene un atributo específico.

---

1.5 OBTENER ATRIBUTOS HTML
──────────────────────────

Paso 6: Obtener el valor de un atributo y guardarlo en variable
Sintaxis:
  obtengo el atributo "{attribute_name}" del elemento "{element_name}" con identificador "{identifier}" y lo guardo en la variable "{variable_name}"

Ejemplo:
  obtengo el atributo "value" del elemento "Input" con identificador "$.FORM.email" y lo guardo en la variable "email_value"

Ubicación: hakalab_framework/steps/interaction_steps.py (línea ~250)

Descripción:
  Obtiene el valor de un atributo HTML y lo guarda en una variable para usar después.
  Útil para extraer valores dinámicos de elementos.

================================================================================
                        2. CORRECCIONES REALIZADAS
================================================================================

2.1 CORRECCIÓN: step_remove_attribute
─────────────────────────────────────

Archivo: hakalab_framework/steps/interaction_steps.py
Línea: 185

PROBLEMA:
  Error de sintaxis JavaScript cuando el nombre del atributo contenía caracteres especiales.
  Error: "SyntaxError: missing ) after argument list"

CAUSA:
  Se usaba interpolación de strings en JavaScript:
    element.evaluate(f"el => el.removeAttribute('{attribute_name}')")
  
  Si attribute_name contenía comillas u otros caracteres especiales, rompía la sintaxis.

SOLUCIÓN:
  Usar parámetros en lugar de interpolación de strings:
    element.evaluate("el => el.removeAttribute(arguments[0])", attribute_name)

RESULTADO:
  El paso ahora funciona correctamente sin errores de sintaxis.

================================================================================
                        3. EJEMPLOS DE USO
================================================================================

3.1 EJEMPLO 1: Validación de Campos Vacíos
───────────────────────────────────────────

Feature: Validación de Campos Vacíos

  Scenario: Limpiar campo y verificar que está vacío
    Given navego a "https://mi-aplicacion.com/formulario"
    When relleno el campo "Email" con "test@example.com" con identificador "$.FORM.email"
    And limpio el campo "Email" con identificador "$.FORM.email"
    Then el campo "Email" debería estar vacío con identificador "$.FORM.email"

  Scenario: Verificar que un campo no está vacío
    Given navego a "https://mi-aplicacion.com/formulario"
    When relleno el campo "Nombre" con "Juan Pérez" con identificador "$.FORM.nombre"
    Then el campo "Nombre" no debería estar vacío con identificador "$.FORM.nombre"

---

3.2 EJEMPLO 2: Remover Atributos HTML
──────────────────────────────────────

Feature: Edición de Campos Protegidos

  Scenario: Remover readonly y editar campo
    Given navego a "https://mi-aplicacion.com/solicitud"
    When remuevo el atributo "readonly" del elemento "Total Días" con identificador "$.KIBERPRO_SOLICITUD.input_total_dias"
    And relleno el campo "Total Días" con "10" con identificador "$.KIBERPRO_SOLICITUD.input_total_dias"
    Then el campo "Total Días" debería tener el valor "10" con identificador "$.KIBERPRO_SOLICITUD.input_total_dias"

  Scenario: Habilitar botón deshabilitado
    Given navego a "https://mi-aplicacion.com/formulario"
    When remuevo el atributo "disabled" del elemento "Enviar" con identificador "$.FORM.submit_button"
    And hago click en el elemento "Enviar" con identificador "$.FORM.submit_button"
    Then debería ver el texto "Formulario enviado"

---

3.3 EJEMPLO 3: Upload de Archivos
──────────────────────────────────

Feature: Upload de Certificados

  Scenario: Subir certificado de permiso
    Given navego a "https://mi-aplicacion.com/solicitud"
    When subo el archivo "C:/archivos/certificado.pdf" al campo "Certificado" con identificador "$.KIBERPRO_SOLICITUD.certificado_input"
    Then debería ver el texto "Certificado cargado exitosamente"

  Scenario: Subir archivo usando botón
    Given navego a "https://mi-aplicacion.com/solicitud"
    When subo el archivo "C:/archivos/certificado.pdf" haciendo click en el elemento "Seleccionar archivo" con identificador "$.KIBERPRO_SOLICITUD.upload_button"
    Then debería ver el elemento "Certificado cargado" con identificador "$.KIBERPRO_SOLICITUD.success_message"

  Scenario: Subir archivo desde downloads
    Given navego a "https://mi-aplicacion.com/solicitud"
    When subo el archivo de descargas "documento.pdf" haciendo click en el elemento "Seleccionar archivo" con identificador "$.KIBERPRO_SOLICITUD.upload_button"
    Then debería ver el texto "Archivo cargado"

---

3.4 EJEMPLO 4: Flujo Completo
──────────────────────────────

Feature: Solicitud Completa de Permiso

  Background:
    Given navego a "https://mi-aplicacion.com"
    And espero a que la página cargue
    And me autentico con usuario "empleado" y contraseña "password123"

  Scenario: Crear solicitud de permiso con certificado
    # Navegar al formulario
    When hago click en el elemento "Nueva Solicitud" con identificador "$.MENU.new_request"
    Then debería ver el elemento "Formulario Solicitud" con identificador "$.FORM.container"
    
    # Rellenar datos básicos
    When relleno el campo "Nombre" con "Juan Pérez" con identificador "$.FORM.nombre"
    And relleno el campo "Email" con "juan@example.com" con identificador "$.FORM.email"
    And relleno el campo de fecha "Fecha Inicio" con "01-02-2027" con identificador "$.FORM.fecha_inicio"
    
    # Rellenar días (removiendo readonly si es necesario)
    When remuevo el atributo "readonly" del elemento "Total Días" con identificador "$.FORM.total_dias"
    And relleno el campo "Total Días" con "5" con identificador "$.FORM.total_dias"
    
    # Subir certificado
    When subo el archivo "C:/documentos/certificado.pdf" al campo "Certificado" con identificador "$.FORM.certificado_input"
    Then debería ver el texto "Certificado cargado"
    
    # Verificar que el formulario está completo
    And el campo "Nombre" no debería estar vacío con identificador "$.FORM.nombre"
    And el campo "Email" no debería estar vacío con identificador "$.FORM.email"
    And el campo "Total Días" debería tener el valor "5" con identificador "$.FORM.total_dias"
    
    # Enviar formulario
    When hago click en el elemento "Enviar" con identificador "$.FORM.submit_button"
    Then debería ver el texto "Solicitud creada exitosamente"
    And la url actual debería contener "/solicitudes"

================================================================================
                4. RESPUESTAS A PREGUNTAS FRECUENTES
================================================================================

P1: ¿Cuál es el paso nuevo?
R: Se agregaron 5 pasos nuevos para trabajar con atributos HTML:
   - Validar campos vacíos (2 pasos)
   - Remover atributos (1 paso)
   - Establecer atributos (1 paso)
   - Verificar atributos (2 pasos)
   - Obtener atributos (1 paso)

---

P2: ¿Por qué me da error de sintaxis?
R: El error ocurría porque las comillas en el nombre del atributo rompían la 
   sintaxis JavaScript. Ya está corregido en interaction_steps.py línea 185.

---

P3: ¿Cómo subo archivos desde downloads?
R: Usa el paso:
   subo el archivo de descargas "{filename}" haciendo click en el elemento "{element_name}" con identificador "{identifier}"
   
   O directamente a un input[type=file]:
   subo el archivo "{file_path}" al campo "{field_name}" con identificador "{identifier}"

---

P4: ¿Cómo valido campos vacíos?
R: Usa estos pasos:
   - el campo "{field_name}" debería estar vacío con identificador "{identifier}"
   - el campo "{field_name}" no debería estar vacío con identificador "{identifier}"

---

P5: ¿Es seguro usar Background fijo en reportes?
R: SÍ es seguro. Ventajas:
   - Reduce repetición en el reporte
   - Hace el reporte más limpio y legible
   - Reduce tamaño del archivo HTML
   
   Consideraciones:
   - Si el background falla, todos los escenarios fallarán
   - El background debe ser simple y confiable

---

P6: ¿Cómo uso los pasos en mis features?
R: Ejemplo:
   When remuevo el atributo "readonly" del elemento "Total Días" con identificador "$.KIBERPRO_SOLICITUD.input_total_dias"
   Then el campo "Email" debería estar vacío con identificador "$.FORM.email"

================================================================================
                5. ERRORES COMUNES Y SOLUCIONES
================================================================================

ERROR 1: "SyntaxError: missing ) after argument list"
────────────────────────────────────────────────────

Causa: Comillas en el nombre del atributo rompen la sintaxis JavaScript.

Solución: Ya está corregido en la versión actual. Usa el paso normalmente:
  remuevo el atributo "readonly" del elemento "Input" con identificador "$.FORM.input"

---

ERROR 2: "Failed to execute 'querySelector' on 'Document'"
──────────────────────────────────────────────────────────

Causa: Identificador inválido o selector XPath directo.

Solución: Usa identificadores JSON:
  ❌ INCORRECTO: con identificador "//*[@id='totalDias']"
  ✅ CORRECTO: con identificador "$.KIBERPRO_SOLICITUD.input_total_dias"

---

ERROR 3: "Elemento no encontrado"
─────────────────────────────────

Causa: El identificador no existe en SELECTORS.json o está mal escrito.

Solución: Verifica que el identificador existe en tu archivo SELECTORS.json:
  {
    "KIBERPRO_SOLICITUD": {
      "input_total_dias": "#totalDias"
    }
  }

---

ERROR 4: "Atributo no existe"
────────────────────────────

Causa: Intentas remover un atributo que el elemento no tiene.

Solución: Verifica primero que el atributo existe:
  When verifico que el elemento "Input" con identificador "$.FORM.input" tiene el atributo "readonly"
  And remuevo el atributo "readonly" del elemento "Input" con identificador "$.FORM.input"

================================================================================
                            RESUMEN FINAL
================================================================================

✅ Se agregaron 5 pasos nuevos para trabajar con atributos HTML
✅ Se corrigió 1 error en step_remove_attribute
✅ Se proporcionaron 4 ejemplos prácticos completos
✅ Se respondieron 6 preguntas frecuentes
✅ Se documentaron 4 errores comunes y sus soluciones

PRÓXIMOS PASOS:
1. Actualizar SELECTORS.json con tus identificadores
2. Usar los pasos en tus features
3. Ejecutar tests para validar
4. Revisar reportes

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


================================================================================
                    PASOS ADICIONALES: VALIDAR EXISTENCIA
================================================================================

Se han agregado 4 pasos adicionales para validar si un elemento existe:

PASO 7: Verificar que un elemento EXISTE (sin valor dinámico)
──────────────────────────────────────────────────────────────

Sintaxis:
  el elemento "{element_name}" debería existir con identificador "{identifier}"

Ejemplo:
  el elemento "Usuario" debería existir con identificador "$.SELECTORS.user_element"
  el elemento "Fila" debería existir con identificador "$.TABLE.row=1"

Ubicación: hakalab_framework/steps/assertion_steps.py

Descripción:
  Verifica que un elemento existe en el DOM (sin importar si es visible).
  Soporta localizadores dinámicos con placeholders.
  Útil para validar que un elemento fue creado dinámicamente.

Diferencia con "debería ver el elemento":
  - "debería ver" → Verifica que el elemento es VISIBLE
  - "debería existir" → Verifica que el elemento EXISTE en el DOM (puede estar oculto)

---

PASO 8: Verificar que un elemento EXISTE (con valor dinámico)
──────────────────────────────────────────────────────────────

Sintaxis:
  el elemento "{element_name}" debería existir con identificador "{identifier}" y valor "{value}"

Ejemplo:
  el elemento "Fila" debería existir con identificador "$.TABLE.row" y valor "1"
  el elemento "Item" debería existir con identificador "$.LIST.item" y valor "producto_123"
  el elemento "Botón" debería existir con identificador "$.BUTTONS.action" y valor "delete"

Ubicación: hakalab_framework/steps/assertion_steps.py

Descripción:
  Verifica que un elemento existe en el DOM usando un localizador dinámico.
  El valor reemplaza el placeholder en el localizador.
  Soporta variables (se resuelven automáticamente).
  Útil para validar elementos dinámicos en tablas, listas, etc.

Cómo funciona:
  1. Toma el identificador: $.TABLE.row
  2. Reemplaza el placeholder con el valor: $.TABLE.row=1
  3. Obtiene el localizador final
  4. Verifica que el elemento existe

---

PASO 9: Verificar que un elemento NO EXISTE (sin valor dinámico)
─────────────────────────────────────────────────────────────────

Sintaxis:
  el elemento "{element_name}" no debería existir con identificador "{identifier}"

Ejemplo:
  el elemento "Error" no debería existir con identificador "$.SELECTORS.error_message"
  el elemento "Fila" no debería existir con identificador "$.TABLE.row=999"

Ubicación: hakalab_framework/steps/assertion_steps.py

Descripción:
  Verifica que un elemento NO existe en el DOM.
  Soporta localizadores dinámicos con placeholders.
  Útil para validar que un elemento fue removido o no fue creado.

---

PASO 10: Verificar que un elemento NO EXISTE (con valor dinámico)
──────────────────────────────────────────────────────────────────

Sintaxis:
  el elemento "{element_name}" no debería existir con identificador "{identifier}" y valor "{value}"

Ejemplo:
  el elemento "Error" no debería existir con identificador "$.FORM.error" y valor "email"
  el elemento "Fila" no debería existir con identificador "$.TABLE.row" y valor "999"
  el elemento "Item" no debería existir con identificador "$.LIST.item" y valor "deleted_123"

Ubicación: hakalab_framework/steps/assertion_steps.py

Descripción:
  Verifica que un elemento NO existe en el DOM usando un localizador dinámico.
  El valor reemplaza el placeholder en el localizador.
  Soporta variables (se resuelven automáticamente).
  Útil para validar que elementos dinámicos fueron removidos.

---

EJEMPLO DE USO CON LOCALIZADORES DINÁMICOS:

Feature: Validar Existencia de Elementos

  Scenario: Validar que una fila existe en una tabla (con valor dinámico)
    Given navego a "https://mi-aplicacion.com/tabla"
    When hago click en el elemento "Agregar Fila" con identificador "$.BUTTONS.add_row"
    Then el elemento "Fila" debería existir con identificador "$.TABLE.row" y valor "1"

  Scenario: Validar que un mensaje de error no existe (con valor dinámico)
    Given navego a "https://mi-aplicacion.com/formulario"
    When relleno el campo "Email" con "test@example.com" con identificador "$.FORM.email"
    Then el elemento "Error" no debería existir con identificador "$.FORM.error" y valor "email"

  Scenario: Validar que un elemento dinámico fue removido (con valor dinámico)
    Given navego a "https://mi-aplicacion.com/lista"
    When hago click en el elemento "Eliminar" con identificador "$.LIST.delete_button" y valor "1"
    Then el elemento "Item" no debería existir con identificador "$.LIST.item" y valor "1"

  Scenario: Validar con variables
    Given navego a "https://mi-aplicacion.com/tabla"
    And establezco la variable "row_id" a "5"
    When hago click en el elemento "Agregar Fila" con identificador "$.BUTTONS.add_row"
    Then el elemento "Fila" debería existir con identificador "$.TABLE.row" y valor "{row_id}"

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


================================================================================
                    PASOS PARA VALIDAR TABLAS COMPLETAS
================================================================================

Se han agregado 2 pasos nuevos para validar filas completas y headers de tablas:

PASO 11: Verificar que una fila tiene datos específicos
────────────────────────────────────────────────────────

Sintaxis:
  verifico que la fila "{row_number}" de la tabla "{table_name}" tiene los siguientes datos con identificador "{identifier}"

Ubicación: hakalab_framework/steps/table_steps.py

Descripción:
  Verifica que una fila completa tiene exactamente los datos esperados.
  Usa una tabla de datos en el feature para especificar los valores.
  Compara cada celda de la fila con los valores esperados.

Ejemplo en Feature:
  verifico que la fila "1" de la tabla "Usuarios" tiene los siguientes datos con identificador "$.TABLE.users"
    | datos |
    | 1     |
    | Juan  |
    | admin |
    | activo|

Cómo funciona:
  1. Obtiene la fila número 1 de la tabla
  2. Extrae los datos de cada celda
  3. Compara con los valores esperados: 1, Juan, admin, activo
  4. Si algún valor no coincide, muestra error indicando columna y valores

Validaciones:
  - Verifica que el número de columnas coincide
  - Verifica que cada celda tiene el valor exacto esperado
  - Muestra error detallado si hay discrepancia

---

PASO 12: Verificar que el header tiene columnas específicas
───────────────────────────────────────────────────────────

Sintaxis:
  verifico que el header de la tabla "{table_name}" tiene las siguientes columnas con identificador "{identifier}"

Ubicación: hakalab_framework/steps/table_steps.py

Descripción:
  Verifica que el header de la tabla tiene exactamente las columnas esperadas.
  Usa una tabla de datos en el feature para especificar los nombres de columnas.
  Compara cada header con los nombres esperados.

Ejemplo en Feature:
  verifico que el header de la tabla "Usuarios" tiene las siguientes columnas con identificador "$.TABLE.users"
    | columnas |
    | ID       |
    | Nombre   |
    | Rol      |
    | Estado   |

Cómo funciona:
  1. Obtiene todos los headers de la tabla
  2. Extrae el texto de cada header
  3. Compara con los nombres esperados: ID, Nombre, Rol, Estado
  4. Si algún nombre no coincide, muestra error indicando columna y valores

Validaciones:
  - Verifica que el número de columnas coincide
  - Verifica que cada header tiene el nombre exacto esperado
  - Muestra error detallado si hay discrepancia

---

EJEMPLO COMPLETO: Validar Tabla Completa

Feature: Validar Tabla de Usuarios

  Scenario: Validar estructura y datos de tabla
    Given navego a "https://mi-aplicacion.com/usuarios"
    
    # Validar que el header tiene las columnas correctas
    Then verifico que el header de la tabla "Usuarios" tiene las siguientes columnas con identificador "$.TABLE.users"
      | columnas |
      | ID       |
      | Nombre   |
      | Rol      |
      | Estado   |
    
    # Validar que la fila 1 tiene los datos correctos
    And verifico que la fila "1" de la tabla "Usuarios" tiene los siguientes datos con identificador "$.TABLE.users"
      | datos  |
      | 1      |
      | Juan   |
      | admin  |
      | activo |
    
    # Validar que la fila 2 tiene los datos correctos
    And verifico que la fila "2" de la tabla "Usuarios" tiene los siguientes datos con identificador "$.TABLE.users"
      | datos   |
      | 2       |
      | María   |
      | user    |
      | activo  |
    
    # Validar que la fila 3 tiene los datos correctos
    And verifico que la fila "3" de la tabla "Usuarios" tiene los siguientes datos con identificador "$.TABLE.users"
      | datos    |
      | 3        |
      | Carlos   |
      | viewer   |
      | inactivo |

---

EJEMPLO CON DATOS DINÁMICOS:

Feature: Validar Tabla con Datos Dinámicos

  Scenario: Validar fila con datos de variables
    Given navego a "https://mi-aplicacion.com/usuarios"
    And establezco la variable "user_id" a "5"
    And establezco la variable "user_name" a "Pedro"
    And establezco la variable "user_role" a "editor"
    
    # Validar fila con valores de variables
    Then verifico que la fila "1" de la tabla "Usuarios" tiene los siguientes datos con identificador "$.TABLE.users"
      | datos         |
      | {user_id}     |
      | {user_name}   |
      | {user_role}   |
      | activo        |

---

CASOS DE USO:

1. Validar que una tabla tiene la estructura correcta
   - Verificar headers
   - Verificar número de columnas

2. Validar que los datos de una fila son correctos
   - Después de crear un nuevo registro
   - Después de editar un registro
   - Después de filtrar/buscar

3. Validar múltiples filas
   - Ejecutar el paso para cada fila que necesites validar

4. Validar con datos dinámicos
   - Usar variables en los valores esperados
   - Útil para tests parametrizados

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


================================================================================
                    PASOS PARA VALIDACIÓN DE ARCHIVOS PDF
================================================================================

Se han agregado 10 pasos nuevos para validar contenido de archivos PDF:

PASO 1: Verificar que PDF contiene texto
─────────────────────────────────────────

Sintaxis:
  verifico que el archivo PDF "{filename}" contiene el texto "{text}"

Ubicación: hakalab_framework/steps/pdf_steps.py

Descripción:
  Verifica que un PDF contiene un texto específico.
  Busca el texto en todas las páginas del PDF.

Ejemplo:
  verifico que el archivo PDF "documento.pdf" contiene el texto "Aprobado"

---

PASO 2: Verificar que PDF NO contiene texto
────────────────────────────────────────────

Sintaxis:
  verifico que el archivo PDF "{filename}" no contiene el texto "{text}"

Descripción:
  Verifica que un PDF NO contiene un texto específico.

Ejemplo:
  verifico que el archivo PDF "documento.pdf" no contiene el texto "Rechazado"

---

PASO 3: Verificar número de páginas
────────────────────────────────────

Sintaxis:
  verifico que el archivo PDF "{filename}" tiene "{expected_pages}" páginas

Descripción:
  Verifica que un PDF tiene un número específico de páginas.

Ejemplo:
  verifico que el archivo PDF "documento.pdf" tiene "5" páginas

---

PASO 4: Verificar texto en página específica
─────────────────────────────────────────────

Sintaxis:
  verifico que la página "{page_number}" del PDF "{filename}" contiene el texto "{text}"

Descripción:
  Verifica que una página específica del PDF contiene un texto.

Ejemplo:
  verifico que la página "1" del PDF "documento.pdf" contiene el texto "Título"

---

PASO 5: Extraer texto completo del PDF
───────────────────────────────────────

Sintaxis:
  extraigo el texto del PDF "{filename}" y lo guardo en la variable "{variable_name}"

Descripción:
  Extrae todo el texto de un PDF y lo guarda en una variable.
  Útil para validaciones complejas o procesamiento posterior.

Ejemplo:
  extraigo el texto del PDF "documento.pdf" y lo guardo en la variable "pdf_content"

---

PASO 6: Extraer texto de página específica
───────────────────────────────────────────

Sintaxis:
  extraigo el texto de la página "{page_number}" del PDF "{filename}" y lo guardo en la variable "{variable_name}"

Descripción:
  Extrae el texto de una página específica del PDF y lo guarda en una variable.

Ejemplo:
  extraigo el texto de la página "1" del PDF "documento.pdf" y lo guardo en la variable "first_page"

---

PASO 7: Verificar que PDF está encriptado
──────────────────────────────────────────

Sintaxis:
  verifico que el archivo PDF "{filename}" está encriptado

Descripción:
  Verifica que un PDF está encriptado (protegido con contraseña).

Ejemplo:
  verifico que el archivo PDF "documento_seguro.pdf" está encriptado

---

PASO 8: Verificar que PDF NO está encriptado
──────────────────────────────────────────────

Sintaxis:
  verifico que el archivo PDF "{filename}" no está encriptado

Descripción:
  Verifica que un PDF NO está encriptado.

Ejemplo:
  verifico que el archivo PDF "documento.pdf" no está encriptado

---

PASO 9: Verificar metadatos del PDF
────────────────────────────────────

Sintaxis:
  verifico que el PDF "{filename}" tiene metadato "{key}" con valor "{value}"

Descripción:
  Verifica que un PDF contiene metadatos específicos.
  Metadatos comunes: Author, Title, Subject, Creator, Producer

Ejemplo:
  verifico que el PDF "documento.pdf" tiene metadato "Author" con valor "Juan"

---

PASO 10: Verificar texto con patrón regex
──────────────────────────────────────────

Sintaxis:
  verifico que el PDF "{filename}" contiene texto que coincide con el patrón "{pattern}"

Descripción:
  Verifica que un PDF contiene texto que coincide con un patrón regex.
  Útil para validar formatos específicos (fechas, números, etc.)

Ejemplo:
  verifico que el PDF "documento.pdf" contiene texto que coincide con el patrón "Total: \\$[0-9]+"

---

EJEMPLO COMPLETO: Validar PDF

Feature: Validar Documento PDF

  Scenario: Validar contenido de PDF descargado
    Given navego a "https://mi-aplicacion.com/reportes"
    When hago click en el elemento "Descargar PDF" con identificador "$.BUTTONS.download_pdf"
    And espero a que complete la descarga
    And guardo la descarga como "reporte.pdf"
    
    # Validar estructura
    Then verifico que el archivo PDF "reporte.pdf" tiene "5" páginas
    And verifico que el archivo PDF "reporte.pdf" no está encriptado
    
    # Validar contenido
    And verifico que el archivo PDF "reporte.pdf" contiene el texto "Reporte Mensual"
    And verifico que la página "1" del PDF "reporte.pdf" contiene el texto "Enero 2027"
    And verifico que el archivo PDF "reporte.pdf" contiene texto que coincide con el patrón "Total: \\$[0-9,]+"
    
    # Validar metadatos
    And verifico que el PDF "reporte.pdf" tiene metadato "Author" con valor "Sistema"
    
    # Extraer contenido
    And extraigo el texto del PDF "reporte.pdf" y lo guardo en la variable "report_content"
    And extraigo el texto de la página "1" del PDF "reporte.pdf" y lo guardo en la variable "first_page"

---

INSTALACIÓN

Los pasos de PDF requieren la librería pypdf. Ya está agregada a requirements.txt.

Para instalar:
  pip install -r requirements.txt

O instalar solo pypdf:
  pip install pypdf>=4.0.0

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