;; Tests for the htmx demo page
;; Each deftest declares its runner: :playwright (live browser) or :harness (mock IO)

;; ── Click to Load ──────────────────────────────────────────────

(deftest
  click-to-load
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (click "button[hx-get]")
  (wait 2000)
  (assert-text "#click-result" :contains "Content loaded!")
  (assert-text "#click-result" :contains "Fetched from the server via sx-get"))

(deftest
  click-to-load-network
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (click "button[hx-get]")
  (assert-network :method "GET" :url-contains "api.click"))

;; ── Active Search ──────────────────────────────────────────────

(deftest
  search-debounce
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (fill "input[hx-get]" "swap")
  (wait 1500)
  (assert-network
    :method "GET"
    :url-contains "api.search"
    :url-contains "q=swap")
  (assert-text "#search-results" :not-contains "Type to search"))

(deftest
  search-empty
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (fill "input[hx-get]" "xyznonexistent")
  (wait 1500)
  (assert-text "#search-results" :contains "No results"))

;; ── Tabs ───────────────────────────────────────────────────────

(deftest
  tab-switch
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (click "button[hx-get*=\"tab=features\"]")
  (wait 2000)
  (assert-text "#htmx-tab-content" :not-contains "Click a tab")
  (assert-network :method "GET" :url-contains "api.tab"))

(deftest
  tab-overview
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (click "button[hx-get*=\"tab=overview\"]")
  (wait 2000)
  (assert-text "#htmx-tab-content" :contains "htmx gives you access"))

;; ── Append Items ───────────────────────────────────────────────

(deftest
  append-item
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (assert-count "#item-list > *" 0)
  (click "button[hx-post*=\"api.append\"]")
  (wait 2000)
  (assert-count "#item-list > *" :gte 1)
  (assert-network :method "POST" :url-contains "api.append"))

(deftest
  append-multiple
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (click "button[hx-post*=\"api.append\"]")
  (wait 1500)
  (click "button[hx-post*=\"api.append\"]")
  (wait 1500)
  (assert-count "#item-list > *" :gte 2))

;; ── Delete with Confirm ────────────────────────────────────────

(deftest
  delete-item
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (assert-count "#delete-list .item" 3)
  (accept-dialog)
  (click "button[hx-delete]:first-of-type")
  (wait 2000)
  (assert-count "#delete-list .item" 2)
  (assert-network :method "DELETE" :url-contains "api.delete"))

;; ── Form Submission ────────────────────────────────────────────

(deftest
  form-submit
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (fill "form[hx-post] input[name=\"name\"]" "Alice")
  (fill "form[hx-post] input[name=\"email\"]" "alice@example.com")
  (click "form[hx-post] button[type=\"submit\"]")
  (wait 2000)
  (assert-text "#form-result" :contains "Alice")
  (assert-text "#form-result" :contains "alice@example.com")
  (assert-network :method "POST" :url-contains "api.form"))

;; ── Boot & Activation ──────────────────────────────────────────

(deftest
  htmx-boot-activates
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (assert-count "[hx-get],[hx-post],[hx-delete]" :gte 8)
  (eval "(type-of htmx-boot-subtree!)" :equals "function"))

(deftest
  no-console-errors
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (assert-no-errors)
  (assert-text "[data-sx-ready]" :exists true))

;; ── OOB Swap Filtering ────────────────────────────────────────

(deftest
  oob-not-visible
  :runner :playwright
  :url "/sx/(applications.(htmx))"
  (click "button[hx-get]")
  (wait 2000)
  (assert-text "#click-result" :not-contains "defcomp")
  (assert-text "#click-result" :not-contains "~examples"))
