diff --git a/spec/tests/test-hyperscript-behavioral.sx b/spec/tests/test-hyperscript-behavioral.sx index f415239a..47d35741 100644 --- a/spec/tests/test-hyperscript-behavioral.sx +++ b/spec/tests/test-hyperscript-behavioral.sx @@ -1,5 +1,5 @@ ;; Hyperscript behavioral tests — auto-generated from upstream _hyperscript test suite -;; Source: spec/tests/hyperscript-upstream-tests.json (346 tests) +;; Source: spec/tests/hyperscript-upstream-tests.json (831 tests, v0.9.14 + dev) ;; DO NOT EDIT — regenerate with: python3 tests/playwright/generate-sx-tests.py ;; ── Test helpers ────────────────────────────────────────────────── @@ -179,8 +179,8 @@ (hs-activate! _el-trigger) (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d2) - ;; SKIP action: find___trigger__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass(/foo/) + (dom-dispatch (dom-query-by-id "trigger") "click" nil) + (assert (dom-has-class? (dom-query-by-id "d2") "foo")) )) (deftest "when clause sets result to matched elements" (hs-cleanup!) @@ -199,8 +199,8 @@ (dom-set-attr _el-none "id" "none") (dom-set-attr _el-none "style" "display:none") (dom-append (dom-body) _el-none) - ;; SKIP action: find___trigger__.dispatchEvent__click__ - ;; SKIP check: skip toBeHidden() + (dom-dispatch (dom-query-by-id "trigger") "click" nil) + (assert (not (dom-visible? (dom-query-by-id "none")))) )) (deftest "when clause result is empty when nothing matches" (hs-cleanup!) @@ -214,8 +214,8 @@ (dom-append (dom-body) _el-d1) (dom-set-attr _el-none "id" "none") (dom-append (dom-body) _el-none) - ;; SKIP action: find___trigger__.dispatchEvent__click__ - ;; SKIP check: skip toHaveAttribute('hidden') + (dom-dispatch (dom-query-by-id "trigger") "click" nil) + (assert (not (dom-has-attr? (dom-query-by-id "none") "hidden"))) )) (deftest "can add a value to an array" (hs-cleanup!) @@ -223,8 +223,8 @@ (dom-set-attr _el-div "_" "on click set :arr to [1,2,3] add 4 to :arr put :arr as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("1,2,3,4") + (dom-dispatch _el-div "click" nil) + (assert= "1,2,3,4" (dom-text-content _el-div)) )) (deftest "can add a value to a set" (hs-cleanup!) @@ -232,8 +232,8 @@ (dom-set-attr _el-div "_" "on click set :s to [] as Set add 'a' to :s add 'b' to :s add 'a' to :s put :s.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("2") + (dom-dispatch _el-div "click" nil) + (assert= "2" (dom-text-content _el-div)) )) ) @@ -354,8 +354,9 @@ (dom-add-class _el-d2 "item") (dom-add-class _el-d2 "highlight") (dom-append (dom-body) _el-d2) - ;; SKIP action: find___trigger__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass(/highlight/); toHaveClass(/highlight/) + (dom-dispatch (dom-query-by-id "trigger") "click" nil) + (assert (not (dom-has-class? (dom-query-by-id "d1") "highlight"))) + (assert (dom-has-class? (dom-query-by-id "d2") "highlight")) )) (deftest "can remove CSS properties" (hs-cleanup!) @@ -364,8 +365,7 @@ (dom-set-attr _el-div "style" "color: red; font-weight: bold;") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toBe(''); toBe('bold') + (dom-dispatch _el-div "click" nil) )) (deftest "can remove multiple CSS properties" (hs-cleanup!) @@ -374,8 +374,7 @@ (dom-set-attr _el-div "style" "color: red; font-weight: bold; opacity: 0.5;") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toBe(''); toBe(''); toBe('0.5') + (dom-dispatch _el-div "click" nil) )) (deftest "can remove a value from an array" (hs-cleanup!) @@ -383,8 +382,8 @@ (dom-set-attr _el-div "_" "on click set :arr to [1,2,3,4] remove 3 from :arr put :arr as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("1,2,4") + (dom-dispatch _el-div "click" nil) + (assert= "1,2,4" (dom-text-content _el-div)) )) (deftest "can remove a value from a set" (hs-cleanup!) @@ -392,8 +391,8 @@ (dom-set-attr _el-div "_" "on click set :s to ['a','b','c'] as Set remove 'b' from :s put :s.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("2") + (dom-dispatch _el-div "click" nil) + (assert= "2" (dom-text-content _el-div)) )) ) @@ -609,17 +608,21 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveAttribute('data-state', 'active'); toHaveAttribute('da + (dom-append (dom-body) _el-div) + (dom-dispatch _el-div "click" nil) + (assert= "inactive" (dom-get-attr _el-div "data-state")) + (dom-dispatch _el-div "click" nil) + (assert= "active" (dom-get-attr _el-div "data-state")) )) (deftest "can toggle between different attributes" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveAttribute('enabled', 'true'); toHaveAttribute('disable + (dom-append (dom-body) _el-div) + (dom-dispatch _el-div "click" nil) + (assert= "true" (dom-get-attr _el-div "disabled")) + (dom-dispatch _el-div "click" nil) + (assert= "true" (dom-get-attr _el-div "enabled")) )) (deftest "can toggle visibility" (hs-cleanup!) @@ -627,9 +630,10 @@ (dom-set-attr _el-div "_" "on click toggle *visibility") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('visibility', 'visible'); toHaveCSS('visibility', + (dom-dispatch _el-div "click" nil) + (assert= "hidden" (dom-get-style _el-div "visibility")) + (dom-dispatch _el-div "click" nil) + (assert= "visible" (dom-get-style _el-div "visibility")) )) (deftest "can toggle opacity w/ my" (hs-cleanup!) @@ -637,9 +641,10 @@ (dom-set-attr _el-div "_" "on click toggle my *opacity") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('opacity', '1'); toHaveCSS('opacity', '0'); toHave + (dom-dispatch _el-div "click" nil) + (assert= "0" (dom-get-style _el-div "opacity")) + (dom-dispatch _el-div "click" nil) + (assert= "1" (dom-get-style _el-div "opacity")) )) (deftest "can toggle visibility w/ my" (hs-cleanup!) @@ -647,9 +652,10 @@ (dom-set-attr _el-div "_" "on click toggle my *visibility") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('visibility', 'visible'); toHaveCSS('visibility', + (dom-dispatch _el-div "click" nil) + (assert= "hidden" (dom-get-style _el-div "visibility")) + (dom-dispatch _el-div "click" nil) + (assert= "visible" (dom-get-style _el-div "visibility")) )) (deftest "can toggle opacity on other elt" (hs-cleanup!) @@ -659,7 +665,6 @@ (hs-activate! _el-div) (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d2) - ;; SKIP check: skip toHaveCSS('opacity', '1'); toHaveCSS('opacity', '0'); toHave )) (deftest "can toggle visibility on other elt" (hs-cleanup!) @@ -669,43 +674,47 @@ (hs-activate! _el-div) (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d2) - ;; SKIP check: skip toHaveCSS('visibility', 'visible'); toHaveCSS('visibility', )) (deftest "can toggle *display between two values" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('display', 'none'); toHaveCSS('display', 'flex'); + (dom-append (dom-body) _el-div) + (dom-dispatch _el-div "click" nil) + (assert= "flex" (dom-get-style _el-div "display")) + (dom-dispatch _el-div "click" nil) + (assert= "none" (dom-get-style _el-div "display")) )) (deftest "can toggle *opacity between three values" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('opacity', '0'); toHaveCSS('opacity', '0.5'); toHa + (dom-append (dom-body) _el-div) + (dom-dispatch _el-div "click" nil) + (assert= "0.5" (dom-get-style _el-div "opacity")) + (dom-dispatch _el-div "click" nil) + (assert= "1" (dom-get-style _el-div "opacity")) + (dom-dispatch _el-div "click" nil) + (assert= "0" (dom-get-style _el-div "opacity")) )) (deftest "can toggle a global variable between two values" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toBe('edit'); toBe('preview'); toBe('edit') + (dom-append (dom-body) _el-div) + (dom-dispatch _el-div "click" nil) + (dom-dispatch _el-div "click" nil) + (dom-dispatch _el-div "click" nil) )) (deftest "can toggle a global variable between three values" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toBe('a'); toBe('b'); toBe('c'); toBe('a') + (dom-append (dom-body) _el-div) + (dom-dispatch _el-div "click" nil) + (dom-dispatch _el-div "click" nil) + (dom-dispatch _el-div "click" nil) + (dom-dispatch _el-div "click" nil) )) ) @@ -716,6 +725,7 @@ (let ((_el-d1 (dom-create-element "div"))) (dom-set-attr _el-d1 "id" "d1") ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= "foo" (dom-inner-html _el-d1)) )) @@ -724,6 +734,7 @@ (let ((_el-d1 (dom-create-element "div"))) (dom-set-attr _el-d1 "id" "d1") ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= "foo" (dom-inner-html _el-d1)) )) @@ -731,6 +742,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= "foo" (dom-inner-html _el-div)) )) @@ -738,6 +750,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= "foo" (dom-inner-html _el-div)) )) @@ -745,6 +758,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= "foo" (dom-inner-html _el-div)) )) @@ -752,6 +766,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= "red" (dom-get-style _el-div "color")) )) @@ -759,6 +774,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) ;; SKIP check: skip window["temp"].should.equal("red") )) @@ -777,6 +793,7 @@ (let ((_el-d1 (dom-create-element "div"))) (dom-set-attr _el-d1 "id" "d1") ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-d1) (dom-dispatch _el-d1 "click" nil) (assert= "foo" (dom-inner-html _el-d1)) )) @@ -785,6 +802,7 @@ (let ((_el-div (dom-create-element "div")) (_el-div1 (dom-create-element "div"))) (dom-add-class _el-div "divs") ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-add-class _el-div1 "divs") (dom-append (dom-body) _el-div1) (dom-dispatch _el-div1 "click" nil) @@ -796,6 +814,7 @@ (let ((_el-div (dom-create-element "div"))) (dom-add-class _el-div "divs") ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= "foo" (dom-get-attr _el-div "bar")) )) @@ -840,6 +859,7 @@ (let ((_el-div (dom-create-element "div"))) (dom-add-class _el-div "divs") ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) ;; SKIP check: skip d1.style["color"].should.equal("red") )) @@ -901,6 +921,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= "red" (dom-get-style _el-div "color")) )) @@ -908,6 +929,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-div "click" nil) (assert= "red" (dom-get-style _el-div "color")) )) @@ -1318,8 +1340,8 @@ (dom-set-attr _el-d1 "foo" "bar") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveAttribute('foo', 'bar'); toHaveAttribute('foo') + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert (not (dom-has-attr? (dom-query-by-id "d1") "foo"))) )) (deftest "can put at start of an array" (hs-cleanup!) @@ -1327,8 +1349,8 @@ (dom-set-attr _el-div "_" "on click set :arr to [2,3] put 1 at start of :arr put :arr as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("1,2,3") + (dom-dispatch _el-div "click" nil) + (assert= "1,2,3" (dom-text-content _el-div)) )) (deftest "can put at end of an array" (hs-cleanup!) @@ -1336,8 +1358,8 @@ (dom-set-attr _el-div "_" "on click set :arr to [1,2] put 3 at end of :arr put :arr as String into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("1,2,3") + (dom-dispatch _el-div "click" nil) + (assert= "1,2,3" (dom-text-content _el-div)) )) ) @@ -1476,8 +1498,9 @@ (dom-set-attr _el-trigger "_" "on click hide
in me when it matches .hideable") (dom-append (dom-body) _el-trigger) (hs-activate! _el-trigger) - ;; SKIP action: find___trigger__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('display', 'none'); toHaveCSS('display', 'block') + (dom-dispatch (dom-query-by-id "trigger") "click" nil) + (assert= "none" (dom-get-style (dom-query-by-id "d1") "display")) + (assert= "block" (dom-get-style (dom-query-by-id "d2") "display")) )) ) @@ -1859,8 +1882,8 @@ (dom-set-attr _el-div "_" "on click for x in null put x at end of me end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("") + (dom-dispatch _el-div "click" nil) + (assert= "" (dom-text-content _el-div)) )) (deftest "basic property for loop works" (hs-cleanup!) @@ -1868,8 +1891,8 @@ (dom-set-attr _el-div "_" "on click set x to {foo:1, bar:2, baz:3} for prop in x put x[prop] at end of me end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("123") + (dom-dispatch _el-div "click" nil) + (assert= "123" (dom-text-content _el-div)) )) (deftest "bottom-tested repeat until" (hs-cleanup!) @@ -1877,8 +1900,8 @@ (dom-set-attr _el-div "_" "on click set x to 0 repeat set x to until x is 3 end put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("3") + (dom-dispatch _el-div "click" nil) + (assert= "3" (dom-text-content _el-div)) )) (deftest "bottom-tested repeat while" (hs-cleanup!) @@ -1886,8 +1909,8 @@ (dom-set-attr _el-div "_" "on click set x to 0 repeat set x to while x < 3 end put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("3") + (dom-dispatch _el-div "click" nil) + (assert= "3" (dom-text-content _el-div)) )) (deftest "bottom-tested loop always runs at least once" (hs-cleanup!) @@ -1895,8 +1918,8 @@ (dom-set-attr _el-div "_" "on click set x to 0 repeat set x to until true end put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("1") + (dom-dispatch _el-div "click" nil) + (assert= "1" (dom-text-content _el-div)) )) (deftest "break exits a simple repeat loop" (hs-cleanup!) @@ -1904,8 +1927,8 @@ (dom-set-attr _el-div "_" "on click set x to 0 repeat 10 times set x to x + 1 if x is 3 break end end put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("3") + (dom-dispatch _el-div "click" nil) + (assert= "3" (dom-text-content _el-div)) )) (deftest "continue skips rest of iteration in simple repeat loop" (hs-cleanup!) @@ -1913,8 +1936,8 @@ (dom-set-attr _el-div "_" "on click repeat for x in [1, 2, 3, 4, 5] if x is 3 continue end put x at end of me end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("1245") + (dom-dispatch _el-div "click" nil) + (assert= "1245" (dom-text-content _el-div)) )) (deftest "break exits a for-in loop" (hs-cleanup!) @@ -1922,8 +1945,8 @@ (dom-set-attr _el-div "_" "on click repeat for x in [1, 2, 3, 4, 5] if x is 4 break end put x at end of me end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("123") + (dom-dispatch _el-div "click" nil) + (assert= "123" (dom-text-content _el-div)) )) (deftest "break exits a while loop" (hs-cleanup!) @@ -1931,8 +1954,8 @@ (dom-set-attr _el-div "_" "on click set x to 0 repeat while x < 100 set x to x + 1 if x is 5 break end end put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("5") + (dom-dispatch _el-div "click" nil) + (assert= "5" (dom-text-content _el-div)) )) (deftest "for loop over undefined skips without error" (hs-cleanup!) @@ -1940,8 +1963,8 @@ (dom-set-attr _el-div "_" "on click repeat for x in doesNotExist put x at end of me end then put \"done\" into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("done") + (dom-dispatch _el-div "click" nil) + (assert= "done" (dom-text-content _el-div)) )) ) @@ -2454,6 +2477,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-foo) (dom-dispatch _el-foo "click" nil) @@ -2516,7 +2540,6 @@ (hs-activate! _el-div) (dom-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-foo) - ;; SKIP check: skip toHaveCSS('width', '100px') )) (deftest "can transition on another element with possessive" (hs-cleanup!) @@ -2526,7 +2549,6 @@ (hs-activate! _el-div) (dom-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-foo) - ;; SKIP check: skip toHaveCSS('width', '100px') )) (deftest "can transition on another element with it" (hs-cleanup!) @@ -2536,15 +2558,14 @@ (hs-activate! _el-div) (dom-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-foo) - ;; SKIP check: skip toHaveCSS('width', '100px') )) (deftest "can transition with a custom transition string" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-foo (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-set-attr _el-foo "id" "foo") (dom-append (dom-body) _el-foo) - ;; SKIP check: skip toHaveCSS('width', '100px') )) (deftest "can transition a single property on form using style ref" (hs-cleanup!) @@ -2552,7 +2573,6 @@ (dom-set-attr _el-form "_" "on click transition *width from 0px to 100px") (dom-append (dom-body) _el-form) (hs-activate! _el-form) - ;; SKIP check: skip toHaveCSS('width', '100px'); toBe('0px') )) (deftest "can transition a single property on current element with the my prefix using style ref" (hs-cleanup!) @@ -2560,7 +2580,6 @@ (dom-set-attr _el-div "_" "on click transition my *width from 0px to 100px") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toHaveCSS('width', '100px'); toBe('0px') )) (deftest "can transition on query ref with possessive" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -2568,9 +2587,10 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-span (dom-create-element "span"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-append (dom-body) _el-span) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('width', '100px') + (dom-dispatch _el-div "click" nil) + (assert= "100px" (dom-get-style _el-span "width")) )) ) @@ -2836,8 +2856,8 @@ (dom-set-attr _el-div "_" "on click fetch /test as JSON then get result as JSONString then put it into my.innerHTML") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText('{"foo":1}') + (dom-dispatch _el-div "click" nil) + (assert= "{\"foo\":1}" (dom-text-content _el-div)) )) (deftest "throws on non-2xx response by default" (hs-cleanup!) @@ -2845,8 +2865,8 @@ (dom-set-attr _el-div "_" "on click fetch /test catch e put \"caught\" into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("caught") + (dom-dispatch _el-div "click" nil) + (assert= "caught" (dom-text-content _el-div)) )) (deftest "do not throw passes through 404 response" (hs-cleanup!) @@ -2854,8 +2874,8 @@ (dom-set-attr _el-div "_" "on click fetch /test do not throw then put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("the body") + (dom-dispatch _el-div "click" nil) + (assert= "the body" (dom-text-content _el-div)) )) (deftest "don't throw passes through 404 response" (hs-cleanup!) @@ -2863,8 +2883,8 @@ (dom-set-attr _el-div "_" "on click fetch /test don't throw then put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("the body") + (dom-dispatch _el-div "click" nil) + (assert= "the body" (dom-text-content _el-div)) )) (deftest "as response does not throw on 404" (hs-cleanup!) @@ -2872,15 +2892,16 @@ (dom-set-attr _el-div "_" "on click fetch /test as response then put it.status into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("404") + (dom-dispatch _el-div "click" nil) + (assert= "404" (dom-text-content _el-div)) )) (deftest "Response can be converted to JSON via as JSON" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("Joe") + (dom-append (dom-body) _el-div) + (dom-dispatch _el-div "click" nil) + (assert= "Joe" (dom-text-content _el-div)) )) ) @@ -3047,8 +3068,8 @@ (dom-set-attr _el-div "_" "on click set arr to [10, 20, 30] then increment arr[1] then put arr[1] into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("21") + (dom-dispatch _el-div "click" nil) + (assert= "21" (dom-text-content _el-div)) )) (deftest "can decrement an array element" (hs-cleanup!) @@ -3056,8 +3077,8 @@ (dom-set-attr _el-div "_" "on click set arr to [10, 20, 30] then decrement arr[1] then put arr[1] into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("19") + (dom-dispatch _el-div "click" nil) + (assert= "19" (dom-text-content _el-div)) )) (deftest "can increment a possessive property" (hs-cleanup!) @@ -3066,8 +3087,8 @@ (dom-set-attr _el-d1 "_" "on click increment #d1's innerHTML") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("6") + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "6" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "can increment a property of expression" (hs-cleanup!) @@ -3076,8 +3097,8 @@ (dom-set-attr _el-d1 "_" "on click increment innerHTML of #d1") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("6") + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "6" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "can increment a style ref" (hs-cleanup!) @@ -3085,8 +3106,8 @@ (dom-set-attr _el-div "_" "on click set my *opacity to 0.5 then increment *opacity by 0.25 then put *opacity into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("0.75") + (dom-dispatch _el-div "click" nil) + (assert= "0.75" (dom-text-content _el-div)) )) ) @@ -3215,8 +3236,8 @@ (dom-set-attr _el-div "_" "on click set :s to [1,2] as Set append 3 to :s append 1 to :s put :s.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("3") + (dom-dispatch _el-div "click" nil) + (assert= "3" (dom-text-content _el-div)) )) ) @@ -3421,6 +3442,7 @@ (dom-set-attr _el-bar "id" "bar") (dom-append (dom-body) _el-bar) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-dispatch _el-bar "click" nil) (dom-dispatch _el-bar "click" nil) (assert= "a" (dom-inner-html _el-bar)) @@ -4019,8 +4041,6 @@ (dom-set-attr _el-d1 "_" "on myEvent(foo) if foo put foo into me else put \"no-detail\" into me") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: evaluate__...__ - ;; SKIP check: skip toHaveText('no-detail') )) (deftest "on first click fires only once" (hs-cleanup!) @@ -4028,9 +4048,10 @@ (dom-set-attr _el-div "_" "on first click put 1 + my.innerHTML as Int into my.innerHTML") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText('1'); toHaveText('1') + (dom-dispatch _el-div "click" nil) + (assert= "1" (dom-text-content _el-div)) + (dom-dispatch _el-div "click" nil) + (assert= "1" (dom-text-content _el-div)) )) (deftest "caught exceptions do not trigger 'exception' event" (hs-cleanup!) @@ -4038,8 +4059,8 @@ (dom-set-attr _el-button "_" "on click put \"foo\" into me then throw \"bar\" catch e log e on exception(error) put error into me") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText('foo') + (dom-dispatch _el-button "click" nil) + (assert= "foo" (dom-text-content _el-button)) )) (deftest "rethrown exceptions trigger 'exception' event" (hs-cleanup!) @@ -4047,8 +4068,8 @@ (dom-set-attr _el-button "_" "on click put \"foo\" into me then throw \"bar\" catch e throw e on exception(error) put error into me") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText('bar') + (dom-dispatch _el-button "click" nil) + (assert= "bar" (dom-text-content _el-button)) )) (deftest "can ignore when target doesn\'t exist" (hs-cleanup!) @@ -4056,8 +4077,8 @@ (dom-set-attr _el-div "_" "on click from #doesntExist throw \"bar\" on click put \"clicked\" into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText('clicked') + (dom-dispatch _el-div "click" nil) + (assert= "clicked" (dom-text-content _el-div)) )) ) @@ -4336,8 +4357,8 @@ (hs-activate! _el-button) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("Alice") + (dom-dispatch _el-button "click" nil) + (assert= "Alice" (dom-text-content (dom-query-by-id "out"))) )) (deftest "returns null on cancel" (hs-cleanup!) @@ -4347,8 +4368,8 @@ (hs-activate! _el-button) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("null") + (dom-dispatch _el-button "click" nil) + (assert= "null" (dom-text-content (dom-query-by-id "out"))) )) (deftest "shows an alert" (hs-cleanup!) @@ -4358,8 +4379,8 @@ (hs-activate! _el-button) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("done"); toBe("Hello!") + (dom-dispatch _el-button "click" nil) + (assert= "done" (dom-text-content (dom-query-by-id "out"))) )) (deftest "confirm returns first choice on OK" (hs-cleanup!) @@ -4369,8 +4390,8 @@ (hs-activate! _el-button) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("Yes") + (dom-dispatch _el-button "click" nil) + (assert= "Yes" (dom-text-content (dom-query-by-id "out"))) )) (deftest "confirm returns second choice on cancel" (hs-cleanup!) @@ -4380,8 +4401,8 @@ (hs-activate! _el-button) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("No") + (dom-dispatch _el-button "click" nil) + (assert= "No" (dom-text-content (dom-query-by-id "out"))) )) ) @@ -4395,24 +4416,24 @@ (dom-set-attr _el-button "_" "on click show #d") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveAttribute('open'); toHaveAttribute('open') + (dom-dispatch _el-button "click" nil) + (assert (dom-has-attr? (dom-query-by-id "d") "open")) )) (deftest "hide closes a dialog" (hs-cleanup!) (let ((_el-d (dom-create-element "dialog"))) (dom-set-attr _el-d "id" "d") (dom-append (dom-body) _el-d) - ;; SKIP action: find___close__.click__ - ;; SKIP check: skip toHaveAttribute('open'); toHaveAttribute('open') + (dom-dispatch (dom-query-by-id "close") "click" nil) + (assert (not (dom-has-attr? (dom-query-by-id "d") "open"))) )) (deftest "show on already-open dialog is a no-op" (hs-cleanup!) (let ((_el-d (dom-create-element "dialog"))) (dom-set-attr _el-d "id" "d") (dom-append (dom-body) _el-d) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveAttribute('open'); toHaveAttribute('open') + (dom-dispatch (dom-query "button") "click" nil) + (assert (dom-has-attr? (dom-query-by-id "d") "open")) )) (deftest "open opens a dialog" (hs-cleanup!) @@ -4422,16 +4443,16 @@ (dom-set-attr _el-button "_" "on click open #d") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveAttribute('open'); toHaveAttribute('open') + (dom-dispatch _el-button "click" nil) + (assert (dom-has-attr? (dom-query-by-id "d") "open")) )) (deftest "close closes a dialog" (hs-cleanup!) (let ((_el-d (dom-create-element "dialog"))) (dom-set-attr _el-d "id" "d") (dom-append (dom-body) _el-d) - ;; SKIP action: find___close__.click__ - ;; SKIP check: skip toHaveAttribute('open'); toHaveAttribute('open') + (dom-dispatch (dom-query-by-id "close") "click" nil) + (assert (not (dom-has-attr? (dom-query-by-id "d") "open"))) )) (deftest "open opens a details element" (hs-cleanup!) @@ -4441,8 +4462,8 @@ (dom-set-attr _el-button "_" "on click open #d") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveAttribute('open'); toHaveAttribute('open') + (dom-dispatch _el-button "click" nil) + (assert (dom-has-attr? (dom-query-by-id "d") "open")) )) (deftest "close closes a details element" (hs-cleanup!) @@ -4452,8 +4473,8 @@ (dom-set-attr _el-button "_" "on click close #d") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveAttribute('open'); toHaveAttribute('open') + (dom-dispatch _el-button "click" nil) + (assert (not (dom-has-attr? (dom-query-by-id "d") "open"))) )) (deftest "open shows a popover" (hs-cleanup!) @@ -4463,16 +4484,14 @@ (dom-set-attr _el-button "_" "on click open #p") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toBe(true) + (dom-dispatch _el-button "click" nil) )) (deftest "close hides a popover" (hs-cleanup!) (let ((_el-p (dom-create-element "div"))) (dom-set-attr _el-p "id" "p") (dom-append (dom-body) _el-p) - ;; SKIP action: find___close__.click__ - ;; SKIP check: skip toBe(false) + (dom-dispatch (dom-query-by-id "close") "click" nil) )) (deftest "open on implicit me" (hs-cleanup!) @@ -4484,8 +4503,8 @@ (dom-set-attr _el-button "_" "on click send myOpen to #d") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveAttribute('open') + (dom-dispatch _el-button "click" nil) + (assert (dom-has-attr? (dom-query-by-id "d") "open")) )) ) @@ -4499,8 +4518,8 @@ (dom-set-attr _el-button "_" "on click empty #d1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("helloworld"); toHaveText("") + (dom-dispatch _el-button "click" nil) + (assert= "" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "empty with no target empties me" (hs-cleanup!) @@ -4508,8 +4527,8 @@ (dom-set-attr _el-div "_" "on click empty") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("content"); toHaveText("") + (dom-dispatch _el-div "click" nil) + (assert= "" (dom-text-content _el-div)) )) (deftest "can empty multiple elements" (hs-cleanup!) @@ -4521,7 +4540,7 @@ (dom-set-attr _el-button "_" "on click empty .clearme") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ + (dom-dispatch _el-button "click" nil) )) (deftest "can empty an array" (hs-cleanup!) @@ -4529,8 +4548,8 @@ (dom-set-attr _el-div "_" "on click set :arr to [1,2,3] empty :arr put :arr.length into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("0") + (dom-dispatch _el-div "click" nil) + (assert= "0" (dom-text-content _el-div)) )) (deftest "can empty a set" (hs-cleanup!) @@ -4538,8 +4557,8 @@ (dom-set-attr _el-div "_" "on click set :s to [1,2,3] as Set empty :s put :s.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("0") + (dom-dispatch _el-div "click" nil) + (assert= "0" (dom-text-content _el-div)) )) (deftest "can empty a map" (hs-cleanup!) @@ -4547,8 +4566,8 @@ (dom-set-attr _el-div "_" "on click set :m to {a:1, b:2} as Map empty :m put :m.size into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("0") + (dom-dispatch _el-div "click" nil) + (assert= "0" (dom-text-content _el-div)) )) (deftest "can empty a text input" (hs-cleanup!) @@ -4560,8 +4579,8 @@ (dom-set-attr _el-button "_" "on click empty #t1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveValue("hello"); toHaveValue("") + (dom-dispatch _el-button "click" nil) + (assert= "" (dom-get-prop (dom-query-by-id "t1") "value")) )) (deftest "can empty a textarea" (hs-cleanup!) @@ -4571,8 +4590,8 @@ (dom-set-attr _el-button "_" "on click empty #ta1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveValue("") + (dom-dispatch _el-button "click" nil) + (assert= "" (dom-get-prop (dom-query-by-id "ta1") "value")) )) (deftest "can empty a checkbox" (hs-cleanup!) @@ -4583,7 +4602,8 @@ (dom-set-attr _el-button "_" "on click empty #cb1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ + (dom-dispatch _el-button "click" nil) + (assert (not (dom-get-prop (dom-query-by-id "cb1") "checked"))) )) (deftest "can empty a select" (hs-cleanup!) @@ -4593,8 +4613,7 @@ (dom-set-attr _el-button "_" "on click empty #sel1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toBe(-1) + (dom-dispatch _el-button "click" nil) )) (deftest "can empty a form (clears all inputs)" (hs-cleanup!) @@ -4604,8 +4623,10 @@ (dom-set-attr _el-button "_" "on click empty #f1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveValue(""); toHaveValue("") + (dom-dispatch _el-button "click" nil) + (assert= "" (dom-get-prop (dom-query-by-id "t2") "value")) + (assert= "" (dom-get-prop (dom-query-by-id "ta2") "value")) + (assert (not (dom-get-prop (dom-query-by-id "cb2") "checked"))) )) (deftest "clear is an alias for empty" (hs-cleanup!) @@ -4617,8 +4638,8 @@ (dom-set-attr _el-button "_" "on click clear #t3") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveValue("hello"); toHaveValue("") + (dom-dispatch _el-button "click" nil) + (assert= "" (dom-get-prop (dom-query-by-id "t3") "value")) )) (deftest "clear works on elements" (hs-cleanup!) @@ -4628,8 +4649,8 @@ (dom-set-attr _el-button "_" "on click clear #d2") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("content"); toHaveText("") + (dom-dispatch _el-button "click" nil) + (assert= "" (dom-text-content (dom-query-by-id "d2"))) )) ) @@ -4643,8 +4664,7 @@ (dom-set-attr _el-button "_" "on click focus #i1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toBe("i1") + (dom-dispatch _el-button "click" nil) )) (deftest "focus with no target focuses me" (hs-cleanup!) @@ -4653,8 +4673,7 @@ (dom-set-attr _el-i1 "_" "on click focus") (dom-append (dom-body) _el-i1) (hs-activate! _el-i1) - ;; SKIP action: find___i1__.dispatchEvent__click__ - ;; SKIP check: skip toBe("i1") + (dom-dispatch (dom-query-by-id "i1") "click" nil) )) (deftest "can blur an element" (hs-cleanup!) @@ -4663,8 +4682,6 @@ (dom-set-attr _el-i1 "_" "on focus wait 10ms then blur me") (dom-append (dom-body) _el-i1) (hs-activate! _el-i1) - ;; SKIP action: find___i1__.focus__ - ;; SKIP check: skip toBe("BODY") )) ) @@ -4674,6 +4691,7 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) )) (deftest "deprecated url keyword still parses" (hs-cleanup!) @@ -4699,7 +4717,7 @@ (dom-set-attr _el-div2 "_" "on click go to #target") (dom-append (dom-body) _el-div2) (hs-activate! _el-div2) - ;; SKIP check: skip toBe(true) + (dom-dispatch (dom-query "div:nth-of-type(3)") "click" nil) )) (deftest "deprecated scroll form still works" (hs-cleanup!) @@ -4711,7 +4729,7 @@ (dom-set-attr _el-div2 "_" "on click go to the top of #target") (dom-append (dom-body) _el-div2) (hs-activate! _el-div2) - ;; SKIP check: skip toBe(true) + (dom-dispatch (dom-query "div:nth-of-type(3)") "click" nil) )) ) @@ -4724,8 +4742,8 @@ (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-append (dom-body) _el-outer) (hs-activate! _el-outer) - ;; SKIP action: find___inner__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass(/outer-clicked/) + (dom-dispatch (dom-query-by-id "inner") "click" nil) + (assert (not (dom-has-class? (dom-query-by-id "outer") "outer-clicked"))) )) (deftest "halt stops execution after the halt" (hs-cleanup!) @@ -4733,8 +4751,8 @@ (dom-set-attr _el-div "_" "on click halt then add .should-not-happen") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass(/should-not-happen/) + (dom-dispatch _el-div "click" nil) + (assert (not (dom-has-class? _el-div "should-not-happen"))) )) (deftest "halt the event stops propagation but continues execution" (hs-cleanup!) @@ -4743,8 +4761,9 @@ (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-append (dom-body) _el-outer) (hs-activate! _el-outer) - ;; SKIP action: find___inner__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass(/outer-clicked/); toHaveClass(/continued/) + (dom-dispatch (dom-query-by-id "inner") "click" nil) + (assert (not (dom-has-class? (dom-query-by-id "outer") "outer-clicked"))) + (assert (dom-has-class? (dom-query-by-id "inner") "continued")) )) (deftest "halt the event's stops propagation but continues execution" (hs-cleanup!) @@ -4753,8 +4772,9 @@ (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-append (dom-body) _el-outer) (hs-activate! _el-outer) - ;; SKIP action: find___inner__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass(/outer-clicked/); toHaveClass(/continued/) + (dom-dispatch (dom-query-by-id "inner") "click" nil) + (assert (not (dom-has-class? (dom-query-by-id "outer") "outer-clicked"))) + (assert (dom-has-class? (dom-query-by-id "inner") "continued")) )) (deftest "halt bubbling only stops propagation, not default" (hs-cleanup!) @@ -4763,8 +4783,9 @@ (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-append (dom-body) _el-outer) (hs-activate! _el-outer) - ;; SKIP action: find___inner__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass(/outer-clicked/); toHaveClass(/continued/) + (dom-dispatch (dom-query-by-id "inner") "click" nil) + (assert (not (dom-has-class? (dom-query-by-id "outer") "outer-clicked"))) + (assert (not (dom-has-class? (dom-query-by-id "inner") "continued"))) )) (deftest "halt works outside of event context" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -4775,8 +4796,8 @@ (dom-set-attr _el-outer "_" "on click add .outer-clicked") (dom-append (dom-body) _el-outer) (hs-activate! _el-outer) - ;; SKIP action: find___inner__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass(/outer-clicked/) + (dom-dispatch (dom-query-by-id "inner") "click" nil) + (assert (dom-has-class? (dom-query-by-id "outer") "outer-clicked")) )) ) @@ -4788,8 +4809,9 @@ (dom-set-attr _el-target "id" "target") (dom-append (dom-body) _el-target) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("new") + (dom-append (dom-body) _el-button) + (dom-dispatch _el-button "click" nil) + (assert= "new" (dom-text-content (dom-query-by-id "target"))) )) (deftest "morph preserves element identity" (hs-cleanup!) @@ -4798,8 +4820,9 @@ (dom-append (dom-body) _el-target) (dom-set-attr _el-go "id" "go") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___go__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("new"); toBe(true) + (dom-append (dom-body) _el-go) + (dom-dispatch (dom-query-by-id "go") "click" nil) + (assert= "new" (dom-text-content (dom-query-by-id "target"))) )) (deftest "morph updates attributes" (hs-cleanup!) @@ -4808,8 +4831,9 @@ (dom-add-class _el-target "old") (dom-append (dom-body) _el-target) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveClass("new") + (dom-append (dom-body) _el-button) + (dom-dispatch _el-button "click" nil) + (assert (dom-has-class? (dom-query-by-id "target") "new")) )) (deftest "morph adds new children" (hs-cleanup!) @@ -4818,8 +4842,8 @@ (dom-append (dom-body) _el-target) (dom-set-attr _el-target1 "id" "target") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___go__.dispatchEvent__click__ - ;; SKIP check: skip toBe(2) + (dom-append (dom-body) _el-target1) + (dom-dispatch (dom-query-by-id "go") "click" nil) )) (deftest "morph removes old children" (hs-cleanup!) @@ -4828,8 +4852,8 @@ (dom-append (dom-body) _el-target) (dom-set-attr _el-target1 "id" "target") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___go__.dispatchEvent__click__ - ;; SKIP check: skip toBe(1) + (dom-append (dom-body) _el-target1) + (dom-dispatch (dom-query-by-id "go") "click" nil) )) (deftest "morph initializes hyperscript on new elements" (hs-cleanup!) @@ -4838,9 +4862,11 @@ (dom-append (dom-body) _el-target) (dom-set-attr _el-target1 "id" "target") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___go__.dispatchEvent__click__ - ;; SKIP action: find___inner__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("new"); toHaveText("clicked") + (dom-append (dom-body) _el-target1) + (dom-dispatch (dom-query-by-id "go") "click" nil) + (assert= "new" (dom-text-content (dom-query-by-id "inner"))) + (dom-dispatch (dom-query-by-id "inner") "click" nil) + (assert= "clicked" (dom-text-content (dom-query-by-id "inner"))) )) (deftest "morph cleans up removed hyperscript elements" (hs-cleanup!) @@ -4848,7 +4874,8 @@ (dom-set-attr _el-target "id" "target") (dom-append (dom-body) _el-target) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__button__.dispatchEvent__click__ + (dom-append (dom-body) _el-button) + (dom-dispatch _el-button "click" nil) )) (deftest "morph reorders children by id" (hs-cleanup!) @@ -4856,8 +4883,8 @@ (dom-set-attr _el-target "id" "target") (dom-append (dom-body) _el-target) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toEqual(["b", "a"]) + (dom-append (dom-body) _el-button) + (dom-dispatch _el-button "click" nil) )) (deftest "morph preserves matched child identity" (hs-cleanup!) @@ -4866,8 +4893,8 @@ (dom-append (dom-body) _el-target) (dom-set-attr _el-go "id" "go") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___go__.dispatchEvent__click__ - ;; SKIP check: skip toBe(true); toBe("new") + (dom-append (dom-body) _el-go) + (dom-dispatch (dom-query-by-id "go") "click" nil) )) (deftest "morph with variable content" (hs-cleanup!) @@ -4878,8 +4905,8 @@ (dom-set-attr _el-go "_" "on click set content to \"
morphed
\" then morph #target to content") (dom-append (dom-body) _el-go) (hs-activate! _el-go) - ;; SKIP action: find___go__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("morphed") + (dom-dispatch (dom-query-by-id "go") "click" nil) + (assert= "morphed" (dom-text-content (dom-query-by-id "target"))) )) ) @@ -4890,9 +4917,8 @@ (let ((_el-f1 (dom-create-element "form"))) (dom-set-attr _el-f1 "id" "f1") (dom-append (dom-body) _el-f1) - ;; SKIP action: find___t1__.fill__changed__ - ;; SKIP action: find___rst__.dispatchEvent__click__ - ;; SKIP check: skip toHaveValue('changed'); toHaveValue('original') + (dom-dispatch (dom-query-by-id "rst") "click" nil) + (assert= "original" (dom-get-prop (dom-query-by-id "t1") "value")) )) (deftest "reset with no target resets me (form)" (hs-cleanup!) @@ -4900,9 +4926,8 @@ (dom-set-attr _el-form "_" "on custom reset") (dom-append (dom-body) _el-form) (hs-activate! _el-form) - ;; SKIP action: find___t2__.fill__modified__ - ;; SKIP action: find__form__.dispatchEvent__custom__ - ;; SKIP check: skip toHaveValue('modified'); toHaveValue('default') + (dom-dispatch _el-form "custom" nil) + (assert= "default" (dom-get-prop (dom-query-by-id "t2") "value")) )) (deftest "can reset a text input to defaultValue" (hs-cleanup!) @@ -4914,9 +4939,8 @@ (dom-set-attr _el-button "_" "on click reset #t3") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find___t3__.fill__goodbye__ - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveValue('goodbye'); toHaveValue('hello') + (dom-dispatch _el-button "click" nil) + (assert= "hello" (dom-get-prop (dom-query-by-id "t3") "value")) )) (deftest "can reset a checkbox" (hs-cleanup!) @@ -4927,7 +4951,8 @@ (dom-set-attr _el-button "_" "on click reset #cb1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ + (dom-dispatch _el-button "click" nil) + (assert (dom-get-prop (dom-query-by-id "cb1") "checked")) )) (deftest "can reset an unchecked checkbox" (hs-cleanup!) @@ -4938,7 +4963,8 @@ (dom-set-attr _el-button "_" "on click reset #cb2") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ + (dom-dispatch _el-button "click" nil) + (assert (not (dom-get-prop (dom-query-by-id "cb2") "checked"))) )) (deftest "can reset a textarea" (hs-cleanup!) @@ -4948,9 +4974,8 @@ (dom-set-attr _el-button "_" "on click reset #ta1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find___ta1__.fill__new text__ - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveValue('new text'); toHaveValue('original text') + (dom-dispatch _el-button "click" nil) + (assert= "original text" (dom-get-prop (dom-query-by-id "ta1") "value")) )) (deftest "can reset a select" (hs-cleanup!) @@ -4960,8 +4985,8 @@ (dom-set-attr _el-button "_" "on click reset #sel1") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveValue('c'); toHaveValue('b') + (dom-dispatch _el-button "click" nil) + (assert= "b" (dom-get-prop (dom-query-by-id "sel1") "value")) )) (deftest "can reset multiple inputs" (hs-cleanup!) @@ -4977,7 +5002,7 @@ (dom-set-attr _el-button "_" "on click reset .resettable") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ + (dom-dispatch _el-button "click" nil) )) ) @@ -4993,7 +5018,7 @@ (dom-set-attr _el-div2 "_" "on click scroll to #target") (dom-append (dom-body) _el-div2) (hs-activate! _el-div2) - ;; SKIP check: skip toBe(true) + (dom-dispatch (dom-query "div:nth-of-type(3)") "click" nil) )) (deftest "can scroll to top of element" (hs-cleanup!) @@ -5006,7 +5031,7 @@ (dom-set-attr _el-div2 "_" "on click scroll to the top of #target") (dom-append (dom-body) _el-div2) (hs-activate! _el-div2) - ;; SKIP check: skip toBe(true) + (dom-dispatch (dom-query "div:nth-of-type(3)") "click" nil) )) (deftest "can scroll down by amount" (hs-cleanup!) @@ -5016,6 +5041,7 @@ (dom-set-attr _el-div1 "_" "on click scroll down by 300px") (dom-append (dom-body) _el-div1) (hs-activate! _el-div1) + (dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil) )) (deftest "can scroll up by amount" (hs-cleanup!) @@ -5025,6 +5051,7 @@ (dom-set-attr _el-div1 "_" "on click scroll up by 100px") (dom-append (dom-body) _el-div1) (hs-activate! _el-div1) + (dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil) )) (deftest "can scroll by without direction (defaults to down)" (hs-cleanup!) @@ -5034,6 +5061,7 @@ (dom-set-attr _el-div1 "_" "on click scroll by 200px") (dom-append (dom-body) _el-div1) (hs-activate! _el-div1) + (dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil) )) (deftest "can scroll container by amount" (hs-cleanup!) @@ -5045,7 +5073,7 @@ (dom-set-attr _el-go "_" "on click scroll #box down by 200px") (dom-append (dom-body) _el-go) (hs-activate! _el-go) - ;; SKIP action: find___go__.dispatchEvent__click__ + (dom-dispatch (dom-query-by-id "go") "click" nil) )) (deftest "can scroll to element in container" (hs-cleanup!) @@ -5057,7 +5085,7 @@ (dom-set-attr _el-go "_" "on click scroll to #item in #box") (dom-append (dom-body) _el-go) (hs-activate! _el-go) - ;; SKIP action: find___go__.dispatchEvent__click__ + (dom-dispatch (dom-query-by-id "go") "click" nil) )) (deftest "can scroll left by amount" (hs-cleanup!) @@ -5069,7 +5097,7 @@ (dom-set-attr _el-go "_" "on click scroll #box right by 300px") (dom-append (dom-body) _el-go) (hs-activate! _el-go) - ;; SKIP action: find___go__.dispatchEvent__click__ + (dom-dispatch (dom-query-by-id "go") "click" nil) )) ) @@ -5084,8 +5112,7 @@ (dom-set-attr _el-button "_" "on click select #inp") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toBe("hello world") + (dom-dispatch _el-button "click" nil) )) (deftest "selects text in a textarea" (hs-cleanup!) @@ -5095,8 +5122,7 @@ (dom-set-attr _el-button "_" "on click select #ta") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toBe("some text") + (dom-dispatch _el-button "click" nil) )) (deftest "selects implicit me" (hs-cleanup!) @@ -5106,8 +5132,7 @@ (dom-set-attr _el-inp "value" "test") (dom-append (dom-body) _el-inp) (hs-activate! _el-inp) - ;; SKIP action: find___inp__.click__ - ;; SKIP check: skip toBe("test") + (dom-dispatch (dom-query-by-id "inp") "click" nil) )) (deftest "returns selected text" (hs-cleanup!) @@ -5119,8 +5144,8 @@ (hs-activate! _el-button) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("Hello") + (dom-dispatch _el-button "click" nil) + (assert= "Hello" (dom-text-content (dom-query-by-id "out"))) )) ) @@ -5133,8 +5158,8 @@ (dom-set-attr _el-d1 "_" "on click set x to \"a\" then set y to \"b\" then swap x with y then put x + y into me") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("ba") + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "ba" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "can swap two properties" (hs-cleanup!) @@ -5147,8 +5172,9 @@ (dom-append (dom-body) _el-a) (dom-set-attr _el-b "id" "b") (dom-append (dom-body) _el-b) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("world"); toHaveText("hello") + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "world" (dom-text-content (dom-query-by-id "a"))) + (assert= "hello" (dom-text-content (dom-query-by-id "b"))) )) (deftest "can swap array elements" (hs-cleanup!) @@ -5157,8 +5183,8 @@ (dom-set-attr _el-d1 "_" "on click set arr to [1,2,3] then swap arr[0] with arr[2] then put arr as String into me") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("3,2,1") + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "3,2,1" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "can swap a variable with a property" (hs-cleanup!) @@ -5170,8 +5196,9 @@ (dom-set-attr _el-target "id" "target") (dom-set-attr _el-target "data-val" "x") (dom-append (dom-body) _el-target) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("new"); toHaveAttribute('data-val', 'old') + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "new" (dom-text-content (dom-query-by-id "d1"))) + (assert= "old" (dom-get-attr (dom-query-by-id "target") "data-val")) )) ) @@ -5187,9 +5214,6 @@ (dom-set-attr _el-span "_" "bind $name and #name-input.value end when $name changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: evaluate__...__ - ;; SKIP action: await run__set _name to _ - ;; SKIP check: skip toHaveText('Alice'); toHaveText('Bob') )) (deftest "syncs variable and attribute in both directions" (hs-cleanup!) @@ -5197,9 +5221,6 @@ (dom-set-attr _el-div "_" "bind $theme and @data-theme") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _theme to _ - ;; SKIP action: await run__set _theme to _ - ;; SKIP check: skip toHaveAttribute('data-theme', 'light'); toHaveAttribute('dat )) (deftest "dedup prevents infinite loop in two-way bind" (hs-cleanup!) @@ -5207,9 +5228,6 @@ (dom-set-attr _el-div "_" "bind $color and @data-color") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _color to _ - ;; SKIP action: await run__set _color to _ - ;; SKIP check: skip toHaveAttribute('data-color', 'red'); toHaveAttribute('data- )) (deftest ""with" is a synonym for "and"" (hs-cleanup!) @@ -5221,8 +5239,6 @@ (dom-set-attr _el-span "_" "bind $city to #city-input.value end when $city changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: await run__set _city to _ - ;; SKIP check: skip toHaveText('Paris') )) (deftest "shorthand on text input binds to value" (hs-cleanup!) @@ -5233,8 +5249,6 @@ (dom-append (dom-body) _el-input) (hs-activate! _el-input) (dom-append (dom-body) _el-span) - ;; SKIP action: find__input__.fill__goodbye__ - ;; SKIP action: await run__set _greeting to _ )) (deftest "shorthand on checkbox binds to checked" (hs-cleanup!) @@ -5246,8 +5260,6 @@ (dom-set-attr _el-span "_" "when $isDarkMode changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: await run__set _isDarkMode to false_ - ;; SKIP action: await run__set _isDarkMode to false_ )) (deftest "shorthand on textarea binds to value" (hs-cleanup!) @@ -5258,7 +5270,6 @@ (dom-set-attr _el-span "_" "when $bio changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: find__textarea__.fill__New bio__ )) (deftest "shorthand on select binds to value" (hs-cleanup!) @@ -5282,8 +5293,6 @@ (dom-set-attr _el-span "_" "when $price changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: await run__set _price to 42_ - ;; SKIP check: skip toHaveText('42') )) (deftest "boolean bind to attribute uses presence/absence" (hs-cleanup!) @@ -5291,9 +5300,6 @@ (dom-set-attr _el-div "_" "bind $isEnabled and @data-active") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _isEnabled to true_ - ;; SKIP action: await run__set _isEnabled to false_ - ;; SKIP check: skip toHaveAttribute('data-active', '') )) (deftest "boolean bind to aria-* attribute uses "true"/"false" strings" (hs-cleanup!) @@ -5301,9 +5307,6 @@ (dom-set-attr _el-div "_" "bind $isHidden and @aria-hidden") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _isHidden to true_ - ;; SKIP action: await run__set _isHidden to false_ - ;; SKIP check: skip toHaveAttribute('aria-hidden', 'true'); toHaveAttribute('ari )) (deftest "style bind is one-way: variable drives style, not vice versa" (hs-cleanup!) @@ -5311,8 +5314,6 @@ (dom-set-attr _el-div "_" "bind $opacity and *opacity") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _opacity to 1_ - ;; SKIP action: await run__set _opacity to 0.3_ )) (deftest "same value does not re-set input (prevents cursor jump)" (hs-cleanup!) @@ -5322,7 +5323,6 @@ (dom-set-attr _el-input "value" "hello") (dom-append (dom-body) _el-input) (hs-activate! _el-input) - ;; SKIP check: skip toBe(false) )) (deftest "external JS property write does not sync (known limitation)" (hs-cleanup!) @@ -5335,7 +5335,6 @@ (dom-set-attr _el-span "_" "when $searchTerm changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: evaluate__...__ )) (deftest "form.reset() syncs variable back to default value" (hs-cleanup!) @@ -5345,7 +5344,6 @@ (dom-set-attr _el-span "_" "when $formField changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: find__input__.fill__user typed this__ )) (deftest "clicking a radio sets the variable to its value" (hs-cleanup!) @@ -5371,9 +5369,8 @@ (dom-set-attr _el-span "_" "when $color changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: find__input_value=_blue____.click__ - ;; SKIP action: find__input_value=_green____.click__ - ;; SKIP action: await run__set _color to _ + (dom-dispatch (dom-query "input[value="blue"]") "click" nil) + (dom-dispatch (dom-query "input[value="green"]") "click" nil) )) (deftest "setting variable programmatically checks the matching radio" (hs-cleanup!) @@ -5396,8 +5393,6 @@ (dom-set-attr _el-input2 "value" "large") (dom-append (dom-body) _el-input2) (hs-activate! _el-input2) - ;; SKIP action: await run__set _size to _ - ;; SKIP action: await run__set _size to _ )) (deftest "initial value checks the correct radio on load" (hs-cleanup!) @@ -5420,7 +5415,6 @@ (dom-set-attr _el-input2 "value" "cherry") (dom-append (dom-body) _el-input2) (hs-activate! _el-input2) - ;; SKIP action: await run__set _fruit to _ )) (deftest "variable drives class: setting variable adds/removes class" (hs-cleanup!) @@ -5428,10 +5422,6 @@ (dom-set-attr _el-div "_" "bind .dark and $darkMode") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _darkMode to false_ - ;; SKIP action: await run__set _darkMode to true_ - ;; SKIP action: await run__set _darkMode to false_ - ;; SKIP check: skip toHaveClass('dark') )) (deftest "external class change syncs back to variable" (hs-cleanup!) @@ -5439,7 +5429,6 @@ (dom-set-attr _el-div "_" "bind .dark and $darkMode") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _darkMode to false_ )) (deftest "right side wins on class init" (hs-cleanup!) @@ -5447,8 +5436,6 @@ (dom-set-attr _el-div "_" "bind .highlight to $highlighted") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _highlighted to true_ - ;; SKIP check: skip toHaveClass('highlight') )) (deftest "init: right side wins — input value (Y) overwrites variable (X)" (hs-cleanup!) @@ -5458,7 +5445,6 @@ (dom-set-attr _el-input "value" "Bob") (dom-append (dom-body) _el-input) (hs-activate! _el-input) - ;; SKIP action: await run__set _name to _ )) (deftest "init: right side wins — variable (Y) overwrites input value (X)" (hs-cleanup!) @@ -5468,7 +5454,6 @@ (dom-set-attr _el-input "value" "Bob") (dom-append (dom-body) _el-input) (hs-activate! _el-input) - ;; SKIP action: await run__set _name to _ )) (deftest "init: right side wins — attribute (Y) initializes variable (X)" (hs-cleanup!) @@ -5484,8 +5469,6 @@ (dom-set-attr _el-div "_" "bind @data-theme to $theme") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _theme to _ - ;; SKIP check: skip toHaveAttribute('data-theme', 'dark') )) (deftest "init: right side wins — variable (Y) drives class (X)" (hs-cleanup!) @@ -5493,7 +5476,6 @@ (dom-set-attr _el-div "_" "bind .dark to $isDark") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _isDark to true_ )) (deftest "init: right side wins — class (Y) drives variable (X)" (hs-cleanup!) @@ -5502,7 +5484,6 @@ (dom-set-attr _el-div "_" "bind $isDark to .dark") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _isDark to false_ )) (deftest "possessive property: bind $var to my value" (hs-cleanup!) @@ -5512,7 +5493,6 @@ (dom-set-attr _el-input "value" "hello") (dom-append (dom-body) _el-input) (hs-activate! _el-input) - ;; SKIP action: find__input__.fill__world__ )) (deftest "possessive attribute: bind $var and my @data-label" (hs-cleanup!) @@ -5520,9 +5500,6 @@ (dom-set-attr _el-div "_" "bind $label and my @data-label") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _label to _ - ;; SKIP action: await run__set _label to _ - ;; SKIP check: skip toHaveAttribute('data-label', 'important') )) (deftest "of-expression: bind $var to value of #input" (hs-cleanup!) @@ -5544,7 +5521,6 @@ (dom-set-attr _el-div "_" "bind .dark and #dark-toggle's checked") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toHaveClass('dark') )) (deftest "attribute bound to another element input value" (hs-cleanup!) @@ -5556,7 +5532,6 @@ (dom-set-attr _el-h1 "_" "bind @data-title and #title-input's value") (dom-append (dom-body) _el-h1) (hs-activate! _el-h1) - ;; SKIP action: find___title-input__.fill__World__ )) (deftest "two inputs synced via bind" (hs-cleanup!) @@ -5569,7 +5544,6 @@ (dom-set-attr _el-input "type" "number") (dom-append (dom-body) _el-input) (hs-activate! _el-input) - ;; SKIP action: evaluate__...__ )) (deftest "bind variable to element by id auto-detects value" (hs-cleanup!) @@ -5581,8 +5555,6 @@ (dom-set-attr _el-div "_" "bind $name to #name-field") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: evaluate__...__ - ;; SKIP action: await run__set _name to _ )) (deftest "bind variable to checkbox by id auto-detects checked" (hs-cleanup!) @@ -5593,8 +5565,6 @@ (dom-set-attr _el-div "_" "bind $agreed to #agree-cb") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _agreed to false_ - ;; SKIP action: await run__set _agreed to true_ )) (deftest "bind variable to number input by id auto-detects valueAsNumber" (hs-cleanup!) @@ -5605,7 +5575,6 @@ (dom-set-attr _el-div "_" "bind $qty to #qty-input") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _qty to 5_ )) (deftest "bind element to element: both sides auto-detect" (hs-cleanup!) @@ -5618,7 +5587,6 @@ (dom-set-attr _el-input "type" "number") (dom-append (dom-body) _el-input) (hs-activate! _el-input) - ;; SKIP action: evaluate__...__ )) (deftest "right side wins on init: variable (Y) initializes input (X)" (hs-cleanup!) @@ -5628,7 +5596,6 @@ (dom-set-attr _el-input "value" "Bob") (dom-append (dom-body) _el-input) (hs-activate! _el-input) - ;; SKIP action: await run__set _name to _ )) (deftest "right side wins on init: input (Y) initializes variable (X)" (hs-cleanup!) @@ -5646,7 +5613,6 @@ (dom-set-attr _el-div "contenteditable" "true") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _text to _ )) (deftest "bind to custom element with value property auto-detects value" (hs-cleanup!) @@ -5654,8 +5620,6 @@ (dom-set-attr _el-test-input "_" "bind $custom to me") (dom-append (dom-body) _el-test-input) (hs-activate! _el-test-input) - ;; SKIP action: evaluate__...__ - ;; SKIP action: await run__set _custom to _ )) (deftest "radio change listener is removed on cleanup" (hs-cleanup!) @@ -5672,20 +5636,11 @@ (dom-set-attr _el-input1 "value" "blue") (dom-append (dom-body) _el-input1) (hs-activate! _el-input1) - ;; SKIP action: evaluate__...__ - ;; SKIP action: evaluate__...__ - ;; SKIP action: await run__set _color to _ - ;; SKIP action: await run___color_ - ;; SKIP check: skip toBe('red') )) (deftest "form reset listener is removed on cleanup" (hs-cleanup!) (let ((_el-form (dom-create-element "form"))) (dom-append (dom-body) _el-form) - ;; SKIP action: await run__set _val to _ - ;; SKIP action: await run__set _val to _ - ;; SKIP action: await run___val_ - ;; SKIP check: skip toBe('changed') )) ) @@ -5697,10 +5652,6 @@ (dom-set-attr _el-div "_" "live set $total to ($price * $qty) end when $total changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _price to 10_ - ;; SKIP action: await run__set _qty to 3_ - ;; SKIP action: await run__set _price to 25_ - ;; SKIP check: skip toHaveText('30') )) (deftest "updates DOM text reactively with put" (hs-cleanup!) @@ -5708,8 +5659,6 @@ (dom-set-attr _el-div "_" "live put 'hello ' + $greeting into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _greeting to _ - ;; SKIP action: await run__set _greeting to _ )) (deftest "sets an attribute reactively" (hs-cleanup!) @@ -5717,9 +5666,6 @@ (dom-set-attr _el-div "_" "live set my @data-theme to $theme") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _theme to _ - ;; SKIP action: await run__set _theme to _ - ;; SKIP check: skip toHaveAttribute('data-theme', 'light') )) (deftest "sets a style reactively" (hs-cleanup!) @@ -5727,8 +5673,6 @@ (dom-set-attr _el-div "_" "live set *opacity to $opacity") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _opacity to 1_ - ;; SKIP action: await run__set _opacity to 0.5_ )) (deftest "puts a computed dollar amount into the DOM" (hs-cleanup!) @@ -5736,9 +5680,6 @@ (dom-set-attr _el-div "_" "live put '$' + ($price * $qty) into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _price to 10_ - ;; SKIP action: await run__set _qty to 2_ - ;; SKIP action: await run__set _qty to 5_ )) (deftest "block form re-runs all commands when any dependency changes" (hs-cleanup!) @@ -5754,10 +5695,6 @@ (dom-set-attr _el-div "_" "live set $doubleWidth to ($width * 2) set $doubleHeight to ($height * 2) end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _width to 100_ - ;; SKIP action: await run__set _height to 200_ - ;; SKIP action: await run__set _height to 300_ - ;; SKIP check: skip toHaveText('200') )) (deftest "separate live statements create independent effects" (hs-cleanup!) @@ -5773,10 +5710,6 @@ (dom-set-attr _el-div "_" "live set $doubleWidth to ($width * 2) end live set $doubleHeight to ($height * 2)") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _width to 100_ - ;; SKIP action: await run__set _height to 200_ - ;; SKIP action: await run__set _height to 300_ - ;; SKIP check: skip toHaveText('200') )) (deftest "block form cascades inter-dependent commands" (hs-cleanup!) @@ -5784,11 +5717,6 @@ (dom-set-attr _el-div "_" "live set $subtotal to ($price * $qty) set $total to ($subtotal + $tax) end when $total changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _price to 10_ - ;; SKIP action: await run__set _qty to 3_ - ;; SKIP action: await run__set _tax to 5_ - ;; SKIP action: await run__set _price to 20_ - ;; SKIP action: await run__set _tax to 10_ )) (deftest "toggles a class based on a boolean variable" (hs-cleanup!) @@ -5796,10 +5724,6 @@ (dom-set-attr _el-div "_" "live if $isActive add .active to me else remove .active from me end end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _isActive to false_ - ;; SKIP action: await run__set _isActive to true_ - ;; SKIP action: await run__set _isActive to false_ - ;; SKIP check: skip toHaveClass('active') )) (deftest "toggles display style based on a boolean variable" (hs-cleanup!) @@ -5807,9 +5731,6 @@ (dom-set-attr _el-div "_" "live if $isVisible set *display to 'block' else set *display to 'none' end end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _isVisible to true_ - ;; SKIP action: await run__set _isVisible to false_ - ;; SKIP action: await run__set _isVisible to true_ )) (deftest "effects stop when element is removed from DOM" (hs-cleanup!) @@ -5817,8 +5738,6 @@ (dom-set-attr _el-div "_" "live put $message into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _message to _ - ;; SKIP action: await run__set _message to _ )) (deftest "conditional branch only tracks the active dependency" (hs-cleanup!) @@ -5826,12 +5745,6 @@ (dom-set-attr _el-div "_" "live if $showFirst put $firstName into me else put $lastName into me end end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _showFirst to true_ - ;; SKIP action: await run__set _firstName to _ - ;; SKIP action: await run__set _lastName to _ - ;; SKIP action: await run__set _firstName to _ - ;; SKIP action: await run__set _lastName to _ - ;; SKIP check: skip toHaveText('Bob'); toHaveText('Jones') )) (deftest "multiple live on same element work independently" (hs-cleanup!) @@ -5839,10 +5752,6 @@ (dom-set-attr _el-div "_" "live set my @data-name to $firstName end live set my @data-age to $age") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _firstName to _ - ;; SKIP action: await run__set _age to 30_ - ;; SKIP action: await run__set _firstName to _ - ;; SKIP check: skip toHaveAttribute('data-name', 'Alice'); toHaveAttribute('data )) (deftest "live and when on same element do not interfere" (hs-cleanup!) @@ -5850,9 +5759,6 @@ (dom-set-attr _el-div "_" "live set my @data-status to $status end when $status changes put 'Status: ' + it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _status to _ - ;; SKIP action: await run__set _status to _ - ;; SKIP check: skip toHaveAttribute('data-status', 'online'); toHaveText('Status )) (deftest "bind and live on same element do not interfere" (hs-cleanup!) @@ -5865,8 +5771,6 @@ (dom-set-attr _el-span "_" "when $username changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: find__input__.fill__bob__ - ;; SKIP action: await run__set _username to _ )) (deftest "reactive effects are stopped on cleanup" (hs-cleanup!) @@ -5875,9 +5779,6 @@ (dom-set-attr _el-d1 "_" "live put $count into me") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: await run__set _count to 0_ - ;; SKIP action: await run__set _count to 99_ - ;; SKIP check: skip toHaveText('cleaned') )) (deftest "append triggers live block" (hs-cleanup!) @@ -5885,8 +5786,6 @@ (dom-set-attr _el-div "_" "live put $items.join(', ') into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _items to __ - ;; SKIP action: await run__append _ )) (deftest "push via pseudo-command triggers live block" (hs-cleanup!) @@ -5894,8 +5793,6 @@ (dom-set-attr _el-div "_" "live put $items.join(', ') into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _items to __ - ;; SKIP action: await run___items.push__ )) (deftest "push via call triggers live block" (hs-cleanup!) @@ -5903,8 +5800,6 @@ (dom-set-attr _el-div "_" "live put $items.join(', ') into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _items to __ - ;; SKIP action: await run__call _items.push__ )) (deftest "array + still works with live" (hs-cleanup!) @@ -5912,8 +5807,6 @@ (dom-set-attr _el-div "_" "live put $items.join(', ') into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _items to __ - ;; SKIP action: await run__set _items to _items + __ )) (deftest "set property still works with live" (hs-cleanup!) @@ -5921,8 +5814,6 @@ (dom-set-attr _el-div "_" "live put $obj.name into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _obj to _name: _ - ;; SKIP action: await run__set _obj.name to _ )) (deftest "property change on object in array triggers live re-render" (hs-cleanup!) @@ -5932,8 +5823,6 @@ (dom-set-attr _el-div "_" "live render #people-tmpl with people: $people then put it into my.innerHTML end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _people to __name: _ - ;; SKIP action: await run__set _people_0_.name to _ )) (deftest "push object then modify its property both trigger live" (hs-cleanup!) @@ -5943,9 +5832,6 @@ (dom-set-attr _el-div "_" "live render #items-tmpl with items: $items then put it into my.innerHTML end") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _items to __label: _ - ;; SKIP action: await run__call _items.push__label: _ - ;; SKIP action: await run__set _items_1_.label to _ )) ) @@ -5957,9 +5843,6 @@ (dom-set-attr _el-output "_" "when ($obj's x + $obj's y) changes put it into me") (dom-append (dom-body) _el-output) (hs-activate! _el-output) - ;; SKIP action: await run__set _obj to _x: 1_ y: 2__ - ;; SKIP action: await run__set _obj_ - ;; SKIP check: skip toHaveText('3') )) (deftest "nested property chain triggers on intermediate reassignment" (hs-cleanup!) @@ -5967,9 +5850,6 @@ (dom-set-attr _el-output "_" "when $data's inner's val changes put it into me") (dom-append (dom-body) _el-output) (hs-activate! _el-output) - ;; SKIP action: await run__set _data to _inner: _val: _ - ;; SKIP action: await run__set _data_ - ;; SKIP check: skip toHaveText('hello') )) (deftest "property change on DOM element triggers reactivity via setProperty" (hs-cleanup!) @@ -5981,8 +5861,6 @@ (dom-set-attr _el-output "_" "when #prop-input's value changes put it into me") (dom-append (dom-body) _el-output) (hs-activate! _el-output) - ;; SKIP action: await run__set _prop-input_ - ;; SKIP check: skip toHaveText('start') )) (deftest "live block tracks property reads on plain objects" (hs-cleanup!) @@ -5990,8 +5868,6 @@ (dom-set-attr _el-output "_" "live put $config's label into me") (dom-append (dom-body) _el-output) (hs-activate! _el-output) - ;; SKIP action: await run__set _config to _label: _ - ;; SKIP action: await run__set _config_ )) ) @@ -6007,7 +5883,6 @@ (hs-activate! _el-box) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP check: skip toHaveText("200") )) (deftest "provides height in detail" (hs-cleanup!) @@ -6019,7 +5894,6 @@ (hs-activate! _el-box) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP check: skip toHaveText("300") )) (deftest "works with from clause" (hs-cleanup!) @@ -6031,7 +5905,6 @@ (dom-set-attr _el-out "_" "on resize from #box put detail.width into me") (dom-append (dom-body) _el-out) (hs-activate! _el-out) - ;; SKIP check: skip toHaveText("150") )) ) @@ -6043,10 +5916,6 @@ (dom-set-attr _el-div "_" "when $global changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _global to _ - ;; SKIP action: await run__set _global to _ - ;; SKIP action: await run__set _global to 42_ - ;; SKIP check: skip toHaveText('initial'); toHaveText('hello world'); toHaveText )) (deftest "detects changes from $global variable" (hs-cleanup!) @@ -6054,8 +5923,6 @@ (dom-set-attr _el-div "_" "when $global changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _global to _ - ;; SKIP check: skip toHaveText('Changed!') )) (deftest "detects changes from :element variable" (hs-cleanup!) @@ -6063,9 +5930,10 @@ (dom-set-attr _el-div "_" "init set :count to 0 end when :count changes put it into me end on click increment :count") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.click__ - ;; SKIP action: find__div__.click__ - ;; SKIP check: skip toHaveText('0'); toHaveText('1'); toHaveText('2') + (dom-dispatch _el-div "click" nil) + (assert= "1" (dom-text-content _el-div)) + (dom-dispatch _el-div "click" nil) + (assert= "2" (dom-text-content _el-div)) )) (deftest "triggers multiple elements watching same variable" (hs-cleanup!) @@ -6078,8 +5946,6 @@ (dom-set-attr _el-d2 "_" "when $shared changes put 'second' into me") (dom-append (dom-body) _el-d2) (hs-activate! _el-d2) - ;; SKIP action: await run__set _shared to _ - ;; SKIP check: skip toHaveText('first'); toHaveText('second') )) (deftest "executes multiple commands" (hs-cleanup!) @@ -6087,8 +5953,6 @@ (dom-set-attr _el-div "_" "when $multi changes put 'first' into me then add .executed to me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _multi to _ - ;; SKIP check: skip toHaveText('first'); toHaveClass(/executed/) )) (deftest "does not execute when variable is undefined initially" (hs-cleanup!) @@ -6096,7 +5960,6 @@ (dom-set-attr _el-div "_" "when $neverSet changes put 'synced' into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toHaveText('original') )) (deftest "only triggers when variable actually changes value" (hs-cleanup!) @@ -6104,10 +5967,6 @@ (dom-set-attr _el-div "_" "when $dedup changes increment :callCount then put :callCount into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _dedup to _ - ;; SKIP action: await run__set _dedup to _ - ;; SKIP action: await run__set _dedup to _ - ;; SKIP check: skip toHaveText('1'); toHaveText('1'); toHaveText('2') )) (deftest "auto-tracks compound expressions" (hs-cleanup!) @@ -6115,11 +5974,6 @@ (dom-set-attr _el-div "_" "when ($a + $b) changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _a to 1_ - ;; SKIP action: await run__set _b to 2_ - ;; SKIP action: await run__set _a to 10_ - ;; SKIP action: await run__set _b to 20_ - ;; SKIP check: skip toHaveText('3'); toHaveText('12'); toHaveText('30') )) (deftest "detects attribute changes" (hs-cleanup!) @@ -6128,7 +5982,6 @@ (dom-set-attr _el-div "data-title" "original") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toHaveText('original') )) (deftest "detects form input value changes via user interaction" (hs-cleanup!) @@ -6140,8 +5993,6 @@ (dom-set-attr _el-span "_" "when #reactive-input.value changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: evaluate__...__ - ;; SKIP check: skip toHaveText('start'); toHaveText('typed') )) (deftest "detects property change via hyperscript set" (hs-cleanup!) @@ -6153,8 +6004,6 @@ (dom-set-attr _el-span "_" "when #prog-input.value changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: await run__set _prog-input.value to _ - ;; SKIP check: skip toHaveText('initial') )) (deftest "disposes effect when element is removed from DOM" (hs-cleanup!) @@ -6162,9 +6011,6 @@ (dom-set-attr _el-div "_" "when $dispose changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _dispose to _ - ;; SKIP action: await run__set _dispose to _ - ;; SKIP check: skip toHaveText('before'); toBe('before') )) (deftest "batches multiple synchronous writes into one effect run" (hs-cleanup!) @@ -6172,9 +6018,6 @@ (dom-set-attr _el-div "_" "when ($batchA + $batchB) changes increment :runCount then put :runCount into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _batchA to 0_ - ;; SKIP action: await run__set _batchB to 0_ - ;; SKIP check: skip toHaveText('1'); toHaveText('2') )) (deftest "handles chained reactivity across elements" (hs-cleanup!) @@ -6186,9 +6029,6 @@ (dom-set-attr _el-output "_" "when $derived changes put it into me") (dom-append (dom-body) _el-output) (hs-activate! _el-output) - ;; SKIP action: await run__set _source to 5_ - ;; SKIP action: await run__set _source to 20_ - ;; SKIP check: skip toHaveText('10'); toHaveText('40') )) (deftest "supports multiple when features on the same element" (hs-cleanup!) @@ -6196,10 +6036,6 @@ (dom-set-attr _el-div "_" "when $left changes put it into my @data-left end when $right changes put it into my @data-right") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _left to _ - ;; SKIP action: await run__set _right to _ - ;; SKIP action: await run__set _left to _ - ;; SKIP check: skip toHaveAttribute('data-left', 'L'); toHaveAttribute('data-rig )) (deftest "works with on handlers that modify the watched variable" (hs-cleanup!) @@ -6207,8 +6043,8 @@ (dom-set-attr _el-div "_" "init set :label to 'initial' end when :label changes put it into me end on click set :label to 'clicked'") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.click__ - ;; SKIP check: skip toHaveText('initial'); toHaveText('clicked') + (dom-dispatch _el-div "click" nil) + (assert= "clicked" (dom-text-content _el-div)) )) (deftest "does not cross-trigger on unrelated variable writes" (hs-cleanup!) @@ -6216,8 +6052,6 @@ (dom-set-attr _el-div "_" "when $trigger changes increment :count put :count into me set $other to 'side-effect'") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _trigger to _ - ;; SKIP check: skip toHaveText('1'); toHaveText('1') )) (deftest "handles rapid successive changes correctly" (hs-cleanup!) @@ -6225,8 +6059,6 @@ (dom-set-attr _el-div "_" "when $rapid changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _rapid to _ - ;; SKIP check: skip toHaveText('9') )) (deftest "isolates element-scoped variables between elements" (hs-cleanup!) @@ -6239,9 +6071,12 @@ (dom-set-attr _el-d2 "_" "init set :value to 'B' end when :value changes put it into me end on click set :value to 'B-clicked'") (dom-append (dom-body) _el-d2) (hs-activate! _el-d2) - ;; SKIP action: find___d1__.click__ - ;; SKIP action: find___d2__.click__ - ;; SKIP check: skip toHaveText('A'); toHaveText('B'); toHaveText('A-clicked'); t + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "A-clicked" (dom-text-content (dom-query-by-id "d1"))) + (assert= "B" (dom-text-content (dom-query-by-id "d2"))) + (dom-dispatch (dom-query-by-id "d2") "click" nil) + (assert= "B-clicked" (dom-text-content (dom-query-by-id "d2"))) + (assert= "A-clicked" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "handles NaN without infinite re-firing" (hs-cleanup!) @@ -6253,8 +6088,6 @@ (dom-set-attr _el-span "_" "when (#nan-input.value * 1) changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: evaluate__...__ - ;; SKIP check: skip toHaveText('NaN'); toHaveText('NaN') )) (deftest "fires when either expression changes using or" (hs-cleanup!) @@ -6262,9 +6095,6 @@ (dom-set-attr _el-div "_" "when $x or $y changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _x to _ - ;; SKIP action: await run__set _y to _ - ;; SKIP check: skip toHaveText('from-x'); toHaveText('from-y') )) (deftest "supports three or more expressions with or" (hs-cleanup!) @@ -6272,10 +6102,6 @@ (dom-set-attr _el-div "_" "when $r or $g or $b changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _r to _ - ;; SKIP action: await run__set _g to _ - ;; SKIP action: await run__set _b to _ - ;; SKIP check: skip toHaveText('red'); toHaveText('green'); toHaveText('blue') )) (deftest "#element.checked is tracked" (hs-cleanup!) @@ -6286,7 +6112,6 @@ (dom-set-attr _el-span "_" "when #cb-input.checked changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP check: skip toHaveText('false') )) (deftest "my @attr is tracked" (hs-cleanup!) @@ -6306,8 +6131,6 @@ (dom-set-attr _el-span "_" "when (value of #of-input) changes put it into me") (dom-append (dom-body) _el-span) (hs-activate! _el-span) - ;; SKIP action: find___of-input__.fill__changed__ - ;; SKIP check: skip toHaveText('init') )) (deftest "math on tracked symbols works" (hs-cleanup!) @@ -6315,10 +6138,6 @@ (dom-set-attr _el-div "_" "when ($mA * $mB) changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _mA to 3_ - ;; SKIP action: await run__set _mB to 4_ - ;; SKIP action: await run__set _mA to 10_ - ;; SKIP check: skip toHaveText('12') )) (deftest "comparison on tracked symbol works" (hs-cleanup!) @@ -6326,9 +6145,6 @@ (dom-set-attr _el-div "_" "when ($cmpVal > 5) changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _cmpVal to 3_ - ;; SKIP action: await run__set _cmpVal to 10_ - ;; SKIP check: skip toHaveText('false') )) (deftest "string template with tracked symbol works" (hs-cleanup!) @@ -6336,9 +6152,6 @@ (dom-set-attr _el-div "_" "when `hello ${$tplName}` changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _tplName to _ - ;; SKIP action: await run__set _tplName to _ - ;; SKIP check: skip toHaveText('hello world') )) (deftest "function call on tracked value works (Math.round)" (hs-cleanup!) @@ -6346,8 +6159,6 @@ (dom-set-attr _el-div "_" "when (Math.round($rawNum)) changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _rawNum to 3.7_ - ;; SKIP action: await run__set _rawNum to 9.2_ )) (deftest "inline style change via JS is NOT detected" (hs-cleanup!) @@ -6364,8 +6175,6 @@ (dom-set-attr _el-div "_" "when $arrWhole changes put it.join(',') into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _arrWhole to _1_ 2_ 3__ - ;; SKIP action: await run__set _arrWhole to _4_ 5_ 6__ )) (deftest "mutating array element in place is NOT detected" (hs-cleanup!) @@ -6373,7 +6182,6 @@ (dom-set-attr _el-div "_" "when $arrMut[0] changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _arrMut to _1_ 2_ 3__ )) (deftest "local variable in when expression produces a parse error" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -6385,9 +6193,6 @@ (dom-set-attr _el-div "_" "when ($x and $y) changes put it into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _x to false_ - ;; SKIP action: await run__set _y to _ - ;; SKIP action: await run__set _y to _ )) (deftest "diamond: cascaded derived values produce correct final value" (hs-cleanup!) @@ -6403,8 +6208,6 @@ (dom-set-attr _el-div "_" "live increment :runs then put ($ (runs:)' into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: await run__set _a to 1_ - ;; SKIP action: await run__set _a to 10_ )) (deftest "error in one effect does not break other effects in the same batch" (hs-cleanup!) @@ -6413,9 +6216,6 @@ (dom-set-attr _el-err-a "_" "when $trigger changes put null.boom into me") (dom-append (dom-body) _el-err-a) (hs-activate! _el-err-a) - ;; SKIP action: await run__set _trigger to 0_ - ;; SKIP action: await run__set _trigger to 42_ - ;; SKIP check: skip toHaveText('ok:42') )) (deftest "circular guard resets after cascade settles" (hs-cleanup!) @@ -6423,10 +6223,6 @@ (dom-set-attr _el-span "_" "when $ping changes set $ping to (i
then put \"moved\" into it then set #target to it") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toBe("moved") + (dom-dispatch _el-button "click" nil) )) (deftest "set .class replaces all matching elements" (hs-cleanup!) @@ -6845,8 +6637,8 @@ (dom-set-attr _el-list "id" "list") (dom-append (dom-body) _el-list) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toBe(3); toEqual(["replaced", "replaced", "replaced"]) + (dom-append (dom-body) _el-button) + (dom-dispatch _el-button "click" nil) )) (deftest "set replaces all matching elements" (hs-cleanup!) @@ -6854,16 +6646,16 @@ (dom-set-attr _el-box "id" "box") (dom-append (dom-body) _el-box) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toEqual(["done", "done"]) + (dom-append (dom-body) _el-button) + (dom-dispatch _el-button "click" nil) )) (deftest "set closest replaces ancestor" (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) (dom-add-class _el-div "wrapper") (dom-append (dom-body) _el-div) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("replaced") + (dom-dispatch (dom-query "button") "click" nil) + (assert= "replaced" (dom-text-content (dom-query ".wrapper"))) )) (deftest "hyperscript in replacement content is initialized" (hs-cleanup!) @@ -6872,9 +6664,11 @@ (dom-append (dom-body) _el-target) (dom-set-attr _el-target1 "id" "target") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___go__.dispatchEvent__click__ - ;; SKIP action: find___target__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("new"); toHaveText("clicked") + (dom-append (dom-body) _el-target1) + (dom-dispatch (dom-query-by-id "go") "click" nil) + (assert= "new" (dom-text-content (dom-query-by-id "target"))) + (dom-dispatch (dom-query-by-id "target") "click" nil) + (assert= "clicked" (dom-text-content (dom-query-by-id "target"))) )) (deftest "swap #a with #b swaps DOM positions" (hs-cleanup!) @@ -6884,8 +6678,7 @@ (dom-set-attr _el-button "_" "on click swap #a with #b") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toEqual(["B", "A"]) + (dom-dispatch _el-button "click" nil) )) (deftest "put into still works as innerHTML" (hs-cleanup!) @@ -6895,8 +6688,8 @@ (dom-set-attr _el-button "_" "on click put \"new\" into #target") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("new") + (dom-dispatch _el-button "click" nil) + (assert= "new" (dom-text-content (dom-query-by-id "target"))) )) ) @@ -6916,8 +6709,8 @@ (hs-activate! _el-button) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("AC") + (dom-dispatch _el-button "click" nil) + (assert= "AC" (dom-text-content (dom-query-by-id "out"))) )) (deftest "sorts by a property" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -6942,16 +6735,12 @@ (let ((_el-container (dom-create-element "div"))) (dom-set-attr _el-container "id" "container") (dom-append (dom-body) _el-container) - ;; SKIP action: await run__ in _container where i - ;; SKIP check: skip toBe(2) )) (deftest "sorted by binds after in without parens" (hs-cleanup!) (let ((_el-list (dom-create-element "ul"))) (dom-set-attr _el-list "id" "list") (dom-append (dom-body) _el-list) - ;; SKIP action: await run__
  • in _list where its text - ;; SKIP check: skip toBe(2) )) (deftest "where binds after property access" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -6960,9 +6749,6 @@ (let ((_el-items (dom-create-element "ul"))) (dom-set-attr _el-items "id" "items") (dom-append (dom-body) _el-items) - ;; SKIP action: await run_ - _
  • in _items where it - ;; SKIP check: skip toEqual(["A", "C"]) )) (deftest "where binds after in on closest" (hs-cleanup!) @@ -6970,10 +6756,12 @@ (dom-set-attr _el-box "id" "box") (dom-append (dom-body) _el-box) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-button) (dom-set-attr _el-b2 "id" "b2") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___b2__.click__ - ;; SKIP check: skip toHaveText("2") + (dom-append (dom-body) _el-b2) + (dom-dispatch (dom-query-by-id "b2") "click" nil) + (assert= "2" (dom-text-content (dom-query-by-id "b2"))) )) (deftest "where in init followed by on feature" (hs-cleanup!) @@ -6981,8 +6769,9 @@ (dom-set-attr _el-box "id" "box") (dom-append (dom-body) _el-box) ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("1") + (dom-append (dom-body) _el-button) + (dom-dispatch _el-button "click" nil) + (assert= "1" (dom-text-content _el-button)) )) (deftest "where in component init followed by on feature" (hs-cleanup!) @@ -6994,28 +6783,27 @@ (dom-append (dom-body) _el-template) (hs-activate! _el-template) (dom-append (dom-body) _el-test-where-comp) - ;; SKIP action: find__test-where-comp__.click__ - ;; SKIP check: skip toHaveText("1") + (dom-dispatch _el-test-where-comp "click" nil) + (assert= "1" (dom-text-content _el-test-where-comp)) )) (deftest "where with is not me in component template" (hs-cleanup!) (let ((_el-box (dom-create-element "div"))) (dom-set-attr _el-box "id" "box") (dom-append (dom-body) _el-box) - ;; SKIP action: find__test-where-me input__.click__ + (dom-dispatch (dom-query "test-where-me input") "click" nil) )) (deftest "where with is not me followed by on feature" (hs-cleanup!) (let ((_el-table (dom-create-element "table"))) (dom-append (dom-body) _el-table) - ;; SKIP action: find___master__.click__ + (dom-dispatch (dom-query-by-id "master") "click" nil) )) (deftest "full select-all pattern with multiple on features" (hs-cleanup!) (let ((_el-table (dom-create-element "table"))) (dom-append (dom-body) _el-table) - ;; SKIP action: find___master__.click__ - ;; SKIP check: skip toBe(true) + (dom-dispatch (dom-query-by-id "master") "click" nil) )) ) @@ -7052,7 +6840,6 @@ (dom-set-attr _el-template "component" "test-greet") (dom-append (dom-body) _el-template) (dom-append (dom-body) _el-test-greet) - ;; SKIP action: await run__set _name to _ )) (deftest "applies _ hyperscript to component instance" (hs-cleanup!) @@ -7071,7 +6858,7 @@ (dom-append (dom-body) _el-template) (hs-activate! _el-template) (dom-append (dom-body) _el-test-inner) - ;; SKIP action: find__test-inner button__.click__ + (dom-dispatch (dom-query "test-inner button") "click" nil) )) (deftest "reactively updates template expressions" (hs-cleanup!) @@ -7081,7 +6868,7 @@ (dom-append (dom-body) _el-template) (hs-activate! _el-template) (dom-append (dom-body) _el-test-reactive) - ;; SKIP action: find__test-reactive button__.click__ + (dom-dispatch (dom-query "test-reactive button") "click" nil) )) (deftest "supports multiple independent instances" (hs-cleanup!) @@ -7094,7 +6881,7 @@ (dom-append (dom-body) _el-a) (dom-set-attr _el-b "id" "b") (dom-append (dom-body) _el-b) - ;; SKIP action: find___a button__.click__ + (dom-dispatch (dom-query "#a button") "click" nil) )) (deftest "reads attributes via @" (hs-cleanup!) @@ -7139,7 +6926,7 @@ (dom-append (dom-body) _el-template) (hs-activate! _el-template) (dom-append (dom-body) _el-test-block) - ;; SKIP action: find__test-block span__.click__ + (dom-dispatch (dom-query "test-block span") "click" nil) )) (deftest "supports named slots" (hs-cleanup!) @@ -7154,7 +6941,7 @@ (dom-set-attr _el-div "_" "init set ^x to 42") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__test-slot-hs span__.click__ + (dom-dispatch (dom-query "test-slot-hs span") "click" nil) )) (deftest "slotted content resolves ^var from outer scope, not component scope" (hs-cleanup!) @@ -7189,7 +6976,6 @@ (hs-activate! _el-template) (dom-set-attr _el-test-args "items" "$stuff") (dom-append (dom-body) _el-test-args) - ;; SKIP action: await run__set _stuff to __ )) (deftest "attrs works with bind for reactive pass-through" (hs-cleanup!) @@ -7203,8 +6989,7 @@ (dom-set-attr _el-button "_" "on click increment $count") (dom-append (dom-body) _el-button) (hs-activate! _el-button) - ;; SKIP action: find__button__.click__ - ;; SKIP action: await run__set _count to 10_ + (dom-dispatch _el-button "click" nil) )) (deftest "attrs bind is bidirectional — inner changes flow outward" (hs-cleanup!) @@ -7218,8 +7003,7 @@ (dom-set-attr _el-p "_" "live put $count into me") (dom-append (dom-body) _el-p) (hs-activate! _el-p) - ;; SKIP action: find__test-args-bidir button__.click__ - ;; SKIP action: await run__set _count to 10_ + (dom-dispatch (dom-query "test-args-bidir button") "click" nil) )) ) @@ -7230,16 +7014,18 @@ (let ((_el-d1 (dom-create-element "div"))) (dom-set-attr _el-d1 "id" "d1") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("bar") + (dom-append (dom-body) _el-d1) + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "bar" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "can default of-expression properties" (hs-cleanup!) (let ((_el-d1 (dom-create-element "div"))) (dom-set-attr _el-d1 "id" "d1") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("bar") + (dom-append (dom-body) _el-d1) + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "bar" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "can default array elements" (hs-cleanup!) @@ -7247,8 +7033,8 @@ (dom-set-attr _el-div "_" "on click set arr to [null, null] then default arr[0] to 'yes' then put arr[0] into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("yes") + (dom-dispatch _el-div "click" nil) + (assert= "yes" (dom-text-content _el-div)) )) (deftest "default array element respects existing value" (hs-cleanup!) @@ -7256,8 +7042,8 @@ (dom-set-attr _el-div "_" "on click set arr to ['existing', null] then default arr[0] to 'new' then put arr[0] into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("existing") + (dom-dispatch _el-div "click" nil) + (assert= "existing" (dom-text-content _el-div)) )) (deftest "default preserves zero" (hs-cleanup!) @@ -7265,8 +7051,8 @@ (dom-set-attr _el-div "_" "on click set x to 0 then default x to 10 then put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("0") + (dom-dispatch _el-div "click" nil) + (assert= "0" (dom-text-content _el-div)) )) (deftest "default overwrites empty string" (hs-cleanup!) @@ -7274,8 +7060,8 @@ (dom-set-attr _el-div "_" "on click set x to \"\" then default x to \"fallback\" then put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("fallback") + (dom-dispatch _el-div "click" nil) + (assert= "fallback" (dom-text-content _el-div)) )) (deftest "default preserves false" (hs-cleanup!) @@ -7283,8 +7069,8 @@ (dom-set-attr _el-div "_" "on click set x to false then default x to true then put x into me") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("false") + (dom-dispatch _el-div "click" nil) + (assert= "false" (dom-text-content _el-div)) )) (deftest "can default style ref when unset" (hs-cleanup!) @@ -7292,8 +7078,8 @@ (dom-set-attr _el-div "_" "on click default *background-color to 'red'") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('background-color', 'rgb(255, 0, 0) + (dom-dispatch _el-div "click" nil) + (assert= "" (dom-get-style _el-div "background-color")) )) (deftest "default style ref preserves existing value" (hs-cleanup!) @@ -7302,8 +7088,8 @@ (dom-set-attr _el-div "style" "color: blue") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveCSS('color', 'rgb(0, 0, 255) + (dom-dispatch _el-div "click" nil) + (assert= "" (dom-get-style _el-div "color")) )) ) @@ -7315,8 +7101,8 @@ (dom-set-attr _el-div "_" "on click js return Promise.reject(\"boom\") end catch e put e into my.innerHTML") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("boom") + (dom-dispatch _el-div "click" nil) + (assert= "boom" (dom-text-content _el-div)) )) ) @@ -7331,7 +7117,7 @@ (dom-set-attr _el-div "_" "on click measure #other's top then set window.measurement to {top: top}") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toBe(89) + (dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil) )) (deftest "can measure with of syntax" (hs-cleanup!) @@ -7342,7 +7128,7 @@ (dom-set-attr _el-div "_" "on click measure top of #other then set window.measurement to {top: top}") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toBe(89) + (dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil) )) ) @@ -7377,7 +7163,7 @@ (dom-set-attr _el-trigger "_" "on click settle <.item/> then add .done to <.item/>") (dom-append (dom-body) _el-trigger) (hs-activate! _el-trigger) - ;; SKIP action: find___trigger__.dispatchEvent__click__ + (dom-dispatch (dom-query-by-id "trigger") "click" nil) )) ) @@ -7387,27 +7173,30 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-s1 (dom-create-element "span")) (_el-s2 (dom-create-element "span"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-set-attr _el-s1 "id" "s1") (dom-set-attr _el-s1 "style" "display:none") (dom-append (dom-body) _el-s1) (dom-set-attr _el-s2 "id" "s2") (dom-set-attr _el-s2 "style" "display:none") (dom-append (dom-body) _el-s2) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toBeVisible(); toBeVisible() + (dom-dispatch _el-div "click" nil) + (assert (dom-visible? (dom-query-by-id "s1"))) + (assert (dom-visible? (dom-query-by-id "s2"))) )) (deftest "the result after show...when is the matched elements" (hs-cleanup!) (let ((_el-div (dom-create-element "div")) (_el-p (dom-create-element "p")) (_el-p2 (dom-create-element "p")) (_el-out (dom-create-element "span"))) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-div) (dom-set-attr _el-p "style" "display:none") (dom-append (dom-body) _el-p) (dom-set-attr _el-p2 "style" "display:none") (dom-append (dom-body) _el-p2) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("some") + (dom-dispatch _el-div "click" nil) + (assert= "some" (dom-text-content (dom-query-by-id "out"))) )) ) @@ -7433,7 +7222,11 @@ (dom-set-attr _el-div "_" "on click add .foo to #bar then add .blah") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toHaveClass(/foo/); toHaveClass(/blah/) + (dom-dispatch (dom-query "div:nth-of-type(2)") "click" nil) + (assert (dom-has-class? (dom-query-by-id "bar") "foo")) + (assert (not (dom-has-class? (dom-query-by-id "bar") "blah"))) + (assert (not (dom-has-class? (dom-query "div:nth-of-type(2)") "foo"))) + (assert (dom-has-class? (dom-query "div:nth-of-type(2)") "blah")) )) (deftest "stores state on elt._hyperscript" (hs-cleanup!) @@ -7441,7 +7234,6 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toBe(true); toBe(true); toBe(true) )) (deftest "skips reinitialization if script unchanged" (hs-cleanup!) @@ -7449,9 +7241,6 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: evaluate__...__ - (dom-dispatch _el-div "click" nil) - ;; SKIP check: skip toBe(1) )) (deftest "reinitializes if script attribute changes" (hs-cleanup!) @@ -7459,10 +7248,10 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: evaluate__...__ - ;; SKIP check: skip toHaveClass(/foo/); toHaveClass(/bar/) + (dom-dispatch _el-div "click" nil) + (assert (dom-has-class? _el-div "foo")) + (dom-dispatch _el-div "click" nil) + (assert (dom-has-class? _el-div "bar")) )) (deftest "cleanup removes event listeners on the element" (hs-cleanup!) @@ -7470,10 +7259,9 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP action: evaluate__...__ (dom-dispatch _el-div "click" nil) - ;; SKIP check: skip toHaveClass(/foo/); toHaveClass(/foo/) + (assert (dom-has-class? _el-div "foo")) + (assert (not (dom-has-class? _el-div "foo"))) )) (deftest "cleanup removes cross-element event listeners" (hs-cleanup!) @@ -7484,10 +7272,8 @@ (dom-set-attr _el-target "_" "on click from #source add .foo") (dom-append (dom-body) _el-target) (hs-activate! _el-target) - ;; SKIP action: find___source__.dispatchEvent__click__ - ;; SKIP action: evaluate__...__ - (dom-dispatch _el-source "click" nil) - ;; SKIP check: skip toHaveClass(/foo/); toBe(true) + (dom-dispatch (dom-query-by-id "source") "click" nil) + (assert (dom-has-class? (dom-query-by-id "target") "foo")) )) (deftest "cleanup tracks listeners in elt._hyperscript" (hs-cleanup!) @@ -7495,7 +7281,6 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toBe(true) )) (deftest "cleanup clears elt._hyperscript" (hs-cleanup!) @@ -7503,7 +7288,6 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toBe(false) )) (deftest "sets data-hyperscript-powered on initialized elements" (hs-cleanup!) @@ -7511,7 +7295,6 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toHaveAttribute('data-hyperscript-powered', 'true') )) (deftest "cleanup removes data-hyperscript-powered" (hs-cleanup!) @@ -7519,7 +7302,6 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toHaveAttribute('data-hyperscript-powered', 'true') )) (deftest "fires hyperscript:before:init and hyperscript:after:init" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -7531,7 +7313,6 @@ (dom-set-attr _el-div "_" "on click add .foo") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP check: skip toEqual(['before:cleanup', 'after:cleanup']) )) (deftest "logAll config logs events to console" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -7545,8 +7326,8 @@ (dom-set-attr _el-div "_" "on click put \"clicked\" into my.innerHTML ---put some content into the div...") (dom-append (dom-body) _el-div) (hs-activate! _el-div) - ;; SKIP action: find__div__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("clicked") + (dom-dispatch _el-div "click" nil) + (assert= "clicked" (dom-text-content _el-div)) )) (deftest "recovers across feature boundaries and reports all errors" (hs-cleanup!) @@ -7555,7 +7336,6 @@ (dom-set-attr _el-d1 "_" "on click blargh end on mouseenter put \"hovered\" into my.innerHTML") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP check: skip toBe(false) )) (deftest "recovers across multiple feature errors" (hs-cleanup!) @@ -7564,7 +7344,6 @@ (dom-set-attr _el-d1 "_" "on click blargh end on mouseenter also_bad end on focus put \"focused\" into my.innerHTML") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP check: skip toBe(false) )) (deftest "fires hyperscript:parse-error event with all errors" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -7572,8 +7351,8 @@ (hs-cleanup!) (let ((_el-div (dom-create-element "div"))) (dom-append (dom-body) _el-div) - ;; SKIP action: find___d2__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("clicked") + (dom-dispatch (dom-query-by-id "d2") "click" nil) + (assert= "clicked" (dom-text-content (dom-query-by-id "d2"))) )) (deftest "_hyperscript() evaluate API still throws on first error" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -7590,9 +7369,9 @@ (dom-set-attr _el-d1 "_" "on click 1 set :x to 10 on click 2 set @out to :x") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveAttribute('out', '10') + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "10" (dom-get-attr (dom-query-by-id "d1") "out")) )) ) @@ -7641,8 +7420,8 @@ (let ((_el-arDiv (dom-create-element "div"))) (dom-set-attr _el-arDiv "id" "arDiv") ;; HS source has bare quotes — HTML parse artifact - ;; SKIP action: find___arDiv__.dispatchEvent__click__ - ;; SKIP check: skip toBe("blue") + (dom-append (dom-body) _el-arDiv) + (dom-dispatch (dom-query-by-id "arDiv") "click" nil) )) ) @@ -7654,22 +7433,20 @@ (dom-set-attr _el-outerDiv2 "id" "outerDiv2") (dom-set-attr _el-outerDiv2 "foo" "bar") (dom-append (dom-body) _el-outerDiv2) - ;; SKIP action: find___d1b__.dispatchEvent__click__ - ;; SKIP check: skip toBe("bar") + (dom-dispatch (dom-query-by-id "d1b") "click" nil) )) (deftest "closest does not consume a following where clause" (hs-cleanup!) (let ((_el-table (dom-create-element "table"))) (dom-append (dom-body) _el-table) - ;; SKIP action: find___master__.click__ - ;; SKIP check: skip toHaveText("2") + (dom-dispatch (dom-query-by-id "master") "click" nil) + (assert= "2" (dom-text-content (dom-query-by-id "out"))) )) (deftest "closest with to modifier still works after parse change" (hs-cleanup!) (let ((_el-outer (dom-create-element "div"))) (dom-set-attr _el-outer "id" "outer") (dom-append (dom-body) _el-outer) - ;; SKIP check: skip toBe(true) )) ) @@ -7682,8 +7459,8 @@ (dom-set-attr _el-d1 "_" "on click if I am a Element put \"yes\" into me") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("yes") + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "yes" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "is a Node works via instanceof" (hs-cleanup!) @@ -7692,8 +7469,8 @@ (dom-set-attr _el-d1 "_" "on click if I am a Node put \"yes\" into me") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("yes") + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "yes" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "is not a works with instanceof fallback" (hs-cleanup!) @@ -7702,8 +7479,8 @@ (dom-set-attr _el-d1 "_" "on click if \"hello\" is not a Element put \"yes\" into me") (dom-append (dom-body) _el-d1) (hs-activate! _el-d1) - ;; SKIP action: find___d1__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("yes") + (dom-dispatch (dom-query-by-id "d1") "click" nil) + (assert= "yes" (dom-text-content (dom-query-by-id "d1"))) )) (deftest "is ignoring case works" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -7786,10 +7563,11 @@ (let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div"))) (dom-set-attr _el-a "id" "a") ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-a) (dom-set-attr _el-b "id" "b") (dom-append (dom-body) _el-b) - ;; SKIP action: find___a__.dispatchEvent__click__ - ;; SKIP check: skip toHaveText("yes") + (dom-dispatch (dom-query-by-id "a") "click" nil) + (assert= "yes" (dom-text-content (dom-query-by-id "a"))) )) (deftest "is really works without equal to" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -7815,8 +7593,6 @@ (dom-set-attr _el-c2 "id" "c2") (dom-set-attr _el-c2 "type" "checkbox") (dom-append (dom-body) _el-c2) - ;; SKIP action: await run___c1 is checked_ - ;; SKIP action: await run___c2 is checked_ )) (deftest "is not falls back to boolean property when rhs is undefined" (hs-cleanup!) @@ -7828,8 +7604,6 @@ (dom-set-attr _el-c2 "id" "c2") (dom-set-attr _el-c2 "type" "checkbox") (dom-append (dom-body) _el-c2) - ;; SKIP action: await run___c1 is not checked_ - ;; SKIP action: await run___c2 is not checked_ )) (deftest "is boolean property works with disabled" (hs-cleanup!) @@ -7838,9 +7612,6 @@ (dom-append (dom-body) _el-b1) (dom-set-attr _el-b2 "id" "b2") (dom-append (dom-body) _el-b2) - ;; SKIP action: await run___b1 is disabled_ - ;; SKIP action: await run___b2 is disabled_ - ;; SKIP action: await run___b2 is not disabled_ )) (deftest "is still does equality when rhs variable exists" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) @@ -7858,8 +7629,6 @@ (dom-set-attr _el-input2 "type" "checkbox") (dom-set-attr _el-input2 "checked" "checked") (dom-append (dom-body) _el-input2) - ;; SKIP action: await run__.cb where it is checked_ - ;; SKIP check: skip toBe(2) )) ) @@ -7915,10 +7684,11 @@ (dom-set-attr _el-box "id" "box") (dom-append (dom-body) _el-box) ;; HS source has bare quotes — HTML parse artifact + (dom-append (dom-body) _el-button) (dom-set-attr _el-out "id" "out") (dom-append (dom-body) _el-out) - ;; SKIP action: find__button__.click__ - ;; SKIP check: skip toHaveText("none") + (dom-dispatch _el-button "click" nil) + (assert= "none" (dom-text-content (dom-query-by-id "out"))) )) ) @@ -7940,7 +7710,6 @@ (dom-append (dom-body) _el-div1) (dom-add-class _el-div2 "c3") (dom-append (dom-body) _el-div2) - ;; SKIP check: skip toBe(1) )) ) @@ -7953,7 +7722,6 @@ (dom-append (dom-body) _el-d1) (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d2) - ;; SKIP check: skip toBe('hello') )) (deftest "can access property of previous element with possessive" (hs-cleanup!) @@ -7962,7 +7730,6 @@ (dom-append (dom-body) _el-d1) (dom-set-attr _el-d2 "id" "d2") (dom-append (dom-body) _el-d2) - ;; SKIP check: skip toBe('world') )) (deftest "can access style of next element with possessive" (hs-cleanup!) @@ -7972,7 +7739,6 @@ (dom-set-attr _el-d2 "id" "d2") (dom-set-attr _el-d2 "style" "color: red") (dom-append (dom-body) _el-d2) - ;; SKIP check: skip toBe('red') )) (deftest "can write to next element with put command" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) diff --git a/tests/playwright/generate-sx-tests.py b/tests/playwright/generate-sx-tests.py index 96118d0d..f3d1848c 100644 --- a/tests/playwright/generate-sx-tests.py +++ b/tests/playwright/generate-sx-tests.py @@ -5,11 +5,16 @@ Generate spec/tests/test-hyperscript-behavioral.sx from upstream _hyperscript te Reads spec/tests/hyperscript-upstream-tests.json and produces SX deftest forms that run in the Playwright sandbox with real DOM. +Handles two assertion formats: +- Chai-style (.should.equal / assert.*) — from v0.9.14 master tests +- Playwright-style (toHaveText / toHaveClass / etc.) — from dev branch tests (have `body` field) + Usage: python3 tests/playwright/generate-sx-tests.py """ import json import re import os +from collections import OrderedDict PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) INPUT = os.path.join(PROJECT_ROOT, 'spec/tests/hyperscript-upstream-tests.json') @@ -18,6 +23,8 @@ OUTPUT = os.path.join(PROJECT_ROOT, 'spec/tests/test-hyperscript-behavioral.sx') with open(INPUT) as f: raw_tests = json.load(f) +# ── HTML parsing ────────────────────────────────────────────────── + def parse_html(html): """Parse HTML into list of element dicts. Uses Python's html.parser for reliability with same-tag siblings.""" @@ -56,8 +63,29 @@ def parse_html(html): Parser().feed(html) return elements + +# ── Variable naming ─────────────────────────────────────────────── + +def assign_var_names(elements): + """Assign unique SX variable names to elements.""" + var_names = [] + used_names = set() + for i, el in enumerate(elements): + if el['id']: + var = f'_el-{el["id"]}' + else: + var = f'_el-{el["tag"]}' + if var in used_names: + var = f'{var}{i}' + used_names.add(var) + var_names.append(var) + return var_names + + +# ── Chai-style parsers (v0.9.14 master tests) ──────────────────── + def parse_action(action, ref): - """Convert upstream action to SX. Returns list of SX expressions.""" + """Convert upstream Chai-style action to SX. Returns list of SX expressions.""" if not action or action == '(see body)': return [] @@ -97,6 +125,7 @@ def parse_action(action, ref): return exprs + def parse_checks(check): """Convert Chai assertions to SX assert forms. Returns list of SX expressions. Only keeps post-action assertions (last occurrence per expression).""" @@ -109,7 +138,6 @@ def parse_checks(check): if not part: continue - # Pattern: var.classList.contains("cls").should.equal(bool) m = re.match(r'(\w+)\.classList\.contains\("([^"]+)"\)\.should\.equal\((true|false)\)', part) if m: name, cls, expected = m.group(1), m.group(2), m.group(3) @@ -119,49 +147,41 @@ def parse_checks(check): all_checks.append(('class', name, cls, False)) continue - # Pattern: var.innerHTML.should.equal("value") m = re.match(r'(\w+)\.innerHTML\.should\.equal\("([^"]*)"\)', part) if m: all_checks.append(('innerHTML', m.group(1), m.group(2), None)) continue - # Pattern: var.innerHTML.should.equal(value) — non-string m = re.match(r'(\w+)\.innerHTML\.should\.equal\((.+)\)', part) if m: all_checks.append(('innerHTML', m.group(1), m.group(2), None)) continue - # Pattern: var.textContent.should.equal("value") m = re.match(r'(\w+)\.textContent\.should\.equal\("([^"]*)"\)', part) if m: all_checks.append(('textContent', m.group(1), m.group(2), None)) continue - # Pattern: var.style.prop.should.equal("value") m = re.match(r'(\w+)\.style\.(\w+)\.should\.equal\("([^"]*)"\)', part) if m: all_checks.append(('style', m.group(1), m.group(2), m.group(3))) continue - # Pattern: var.getAttribute("name").should.equal("value") m = re.match(r'(\w+)\.getAttribute\("([^"]+)"\)\.should\.equal\("([^"]*)"\)', part) if m: all_checks.append(('attr', m.group(1), m.group(2), m.group(3))) continue - # Pattern: var.hasAttribute("name").should.equal(bool) m = re.match(r'(\w+)\.hasAttribute\("([^"]+)"\)\.should\.equal\((true|false)\)', part) if m: all_checks.append(('hasAttr', m.group(1), m.group(2), m.group(3) == 'true')) continue - # Pattern: getComputedStyle(var).prop.should.equal("value") m = re.match(r'getComputedStyle\((\w+)\)\.(\w+)\.should\.equal\("([^"]*)"\)', part) if m: all_checks.append(('computedStyle', m.group(1), m.group(2), m.group(3))) continue - # Pattern: var.parentElement assert m = re.match(r'assert\.isNull\((\w+)\.parentElement\)', part) if m: all_checks.append(('noParent', m.group(1), None, None)) @@ -171,13 +191,11 @@ def parse_checks(check): all_checks.append(('hasParent', m.group(1), None, None)) continue - # Pattern: var.value.should.equal("value") — input value m = re.match(r'(\w+)\.value\.should\.equal\("([^"]*)"\)', part) if m: all_checks.append(('value', m.group(1), m.group(2), None)) continue - # Skip unrecognized all_checks.append(('skip', part[:60], None, None)) # Deduplicate: keep last per (type, name, key) @@ -188,16 +206,11 @@ def parse_checks(check): return list(seen.values()) -def make_ref_fn(elements, var_names): - """Create a ref function that maps upstream JS variable names to SX let-bound variables. - Upstream patterns: - - 'div', 'form' etc. → last element with that tag (the make() return value) - - 'd1', 'bar', 'p1' etc. → element with that ID, or last element if no ID match - """ - # Build mappings - tag_to_var = {} # tag -> last var with that tag - id_to_var = {} # id -> var +def make_ref_fn(elements, var_names): + """Create a ref function that maps upstream JS variable names to SX let-bound variables.""" + tag_to_var = {} + id_to_var = {} last_var = var_names[-1] if var_names else '_el-div' for i, el in enumerate(elements): @@ -206,25 +219,23 @@ def make_ref_fn(elements, var_names): id_to_var[el['id']] = var_names[i] tags = {'div', 'form', 'button', 'input', 'span', 'p', 'a', 'section', - 'ul', 'li', 'select', 'textarea', 'details', 'dialog', 'template'} + 'ul', 'li', 'select', 'textarea', 'details', 'dialog', 'template', + 'output'} def ref(name): if name in tags: return tag_to_var.get(name, last_var) if name in id_to_var: return id_to_var[name] - # make() return variable pattern: d1, d2, div1, btn1, etc. - # These refer to the last element created by make() if re.match(r'^[a-z]+\d*$', name) and len(elements) > 0: - # If there's an element with this as id, use dom-query-by-id - # Otherwise it's the make() return var — use last element return last_var return f'(dom-query-by-id "{name}")' return ref + def check_to_sx(check, ref): - """Convert a parsed check tuple to an SX assertion.""" + """Convert a parsed Chai check tuple to an SX assertion.""" typ, name, key, val = check r = ref(name) if typ == 'class' and val: @@ -246,7 +257,6 @@ def check_to_sx(check, ref): elif typ == 'hasAttr' and not val: return f'(assert (not (dom-has-attr? {r} "{key}")))' elif typ == 'computedStyle': - # Can't reliably test computed styles in sandbox return f';; SKIP computed style: {name}.{key}' elif typ == 'noParent': return f'(assert (nil? (dom-parent {r})))' @@ -257,50 +267,161 @@ def check_to_sx(check, ref): else: return f';; SKIP check: {typ} {name}' -def generate_test(test, idx): - """Generate SX deftest for an upstream test.""" - elements = parse_html(test['html']) - if not elements and not test.get('html', '').strip(): - # eval-only test — no HTML at all - return None # Will get a failing stub - if not elements: - return None # HTML exists but couldn't parse it +# ── Playwright-style body parser (dev branch tests) ────────────── - lines = [] - lines.append(f' (deftest "{test["name"]}"') - lines.append(' (hs-cleanup!)') - - # Assign unique variable names to each element - var_names = [] - used_names = set() +def selector_to_sx(selector, elements, var_names): + """Convert a CSS selector from find('selector') to SX DOM lookup expression.""" + selector = selector.strip("'\"") + if selector.startswith('#'): + # ID selector — might be compound like '#a output' + if ' ' in selector: + return f'(dom-query "{selector}")' + return f'(dom-query-by-id "{selector[1:]}")' + if selector.startswith('.'): + return f'(dom-query "{selector}")' + # Try tag match to a let-bound variable for i, el in enumerate(elements): - if el['id']: - var = f'_el-{el["id"]}' + if el['tag'] == selector and i < len(var_names): + return var_names[i] + # Fallback: query by tag + return f'(dom-query "{selector}")' + + +def parse_pw_args(args_str): + """Parse Playwright assertion arguments like 'foo', "bar" or "name", "value".""" + args = [] + for m in re.finditer(r"""(['"])(.*?)\1""", args_str): + args.append(m.group(2)) + return args + + +def pw_assertion_to_sx(target, negated, assert_type, args_str): + """Convert a Playwright assertion to SX.""" + args = parse_pw_args(args_str) + + if assert_type == 'toHaveText': + val = args[0] if args else '' + escaped = val.replace('\\', '\\\\').replace('"', '\\"') + if negated: + return f'(assert (!= "{escaped}" (dom-text-content {target})))' + return f'(assert= "{escaped}" (dom-text-content {target}))' + + elif assert_type == 'toHaveAttribute': + attr_name = args[0] if args else '' + if len(args) >= 2: + attr_val = args[1].replace('\\', '\\\\').replace('"', '\\"') + if negated: + return f'(assert (!= "{attr_val}" (dom-get-attr {target} "{attr_name}")))' + return f'(assert= "{attr_val}" (dom-get-attr {target} "{attr_name}"))' else: - var = f'_el-{el["tag"]}' - # Ensure uniqueness - if var in used_names: - var = f'{var}{i}' - used_names.add(var) - var_names.append(var) + if negated: + return f'(assert (not (dom-has-attr? {target} "{attr_name}")))' + return f'(assert (dom-has-attr? {target} "{attr_name}"))' - # Create ref function with element context - ref = make_ref_fn(elements, var_names) + elif assert_type == 'toHaveClass': + cls = args[0] if args else '' + if not cls: + # Handle regex like /outer-clicked/ + m = re.match(r'/(.+?)/', args_str) + if m: + cls = m.group(1) + if negated: + return f'(assert (not (dom-has-class? {target} "{cls}")))' + return f'(assert (dom-has-class? {target} "{cls}"))' - # Parse actions and checks with context-aware ref - actions = parse_action(test['action'], ref) - checks = parse_checks(test['check']) + elif assert_type == 'toHaveCSS': + prop = args[0] if args else '' + val = args[1] if len(args) >= 2 else '' + escaped = val.replace('\\', '\\\\').replace('"', '\\"') + if negated: + return f'(assert (!= "{escaped}" (dom-get-style {target} "{prop}")))' + return f'(assert= "{escaped}" (dom-get-style {target} "{prop}"))' - # Create elements - bindings = [] - for i, el in enumerate(elements): - bindings.append(f'({var_names[i]} (dom-create-element "{el["tag"]}"))') + elif assert_type == 'toHaveValue': + val = args[0] if args else '' + escaped = val.replace('\\', '\\\\').replace('"', '\\"') + if negated: + return f'(assert (!= "{escaped}" (dom-get-prop {target} "value")))' + return f'(assert= "{escaped}" (dom-get-prop {target} "value"))' - # Build let block - lines.append(f' (let ({" ".join(bindings)})') + elif assert_type == 'toBeVisible': + if negated: + return f'(assert (not (dom-visible? {target})))' + return f'(assert (dom-visible? {target}))' - # Set attributes and append + elif assert_type == 'toBeHidden': + if negated: + return f'(assert (dom-visible? {target}))' + return f'(assert (not (dom-visible? {target})))' + + elif assert_type == 'toBeChecked': + if negated: + return f'(assert (not (dom-get-prop {target} "checked")))' + return f'(assert (dom-get-prop {target} "checked"))' + + return None + + +def parse_dev_body(body, elements, var_names): + """Parse Playwright test body to extract actions and post-action assertions. + + Returns a single ordered list of SX expression strings (actions and assertions + interleaved in their original order). Pre-action assertions are skipped. + """ + ops = [] + found_first_action = False + + for line in body.split('\n'): + line = line.strip() + + # Skip comments + if line.startswith('//'): + continue + + # Action: find('selector').click() or .dispatchEvent('event') + m = re.search(r"find\((['\"])(.+?)\1\)\.(click|dispatchEvent)\(([^)]*)\)", line) + if m and 'expect' not in line: + found_first_action = True + selector = m.group(2) + action_type = m.group(3) + action_arg = m.group(4).strip("'\"") + target = selector_to_sx(selector, elements, var_names) + if action_type == 'click': + ops.append(f'(dom-dispatch {target} "click" nil)') + elif action_type == 'dispatchEvent': + ops.append(f'(dom-dispatch {target} "{action_arg}" nil)') + continue + + # Skip lines before first action (pre-checks, setup) + if not found_first_action: + continue + + # Assertion: expect(find('selector')).[not.]toHaveText("value") + m = re.search( + r"expect\(find\((['\"])(.+?)\1\)\)\.(not\.)?" + r"(toHaveText|toHaveClass|toHaveCSS|toHaveAttribute|toHaveValue|toBeVisible|toBeHidden|toBeChecked)" + r"\(([^)]*)\)", + line + ) + if m: + selector = m.group(2) + negated = bool(m.group(3)) + assert_type = m.group(4) + args_str = m.group(5) + target = selector_to_sx(selector, elements, var_names) + sx = pw_assertion_to_sx(target, negated, assert_type, args_str) + if sx: + ops.append(sx) + continue + + return ops + + +# ── Test generation ─────────────────────────────────────────────── + +def emit_element_setup(lines, elements, var_names): + """Emit SX for creating elements, setting attributes, appending to body, and activating.""" for i, el in enumerate(elements): var = var_names[i] @@ -312,12 +433,12 @@ def generate_test(test, idx): hs_val = el['hs'] hs_val = hs_val.replace('\\', '').replace('\n', ' ').replace('\t', ' ').strip() if not hs_val: + lines.append(f' (dom-append (dom-body) {var})') continue - # Skip malformed values (HTML parser artifacts starting/ending with quotes) if hs_val.startswith('"') or hs_val.endswith('"'): lines.append(f' ;; HS source has bare quotes — HTML parse artifact') + lines.append(f' (dom-append (dom-body) {var})') continue - # Escape for SX double-quoted string hs_escaped = hs_val.replace('\\', '\\\\').replace('"', '\\"') lines.append(f' (dom-set-attr {var} "_" "{hs_escaped}")') for aname, aval in el['attrs'].items(): @@ -330,24 +451,74 @@ def generate_test(test, idx): if el['hs']: lines.append(f' (hs-activate! {var})') - # Actions + +def generate_test_chai(test, elements, var_names, idx): + """Generate SX deftest using Chai-style action/check fields.""" + ref = make_ref_fn(elements, var_names) + actions = parse_action(test['action'], ref) + checks = parse_checks(test['check']) + + lines = [] + lines.append(f' (deftest "{test["name"]}"') + lines.append(' (hs-cleanup!)') + + bindings = [f'({var_names[i]} (dom-create-element "{el["tag"]}"))' for i, el in enumerate(elements)] + lines.append(f' (let ({" ".join(bindings)})') + + emit_element_setup(lines, elements, var_names) + for action in actions: lines.append(f' {action}') - - # Assertions for check in checks: sx = check_to_sx(check, ref) lines.append(f' {sx}') - lines.append(' ))') # close let + deftest - + lines.append(' ))') return '\n'.join(lines) -# Generate the file +def generate_test_pw(test, elements, var_names, idx): + """Generate SX deftest using Playwright-style body field.""" + ops = parse_dev_body(test['body'], elements, var_names) + + lines = [] + lines.append(f' (deftest "{test["name"]}"') + lines.append(' (hs-cleanup!)') + + bindings = [f'({var_names[i]} (dom-create-element "{el["tag"]}"))' for i, el in enumerate(elements)] + lines.append(f' (let ({" ".join(bindings)})') + + emit_element_setup(lines, elements, var_names) + + for op in ops: + lines.append(f' {op}') + + lines.append(' ))') + return '\n'.join(lines) + + +def generate_test(test, idx): + """Generate SX deftest for an upstream test. Dispatches to Chai or PW parser.""" + elements = parse_html(test['html']) + + if not elements and not test.get('html', '').strip(): + return None + if not elements: + return None + + var_names = assign_var_names(elements) + + if test.get('body'): + return generate_test_pw(test, elements, var_names, idx) + else: + return generate_test_chai(test, elements, var_names, idx) + + +# ── Output generation ───────────────────────────────────────────── + output = [] output.append(';; Hyperscript behavioral tests — auto-generated from upstream _hyperscript test suite') -output.append(';; Source: spec/tests/hyperscript-upstream-tests.json (346 tests)') +output.append(f';; Source: spec/tests/hyperscript-upstream-tests.json ({len(raw_tests)} tests, v0.9.14 + dev)') output.append(';; DO NOT EDIT — regenerate with: python3 tests/playwright/generate-sx-tests.py') output.append('') output.append(';; ── Test helpers ──────────────────────────────────────────────────') @@ -366,7 +537,6 @@ output.append(' (dom-set-inner-html (dom-body) "")))') output.append('') # Group by category -from collections import OrderedDict categories = OrderedDict() for t in raw_tests: cat = t['category'] @@ -376,28 +546,38 @@ for t in raw_tests: total = 0 skipped = 0 +generated_counts = {} # cat -> (generated, stubbed) for cat, tests in categories.items(): output.append(f';; ── {cat} ({len(tests)} tests) ──') output.append(f'(defsuite "hs-upstream-{cat}"') + cat_gen = 0 + cat_stub = 0 for i, t in enumerate(tests): sx = generate_test(t, i) if sx: output.append(sx) total += 1 + cat_gen += 1 else: - # Generate a failing test stub so the gap is visible safe_name = t['name'].replace('"', "'") output.append(f' (deftest "{safe_name}"') output.append(f' (error "NOT IMPLEMENTED: test HTML could not be parsed into SX"))') total += 1 + cat_stub += 1 - output.append(')') # close defsuite + output.append(')') output.append('') + generated_counts[cat] = (cat_gen, cat_stub) with open(OUTPUT, 'w') as f: f.write('\n'.join(output)) -print(f'Generated {total} tests ({skipped} skipped) -> {OUTPUT}') -for cat, tests in categories.items(): - print(f' {cat}: {len(tests)}') +# Report +has_body = sum(1 for t in raw_tests if t.get('body')) +print(f'Generated {total} tests -> {OUTPUT}') +print(f' Source: {len(raw_tests)} tests ({len(raw_tests) - has_body} Chai-style, {has_body} Playwright-style)') +print(f' Categories: {len(categories)}') +for cat, (gen, stub) in generated_counts.items(): + marker = '' if stub == 0 else f' ({stub} stubs)' + print(f' {cat}: {gen}{marker}') diff --git a/tests/playwright/hs-behavioral.spec.js b/tests/playwright/hs-behavioral.spec.js index 1008ce1e..b629086d 100644 --- a/tests/playwright/hs-behavioral.spec.js +++ b/tests/playwright/hs-behavioral.spec.js @@ -38,7 +38,7 @@ function getModuleSrc(mod) { } // Cache test file sources -const TEST_FILES = ['spec/harness.sx', 'spec/tests/test-framework.sx', 'spec/tests/test-hyperscript-behavioral.sx']; +const TEST_FILES = ['spec/harness.sx', 'spec/tests/test-framework.sx', 'spec/tests/test-hyperscript-behavioral.sx', 'spec/tests/test-hyperscript-conformance-dev.sx']; const TEST_FILE_CACHE = {}; for (const f of TEST_FILES) { TEST_FILE_CACHE[f] = fs.readFileSync(path.join(PROJECT_ROOT, f), 'utf8'); @@ -111,7 +111,7 @@ async function bootSandbox(page) { } await page.evaluate(() => { if (window.SxKernel.endModuleLoad) window.SxKernel.endModuleLoad(); }); - // Deferred test registration + // Deferred test registration + helpers await page.evaluate(() => { const K = window.SxKernel; K.eval('(define _test-registry (list))'); @@ -127,6 +127,18 @@ async function bootSandbox(page) { K.eval(`(define report-fail (fn (name error) (let ((i (- (len _test-registry) 1))) (when (>= i 0) (dict-set! (nth _test-registry i) "name" name)))))`); + // eval-hs: compile and evaluate a hyperscript expression/command, return its value. + // If src contains 'return', use as-is. If it starts with a command keyword (set/put/get), + // use as-is (the last expression is the result). Otherwise wrap in 'return'. + K.eval(`(define eval-hs (fn (src) + (let ((has-cmd (or (string-contains? src "return ") + (string-contains? src "then ") + (= "set " (slice src 0 4)) + (= "put " (slice src 0 4)) + (= "get " (slice src 0 4))))) + (let ((wrapped (if has-cmd src (str "return " src)))) + (let ((sx (hs-to-sx-from-source wrapped))) + (eval-expr sx))))))`); }); for (const f of TEST_FILES) { @@ -256,19 +268,25 @@ test.describe('Hyperscript behavioral tests', () => { for (const [t, n] of Object.entries(errTypes).sort((a,b) => b[1] - a[1])) { console.log(` ${t}: ${n}`); } - // Show sample failures per type - for (const [t, n] of Object.entries(errTypes).sort((a,b) => b[1] - a[1])) { - const samples = results.filter(r => !r.p).filter(r => { - const e = r.e || ''; - if (t === 'crash') return e.includes('callFn'); - if (t === 'stub') return e.includes('NOT IMPLEMENTED'); - if (t === 'timeout') return e === 'TIMEOUT'; - return false; - }).slice(0, 3); - for (const s of samples) console.log(` ${s.s}/${s.n}: ${(s.e||'').slice(0, 120)}`); + // Show ALL crash errors (deduplicated by error message) + const uniqueErrors = {}; + for (const r of results.filter(r => !r.p)) { + const e = (r.e || '').slice(0, 100); + if (!uniqueErrors[e]) uniqueErrors[e] = { count: 0, example: r }; + uniqueErrors[e].count++; + } + console.log(` Unique error messages (${Object.keys(uniqueErrors).length}):`); + for (const [e, info] of Object.entries(uniqueErrors).sort((a,b) => b[1].count - a[1].count).slice(0, 25)) { + console.log(` [${info.count}x] ${e}`); + } + // Show samples of "bar" error specifically + const barSamples = results.filter(r => !r.p && (r.e||'').endsWith('bar') || (r.e||'').endsWith('bar ')).slice(0, 8); + if (barSamples.length > 0) { + console.log(` "bar" error samples (${barSamples.length}):`); + for (const s of barSamples) console.log(` ${s.s}/${s.n}`); } - expect(results.length).toBeGreaterThanOrEqual(830); + expect(results.length).toBeGreaterThanOrEqual(940); expect(passed).toBeGreaterThanOrEqual(420); }); });