ai cooking
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #161 from paulgmiller/pmiller/e2esinglerecipe

Improve e2e

authored by

Paul Miller and committed by
GitHub
54cf4f24 daa186b6

+40 -1
+1
AGENTS.md
··· 23 23 - Prefer simple html to javascript frameworks 24 24 25 25 ## Testing Guidelines 26 + - Always run tests after making code changes. Default to `go test ./...`; use a narrower `go test ./... -run TestName` only when appropriate for quick iteration. If you cannot run tests, explicitly say why. 26 27 - Place tests alongside code in `*_test.go`; prefer table-driven cases and explicit fixtures over implicit globals. 27 28 - Use `go test ./... -run TestName` for targeted debugging; keep deterministic by avoiding network calls and using fakes where possible. 28 29 - When touching recipe generation or Kroger client code, add assertions that cover API shape changes and template output (see existing tests in `internal/recipes` and `internal/html`).
+39 -1
cmd/careme/web_e2e_test.go
··· 17 17 "careme/internal/locations" 18 18 "careme/internal/recipes" 19 19 "careme/internal/users" 20 + 21 + "golang.org/x/net/html" 20 22 ) 21 23 22 24 func TestWebEndToEndFlowWithMocks(t *testing.T) { ··· 46 48 } 47 49 48 50 savedHash := recipeHashes[0] 51 + // Step 2b: load a shared recipe page directly. 52 + _ = mustGetBody(t, client, srv.URL+"/recipe/"+url.PathEscape(savedHash)) 49 53 dismissedHashes := recipeHashes[1:3] 50 54 51 55 //step 4 todo regenrate again with commentary then save two more ··· 171 175 body := readAll(t, resp.Body) 172 176 t.Fatalf("GET %s expected 200, got %d: %s", url, resp.StatusCode, body) 173 177 } 174 - return readAll(t, resp.Body) 178 + body := readAll(t, resp.Body) 179 + requireValidHTML(t, url, resp.Header.Get("Content-Type"), body) 180 + return body 175 181 } 176 182 177 183 func followUntilRecipes(t *testing.T, client *http.Client, startURL string, expectSpinner bool) (string, string) { ··· 278 284 } 279 285 return string(data) 280 286 } 287 + 288 + func requireValidHTML(t *testing.T, url, contentType, body string) { 289 + t.Helper() 290 + if strings.TrimSpace(body) == "" { 291 + t.Fatalf("GET %s returned empty body", url) 292 + } 293 + if contentType != "" && !strings.Contains(strings.ToLower(contentType), "text/html") { 294 + t.Fatalf("GET %s expected HTML content-type, got %q", url, contentType) 295 + } 296 + if !strings.Contains(strings.ToLower(body), "<html") { 297 + t.Fatalf("GET %s expected HTML body, missing <html> tag", url) 298 + } 299 + doc, err := html.Parse(strings.NewReader(body)) 300 + if err != nil { 301 + t.Fatalf("GET %s returned invalid HTML: %v", url, err) 302 + } 303 + if !hasElement(doc, "body") { 304 + t.Fatalf("GET %s expected HTML body element", url) 305 + } 306 + } 307 + 308 + func hasElement(n *html.Node, name string) bool { 309 + if n.Type == html.ElementNode && n.Data == name { 310 + return true 311 + } 312 + for child := n.FirstChild; child != nil; child = child.NextSibling { 313 + if hasElement(child, name) { 314 + return true 315 + } 316 + } 317 + return false 318 + }