Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

129 lines
4.4 KiB
Go

package browser
import (
"context"
"encoding/base64"
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
func TestBrowserNodeBackendCallsAuthenticatedDesktopHost(t *testing.T) {
var gotAuthorization string
var gotAgentTurnID string
server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
gotAuthorization = request.Header.Get("Authorization")
var payload struct {
AgentTurnID string `json:"agentTurnId"`
}
_ = json.NewDecoder(request.Body).Decode(&payload)
gotAgentTurnID = payload.AgentTurnID
_ = json.NewEncoder(response).Encode(map[string]any{
"result": map[string]any{"text": "pages"},
})
}))
defer server.Close()
listenerInfoPath := writeBrowserNodeListenerInfo(t, strings.TrimPrefix(server.URL, "http://"), "secret")
backend := newBrowserNodeHTTPBackend(listenerInfoPath)
result, err := backend.Call(context.Background(), "workspace-1", "agent-1", "turn-1", "list_pages", map[string]any{})
if err != nil {
t.Fatal(err)
}
if result.Text != "pages" || gotAuthorization != "Bearer secret" || gotAgentTurnID != "turn-1" {
t.Fatalf("result = %#v, authorization = %q, agentTurnId = %q", result, gotAuthorization, gotAgentTurnID)
}
}
func TestBrowserNodeBackendCheckReadyRequiresReachableLoopback(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, _ *http.Request) {
response.WriteHeader(http.StatusNoContent)
}))
defer server.Close()
backend := newBrowserNodeHTTPBackend(writeBrowserNodeListenerInfo(t, strings.TrimPrefix(server.URL, "http://"), "secret"))
concrete, ok := backend.(*browserNodeHTTPBackend)
if !ok {
t.Fatal("expected HTTP BrowserNode backend")
}
if err := concrete.CheckReady(context.Background()); err != nil {
t.Fatalf("CheckReady: %v", err)
}
}
func TestBrowserNodeBackendWritesScreenshotToRequestedPath(t *testing.T) {
png := []byte("png-data")
server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, _ *http.Request) {
_ = json.NewEncoder(response).Encode(map[string]any{
"result": map[string]any{
"screenshotData": base64.StdEncoding.EncodeToString(png),
"text": "captured",
},
})
}))
defer server.Close()
backend := newBrowserNodeHTTPBackend(writeBrowserNodeListenerInfo(t, strings.TrimPrefix(server.URL, "http://"), "secret"))
screenshotPath := filepath.Join(t.TempDir(), "screenshot.png")
if _, err := backend.Call(context.Background(), "workspace-1", "agent-1", "turn-1", "take_screenshot", map[string]any{"filePath": screenshotPath}); err != nil {
t.Fatal(err)
}
got, err := os.ReadFile(screenshotPath)
if err != nil {
t.Fatal(err)
}
if string(got) != string(png) {
t.Fatalf("screenshot = %q, want %q", got, png)
}
}
func TestBrowserNodeBackendReleasesAgentLease(t *testing.T) {
var gotPath string
var gotAgentSessionID string
server := httptest.NewServer(http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
gotPath = request.URL.Path
var payload struct {
AgentSessionID string `json:"agentSessionId"`
}
_ = json.NewDecoder(request.Body).Decode(&payload)
gotAgentSessionID = payload.AgentSessionID
_ = json.NewEncoder(response).Encode(map[string]any{
"result": map[string]any{"text": "released"},
})
}))
defer server.Close()
backend := newBrowserNodeHTTPBackend(writeBrowserNodeListenerInfo(t, strings.TrimPrefix(server.URL, "http://"), "secret"))
if err := backend.ReleaseAgent(context.Background(), "agent-1"); err != nil {
t.Fatal(err)
}
if gotPath != "/v1/release-agent" || gotAgentSessionID != "agent-1" {
t.Fatalf("path = %q, agentSessionId = %q", gotPath, gotAgentSessionID)
}
}
func TestBrowserNodeBackendRejectsNonLoopbackListener(t *testing.T) {
backend := newBrowserNodeHTTPBackend(writeBrowserNodeListenerInfo(t, "10.0.0.1:1234", "secret"))
_, err := backend.Call(context.Background(), "workspace-1", "agent-1", "turn-1", "list_pages", nil)
if err == nil || !strings.Contains(err.Error(), "loopback") {
t.Fatalf("err = %v, want loopback rejection", err)
}
}
func writeBrowserNodeListenerInfo(t *testing.T, address, token string) string {
t.Helper()
path := filepath.Join(t.TempDir(), "listener.json")
body, err := json.Marshal(browserNodeListenerInfo{Address: address, Token: token, Version: 1})
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(path, body, 0o600); err != nil {
t.Fatal(err)
}
return path
}