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

168 lines
4.5 KiB
Markdown

# 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:
```go
b.Navigate(ctx, url, nil)
time.Sleep(3 * time.Second)
```
Usar eventos CDP:
```go
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:
```go
time.Sleep(2 * time.Second)
html, _ := b.GetHTML(ctx, ".content")
```
Usar:
```go
b.WaitForSelector(ctx, ".content", 30*time.Second)
html, _ := b.GetHTML(ctx, ".content")
```
### 3. Esperar por condiciones JavaScript
En lugar de:
```go
time.Sleep(1 * time.Second)
result, _ := b.Evaluate(ctx, "window.dataReady")
```
Usar:
```go
b.WaitForFunction(ctx, "window.dataReady === true", 100*time.Millisecond)
result, _ := b.Evaluate(ctx, "window.data")
```
### 4. Eventos de red
Esperar que network esté idle:
```go
// 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
```go
// 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
- [x] `examples/basic.go` - Eliminar time.Sleep
- [x] `examples/advanced.go` - Reemplazar con esperas basadas en eventos
- [x] `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()
```go
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
- CDP Page events: https://chromedevtools.github.io/devtools-protocol/tot/Page/#event-loadEventFired
- CDP Network events: https://chromedevtools.github.io/devtools-protocol/tot/Network/
- Puppeteer waitFor: https://pptr.dev/guides/page-interactions#waiting