Files
navegator/pkg/browser/recorder.go
T
Developer 3253828fef
Tests / Lint (push) Has been cancelled
Tests / Unit Tests (push) Has been cancelled
Tests / E2E Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Initial commit: navegator - Chrome CDP automation for LLMs
Add complete navegator system for stealthy browser automation:
- CDP client with WebSocket communication
- Browser API with navigation, storage, network, runtime
- Stealth flags and anti-detection scripts
- Persistent profile support
- Examples and comprehensive documentation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-24 23:33:07 +01:00

118 lines
2.6 KiB
Go

package browser
import (
"encoding/json"
"fmt"
"os"
"sync"
"time"
)
// Action representa una acción realizada en el navegador.
type Action struct {
Timestamp time.Time `json:"timestamp"`
Type string `json:"type"`
Params map[string]interface{} `json:"params"`
Result interface{} `json:"result,omitempty"`
Error string `json:"error,omitempty"`
}
// Recorder registra todas las acciones del navegador.
type Recorder struct {
file *os.File
encoder *json.Encoder
mu sync.Mutex
enabled bool
}
// NewRecorder crea un nuevo recorder que escribe en un archivo.
func NewRecorder(filepath string) (*Recorder, error) {
file, err := os.Create(filepath)
if err != nil {
return nil, fmt.Errorf("failed to create recorder file: %w", err)
}
r := &Recorder{
file: file,
encoder: json.NewEncoder(file),
enabled: true,
}
// Escribir header
fmt.Fprintf(file, "# Navegator Recording - %s\n", time.Now().Format(time.RFC3339))
fmt.Fprintf(file, "# Este archivo puede ser usado para reproducir las acciones\n\n")
return r, nil
}
// Record registra una acción.
func (r *Recorder) Record(actionType string, params map[string]interface{}, result interface{}, err error) {
if !r.enabled {
return
}
r.mu.Lock()
defer r.mu.Unlock()
action := Action{
Timestamp: time.Now(),
Type: actionType,
Params: params,
Result: result,
}
if err != nil {
action.Error = err.Error()
}
// Escribir JSON
r.encoder.Encode(action)
// También escribir comentario legible
if params["url"] != nil {
fmt.Fprintf(r.file, "# %s - %s: %v\n", action.Timestamp.Format("15:04:05"), actionType, params["url"])
} else if params["selector"] != nil {
fmt.Fprintf(r.file, "# %s - %s: %v\n", action.Timestamp.Format("15:04:05"), actionType, params["selector"])
} else {
fmt.Fprintf(r.file, "# %s - %s\n", action.Timestamp.Format("15:04:05"), actionType)
}
}
// Close cierra el recorder.
func (r *Recorder) Close() error {
r.mu.Lock()
defer r.mu.Unlock()
if r.file != nil {
fmt.Fprintf(r.file, "\n# Recording ended at %s\n", time.Now().Format(time.RFC3339))
return r.file.Close()
}
return nil
}
// Enable activa el recording.
func (r *Recorder) Enable() {
r.mu.Lock()
defer r.mu.Unlock()
r.enabled = true
}
// Disable desactiva el recording.
func (r *Recorder) Disable() {
r.mu.Lock()
defer r.mu.Unlock()
r.enabled = false
}
// AddComment agrega un comentario al log.
func (r *Recorder) AddComment(comment string) {
if !r.enabled {
return
}
r.mu.Lock()
defer r.mu.Unlock()
fmt.Fprintf(r.file, "\n# %s\n", comment)
}