Files
navegator/dev/issues/completed/005-eliminar-timeouts-innecesarios.md
T
Developer c165f2f788 docs: issues técnicas para nuevas funcionalidades
Agrega 19 issues técnicas documentando funcionalidades implementadas y pendientes.

Issues completadas (movidas a dev/issues/completed/):
- 001-conversor-web-markdown.md
- 002-accessibility-tree.md
- 003-gestion-cookies-perfil.md
- 004-gestion-extensiones-chrome.md
- 005-eliminar-timeouts-innecesarios.md

Issues implementadas:
- 006-manejo-tabs-ventanas.md
- 016-manejo-iframes.md
- 017-actions-api.md
- 018-file-uploads.md
- 019-expected-conditions-mejoradas.md

Issues pendientes (media prioridad):
- 007-alert-prompt-confirm-handling.md
- 008-screenshot-elementos-especificos.md
- 009-pdf-generation.md
- 010-device-emulation-completo.md
- 011-downloads-handling.md

Issues pendientes (baja prioridad / avanzado):
- 012-browser-contexts-multi-sesion.md
- 013-video-recording.md
- 014-network-mocking-avanzado.md
- 015-geolocation-permissions.md

Incluye también dev/NUEVAS_FUNCIONALIDADES.md con resumen completo.

Directorio: dev/
2026-03-25 00:49:06 +01:00

4.5 KiB

Issue #005: Eliminar timeouts innecesarios del código

Tipo: Improvement Prioridad: Alta Estado: Pendiente

Descripción

Eliminar todos los time.Sleep() y timeouts hardcodeados innecesarios del código, reemplazándolos con esperas basadas en eventos CDP cuando sea posible.

Problema actual

El código tiene múltiples time.Sleep() arbitrarios:

  • time.Sleep(2 * time.Second) en examples/basic.go
  • time.Sleep(3 * time.Second) en cmd/list_blog.go
  • Timeouts hardcodeados en navegación

Estos timeouts son problemáticos porque:

  • No se adaptan a velocidad real de carga
  • Desperdicían tiempo en conexiones rápidas
  • Fallan en conexiones lentas
  • Hacen el código menos robusto

Estrategia de reemplazo

1. Eventos CDP de carga de página

En lugar de:

b.Navigate(ctx, url, nil)
time.Sleep(3 * time.Second)

Usar eventos CDP:

opts := browser.DefaultNavigateOptions()
opts.WaitUntil = "networkidle" // o "load" o "domcontentloaded"
b.Navigate(ctx, url, opts)
// No sleep necesario, Navigate espera el evento

2. Esperar por selectores

En lugar de:

time.Sleep(2 * time.Second)
html, _ := b.GetHTML(ctx, ".content")

Usar:

b.WaitForSelector(ctx, ".content", 30*time.Second)
html, _ := b.GetHTML(ctx, ".content")

3. Esperar por condiciones JavaScript

En lugar de:

time.Sleep(1 * time.Second)
result, _ := b.Evaluate(ctx, "window.dataReady")

Usar:

b.WaitForFunction(ctx, "window.dataReady === true", 100*time.Millisecond)
result, _ := b.Evaluate(ctx, "window.data")

4. Eventos de red

Esperar que network esté idle:

// Implementar WaitForNetworkIdle()
b.WaitForNetworkIdle(ctx, 500*time.Millisecond, 30*time.Second)

Eventos CDP útiles

Page domain

  • Page.loadEventFired - Página cargada completamente
  • Page.domContentEventFired - DOM listo
  • Page.frameStoppedLoading - Frame dejó de cargar

Network domain

  • Network.requestWillBeSent - Request iniciado
  • Network.responseReceived - Response recibida
  • Network.loadingFinished - Recurso terminó de cargar
  • Network.loadingFailed - Recurso falló

Métodos a implementar

// WaitForEvent espera un evento CDP específico
func (b *Browser) WaitForEvent(ctx context.Context, eventName string, timeout time.Duration) error

// WaitForNetworkIdle espera que no haya requests de red por X tiempo
func (b *Browser) WaitForNetworkIdle(ctx context.Context, idleTime, timeout time.Duration) error

// WaitForFunction espera que una función JS retorne true
func (b *Browser) WaitForFunction(ctx context.Context, fn string, checkInterval time.Duration) error

// WaitForNavigation espera que navegación complete
func (b *Browser) WaitForNavigation(ctx context.Context, timeout time.Duration) error

Archivos a revisar y actualizar

  • examples/basic.go - Eliminar time.Sleep
  • examples/advanced.go - Reemplazar con esperas basadas en eventos
  • cmd/list_blog.go - Usar WaitForSelector
  • pkg/browser/navigation.go - Mejorar Navigate() para esperar eventos
  • pkg/browser/browser.go - Agregar métodos de espera

Implementación en Navigate()

func (b *Browser) Navigate(ctx context.Context, url string, opts *NavigateOptions) error {
    if opts == nil {
        opts = DefaultNavigateOptions()
    }

    // Registrar listener ANTES de navegar
    loadedChan := make(chan struct{})
    b.client.On("Page.loadEventFired", func() {
        close(loadedChan)
    })

    // Enviar comando de navegación
    _, err := b.client.SendCommand(ctx, "Page.navigate", map[string]interface{}{
        "url": url,
    })
    if err != nil {
        return err
    }

    // Esperar evento según opts.WaitUntil
    select {
    case <-loadedChan:
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

Beneficios

Más rápido: No espera más de lo necesario Más robusto: Falla con timeout claro, no con misterioso "elemento no encontrado" Más confiable: Se adapta a velocidad real de página Mejor UX: Feedback claro de qué se está esperando

Testing

Probar con:

  • Conexiones rápidas (localhost)
  • Conexiones lentas (throttling)
  • Páginas con mucho JavaScript
  • Páginas con assets pesados
  • SPAs (React, Vue) que cargan async

Referencias