mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 03:57:09 +00:00
fix(chrome): clear storage over cdp instead of scripting an opaque origin
Launch runs while the tab is still on about:blank, whose opaque origin denies storage access, so localStorage.clear() threw SecurityError and every web run died at launch. Storage.clearDataForOrigin needs no navigation. The exception helper lands here because "Uncaught" is what hid this for so long. Claude-Session: https://claude.ai/code/session_01Fj4wJUikdABuMQEETwW55J
This commit is contained in:
1 parent
ea17eed739
commit
715d239477
3 files changed
+163
-11
No files matched your search
@@ -6,10 +6,62 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/chromedp/chromedp"
|
||||
)
|
||||
|
||||
// TestLaunch_ClearStateWipesStorageForTheTargetOrigin covers the CLI's default
|
||||
// path (--clear-data). The tab sits on about:blank when Launch runs, an opaque
|
||||
// origin that denies storage access, so clearing by script there throws
|
||||
// SecurityError and kills every web run before the app loads.
|
||||
func TestLaunch_ClearStateWipesStorageForTheTargetOrigin(t *testing.T) {
|
||||
const page = `<body><script>
|
||||
const visits = Number(localStorage.getItem("visits") ?? "0") + 1;
|
||||
localStorage.setItem("visits", String(visits));
|
||||
sessionStorage.setItem("tab", "dirty");
|
||||
</script></body>`
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
_, _ = w.Write([]byte(page))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
d := New()
|
||||
defer d.Terminate(context.Background())
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := d.Launch(ctx, server.URL, true, nil); err != nil {
|
||||
t.Fatalf("Launch with clearState on a fresh tab: %v", err)
|
||||
}
|
||||
if err := d.Launch(ctx, server.URL, false, nil); err != nil {
|
||||
t.Fatalf("Launch: %v", err)
|
||||
}
|
||||
var visits string
|
||||
if err := chromedp.Run(d.tabCtx,
|
||||
chromedp.Evaluate(`localStorage.getItem("visits")`, &visits)); err != nil {
|
||||
t.Fatalf("read localStorage: %v", err)
|
||||
}
|
||||
if visits != "2" {
|
||||
t.Fatalf("visits = %q, want 2 (two loads, storage kept)", visits)
|
||||
}
|
||||
|
||||
if err := d.Launch(ctx, server.URL, true, nil); err != nil {
|
||||
t.Fatalf("Launch with clearState on the target origin: %v", err)
|
||||
}
|
||||
if err := chromedp.Run(d.tabCtx,
|
||||
chromedp.Evaluate(`localStorage.getItem("visits")`, &visits)); err != nil {
|
||||
t.Fatalf("read localStorage: %v", err)
|
||||
}
|
||||
if visits != "1" {
|
||||
t.Errorf("visits = %q, want 1 (storage cleared before the app loaded)", visits)
|
||||
}
|
||||
}
|
||||
|
||||
// TestActionMethods_HonorCallerCancellation confirms the DeviceDriver action
|
||||
// methods route through runCtx so a cancelled caller context aborts the CDP
|
||||
// round-trip instead of blocking on d.tabCtx. Without this a hung browser would
|
||||
|
||||
Reference in new issue
Block a user