#!/usr/bin/env bb (ns integration-test (:require [babashka.http-client :as http] [clojure.edn :as edn] [clojure.string :as str])) (def default-config {:base-url "http://localhost:3000" :max-retries 30 :retry-delay-ms 1000 :watch? false :watch-interval-ms 5000}) (defn get* [base-url] (http/get base-url {:throw false})) (defn head* [base-url] (http/head base-url {:throw false})) (defn wait-for-server [{:keys [base-url max-retries retry-delay-ms]}] (println (str "=== Waiting for server at " base-url " ===")) (loop [i 1] (let [ready? (try (= 200 (:status (get* base-url))) (catch Exception _ false))] (cond ready? (do (println "Server is ready!") true) (= i max-retries) (do (println (format "ERROR: Server did not become ready after %d attempts" max-retries)) false) :else (do (Thread/sleep retry-delay-ms) (recur (inc i))))))) (defn run-suite "Runs the integration suite once against config's :base-url. Returns {:pass n :fail n :errors [...]}" [{:keys [base-url] :as config}] (if-not (wait-for-server config) {:pass 0 :fail 1 :errors ["server did not become ready"]} (let [pass (atom 0) fail (atom 0) errors (atom []) assert-eq (fn [label expected actual] (if (= expected actual) (do (println " ✓" label) (swap! pass inc)) (do (println " ✗" label) (println " expected:" expected) (println " actual: " actual) (swap! fail inc) (swap! errors conj (format "%s: expected '%s' but got '%s'" label expected actual))))) assert-contains (fn [label needle haystack] (if (str/includes? haystack needle) (do (println " ✓" label) (swap! pass inc)) (do (println " ✗" label) (println " expected to contain:" needle) (println " actual: " haystack) (swap! fail inc) (swap! errors conj (format "%s: did not find '%s'" label needle))))) assert-not-empty (fn [label value] (if-not (str/blank? value) (do (println " ✓" label) (swap! pass inc)) (do (println " ✗" label) (println " expected non-empty value") (swap! fail inc) (swap! errors conj (format "%s: value was empty" label)))))] (println) (println "=== Running Integration Tests ===") (println) (println "Test 1: GET / returns 200") (assert-eq "HTTP status" 200 (:status (get* base-url))) (println) (println "Test 2: Content-Type is text/html") (assert-contains "Content-Type" "text/html" (get (:headers (get* base-url)) "content-type" "")) (println) (println "Test 3: Root serves the HTML shell for the UI") (let [body (:body (get* base-url))] (assert-contains "Body has the mount point" "