Files
rose-ash/tests/playwright/hs-behavioral-data.js
giles 7492ceac4e Restore hyperscript work on stable site base (908f4f80)
Reset to last known-good state (908f4f80) where links, stepper, and
islands all work, then recovered all hyperscript implementation,
conformance tests, behavioral tests, Playwright specs, site sandbox,
IO-aware server loading, and upstream test suite from f271c88a.

Excludes runtime changes (VM resolve hook, VmSuspended browser handler,
sx_ref.ml guard recovery) that need careful re-integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 19:29:56 +00:00

4033 lines
114 KiB
JavaScript

// Auto-generated from _hyperscript upstream test suite
// Source: spec/tests/hyperscript-upstream-tests.json
// 256 tests (90 skipped)
//
// DO NOT EDIT — regenerate with: python3 tests/playwright/generate-hs-tests.py
module.exports = [
{
"category": "add",
"name": "can add class ref on a single div",
"html": "<div id=\"el\" _='on click add .foo'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "add",
"name": "can add class ref w/ double dash on a single div",
"html": "<div id=\"el\" _='on click add .foo--bar'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo--bar\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "add",
"name": "can add class ref on a single form",
"html": "<form id=\"el\" _='on click add .foo'></form>",
"action": "qs(\"form\").click()",
"checks": [
{
"expr": "qs(\"form\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "add",
"name": "can target another div for class ref",
"html": "<div id='bar'></div><div _='on click add .foo to #bar'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "add",
"name": "can add to query in me",
"html": "<div _='on click add .foo to <p/> in me'><p id='p1'></p></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"p1\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "add",
"name": "can add to children",
"html": "<div _='on click add .foo to my children'><p id='p1'></p></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"p1\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "add",
"name": "can add multiple class refs",
"html": "<div id=\"el\" _='on click add .foo .bar'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "add",
"name": "can add class refs w/ colons and dashes",
"html": "<div id=\"el\" _='on click add .foo:bar-doh'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo:bar-doh\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "add",
"name": "can filter class addition via the when clause",
"html": "<div id=\"el\" _='on click add .rey to .bar when it matches .doh'></div><div class='bar'></div><div class='bar doh'></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div2\").classList.contains(\"rey\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div3\").classList.contains(\"rey\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "add",
"name": "can filter property addition via the when clause",
"html": "<div id=\"el\" _='on click add @rey to .bar when it matches .doh'></div><div class='bar'></div><div class='bar doh'></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div2\").hasAttribute(\"rey\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div3\").hasAttribute(\"rey\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "add",
"name": "can add to an HTMLCollection",
"html": "<div _='on click add .foo to the children of #bar'></div><div id='bar'><div id='c1'></div><div id='c2'></div></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"c1\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"c2\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "remove",
"name": "can remove class ref on a single div",
"html": "<div id=\"el\" class='foo' _='on click remove .foo'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "remove",
"name": "can remove class ref on a single form",
"html": "<form id=\"el\" class='foo' _='on click remove .foo'></form>",
"action": "qs(\"form\").click()",
"checks": [
{
"expr": "qs(\"form\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "remove",
"name": "can target another div for class ref",
"html": "<div class='foo' id='bar'></div><div _='on click remove .foo from #bar'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "remove",
"name": "can remove elements",
"html": "<div id=\"el\" _='on click remove me'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").parentElement",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "remove",
"name": "can remove other elements",
"html": "<div _='on click remove #that'></div><div id='that'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"div2\").parentElement",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "remove",
"name": "can remove parent element",
"html": "<div id='p1'><button id='b1' _=\"on click remove my.parentElement\"></button></div> ",
"action": "btn.click()",
"checks": [
{
"expr": "qs(\"div\").parentElement",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "remove",
"name": "can remove multiple class refs",
"html": "<div id=\"el\" class='foo bar doh' _='on click remove .foo .bar'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "qs(\"div\").classList.contains(\"doh\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "remove",
"name": "can remove query refs from specific things",
"html": "<div><div id='d1' _='on click remove <p/> from me'><p>foo</p>bar</div><p>doh</p></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML.includes(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "qs(\"div\").innerHTML.includes(\"bar\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").innerHTML.includes(\"doh\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle class ref on a single div",
"html": "<div id=\"el\" _='on click toggle .foo'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle class ref on a single form",
"html": "<form id=\"el\" _='on click toggle .foo'></form>",
"action": "qs(\"form\").click(); qs(\"form\").click()",
"checks": [
{
"expr": "qs(\"form\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "toggle",
"name": "can target another div for class ref toggle",
"html": "<div id='bar'></div><div _='on click toggle .foo on #bar'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle for a fixed amount of time",
"html": "<div id=\"el\" _='on click toggle .foo for 10ms'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": true
},
{
"category": "toggle",
"name": "can toggle until an event on another element",
"html": "<div id='d1'></div><div _='on click toggle .foo until foo from #d1'></div>",
"action": "qs(\"div\").click(); byId(\"d1\").dispatchEvent(new CustomEvent(\"foo\")",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": true
},
{
"category": "toggle",
"name": "can toggle between two classes",
"html": "<div id=\"el\" class='foo' _='on click toggle between .foo and .bar'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle multiple class refs",
"html": "<div id=\"el\" class='bar' _='on click toggle .foo .bar'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle display",
"html": "<div id=\"el\" _='on click toggle *display'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"block\""
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle opacity",
"html": "<div id=\"el\" _='on click toggle *opacity'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).opacity",
"op": "==",
"expected": "\"1\""
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle opacity",
"html": "<div id=\"el\" _='on click toggle *visibility'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).visibility",
"op": "==",
"expected": "\"visible\""
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle display w/ my",
"html": "<div id=\"el\" _='on click toggle my *display'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"block\""
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle display w/ my",
"html": "<div id=\"el\" _='on click toggle my *opacity'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).opacity",
"op": "==",
"expected": "\"1\""
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle display w/ my",
"html": "<div id=\"el\" _='on click toggle my *visibility'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).visibility",
"op": "==",
"expected": "\"visible\""
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle display on other elt",
"html": "<div _='on click toggle the *display of #d2'></div><div id='d2'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(div2).display",
"op": "==",
"expected": "\"block\""
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle display on other elt",
"html": "<div _='on click toggle the *opacity of #d2'></div><div id='d2'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(div2).opacity",
"op": "==",
"expected": "\"1\""
}
],
"async": false
},
{
"category": "toggle",
"name": "can toggle display on other elt",
"html": "<div _='on click toggle the *visibility of #d2'></div><div id='d2'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(div2).visibility",
"op": "==",
"expected": "\"visible\""
}
],
"async": false
},
{
"category": "set",
"name": "can set properties",
"html": "<div id='d1' _='on click set #d1.innerHTML to \"foo\"'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set indirect properties",
"html": "<div id='d1' _='on click set innerHTML of #d1 to \"foo\"'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set complex indirect properties lhs",
"html": "<div _='on click set parentNode.innerHTML of #d1 to \"foo\"'><div id='d1'></div></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set complex indirect properties rhs",
"html": "<div _='on click set innerHTML of #d1.parentNode to \"foo\"'><div id='d1'></div></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set chained indirect properties",
"html": "<div _='on click set the innerHTML of the parentNode of #d1 to \"foo\"'><div id='d1'></div></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set styles",
"html": "<div id=\"el\" _='on click set my.style.color to \"red\"'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set javascript globals",
"html": "<div id=\"el\" _='on click set window.temp to \"red\"'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "window[\"temp\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set local variables",
"html": "<div id='d1' _='on click set newVar to \"foo\" then put newVar into #d1.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into id ref",
"html": "<div id='d1' _='on click set #d1.innerHTML to \"foo\"'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into class ref",
"html": "<div id=\"el\" class='divs' _='on click set .divs.innerHTML to \"foo\"'></div><div class='divs''></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
},
{
"expr": "byId(\"d2\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into attribute ref",
"html": "<div id=\"el\" class='divs' _='on click set @bar to \"foo\"'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"bar\")",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into indirect attribute ref",
"html": "<div class='divs' _=\"on click set #div2's @bar to 'foo'\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").getAttribute(\"bar\")",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into indirect attribute ref 2",
"html": "<div class='divs' _=\"on click set #div2's @bar to 'foo'\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").getAttribute(\"bar\")",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into indirect attribute ref 3",
"html": "<div class='divs' _=\"on click set @bar of #div2 to 'foo'\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").getAttribute(\"bar\")",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into style ref",
"html": "<div id=\"el\" class='divs' _='on click set *color to \"red\"'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style[\"color\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into indirect style ref",
"html": "<div class='divs' _=\"on click set #div2's *color to 'red'\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").style[\"color\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into indirect style ref 2",
"html": "<div class='divs' _=\"on click set #div2's *color to 'red'\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").style[\"color\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set into indirect style ref 3",
"html": "<div class='divs' _=\"on click set *color of #div2 to 'red'\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").style[\"color\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set many properties at once with object literal",
"html": "<div id=\"el\" _='on click set {bar: 2, baz: 3} on obj'></div>",
"action": "",
"checks": [
{
"expr": "obj",
"op": "deep==",
"expected": "{ foo: 1, bar: 2, baz: 3 }"
}
],
"async": false
},
{
"category": "set",
"name": "can set props w/ array access syntax",
"html": "<div id=\"el\" _='on click set my style[\"color\"] to \"red\"'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set props w/ array access syntax and var",
"html": "<div id=\"el\" _='on click set foo to \"color\" then set my style[foo] to \"red\"'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set arrays w/ array access syntax",
"html": "<div id=\"el\" _='on click set arr to [1, 2, 3] set arr[0] to \"red\" set my *color to arr[0]'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "set",
"name": "can set arrays w/ array access syntax and var",
"html": "<div id=\"el\" _='on click set arr to [1, 2, 3] set idx to 0 set arr[idx] to \"red\" set my *color to arr[0]'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can set properties",
"html": "<div id='d1' _='on click put \"foo\" into #d1.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can put directly into nodes",
"html": "<div id='d1' _='on click put \"foo\" into #d1'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").textContent",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can put nodes into nodes",
"html": "<div id='d1'></div><div id='d2' _='on click put #d1 into #d2'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d2\").firstChild",
"op": "==",
"expected": "d1"
}
],
"async": false
},
{
"category": "put",
"name": "can put directly into symbols",
"html": "<div id=\"el\" _='on click put \"foo\" into me'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "me symbol doesn't get stomped on direct write",
"html": "<div id=\"el\" _='on click put \"foo\" into me then put \"bar\" into me'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": false
},
{
"category": "put",
"name": "can set styles",
"html": "<div id=\"el\" _='on click put \"red\" into my.style.color'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can set javascript globals",
"html": "<div id=\"el\" _='on click put \"red\" into window.temp'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "window[\"temp\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into class ref w/ flatmapped property",
"html": "<div _='on click put \"foo\" into .divs.parentElement.innerHTML'></div><div id='d1'><div class='divs'></div></div><div id='d2'><div class='divs'></div></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"d1\").textContent",
"op": "==",
"expected": "\"foo\""
},
{
"expr": "byId(\"d2\").textContent",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into class ref w/ flatmapped property using of",
"html": "<div _='on click put \"foo\" into innerHTML of parentElement of .divs'></div><div id='d1'><div class='divs'></div></div><div id='d2'><div class='divs'></div></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"d1\").textContent",
"op": "==",
"expected": "\"foo\""
},
{
"expr": "byId(\"d2\").textContent",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can set local variables",
"html": "<div id='d1' _='on click put \"foo\" into newVar then put newVar into #d1.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into id ref",
"html": "<div id='d1' _='on click put \"foo\" into #d1.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can insert before",
"html": "<div id='d2' _='on click put #d1 before #d2'></div><div id='d1'>foo</div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d2\").byId(\"previousSibling\").textContent",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can insert after",
"html": "<div id='d1'>foo</div><div id='d2' _='on click put #d1 after #d2'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d2\").byId(\"nextSibling\").textContent",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can insert after beginning",
"html": "<div id='d1' _='on click put \"foo\" at start of #d1'>*</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").textContent",
"op": "==",
"expected": "\"foo*\""
}
],
"async": false
},
{
"category": "put",
"name": "can insert before end",
"html": "<div id='d1' _='on click put \"foo\" at end of #d1'>*</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").textContent",
"op": "==",
"expected": "\"*foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into attribute ref",
"html": "<div id=\"el\" class='divs' _='on click put \"foo\" into @bar'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"bar\")",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into indirect attribute ref",
"html": "<div id=\"el\" class='divs' _='on click put \"foo\" into my @bar'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"bar\")",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into indirect attribute ref 2",
"html": "<div class='divs' _=\"on click put 'foo' into #div2's @bar\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").getAttribute(\"bar\")",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into indirect attribute ref 3",
"html": "<div class='divs' _=\"on click put 'foo' into @bar of #div2\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").getAttribute(\"bar\")",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into style ref",
"html": "<div id=\"el\" class='divs' _='on click put \"red\" into *color'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style[\"color\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into indirect style ref",
"html": "<div id=\"el\" class='divs' _='on click put \"red\" into my *color'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style[\"color\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into indirect style ref 2",
"html": "<div class='divs' _=\"on click put 'red' into #div2's *color\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").style[\"color\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can set into indirect style ref 3",
"html": "<div class='divs' _=\"on click put 'red' into the *color of #div2\"></div><div id='div2'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d2\").style[\"color\"]",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can put properties w/ array access syntax",
"html": "<div id=\"el\" _='on click put \"red\" into my style[\"color\"]'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can put properties w/ array access syntax and var",
"html": "<div id=\"el\" _='on click set foo to \"color\" then put \"red\" into my style[foo]'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can put array vals w/ array access syntax",
"html": "<div id=\"el\" _='on click set arr to [1, 2, 3] put \"red\" into arr[0] put arr[0] into my *color'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "can put array vals w/ array access syntax and var",
"html": "<div id=\"el\" _='on click set arr to [1, 2, 3] set idx to 0 put \"red\" into arr[idx] put arr[0] into my *color'>lolwat</div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").style.color",
"op": "==",
"expected": "\"red\""
}
],
"async": false
},
{
"category": "put",
"name": "is null tolerant",
"html": "<div id=\"el\" class='divs' _='on click put \"red\" into #a-bad-id-that-does-not-exist'></div>",
"action": "byId(\"d1\").click()",
"checks": [],
"async": false
},
{
"category": "hide",
"name": "can hide element with no target",
"html": "<div id=\"el\" _='on click hide'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"none\""
}
],
"async": false
},
{
"category": "hide",
"name": "hide element then show element retains original display",
"html": "<div id=\"el\" _='on click 1 hide on click 2 show'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").style.display",
"op": "==",
"expected": "\"\""
},
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"block\""
}
],
"async": false
},
{
"category": "hide",
"name": "can hide element with no target followed by command",
"html": "<div id=\"el\" _='on click hide add .foo'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"none\""
},
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "hide",
"name": "can hide element with no target followed by then",
"html": "<div id=\"el\" _='on click hide then add .foo'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"none\""
},
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "hide",
"name": "can hide element with no target with a with",
"html": "<div id=\"el\" _='on click hide with display then add .foo'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"none\""
},
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "hide",
"name": "can hide element, with display:none by default",
"html": "<div id=\"el\" _='on click hide me'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"none\""
}
],
"async": false
},
{
"category": "hide",
"name": "can hide element with display:none explicitly",
"html": "<div id=\"el\" _='on click hide me with display'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).display",
"op": "==",
"expected": "\"none\""
}
],
"async": false
},
{
"category": "hide",
"name": "can hide element with opacity:0",
"html": "<div id=\"el\" _='on click hide me with opacity'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).opacity",
"op": "==",
"expected": "\"0\""
}
],
"async": false
},
{
"category": "hide",
"name": "can hide element with opacity style literal",
"html": "<div id=\"el\" _='on click hide me with *opacity'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).opacity",
"op": "==",
"expected": "\"0\""
}
],
"async": false
},
{
"category": "hide",
"name": "can hide element, with visibility:hidden",
"html": "<div id=\"el\" _='on click hide me with visibility'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(qs(\"div\")).visibility",
"op": "==",
"expected": "\"hidden\""
}
],
"async": false
},
{
"category": "hide",
"name": "can hide other elements",
"html": "<div id=\"el\" class=hideme></div><div _='on click hide .hideme'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "getComputedStyle(hideme).display",
"op": "==",
"expected": "\"none\""
}
],
"async": false
},
{
"category": "hide",
"name": "can hide with custom strategy",
"html": "<div id=\"el\" _='on click hide with myHide'></div>",
"action": "classList.remove(\"foo\"); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "hide",
"name": "can set default to custom strategy",
"html": "<div id=\"el\" _='on click hide'></div>",
"action": "classList.remove(\"foo\"); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "if",
"name": "basic true branch works",
"html": "<div id=\"el\" _='on click if true put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic true branch works with multiple commands",
"html": "<div id=\"el\" _='on click if true log me then put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic true branch works with end",
"html": "<div id=\"el\" _='on click if true put \"foo\" into me.innerHTML end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic true branch works with naked else",
"html": "<div id=\"el\" _='on click if true put \"foo\" into me.innerHTML else'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic true branch works with naked else end",
"html": "<div id=\"el\" _='on click if true put \"foo\" into me.innerHTML else end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic else branch works",
"html": "<div id=\"el\" _='on click if false else put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic else branch works with end",
"html": "<div id=\"el\" _='on click if false else put \"foo\" into me.innerHTML end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic else if branch works",
"html": "<div id=\"el\" _='on click if false else if true put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic else if branch works with end",
"html": "<div id=\"el\" _='on click if false else if true put \"foo\" into me.innerHTML end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "otherwise alias works",
"html": "<div id=\"el\" _='on click if false otherwise put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "triple else if branch works",
"html": "<div id=\"el\" _='on click if false else if false else put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "triple else if branch works with end",
"html": "<div id=\"el\" _='on click if false else if false else put \"foo\" into me.innerHTML end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "basic else branch works with multiple commands",
"html": "<div id=\"el\" _='on click if false put \"bar\" into me.innerHTML else log me then put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "true branch with a wait works",
"html": "<div id=\"el\" _='on click if true wait 10 ms then put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": true
},
{
"category": "if",
"name": "false branch with a wait works",
"html": "<div id=\"el\" _='on click if false else wait 10 ms then put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": true
},
{
"category": "if",
"name": "if properly passes execution along if child is not executed",
"html": "<div id=\"el\" _='on click if false end put \"foo\" into me.innerHTML'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "if properly supports nested if statements and end block",
"html": "<div id=\"el\" _='on click \\n if window.tmp then\\n put \"foo\" into me\\n else if not window.tmp then\\n // do nothing\\n end\\n catch e\\n // just here for the parsing...\\n'</div>",
"action": "byId(\"d1\").click(); byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "if",
"name": "if on new line does not join w/ else",
"html": "<div id=\"el\" _='on click \\n if window.tmp then\\n else\\n if window.tmp then end\\n put \"foo\" into me\\n end\\n '</div>",
"action": "byId(\"d1\").click(); byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"\""
}
],
"async": false
},
{
"category": "repeat",
"name": "basic for loop works",
"html": "<div id=\"el\" _='on click repeat for x in [1, 2, 3] put x at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"123\""
}
],
"async": false
},
{
"category": "repeat",
"name": "basic for loop with null works",
"html": "<div id=\"el\" _='on click repeat for x in null put x at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"\""
}
],
"async": false
},
{
"category": "repeat",
"name": "waiting in for loop works",
"html": "<div id=\"el\" _='on click repeat for x in [1, 2, 3]\\n log me put x at end of me\\n wait 1ms\\n end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"123\""
}
],
"async": true
},
{
"category": "repeat",
"name": "basic raw for loop works",
"html": "<div id=\"el\" _='on click for x in [1, 2, 3] put x at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"123\""
}
],
"async": false
},
{
"category": "repeat",
"name": "basic raw for loop works",
"html": "<div id=\"el\" _='on click for x in null put x at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"\""
}
],
"async": false
},
{
"category": "repeat",
"name": "waiting in raw for loop works",
"html": "<div id=\"el\" _='on click for x in [1, 2, 3]\\n put x at end of me\\n wait 1ms\\n end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"123\""
}
],
"async": true
},
{
"category": "repeat",
"name": "basic in loop works",
"html": "<div id=\"el\" _='on click repeat in [1, 2, 3] put it at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"123\""
}
],
"async": false
},
{
"category": "repeat",
"name": "index syntax works",
"html": "<div id=\"el\" _='on click repeat for x in [\"a\", \"ab\", \"abc\"] index i put x + i at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"a0ab1abc2\""
}
],
"async": false
},
{
"category": "repeat",
"name": "indexed by syntax works",
"html": "<div id=\"el\" _='on click repeat for x in [\"a\", \"ab\", \"abc\"] indexed by i put x + i at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"a0ab1abc2\""
}
],
"async": false
},
{
"category": "repeat",
"name": "basic times loop works",
"html": "<div id=\"el\" _='on click repeat 3 times put \"a\" at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"aaa\""
}
],
"async": false
},
{
"category": "repeat",
"name": "times loop with expression works",
"html": "<div id=\"el\" _='on click repeat 3 + 3 times put \"a\" at end of me end'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"aaaaaa\""
}
],
"async": false
},
{
"category": "repeat",
"name": "loop continue works",
"html": "<div id=\"el\" _=\"on click\n\t\t\t\trepeat 2 times\n\t\t\t\t\tfor x in ['A', 'B', 'C', 'D']\n\t\t\t\t\t\tif (x != 'D') then\n\t\t\t\t\t\t\tput 'success ' + x + '. ' at end of me\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\tput 'FAIL!!. ' at end of me\n\t\t\t\t\t\tend\n\t\t\t\t\t\tput 'expected D. ' at end of me\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\"></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"success A. success B. success C. expected D. success A. success B. success C. expected D. \""
}
],
"async": false
},
{
"category": "repeat",
"name": "loop break works",
"html": "<div id=\"el\" _=\"on click\n\t\t\t\trepeat 2 times\n\t\t\t\t\tfor x in ['A', 'B', 'C', 'D']\n\t\t\t\t\t\tif x is 'C'\n\t\t\t\t\t\t break\n\t\t\t\t\t\tend\n\t\t\t\t\t\tput x at end of me\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\"></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerHTML",
"op": "==",
"expected": "\"ABAB\""
}
],
"async": false
},
{
"category": "wait",
"name": "can wait on time",
"html": "<div id=\"el\" _='on click add .foo then wait 20ms then add .bar'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": true
},
{
"category": "wait",
"name": "can wait on event",
"html": "<div id=\"el\" _='on click add .foo then wait for foo then add .bar'></div>",
"action": "qs(\"div\").click(); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\")",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": true
},
{
"category": "wait",
"name": "waiting on an event sets 'it' to the event",
"html": "<div id=\"el\" _='on click wait for foo then put its.detail into me'></div>",
"action": "qs(\"div\").click(); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\", { detail: \"hyperscript is hyper cool\" })",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"hyperscript is hyper cool\""
}
],
"async": true
},
{
"category": "wait",
"name": "can destructure properties in a wait",
"html": "<div id=\"el\" _='on click wait for foo(bar) then put bar into me'></div>",
"action": "qs(\"div\").click(); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\", { detail: { bar: \"bar\" } })",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": true
},
{
"category": "wait",
"name": "can wait on event on another element",
"html": "<div id='d2'></div><div _='on click add .foo then wait for foo from #d2 then add .bar'></div>",
"action": "qs(\"div\").click(); byId(\"div2\") && byId(\"div2\").dispatchEvent(new CustomEvent(\"foo\")",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": true
},
{
"category": "wait",
"name": "can wait on event or timeout 1",
"html": "<div id='d2'></div><div _='on click add .foo then wait for foo or 0ms then add .bar'></div>",
"action": "qs(\"div\").click(); byId(\"div2\") && byId(\"div2\").dispatchEvent(new CustomEvent(\"foo\")",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": true
},
{
"category": "wait",
"name": "can wait on event or timeout 2",
"html": "<div id='d2'></div><div _='on click add .foo then wait for foo or 0ms then add .bar'></div>",
"action": "qs(\"div\").click(); byId(\"div2\") && byId(\"div2\").dispatchEvent(new CustomEvent(\"foo\")",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "qs(\"div\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": true
},
{
"category": "send",
"name": "can send events",
"html": "<div _='on click send foo to #bar'></div><div id='bar' _='on foo add .foo-sent'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo-sent\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "send",
"name": "can reference sender in events",
"html": "<div _='on click log 0 send foo to #bar log 3'></div><div id='bar' _='on foo add .foo-sent to sender log 1, me, sender'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"foo-sent\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "send",
"name": "can send events with args",
"html": "<div _='on click send foo(x:42) to #bar'></div><div id='bar' _='on foo put event.detail.x into my.innerHTML'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo-sent\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"bar\").innerHTML",
"op": "==",
"expected": "\"42\""
}
],
"async": false
},
{
"category": "send",
"name": "can send events with dots",
"html": "<div _='on click send foo.bar to #bar'></div><div id='bar' _='on foo.bar add .foo-sent'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo-sent\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "send",
"name": "can send events with dots with args",
"html": "<div _='on click send foo.bar(x:42) to #bar'></div><div id='bar' _='on foo.bar put event.detail.x into my.innerHTML'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo-sent\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"bar\").innerHTML",
"op": "==",
"expected": "\"42\""
}
],
"async": false
},
{
"category": "send",
"name": "can send events with colons",
"html": "<div _='on click send foo:bar to #bar'></div><div id='bar' _='on foo:bar add .foo-sent'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo-sent\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "send",
"name": "can send events with colons with args",
"html": "<div _='on click send foo:bar(x:42) to #bar'></div><div id='bar' _='on foo:bar put event.detail.x into my.innerHTML'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo-sent\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"bar\").innerHTML",
"op": "==",
"expected": "\"42\""
}
],
"async": false
},
{
"category": "send",
"name": "can send events to any expression",
"html": "<div _='def bar return #bar on click send foo to bar()'></div><div id='bar' _='on foo add .foo-sent'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"bar\").classList.contains(\"foo-sent\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "take",
"name": "can take a class from other elements",
"html": "<div id=\"el\" class='div foo'></div><div class='div' _='on click take .foo from .div'></div><div class='div'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d2\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"d3\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "take",
"name": "can take a class from other forms",
"html": "<form id=\"el\" class='div foo'></form><form class='div' _='on click take .foo from .div'></form><form class='div'></form>",
"action": "byId(\"f2\").click()",
"checks": [
{
"expr": "byId(\"f1\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"f2\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"f3\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "take",
"name": "can take a class for other elements",
"html": "<div class='div foo'></div><div class='div' _='on click take .foo from .div for #d3'></div><div id='d3' class='div'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d2\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d3\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "take",
"name": "a parent can take a class for other elements",
"html": "<div _='on click take .foo from .div for event.target'><div id='d1' class='div foo'></div><div id='d2' class='div'></div><div id='d3' class='div'></div></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d2\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"d3\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "take",
"name": "can take an attribute from other elements",
"html": "<div id=\"el\" class='div' data-foo='bar'></div><div class='div' _='on click take @data-foo from .div'></div><div class='div'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"bar\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "take",
"name": "can take an attribute with specific value from other elements",
"html": "<div id=\"el\" class='div' data-foo='bar'></div><div class='div' _='on click take @data-foo=baz from .div'></div><div class='div'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"bar\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"baz\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "take",
"name": "can take an attribute value from other elements and set specific values instead",
"html": "<div id=\"el\" class='div' data-foo='bar'></div><div class='div' _='on click take @data-foo=baz with \"qux\" from .div'></div><div class='div'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"qux\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"baz\""
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"qux\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "take",
"name": "can take an attribute value from other elements and set value from an expression instead",
"html": "<div id=\"el\" class='div' data-foo='bar'></div><div class='div' data-foo='qux' _='on click take @data-foo=baz with my @data-foo from .div'></div><div class='div'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"qux\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"baz\""
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"qux\""
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "take",
"name": "can take an attribute for other elements",
"html": "<div class='div' data-foo='bar'></div><div class='div' _='on click take @data-foo from .div for #d3'></div><div id='d3' class='div'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"bar\""
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "take",
"name": "a parent can take an attribute for other elements",
"html": "<div _='on click take @data-foo from .div for event.target'><div id='d1' class='div' data-foo='bar'></div><div id='d2' class='div'></div><div id='d3' class='div'></div></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"bar\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\")",
"op": "==",
"expected": "\"\""
},
{
"expr": "byId(\"d2\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d3\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
},
{
"expr": "byId(\"d1\").getAttribute(\"data-foo\"",
"op": "==",
"expected": "null"
}
],
"async": false
},
{
"category": "take",
"name": "can take multiple classes from other elements",
"html": "<div id=\"el\" class='div foo'></div><div class='div' _='on click take .foo .bar'></div><div class='div bar'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d2\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"d3\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d1\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d2\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"d3\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "take",
"name": "can take multiple classes from specific element",
"html": "<div id=\"el\" class='div1 foo bar'></div><div class='div' _='on click take .foo .bar from .div1'></div><div class='div bar'></div>",
"action": "byId(\"d2\").click()",
"checks": [
{
"expr": "byId(\"d1\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d2\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"d3\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d1\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"d2\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"d3\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "log",
"name": "can log single item",
"html": "<div id=\"el\" _='on click log me'></div>",
"action": "byId(\"d1\").click()",
"checks": [],
"async": false
},
{
"category": "log",
"name": "can log multiple items",
"html": "<div id=\"el\" _='on click log me, my'></div>",
"action": "byId(\"d1\").click()",
"checks": [],
"async": false
},
{
"category": "log",
"name": "can log multiple items with debug",
"html": "<div id=\"el\" _='on click log me, my with console.debug'></div>",
"action": "byId(\"d1\").click()",
"checks": [],
"async": false
},
{
"category": "log",
"name": "can log multiple items with error",
"html": "<div id=\"el\" _='on click log me, my with console.error'></div>",
"action": "byId(\"d1\").click()",
"checks": [],
"async": false
},
{
"category": "call",
"name": "can call javascript instance functions",
"html": "<div id='d1' _='on click call document.getElementById(\"d1\") then put it into window.results'></div>",
"action": "byId(\"d1\").click()",
"checks": [
{
"expr": "value",
"op": "==",
"expected": "d1"
}
],
"async": false
},
{
"category": "call",
"name": "can call global javascript functions",
"html": "<div id=\"el\" _='on click call globalFunction(\"foo\")'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "\"foo\"",
"op": "==",
"expected": "calledWith"
}
],
"async": false
},
{
"category": "call",
"name": "can call no argument functions",
"html": "<div id=\"el\" _='on click call globalFunction()'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "called",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "call",
"name": "can call functions w/ underscores",
"html": "<div id=\"el\" _='on click call global_function()'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "called",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "call",
"name": "can call functions w/ dollar signs",
"html": "<div id=\"el\" _='on click call $()'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "called",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "increment",
"name": "can increment an empty variable",
"html": "<div id=\"el\" _=\"on click increment value then put value into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"1\""
}
],
"async": false
},
{
"category": "increment",
"name": "can increment a variable",
"html": "<div id=\"el\" _=\"on click set value to 20 then increment value by 2 then put value into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"22\""
}
],
"async": false
},
{
"category": "increment",
"name": "can increment refer to result",
"html": "<div id=\"el\" _=\"on click increment value by 2 then put it into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"2\""
}
],
"async": false
},
{
"category": "increment",
"name": "can increment an attribute",
"html": "<div id=\"el\" value=\"5\" _=\"on click increment @value then put @value into me\"></div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"8\""
}
],
"async": false
},
{
"category": "increment",
"name": "can increment an floating point numbers",
"html": "<div id=\"el\" value=\"5\" _=\"on click set value to 5.2 then increment value by 6.1 then put value into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"11.3\""
}
],
"async": false
},
{
"category": "increment",
"name": "can increment a property",
"html": "<div id=\"el\" _=\"on click increment my.innerHTML\">3</div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"6\""
}
],
"async": false
},
{
"category": "increment",
"name": "can increment by zero",
"html": "<div id=\"el\" _=\"on click set value to 20 then increment value by 0 then put value into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"20\""
}
],
"async": false
},
{
"category": "increment",
"name": "can increment a value multiple times",
"html": "<div id=\"el\" _=\"on click increment my.innerHTML\"></div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"5\""
}
],
"async": false
},
{
"category": "increment",
"name": "can decrement an empty variable",
"html": "<div id=\"el\" _=\"on click decrement value then put value into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"-1\""
}
],
"async": false
},
{
"category": "increment",
"name": "can decrement a variable",
"html": "<div id=\"el\" _=\"on click set value to 20 then decrement value by 2 then put value into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"18\""
}
],
"async": false
},
{
"category": "increment",
"name": "can decrement an attribute",
"html": "<div id=\"el\" value=\"5\" _=\"on click decrement @value then put @value into me\"></div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"2\""
}
],
"async": false
},
{
"category": "increment",
"name": "can decrement an floating point numbers",
"html": "<div id=\"el\" value=\"5\" _=\"on click set value to 6.1 then decrement value by 5.1 then put value into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"1\""
}
],
"async": false
},
{
"category": "increment",
"name": "can decrement a property",
"html": "<div id=\"el\" _=\"on click decrement my.innerHTML\">3</div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"0\""
}
],
"async": false
},
{
"category": "increment",
"name": "can decrement a value multiple times",
"html": "<div id=\"el\" _=\"on click decrement my.innerHTML\"></div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"-5\""
}
],
"async": false
},
{
"category": "increment",
"name": "can decrement by zero",
"html": "<div id=\"el\" _=\"on click set value to 20 then decrement value by 0 then put value into me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"20\""
}
],
"async": false
},
{
"category": "append",
"name": "can append a string to another string",
"html": "<div id=\"el\" _=\"on click\n set value to 'Hello there.' then\n append ' General Kenobi.' to value then\n set my.innerHTML to value\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Hello there. General Kenobi.\""
}
],
"async": false
},
{
"category": "append",
"name": "can append a value to a DOM node",
"html": "<div id=\"el\" _=\"on click\n append '<span>This is my inner HTML</span>' to me\n append '<b>With Tags</b>' to me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"<span>This is my inner HTML</span><b>With Tags</b>\""
}
],
"async": false
},
{
"category": "append",
"name": "can append a value to a DOM element",
"html": "<div id=\"content\" _=\"on click\n append 'Content' to #content\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Content\""
}
],
"async": false
},
{
"category": "append",
"name": "can append a value to I",
"html": "<div id=\"el\" _=\"on click \n append 'Content' to I\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Content\""
}
],
"async": false
},
{
"category": "append",
"name": "can append a value to an object property",
"html": "<div id=\"id\" _=\"on click append '_new' to my id\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").id",
"op": "==",
"expected": "\"id_new\""
}
],
"async": false
},
{
"category": "append",
"name": "multiple appends work",
"html": "<div id=\"id\" _=\"on click get 'foo' then append 'bar' then append 'doh' then append it to me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"foobardoh\""
}
],
"async": false
},
{
"category": "append",
"name": "append to undefined ignores the undefined",
"html": "<div id=\"id\" _=\"on click append 'bar' then append it to me\"></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": false
},
{
"category": "append",
"name": "append preserves existing content rather than overwriting it",
"html": "<div _=\"on click append '<a>New Content</a>' to me\"><button id=\"btn1\">Click Me</button></div>",
"action": "btn.click(); qs(\"div\").click(); btn.click()",
"checks": [
{
"expr": "clicks",
"op": "==",
"expected": "1"
},
{
"expr": "btn.parentNode",
"op": "==",
"expected": "div"
}
],
"async": false
},
{
"category": "append",
"name": "new content added by append will be live",
"html": "<div _=\"on click append \\`<button id='b1' _='on click increment window.temp'>Test</button>\\` to me\"></div>",
"action": "qs(\"div\").click(); btn.click()",
"checks": [
{
"expr": "window.temp",
"op": "==",
"expected": "1"
}
],
"async": false
},
{
"category": "tell",
"name": "establishes a proper beingTold symbol",
"html": "<div id='d1' _='on click add .foo tell #d2 add .bar'></div><div id='d2'></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div1\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"div2\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"div2\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "tell",
"name": "does not overwrite the me symbol",
"html": "<div id='d1' _='on click add .foo tell #d2 add .bar to me'></div><div id='d2'></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"div1\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"div2\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div2\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "tell",
"name": "works with an array",
"html": "<div id='d1' _='on click add .foo tell <p/> in me add .bar'><p id='p1'></p><p id='p2'></p><div id='d2'></div></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div1\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"div2\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div2\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"p1\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"p1\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"p2\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"p2\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "tell",
"name": "restores a proper implicit me symbol",
"html": "<div id='d1' _='on click tell #d2 add .bar end add .foo'></div><div id='d2'></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div1\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"div2\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"div2\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "tell",
"name": "ignores null",
"html": "<div id='d1' _='on click tell null add .bar end add .foo'></div><div id='d2'></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div1\").classList.contains(\"foo\")",
"op": "==",
"expected": "true"
},
{
"expr": "byId(\"div2\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div2\").classList.contains(\"foo\")",
"op": "==",
"expected": "false"
}
],
"async": false
},
{
"category": "tell",
"name": "you symbol represents the thing being told",
"html": "<div id='d1' _='on click tell #d2 add .bar to you'></div><div id='d2'></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").classList.contains(\"bar\")",
"op": "==",
"expected": "false"
},
{
"expr": "byId(\"div2\").classList.contains(\"bar\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "tell",
"name": "your symbol represents the thing being told",
"html": "<div id='d1' _='on click tell #d2 put your innerText into me'></div><div id='d2'>foo</div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").innerText",
"op": "==",
"expected": "\"foo\""
},
{
"expr": "byId(\"div2\").innerText",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "tell",
"name": "attributes refer to the thing being told",
"html": "<div id='d1' _='on click tell #d2 put @foo into me'></div><div foo='bar' id='d2'></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").innerText",
"op": "==",
"expected": "\"bar\""
},
{
"expr": "byId(\"div2\").innerText",
"op": "==",
"expected": "\"\""
}
],
"async": false
},
{
"category": "tell",
"name": "yourself attribute also works",
"html": "<div id=\"d1\" _=\"on click tell #d2 remove yourself\"><div id=\"d2\"></div></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").innerHTML",
"op": "==",
"expected": "\"\""
}
],
"async": false
},
{
"category": "tell",
"name": "tell terminates with a feature",
"html": "<div id=\"d1\" _=\"on click tell #d2 remove yourself on click tell #d3 remove yourself\"><div id=\"d2\"></div><div id=\"d3\"></div></div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "byId(\"div1\").innerHTML",
"op": "==",
"expected": "\"\""
}
],
"async": false
},
{
"category": "on",
"name": "can respond to events with dots in names",
"html": "<div _='on click send example.event to #d1'></div><div id='d1' _='on example.event add .called'></div>",
"action": "bar.click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"called\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "on",
"name": "can respond to events with colons in names",
"html": "<div _='on click send example:event to #d1'></div><div id='d1' _='on example:event add .called'></div>",
"action": "bar.click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"called\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "on",
"name": "can respond to events with minus in names",
"html": "<div _='on click send \"a-b\" to #d1'></div><div id='d1' _='on \"a-b\" add .called'></div>",
"action": "bar.click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"called\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "on",
"name": "can respond to events on other elements",
"html": "<div id='bar'></div><div _='on click from #bar add .clicked'></div>",
"action": "bar.click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"clicked\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "on",
"name": "listeners on other elements are removed when the registering element is removed",
"html": "<div id='bar'></div><div _='on click from #bar set #bar.innerHTML to #bar.innerHTML + \"a\"'></div>",
"action": "bar.click(); bar.click()",
"checks": [
{
"expr": "byId(\"bar\").innerHTML",
"op": "==",
"expected": "\"a\""
}
],
"async": false
},
{
"category": "on",
"name": "listeners on self are not removed when the element is removed",
"html": "<div id=\"el\" _='on someCustomEvent put 1 into me'></div>",
"action": "qs(\"div\").remove(); qs(\"div\").dispatchEvent(new Event(\"someCustomEvent\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"1\""
}
],
"async": false
},
{
"category": "on",
"name": "supports \"elsewhere\" modifier",
"html": "<div id=\"el\" _='on click elsewhere add .clicked'></div>",
"action": "qs(\"div\").click(); body.click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"clicked\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "on",
"name": "supports \"from elsewhere\" modifier",
"html": "<div id=\"el\" _='on click from elsewhere add .clicked'></div>",
"action": "qs(\"div\").click(); body.click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"clicked\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "on",
"name": "can pick detail fields out by name",
"html": "<div id='d1' _='on click send custom(foo:\"fromBar\") to #d2'></div><div id='d2' _='on custom(foo) call me.classList.add(foo)'></div>",
"action": "bar.click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"fromBar\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "on",
"name": "can pick event properties out by name",
"html": "<div id='d1' _='on click send fromBar to #d2'></div><div id='d2' _='on fromBar(type) call me.classList.add(type)'></div>",
"action": "bar.click()",
"checks": [
{
"expr": "qs(\"div\").classList.contains(\"fromBar\")",
"op": "==",
"expected": "true"
}
],
"async": false
},
{
"category": "on",
"name": "can fire an event on load",
"html": "<div id='d1' _='on load put \"Loaded\" into my.innerHTML'></div>",
"action": "",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"Loaded\""
}
],
"async": true
},
{
"category": "on",
"name": "can have a simple event filter",
"html": "<div id='d1' _='on click[false] log event then put \"Clicked\" into my.innerHTML'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "byId(\"d1\").innerText",
"op": "==",
"expected": "\"\""
}
],
"async": false
},
{
"category": "on",
"name": "can refer to event properties directly in filter",
"html": "<div id=\"el\" _='on click[buttons==0] log event then put \"Clicked\" into my.innerHTML'></div><div _='on click[buttons==1] log event then put \"Clicked\" into my.innerHTML'></div><div _='on click[buttons==1 and buttons==0] log event then put \"Clicked\" into my.innerHTML'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"\""
}
],
"async": false
},
{
"category": "on",
"name": "can refer to event detail properties directly in filter",
"html": "<div id=\"el\" _='on example[foo] increment @count then put it into me'></div>",
"action": "qs(\"div\").dispatchEvent(event); qs(\"div\").dispatchEvent(event); qs(\"div\").dispatchEvent(event)",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"2\""
}
],
"async": false
},
{
"category": "on",
"name": "can click after a positive event filter",
"html": "<div id=\"el\" _='on foo(bar)[bar] put \"triggered\" into my.innerHTML'></div>",
"action": "qs(\"div\").dispatchEvent(new CustomEvent(\"foo\", { detail: { bar: false } }); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\", { detail: { bar: true } })",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"triggered\""
}
],
"async": false
},
{
"category": "on",
"name": "multiple event handlers at a time are allowed to execute with the every keyword",
"html": "<div id=\"el\" _='on every click put increment() into my.innerHTML then wait for a customEvent'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"3\""
}
],
"async": false
},
{
"category": "on",
"name": "can have multiple event handlers",
"html": "<div id=\"el\" _='on foo put increment() into my.innerHTML end on bar put increment() into my.innerHTML'></div>",
"action": "qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\")",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"3\""
}
],
"async": false
},
{
"category": "on",
"name": "can have multiple event handlers, no end",
"html": "<div id=\"el\" _='on foo put increment() into my.innerHTML on bar put increment() into my.innerHTML'></div>",
"action": "qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\")",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"3\""
}
],
"async": false
},
{
"category": "on",
"name": "can queue events",
"html": "<div id=\"el\" _='on foo wait for bar then call increment()'></div>",
"action": "qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\")",
"checks": [
{
"expr": "i",
"op": "==",
"expected": "2"
}
],
"async": true
},
{
"category": "on",
"name": "can queue first event",
"html": "<div id=\"el\" _='on foo queue first wait for bar then call increment()'></div>",
"action": "qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\")",
"checks": [
{
"expr": "i",
"op": "==",
"expected": "2"
}
],
"async": true
},
{
"category": "on",
"name": "can queue last event",
"html": "<div id=\"el\" _='on foo queue last wait for bar then call increment()'></div>",
"action": "qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\")",
"checks": [
{
"expr": "i",
"op": "==",
"expected": "2"
}
],
"async": true
},
{
"category": "on",
"name": "can queue all events",
"html": "<div id=\"el\" _='on foo queue all wait for bar then call increment()'></div>",
"action": "qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\"); qs(\"div\").dispatchEvent(new CustomEvent(\"bar\")",
"checks": [
{
"expr": "i",
"op": "==",
"expected": "3"
}
],
"async": true
},
{
"category": "on",
"name": "queue none does not allow future queued events",
"html": "<div id=\"el\" _='on click queue none put increment() into my.innerHTML then wait for a customEvent'></div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").dispatchEvent(new CustomEvent(\"customEvent\"); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"2\""
}
],
"async": true
},
{
"category": "on",
"name": "can invoke on multiple events",
"html": "<div id=\"el\" _='on click or foo call increment()'></div>",
"action": "qs(\"div\").click(); qs(\"div\").dispatchEvent(new CustomEvent(\"foo\")",
"checks": [
{
"expr": "i",
"op": "==",
"expected": "2"
}
],
"async": false
},
{
"category": "on",
"name": "can listen for events in another element (lazy)",
"html": "<div _='on click in #d1 put it into window.tmp'> <div id='d1'></div> <div id='d2'></div> </div>",
"action": "byId(\"div1\") && byId(\"div1\").click()",
"checks": [
{
"expr": "div1",
"op": "==",
"expected": "window.tmp"
}
],
"async": false
},
{
"category": "on",
"name": "can mix ranges",
"html": "<div id=\"el\" _='on click 1 put \"one\" into my.innerHTML on click 3 put \"three\" into my.innerHTML on click 2 put \"two\" into my.innerHTML '>0</div>",
"action": "qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click(); qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"three\""
}
],
"async": false
},
{
"category": "on",
"name": "can listen for general mutations",
"html": "<div id=\"el\" _='on mutation put \"Mutated\" into me then wait for hyperscript:mutation'></div>",
"action": "qs(\"div\").setAttribute(\"foo\", \"bar\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Mutated\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for attribute mutations",
"html": "<div id=\"el\" _='on mutation of attributes put \"Mutated\" into me'></div>",
"action": "qs(\"div\").setAttribute(\"foo\", \"bar\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Mutated\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for specific attribute mutations",
"html": "<div id=\"el\" _='on mutation of @foo put \"Mutated\" into me'></div>",
"action": "qs(\"div\").setAttribute(\"foo\", \"bar\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Mutated\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for specific attribute mutations and filter out other attribute mutations",
"html": "<div id=\"el\" _='on mutation of @bar put \"Mutated\" into me'></div>",
"action": "qs(\"div\").setAttribute(\"foo\", \"bar\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for childList mutations",
"html": "<div id=\"el\" _='on mutation of childList put \"Mutated\" into me then wait for hyperscript:mutation'></div>",
"action": "qs(\"div\").appendChild(document.createElement(\"P\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Mutated\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for childList mutation filter out other mutations",
"html": "<div id=\"el\" _='on mutation of childList put \"Mutated\" into me'></div>",
"action": "qs(\"div\").setAttribute(\"foo\", \"bar\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for characterData mutation filter out other mutations",
"html": "<div id=\"el\" _='on mutation of characterData put \"Mutated\" into me'></div>",
"action": "qs(\"div\").setAttribute(\"foo\", \"bar\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for multiple mutations",
"html": "<div id=\"el\" _='on mutation of @foo or @bar put \"Mutated\" into me'></div>",
"action": "qs(\"div\").setAttribute(\"foo\", \"bar\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Mutated\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for multiple mutations 2",
"html": "<div id=\"el\" _='on mutation of @foo or @bar put \"Mutated\" into me'></div>",
"action": "qs(\"div\").setAttribute(\"bar\", \"bar\")",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"Mutated\""
}
],
"async": true
},
{
"category": "on",
"name": "can listen for attribute mutations on other elements",
"html": "<div id='d1'></div><div _='on mutation of attributes from #d1 put \"Mutated\" into me'></div>",
"action": "byId(\"div1\") && byId(\"div1\").setAttribute(\"foo\", \"bar\")",
"checks": [
{
"expr": "byId(\"div2\").innerHTML",
"op": "==",
"expected": "\"Mutated\""
}
],
"async": true
},
{
"category": "on",
"name": "can catch exceptions thrown in js functions",
"html": "<button id=\"el\" _='on click throwBar() catch e put e into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": false
},
{
"category": "on",
"name": "can catch top-level exceptions",
"html": "<button id=\"el\" _='on click throw \"bar\" catch e put e into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": false
},
{
"category": "on",
"name": "can catch async top-level exceptions",
"html": "<button id=\"el\" _='on click wait 1ms then throw \"bar\" catch e put e into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": true
},
{
"category": "on",
"name": "async exceptions don't kill the event queue",
"html": "<button id=\"el\" _='on click increment :x if :x is 1 wait 1ms then throw \"bar\" otherwise put \"success\" into me end catch e put e into me'></button>",
"action": "btn.click(); btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"success\""
}
],
"async": true
},
{
"category": "on",
"name": "exceptions in catch block don't kill the event queue",
"html": "<button id=\"el\" _='on click increment :x if :x is 1 throw \"bar\" otherwise put \"success\" into me end catch e put e into me then throw e'></button>",
"action": "btn.click(); btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"success\""
}
],
"async": false
},
{
"category": "on",
"name": "uncaught exceptions trigger 'exception' event",
"html": "<button id=\"el\" _='on click put \"foo\" into me then throw \"bar\" on exception(error) put error into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": false
},
{
"category": "on",
"name": "caught exceptions do not trigger 'exception' event",
"html": "<button id=\"el\" _='on click put \"foo\" into me then throw \"bar\" catch e log e on exception(error) put error into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"foo\""
}
],
"async": false
},
{
"category": "on",
"name": "rethrown exceptions trigger 'exception' event",
"html": "<button id=\"el\" _='on click put \"foo\" into me then throw \"bar\" catch e throw e on exception(error) put error into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": false
},
{
"category": "on",
"name": "basic finally blocks work",
"html": "<button id=\"el\" _='on click throw \"bar\" finally put \"bar\" into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": false
},
{
"category": "on",
"name": "finally blocks work when exception thrown in catch",
"html": "<button id=\"el\" _='on click throw \"bar\" catch e throw e finally put \"bar\" into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": false
},
{
"category": "on",
"name": "async basic finally blocks work",
"html": "<button id=\"el\" _='on click wait a tick then throw \"bar\" finally put \"bar\" into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"bar\""
}
],
"async": true
},
{
"category": "on",
"name": "async finally blocks work when exception thrown in catch",
"html": "<button id=\"el\" _='on click wait a tick then throw \"bar\" catch e set :foo to \"foo\" then throw e finally put :foo + \"bar\" into me'></button>",
"action": "btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"foobar\""
}
],
"async": true
},
{
"category": "on",
"name": "async exceptions in finally block don't kill the event queue",
"html": "<button id=\"el\" _='on click increment :x finally if :x is 1 wait 1ms then throw \"bar\" otherwise put \"success\" into me end '></button>",
"action": "btn.click(); btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"success\""
}
],
"async": true
},
{
"category": "on",
"name": "exceptions in finally block don't kill the event queue",
"html": "<button id=\"el\" _='on click increment :x finally if :x is 1 throw \"bar\" otherwise put \"success\" into me end '></button>",
"action": "btn.click(); btn.click()",
"checks": [
{
"expr": "byId(\"btn\").innerHTML",
"op": "==",
"expected": "\"success\""
}
],
"async": false
},
{
"category": "on",
"name": "can ignore when target doesn't exist",
"html": "<div id='#d1' _=' \ton click from #doesntExist \t\tthrow \"bar\" \ton click \t\tput \"clicked\" into me\t'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"clicked\""
}
],
"async": false
},
{
"category": "on",
"name": "can handle an or after a from clause",
"html": "<div id='d1'></div><div id='d2'></div><div _=' \ton click from #d1 or click from #d2 \t\t increment @count then put @count into me\t'></div>",
"action": "byId(\"d1\").click(); byId(\"d2\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"2\""
}
],
"async": false
},
{
"category": "init",
"name": "can define an init block inline",
"html": "<div id=\"el\" _='init set my.foo to 42 end on click put my.foo into my.innerHTML'></div>",
"action": "qs(\"div\").click()",
"checks": [
{
"expr": "qs(\"div\").innerHTML",
"op": "==",
"expected": "\"42\""
}
],
"async": true
},
{
"category": "def",
"name": "can install a function on an element and use in children w/ no leak",
"html": "<div _='def func() put 42 into #d3'><div id='d1' _='on click call func()'></div><div id='d2'></div><div id='d3'></div> </div>",
"action": "",
"checks": [
{
"expr": "byId(\"d3\").innerText",
"op": "==",
"expected": "\"42\""
}
],
"async": false
},
{
"category": "def",
"name": "can install a function on an element and use in children w/ return value",
"html": "<div _='def func() return 42'><div id='d1' _='on click put func() into me'></div><div id='d2'></div><div id='d3'></div> </div>",
"action": "",
"checks": [
{
"expr": "byId(\"d1\").innerText",
"op": "==",
"expected": "\"42\""
}
],
"async": false
},
{
"category": "def",
"name": "can install a function on an element and use me symbol correctly",
"html": "<div _='def func() put 42 into me'><div id='d1' _='on click call func()'></div><div id='d2'></div><div id='d3'></div> </div>",
"action": "",
"checks": [
{
"expr": "qs(\"div\").innerText",
"op": "==",
"expected": "\"42\""
}
],
"async": false
}
];