package browser import ( "context" "errors" "net" "net/http" "net/http/httptest" "net/url" "os" "path/filepath" "strconv" "testing" "chub/internal/domain" ) func TestCDPInspectorValidatesEndpointFromProfileFile(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/json/version" { t.Fatalf("path = %q", r.URL.Path) } _, _ = w.Write([]byte(`{"Browser":"Chrome/136.0.0.0"}`)) })) defer server.Close() parsed, err := url.Parse(server.URL) if err != nil { t.Fatal(err) } _, portText, err := net.SplitHostPort(parsed.Host) if err != nil { t.Fatal(err) } profile := t.TempDir() if err := os.WriteFile(filepath.Join(profile, "DevToolsActivePort"), []byte(portText+"\n/devtools/browser/test\n"), 0o600); err != nil { t.Fatal(err) } endpoint, err := NewCDPInspector().InspectRemoteDebugEndpoint(context.Background(), domain.BrowserChrome, profile) if err != nil { t.Fatalf("InspectRemoteDebugEndpoint() error = %v", err) } port, _ := strconv.Atoi(portText) if endpoint.Port != port || endpoint.Browser != "Chrome/136.0.0.0" { t.Fatalf("endpoint = %#v", endpoint) } direct, err := NewCDPInspector().InspectRemoteDebugPort(context.Background(), domain.BrowserChrome, port) if err != nil || direct.Port != port { t.Fatalf("InspectRemoteDebugPort() = %#v, %v", direct, err) } } func TestCDPInspectorRejectsMismatchedAndMalformedEndpoints(t *testing.T) { profile := t.TempDir() if err := os.WriteFile(filepath.Join(profile, "DevToolsActivePort"), []byte("not-a-port\n/devtools/browser/test\n"), 0o600); err != nil { t.Fatal(err) } if _, err := NewCDPInspector().InspectRemoteDebugEndpoint(context.Background(), domain.BrowserChrome, profile); !errors.Is(err, ErrRemoteDebugEndpointUnavailable) { t.Fatalf("malformed endpoint error = %v", err) } server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte(`{"Browser":"Edg/136.0.0.0"}`)) })) defer server.Close() parsed, err := url.Parse(server.URL) if err != nil { t.Fatal(err) } _, portText, err := net.SplitHostPort(parsed.Host) if err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(profile, "DevToolsActivePort"), []byte(portText+"\n/devtools/browser/test\n"), 0o600); err != nil { t.Fatal(err) } if _, err := NewCDPInspector().InspectRemoteDebugEndpoint(context.Background(), domain.BrowserChrome, profile); !errors.Is(err, ErrRemoteDebugEndpointUnavailable) { t.Fatalf("mismatched endpoint error = %v", err) } } func TestCDPInspectorFindsNextAvailablePort(t *testing.T) { listener, err := net.Listen("tcp4", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer listener.Close() start := listener.Addr().(*net.TCPAddr).Port port, err := NewCDPInspector().FindAvailableRemoteDebugPort(context.Background(), start) if err != nil { t.Fatal(err) } if port != start+1 { t.Fatalf("port = %d, want %d", port, start+1) } }