mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
215 lines
6.8 KiB
Go
215 lines
6.8 KiB
Go
package backend
|
|
|
|
import (
|
|
"ant-chrome/backend/internal/browser"
|
|
"ant-chrome/backend/internal/config"
|
|
"net/http"
|
|
"os/exec"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestWaitForBrowserDebugReadyMarksProfileReady(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
port := freeLoopbackPort(t)
|
|
app := NewApp("")
|
|
app.browserMgr = browser.NewManager(config.DefaultConfig(), "")
|
|
app.browserMgr.Profiles = map[string]*BrowserProfile{
|
|
"profile-ready": {
|
|
ProfileId: "profile-ready",
|
|
ProfileName: "Ready Browser",
|
|
Running: true,
|
|
DebugPort: port,
|
|
DebugReady: false,
|
|
RuntimeWarning: "pending",
|
|
LastStartAt: time.Now().Format(time.RFC3339),
|
|
},
|
|
}
|
|
app.browserMgr.BrowserProcesses = make(map[string]*exec.Cmd)
|
|
|
|
serverReady := make(chan *devToolsTestServer, 1)
|
|
go func() {
|
|
time.Sleep(200 * time.Millisecond)
|
|
serverReady <- startDevToolsServerOnPort(t, port, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.URL.Path {
|
|
case "/json/version":
|
|
_, _ = w.Write([]byte(`{"Browser":"Chrome/142.0","webSocketDebuggerUrl":"ws://127.0.0.1/devtools/browser"}`))
|
|
case "/json/list":
|
|
_, _ = w.Write([]byte(`[{"id":"page-1"}]`))
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
}))
|
|
}()
|
|
|
|
snapshot, changed := app.waitForBrowserDebugReady("profile-ready", port, 2*time.Second)
|
|
server := <-serverReady
|
|
defer server.Close()
|
|
|
|
if snapshot == nil {
|
|
t.Fatal("期望等待到调试接口就绪")
|
|
}
|
|
if !changed {
|
|
t.Fatal("期望调试接口就绪后标记实例状态变更")
|
|
}
|
|
if !snapshot.DebugReady {
|
|
t.Fatal("期望实例被标记为调试接口已就绪")
|
|
}
|
|
if snapshot.RuntimeWarning != "" {
|
|
t.Fatalf("期望调试接口就绪后清空警告,实际=%q", snapshot.RuntimeWarning)
|
|
}
|
|
}
|
|
|
|
func TestSanitizeManagedLaunchArgsRemovesSystemManagedFlags(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got, removed := sanitizeManagedLaunchArgs([]string{
|
|
"--lang=en-US",
|
|
"--remote-debugging-port=9222",
|
|
"--user-data-dir", "D:\\profiles\\demo",
|
|
"--proxy-server", "http://127.0.0.1:9000",
|
|
"--remote-debugging-pipe",
|
|
"https://example.com",
|
|
})
|
|
|
|
wantArgs := []string{"--lang=en-US", "https://example.com"}
|
|
if !reflect.DeepEqual(got, wantArgs) {
|
|
t.Fatalf("sanitizeManagedLaunchArgs args mismatch: got=%v want=%v", got, wantArgs)
|
|
}
|
|
|
|
wantRemoved := []string{
|
|
"--remote-debugging-port",
|
|
"--user-data-dir",
|
|
"--proxy-server",
|
|
"--remote-debugging-pipe",
|
|
}
|
|
if !reflect.DeepEqual(removed, wantRemoved) {
|
|
t.Fatalf("sanitizeManagedLaunchArgs removed mismatch: got=%v want=%v", removed, wantRemoved)
|
|
}
|
|
}
|
|
|
|
func TestSanitizeManagedLaunchArgsKeepsUnmanagedFlags(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
input := []string{"--lang=en-US", "--disable-sync", "https://example.com"}
|
|
got, removed := sanitizeManagedLaunchArgs(input)
|
|
if !reflect.DeepEqual(got, input) {
|
|
t.Fatalf("sanitizeManagedLaunchArgs should preserve unmanaged args: got=%v want=%v", got, input)
|
|
}
|
|
if len(removed) != 0 {
|
|
t.Fatalf("sanitizeManagedLaunchArgs should not report managed args, got=%v", removed)
|
|
}
|
|
}
|
|
|
|
func TestResolveBrowserStartProxyUsesTemporaryProxyWithoutMutatingProfile(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cfg := config.DefaultConfig()
|
|
cfg.Browser.Proxies = []config.BrowserProxy{
|
|
{ProxyId: "stored-proxy", ProxyName: "Stored", ProxyConfig: "http://127.0.0.1:18080"},
|
|
{ProxyId: "runtime-proxy", ProxyName: "Runtime", ProxyConfig: "http://127.0.0.1:28080"},
|
|
}
|
|
app := NewApp("")
|
|
app.config = cfg
|
|
app.browserMgr = browser.NewManager(cfg, t.TempDir())
|
|
profile := &BrowserProfile{
|
|
ProfileId: "profile-temporary-proxy",
|
|
ProfileName: "Temporary Proxy",
|
|
ProxyId: "stored-proxy",
|
|
ProxyConfig: "http://127.0.0.1:18080",
|
|
}
|
|
input := newBrowserStartInput(profile.ProfileId, nil, nil, false, false, false, "runtime-proxy", "")
|
|
|
|
effectiveProxy, bridgeKey, releaseBridge, err := app.resolveBrowserStartProxy(input, profile)
|
|
if err != nil {
|
|
t.Fatalf("resolveBrowserStartProxy returned error: %v", err)
|
|
}
|
|
if effectiveProxy != "http://127.0.0.1:28080" {
|
|
t.Fatalf("expected temporary proxy, got %q", effectiveProxy)
|
|
}
|
|
if bridgeKey != "" || releaseBridge {
|
|
t.Fatalf("plain HTTP proxy should not acquire bridge: key=%q release=%v", bridgeKey, releaseBridge)
|
|
}
|
|
if profile.ProxyId != "stored-proxy" || profile.ProxyConfig != "http://127.0.0.1:18080" {
|
|
t.Fatalf("temporary proxy should not mutate profile: %+v", profile)
|
|
}
|
|
|
|
fallbackInput := newBrowserStartInput(profile.ProfileId, nil, nil, false, false, false, "missing-proxy", "http://127.0.0.1:38080")
|
|
effectiveProxy, bridgeKey, releaseBridge, err = app.resolveBrowserStartProxy(fallbackInput, profile)
|
|
if err != nil {
|
|
t.Fatalf("fallback temporary proxy returned error: %v", err)
|
|
}
|
|
if effectiveProxy != "http://127.0.0.1:38080" {
|
|
t.Fatalf("expected fallback temporary proxy config, got %q", effectiveProxy)
|
|
}
|
|
if bridgeKey != "" || releaseBridge {
|
|
t.Fatalf("fallback HTTP proxy should not acquire bridge: key=%q release=%v", bridgeKey, releaseBridge)
|
|
}
|
|
if profile.ProxyId != "stored-proxy" || profile.ProxyConfig != "http://127.0.0.1:18080" {
|
|
t.Fatalf("fallback temporary proxy should not mutate profile: %+v", profile)
|
|
}
|
|
}
|
|
|
|
func TestAppendLaunchTargetsUsesConfiguredDefaultStartURLs(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := appendLaunchTargets([]string{"--disable-sync"}, nil, []string{"https://one.example/", "https://two.example/"}, false, false)
|
|
want := []string{"--disable-sync", "https://one.example/", "https://two.example/"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("appendLaunchTargets mismatch: got=%v want=%v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestAppendLaunchTargetsUsesBlankPageWhenSessionRestoreDisabled(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := appendLaunchTargets([]string{"--disable-sync"}, nil, []string{}, false, false)
|
|
want := []string{"--disable-sync", "about:blank"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("appendLaunchTargets should fall back to about:blank: got=%v want=%v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestAppendLaunchTargetsPreservesSessionRestoreWhenEnabled(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := appendLaunchTargets([]string{"--disable-sync"}, nil, []string{}, false, true)
|
|
want := []string{"--disable-sync"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("appendLaunchTargets should preserve session restore behavior: got=%v want=%v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestBuildBrowserLaunchArgsUsesNoProxyServerForDirectProxy(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
profile := &BrowserProfile{
|
|
ProfileId: "profile-direct",
|
|
}
|
|
|
|
got := buildBrowserLaunchArgs(
|
|
profile,
|
|
`D:\profiles\direct`,
|
|
9222,
|
|
"direct://",
|
|
nil,
|
|
nil,
|
|
[]string{"about:blank"},
|
|
)
|
|
|
|
hasNoProxyServer := false
|
|
for _, arg := range got {
|
|
if arg == "--no-proxy-server" {
|
|
hasNoProxyServer = true
|
|
}
|
|
if arg == "--proxy-server=direct://" {
|
|
t.Fatalf("expected direct proxy launch args to avoid --proxy-server=direct://, got=%v", got)
|
|
}
|
|
}
|
|
if !hasNoProxyServer {
|
|
t.Fatalf("expected direct proxy to use --no-proxy-server, got=%v", got)
|
|
}
|
|
}
|