Test runner: return-value error handling, no guard/cek-try/throws

guard and cek-try both create CEK frames that don't survive async
perform/resume. Instead, run-action returns nil on success and an
error string on failure. The for-each loop checks the return value
and sets fail-msg. No exceptions cross async boundaries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-17 23:09:38 +00:00
parent db8e680caf
commit 84996d74e2
5 changed files with 77 additions and 66 deletions

View File

@@ -999,7 +999,31 @@
(hs-to-sx (nth ast 1)) (hs-to-sx (nth ast 1))
(hs-to-sx (nth ast 2))))) (hs-to-sx (nth ast 2)))))
((= head (quote do)) ((= head (quote do))
(cons (quote do) (map hs-to-sx (rest ast)))) (let
((compiled (map hs-to-sx (rest ast))))
(if
(and
(> (len compiled) 1)
(some
(fn
(c)
(and
(list? c)
(or
(= (first c) (quote hs-fetch))
(= (first c) (quote hs-wait))
(= (first c) (quote perform)))))
compiled))
(reduce
(fn
(body cmd)
(list
(quote let)
(list (list (quote it) cmd))
body))
(nth compiled (- (len compiled) 1))
(reverse (rest (reverse compiled))))
(cons (quote do) compiled))))
((= head (quote wait)) (list (quote hs-wait) (nth ast 1))) ((= head (quote wait)) (list (quote hs-wait) (nth ast 1)))
((= head (quote wait-for)) (emit-wait-for ast)) ((= head (quote wait-for)) (emit-wait-for ast))
((= head (quote log)) ((= head (quote log))

File diff suppressed because one or more lines are too long

View File

@@ -1859,7 +1859,8 @@
(let (let
((acc2 (append acc (list cmd)))) ((acc2 (append acc (list cmd))))
(cond (cond
((match-kw "then") (cl-collect acc2)) ((match-kw "then")
(cl-collect (append acc2 (list (quote __then__)))))
((and (not (at-end?)) (= (tp-type) "keyword") (cmd-kw? (tp-val))) ((and (not (at-end?)) (= (tp-type) "keyword") (cmd-kw? (tp-val)))
(cl-collect acc2)) (cl-collect acc2))
(true acc2))))))) (true acc2)))))))
@@ -1868,7 +1869,10 @@
(cond (cond
((= (len cmds) 0) nil) ((= (len cmds) 0) nil)
((= (len cmds) 1) (first cmds)) ((= (len cmds) 1) (first cmds))
(true (cons (quote do) cmds)))))) (true
(cons
(quote do)
(filter (fn (c) (not (= c (quote __then__)))) cmds)))))))
(define (define
parse-on-feat parse-on-feat
(fn (fn

File diff suppressed because one or more lines are too long

View File

@@ -47,53 +47,44 @@
nil nil
(do (hs-wait 200) (wait-for-el sel (- max-tries 1)))))))) (do (hs-wait 200) (wait-for-el sel (- max-tries 1))))))))
(run-action (run-action
(fn (fn (action)
(action) (let ((doc (get-doc)) (type (first action)))
(let
((doc (get-doc)) (type (first action)))
(cond (cond
(= type :click) (= type :click)
(let (let ((el (host-call doc "querySelector" (nth action 1))))
((el (host-call doc "querySelector" (nth action 1)))) (if (nil? el) (str "Not found: " (nth action 1))
(when (nil? el) (error (str "Not found: " (nth action 1)))) (do (host-call el "click") nil)))
(host-call el "click"))
(= type :fill) (= type :fill)
(let (let ((el (host-call doc "querySelector" (nth action 1))))
((el (host-call doc "querySelector" (nth action 1)))) (if (nil? el) (str "Not found: " (nth action 1))
(when (nil? el) (error (str "Not found: " (nth action 1)))) (do (host-call el "focus")
(host-call el "focus") (dom-set-prop el "value" (nth action 2))
(dom-set-prop el "value" (nth action 2)) (dom-dispatch el "input" nil)
(dom-dispatch el "input" nil) (dom-dispatch el "change" nil)
(dom-dispatch el "change" nil)) nil)))
(= type :wait) (= type :wait)
(hs-wait (nth action 1)) (do (hs-wait (nth action 1)) nil)
(= type :assert-text) (= type :assert-text)
(let (let ((el (host-call doc "querySelector" (nth action 1))))
((el (host-call doc "querySelector" (nth action 1)))) (if (nil? el) (str "Not found: " (nth action 1))
(when (nil? el) (error (str "Not found: " (nth action 1)))) (let ((txt (dom-text-content el))
(let (kw (nth action 2))
((txt (dom-text-content el)) (expected (nth action 3)))
(kw (nth action 2)) (cond
(expected (nth action 3))) (and (= kw :contains) (not (contains? txt expected)))
(when (str "Expected '" expected "' in '" (slice txt 0 60) "'")
(and (= kw :contains) (not (contains? txt expected))) (and (= kw :not-contains) (contains? txt expected))
(error (str "Expected '" expected "' in '" (slice txt 0 60) "'"))) (str "Unexpected '" expected "'")
(when true nil))))
(and (= kw :not-contains) (contains? txt expected))
(error (str "Unexpected '" expected "'")))))
(= type :assert-count) (= type :assert-count)
(let (let ((els (host-call doc "querySelectorAll" (nth action 1))))
((els (host-call doc "querySelectorAll" (nth action 1)))) (let ((count (host-get els "length"))
(let (kw (nth action 2))
((count (host-get els "length")) (expected (nth action 3)))
(kw (nth action 2)) (if (and (= kw :gte) (< count expected))
(expected (nth action 3)))
(when
(and (= kw :gte) (< count expected))
(str "Expected >=" expected " got " count) (str "Expected >=" expected " got " count)
nil))) nil)))
true true nil))))
nil))))
(run-all (run-all
(fn (fn
() ()
@@ -111,26 +102,18 @@
(console-log "[test] reload-frame") (console-log "[test] reload-frame")
(reload-frame) (reload-frame)
(console-log "[test] running actions") (console-log "[test] running actions")
(guard (let ((actions (get test :actions)) (fail-msg nil))
(e (when (not (empty? actions))
(true (let ((first-sel (nth (first actions) 1)))
(reset! results (assoc (deref results) name "fail")) (when (string? first-sel)
(console-log (str "[test] FAIL " name ": " e)))) (console-log (str "[test] wait-for: " first-sel))
(let (let ((found (wait-for-el first-sel 15)))
((actions (get test :actions))) (when (nil? found) (set! fail-msg (str "Timeout: " first-sel)))))))
(when (when (nil? fail-msg)
(not (empty? actions)) (for-each (fn (action) (when (nil? fail-msg) (let ((err (run-action action))) (when (string? err) (set! fail-msg err))))) actions))
(let (if (nil? fail-msg)
((first-sel (nth (first actions) 1))) (do (reset! results (assoc (deref results) name "pass")) (console-log (str "[test] PASS " name)))
(when (do (reset! results (assoc (deref results) name "fail")) (console-log (str "[test] FAIL " name ": " fail-msg)))))))
(string? first-sel)
(console-log (str "[test] wait-for: " first-sel))
(let ((found (wait-for-el first-sel 15)))
(when (nil? found)
(error (str "Timeout waiting for: " first-sel)))))))
(for-each run-action actions)
(reset! results (assoc (deref results) name "pass"))
(console-log (str "[test] PASS " name))))))
tests) tests)
(reset! running false) (reset! running false)
(reset! current "Done") (reset! current "Done")