package latest import ( "context" "os" "testing" "time" "bookmarkmanager/backend/internal/store" ) // TestSmokeComix answers "is comix's challenge clearing from this browser right // now" — a live, time-varying fact, so a red run is something to re-check // before it is a defect. Needs the real browser unit with outbound network: // // cd chrome && BROWSER_BIND_ADDR=127.0.0.1 docker compose up -d --build // SMOKE_BROWSER_WS_URL=ws://127.0.0.1:9222 go test -run TestSmokeComix ./internal/latest // // It walks the whole read: the in-tab page fetch, both parses, and the Cover // bytes by direct navigation to static.comix.to. The Cover address comes out of // the page rather than being pinned in the test, because a stored one rots. func TestSmokeComix(t *testing.T) { ws := os.Getenv("SMOKE_BROWSER_WS_URL") if ws == "" { t.Skip("SMOKE_BROWSER_WS_URL unset") } const seriesURL = "https://comix.to/title/m12d-classmate" f, err := NewBrowserFetcher(ws) if err != nil { t.Fatalf("NewBrowserFetcher: %v", err) } defer f.Close() ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) defer cancel() body, status, err := f.Get(ctx, seriesURL) if err != nil { t.Fatalf("Get: %v", err) } t.Logf("status=%d bytes=%d", status, len(body)) if status != 200 { t.Fatalf("status = %d, want 200 — the sidecar is not clearing the challenge", status) } chapter, ok := latestChapterFrom("comix", seriesURL, body) if !ok { t.Fatalf("no latest chapter in %d bytes — page shape changed", len(body)) } t.Logf("latest chapter: %v %q", chapter.Num, chapter.Label) cover, ok := coverFrom("comix", seriesURL, body) if !ok { t.Fatalf("no cover address in %d bytes — page shape changed", len(body)) } t.Logf("cover: %s", cover) if !browserOnlyCoverURL(cover) { t.Fatalf("cover %q is not claimed by the browser gate: the pin and the live URL shape disagree", cover) } bytes, contentType, err := f.Image(ctx, cover) if err != nil { t.Fatalf("Image: %v", err) } if len(bytes) < 1000 { t.Fatalf("cover is %d bytes, want a real image", len(bytes)) } t.Logf("fetched %d bytes of %s", len(bytes), contentType) if _, ok := store.CoverContentType(contentType); !ok { t.Fatalf("content type %q is not storable", contentType) } }