- Fix host-set → host-set! in emit-inc/emit-dec (increment/decrement properties) - Implement empty/clear command: parser dispatch, compiler, polymorphic runtime - Implement swap command: parser dispatch, compiler (let+do temp swap pattern) - Add parse-compound-event-name: joins dot/colon tokens (example.event, htmx:load) - Add hs-compile to source parser (was only in WASM deploy copy) - Add clear/swap to tokenizer keywords and cmd-kw? list - Generator: fix run() with extra args, String.raw support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5009 lines
155 KiB
JavaScript
5009 lines
155 KiB
JavaScript
// Auto-generated from _hyperscript upstream test suite
|
|
// Source: spec/tests/hyperscript-upstream-tests.json
|
|
// 378 tests (453 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
|
|
},
|
|
{
|
|
"category": "dialog",
|
|
"name": "show opens a dialog as modal",
|
|
"html": "<dialog id='d'><p>Hello</p></dialog><button _='on click show #d'>Open</button>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dialog",
|
|
"name": "open opens a dialog",
|
|
"html": "<dialog id='d'><p>Hello</p></dialog><button _='on click open #d'>Open</button>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dialog",
|
|
"name": "open opens a details element",
|
|
"html": "<details id='d'><summary>More</summary><p>Content</p></details><button _='on click open #d'>Open</button>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dialog",
|
|
"name": "close closes a details element",
|
|
"html": "<details id='d' open><summary>More</summary><p>Content</p></details><button _='on click close #d'>Close</button>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dialog",
|
|
"name": "open on implicit me",
|
|
"html": "<dialog id='d' _='on myOpen open'></dialog><button _='on click send myOpen to #d'>Open</button>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "can empty an element",
|
|
"html": "<div id='d1'><p>hello</p><p>world</p></div><button _='on click empty #d1'></button>",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "empty with no target empties me",
|
|
"html": "<div id=\"el\" _='on click empty'>content</div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "can empty multiple elements",
|
|
"html": "<div id=\"el\" class='clearme'><p>a</p></div><div class='clearme'><p>b</p></div><button _='on click empty .clearme'></button>",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "can empty an array",
|
|
"html": "<div id=\"el\" _=\"on click\n\t\t set :arr to [1,2,3]\n\t\t empty :arr\n\t\t put :arr.length into me\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "can empty a text input",
|
|
"html": "\n\t\t\t<input type=\"text\" id=\"t1\" value=\"hello\" />\n\t\t\t<button _=\"on click empty #t1\">Empty</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "can empty a textarea",
|
|
"html": "\n\t\t\t<textarea id=\"ta1\">some text</textarea>\n\t\t\t<button _=\"on click empty #ta1\">Empty</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "can empty a checkbox",
|
|
"html": "\n\t\t\t<input type=\"checkbox\" id=\"cb1\" checked />\n\t\t\t<button _=\"on click empty #cb1\">Empty</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "can empty a form (clears all inputs)",
|
|
"html": "\n\t\t\t<form id=\"f1\">\n\t\t\t\t<input type=\"text\" id=\"t2\" value=\"val\" />\n\t\t\t\t<textarea id=\"ta2\">text</textarea>\n\t\t\t\t<input type=\"checkbox\" id=\"cb2\" checked />\n\t\t\t</form>\n\t\t\t<button _=\"on click empty #f1\">Empty</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "clear is an alias for empty",
|
|
"html": "\n\t\t\t<input type=\"text\" id=\"t3\" value=\"hello\" />\n\t\t\t<button _=\"on click clear #t3\">Clear</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "empty",
|
|
"name": "clear works on elements",
|
|
"html": "<div id='d2'><p>content</p></div><button _='on click clear #d2'></button>",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "halt",
|
|
"name": "halts event propagation and default",
|
|
"html": "<div id='outer' _='on click add .outer-clicked'> <a id='inner' href='#shouldnot' _='on click halt'>click me</a></div>",
|
|
"action": "find('#inner').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "halt",
|
|
"name": "halt stops execution after the halt",
|
|
"html": "<div id=\"el\" _='on click halt then add .should-not-happen'>test</div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "halt",
|
|
"name": "halt the event stops propagation but continues execution",
|
|
"html": "<div id='outer' _='on click add .outer-clicked'> <div id='inner' _='on click halt the event then add .continued'>click me</div></div>",
|
|
"action": "find('#inner').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "halt",
|
|
"name": "halt the event's stops propagation but continues execution",
|
|
"html": "<div id='outer' _='on click add .outer-clicked'> <div id='inner' _=\\\"on click halt the event's then add .continued\\\">click me</div></div>",
|
|
"action": "find('#inner').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "halt",
|
|
"name": "halt bubbling only stops propagation, not default",
|
|
"html": "<div id='outer' _='on click add .outer-clicked'> <div id='inner' _='on click halt bubbling then add .continued'>click me</div></div>",
|
|
"action": "find('#inner').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "halt",
|
|
"name": "halt default only prevents default, not propagation",
|
|
"html": "<div id='outer' _='on click add .outer-clicked'> <div id='inner' _='on click halt default'>click me</div></div>",
|
|
"action": "find('#inner').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "morph",
|
|
"name": "basic morph updates content",
|
|
"html": "<div id='target'>old</div><button _='on click morph #target to \\\"<div id=target>new</div>\\\"'>go</button>",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "morph",
|
|
"name": "morph updates attributes",
|
|
"html": "<div id='target' class='old'>content</div><button _='on click morph #target to \\\"<div id=target class=new>content</div>\\\"'>go</button>",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "morph",
|
|
"name": "morph initializes hyperscript on new elements",
|
|
"html": "<div id='target'><p>old</p></div><button id='go' _=\\\"on click morph #target to '<div id=target><p id=inner _="on click put `clicked` into me">new</p></div>'\\\">go</button>",
|
|
"action": "find('#go').dispatchEvent('click'); find('#inner').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "morph",
|
|
"name": "morph with variable content",
|
|
"html": "<div id='target'>original</div><button id='go' _='on click set content to \\\"<div id=target>morphed</div>\\\" then morph #target to content'>go</button>",
|
|
"action": "find('#go').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "reset",
|
|
"name": "can reset a form",
|
|
"html": "\n\t\t\t<form id=\"f1\">\n\t\t\t\t<input type=\"text\" id=\"t1\" value=\"original\" />\n\t\t\t\t<button type=\"button\" _=\"on click set #t1's value to 'changed'\">Change</button>\n\t\t\t\t<button type=\"button\" id=\"rst\" _=\"on click reset #f1\">Reset</button>\n\t\t\t</form>\n\t\t",
|
|
"action": "find('#t1').fill('changed'); find('#rst').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "reset",
|
|
"name": "reset with no target resets me (form)",
|
|
"html": "\n\t\t\t<form _=\"on custom reset\">\n\t\t\t\t<input type=\"text\" id=\"t2\" value=\"default\" />\n\t\t\t</form>\n\t\t",
|
|
"action": "find('#t2').fill('modified'); find('form').dispatchEvent('custom')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "reset",
|
|
"name": "can reset a text input to defaultValue",
|
|
"html": "\n\t\t\t<input type=\"text\" id=\"t3\" value=\"hello\" />\n\t\t\t<button _=\"on click reset #t3\">Reset</button>\n\t\t",
|
|
"action": "find('#t3').fill('goodbye'); find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "reset",
|
|
"name": "can reset a checkbox",
|
|
"html": "\n\t\t\t<input type=\"checkbox\" id=\"cb1\" checked />\n\t\t\t<button _=\"on click reset #cb1\">Reset</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "reset",
|
|
"name": "can reset an unchecked checkbox",
|
|
"html": "\n\t\t\t<input type=\"checkbox\" id=\"cb2\" />\n\t\t\t<button _=\"on click reset #cb2\">Reset</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "reset",
|
|
"name": "can reset a textarea",
|
|
"html": "\n\t\t\t<textarea id=\"ta1\">original text</textarea>\n\t\t\t<button _=\"on click reset #ta1\">Reset</button>\n\t\t",
|
|
"action": "find('#ta1').fill('new text'); find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "reset",
|
|
"name": "can reset a select",
|
|
"html": "\n\t\t\t<select id=\"sel1\">\n\t\t\t\t<option value=\"a\">A</option>\n\t\t\t\t<option value=\"b\" selected>B</option>\n\t\t\t\t<option value=\"c\">C</option>\n\t\t\t</select>\n\t\t\t<button _=\"on click reset #sel1\">Reset</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "reset",
|
|
"name": "can reset multiple inputs",
|
|
"html": "\n\t\t\t<input type=\"text\" class=\"resettable\" value=\"one\" />\n\t\t\t<input type=\"text\" class=\"resettable\" value=\"two\" />\n\t\t\t<button _=\"on click reset .resettable\">Reset</button>\n\t\t",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "swap",
|
|
"name": "can swap two variables",
|
|
"html": "<div id='d1' _='on click set x to \"a\" then set y to \"b\" then swap x with y then put x + y into me'></div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "swap",
|
|
"name": "can swap two properties",
|
|
"html": "<div id='d1' _='on click set #a.textContent to \"hello\" then set #b.textContent to \"world\" then swap #a.textContent with #b.textContent'></div>\n\t\t\t<span id='a'>x</span><span id='b'>y</span>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "swap",
|
|
"name": "can swap a variable with a property",
|
|
"html": "<div id='d1' _='on click set x to \"old\" then set #target.dataset.val to \"new\" then swap x with #target.dataset.val then put x into me'></div>\n\t\t\t<span id='target' data-val='x'></span>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "bind",
|
|
"name": "attribute bound to another element input value",
|
|
"html": "<input type=\"text\" id=\"title-input\" value=\"Hello\" /><h1 _=\"bind @data-title and #title-input's value\"></h1>",
|
|
"action": "find('#title-input').fill('World')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "when",
|
|
"name": "detects changes from :element variable",
|
|
"html": "<div id=\"el\" _=\"init set :count to 0 end\n\t\t\t when :count changes put it into me end\n\t\t\t on click increment :count\">0</div>",
|
|
"action": "find('div').click(); find('div').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "when",
|
|
"name": "works with on handlers that modify the watched variable",
|
|
"html": "<div id=\"el\" _=\"init set :label to 'initial' end\n\t\t\t when :label changes put it into me end\n\t\t\t on click set :label to 'clicked'\">initial</div>",
|
|
"action": "find('div').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "when",
|
|
"name": "isolates element-scoped variables between elements",
|
|
"html": "<div id=\"d1\" _=\"init set :value to 'A' end\n\t\t\t when :value changes put it into me end\n\t\t\t on click set :value to 'A-clicked'\">A</div><div id=\"d2\" _=\"init set :value to 'B' end\n\t\t\t when :value changes put it into me end\n\t\t\t on click set :value to 'B-clicked'\">B</div>",
|
|
"action": "find('#d1').click(); find('#d2').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "when",
|
|
"name": "value of #element is tracked",
|
|
"html": "<input type=\"text\" id=\"of-input\" value=\"init\" /><span _=\"when (value of #of-input) changes put it into me\"></span>",
|
|
"action": "find('#of-input').fill('changed')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "liveTemplate",
|
|
"name": "processes hyperscript on inner elements",
|
|
"html": "\n\t\t\t<template live _=\"init set ^val to 0\">\n\t\t\t\t<button _=\"on click increment ^val then put ^val into the next <output/>\">+</button>\n\t\t\t\t<output>0</output>\n\t\t\t</template>\n\t\t",
|
|
"action": "find('[data-live-template] button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "assignableElements",
|
|
"name": "set closest replaces ancestor",
|
|
"html": "<div id=\"el\" class='wrapper'><button _='on click set (closest <div/>) to \\\"<div class=wrapper>replaced</div>\\\"'>go</button></div>",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "assignableElements",
|
|
"name": "hyperscript in replacement content is initialized",
|
|
"html": "<div id='target'>old</div><button id='go' _=\\\"on click set #target to '<div id=target _="on click put `clicked` into me">new</div>'\\\">go</button>",
|
|
"action": "find('#go').dispatchEvent('click'); find('#target').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "assignableElements",
|
|
"name": "put into still works as innerHTML",
|
|
"html": "<div id='target'>old</div><button _='on click put \\\"new\\\" into #target'>go</button>",
|
|
"action": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "collectionExpressions",
|
|
"name": "works with DOM elements",
|
|
"html": "<ul id='list'><li class='yes'>A</li><li>B</li><li class='yes'>C</li></ul><button _='on click set items to <li/> in #list then set matches to items where it matches .yes then put matches mapped to its textContent into #out'>Go</button><div id='out'></div>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "collectionExpressions",
|
|
"name": "where binds after in on closest",
|
|
"html": "<div id='box'><span class='a'>A</span><span class='b'>B</span><span class='a'>C</span></div><button _=\\\"on click set result to (<span/> in #box) where it matches .a then put result.length into me\\\">go (parens)</button><button id='b2' _=\\\"on click set result to <span/> in #box where it matches .a then put result.length into me\\\">go</button>",
|
|
"action": "find('#b2').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "collectionExpressions",
|
|
"name": "where in init followed by on feature",
|
|
"html": "<div id='box'><span class='a'>A</span><span class='b'>B</span></div><button _=\\\"set :items to <span/> in #box where it matches .a on click put :items.length into me\\\">go</button>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "collectionExpressions",
|
|
"name": "where in component init followed by on feature",
|
|
"html": "\n\t\t\t<div id='box'><span class='a'>A</span><span class='b'>B</span></div>\n\t\t\t<template component=\"test-where-comp\"\n\t\t\t\t_=\"set :items to <span/> in #box where it matches .a\n\t\t\t\t on click put :items.length into me\">\n\t\t\t\t<slot/>\n\t\t\t</template>\n\t\t\t<test-where-comp>go</test-where-comp>\n\t\t",
|
|
"action": "find('test-where-comp').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "collectionExpressions",
|
|
"name": "where with is not me followed by on feature",
|
|
"html": "\n\t\t\t<table>\n\t\t\t<tr><td><input type=\"checkbox\" class=\"cb\" checked></td></tr>\n\t\t\t<tr><td><input type=\"checkbox\" class=\"cb\"></td></tr>\n\t\t\t<tr><td><input type=\"checkbox\" class=\"cb\" checked></td></tr>\n\t\t\t<tr><td><input id=\"master\" type=\"checkbox\"\n\t\t\t\t_=\"set :checkboxes to <input[type=checkbox]/> in the closest <table/> where it is not me\n\t\t\t\t on change set checked of the :checkboxes to my checked\"></td></tr>\n\t\t\t</table>\n\t\t",
|
|
"action": "find('#master').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "child reads ^var set by parent",
|
|
"html": "<div id=\"el\" _=\"init set ^count to 42\"> <span _=\"on click put ^count into me\">0</span></div>",
|
|
"action": "find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "child writes ^var and parent sees it",
|
|
"html": "<div id=\"el\" _=\"init set ^count to 0\"> <button _=\"on click set ^count to 99\">set</button> <span _=\"on click put ^count into me\">0</span></div>",
|
|
"action": "find('button').click(); find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "deeply nested child reads ^var from grandparent",
|
|
"html": "<div id=\"el\" _=\"init set ^name to 'alice'\"> <div> <div> <span _=\"on click put ^name into me\">empty</span> </div> </div></div>",
|
|
"action": "find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "closest ancestor wins (shadowing)",
|
|
"html": "<div id=\"el\" _=\"init set ^color to 'red'\"> <div _=\"init set ^color to 'blue'\"> <span _=\"on click put ^color into me\">empty</span> </div></div>",
|
|
"action": "find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "sibling subtrees have independent ^vars",
|
|
"html": "<div id=\"a\" _=\"init set ^val to 'A'\"> <span _=\"on click put ^val into me\">empty</span></div><div id=\"b\" _=\"init set ^val to 'B'\"> <span _=\"on click put ^val into me\">empty</span></div>",
|
|
"action": "find('#a span').click(); find('#b span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "write to ^var not found anywhere creates on current element",
|
|
"html": "<div id=\"el\"> <button _=\"on click set ^newvar to 'created' then put ^newvar into next <span/>\">go</button> <span>empty</span></div>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "child write updates the ancestor, not a local copy",
|
|
"html": "<div id=\"el\" _=\"init set ^shared to 0\"> <button _=\"on click set ^shared to 10\">set</button> <span _=\"on click put ^shared into me\">0</span></div>",
|
|
"action": "find('button').click(); find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "increment works on inherited var",
|
|
"html": "<div id=\"el\" _=\"init set ^count to 0\"> <button _=\"on click increment ^count\" <span _=\"on click put ^count into me\">0</span></div>",
|
|
"action": "find('button').click(); find('button').click(); find('button').click(); find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "dom keyword works as scope modifier",
|
|
"html": "<div id=\"el\" _=\"init set dom count to 42\"> <span _=\"on click put dom count into me\">0</span></div>",
|
|
"action": "find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "set ^var on explicit element",
|
|
"html": "<div id=\"el\" class=\"store\"> <button _=\"on click set ^data on closest .store to 'hello'\">set</button> <span _=\"on click put ^data on closest .store into me\">read</span></div>",
|
|
"action": "find('button').click(); find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "on clause targets a specific ancestor",
|
|
"html": "<div id=\"el\" class=\"outer\" _=\"init set ^outerVal to 'outer'\"> <div class=\"inner\" _=\"init set ^innerVal to 'inner'\"> <span _=\"on click put ^outerVal on closest .outer into me\">read</span> </div></div>",
|
|
"action": "find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "on clause with id reference",
|
|
"html": "<div id=\"state-holder\"></div><button _=\"on click set ^count on #state-holder to 99\">set</button><span _=\"on click put ^count on #state-holder into me\">read</span>",
|
|
"action": "find('button').click(); find('span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "when reacts to ^var changes",
|
|
"html": "<div id=\"el\" _=\"init set ^count to 0\"> <button _=\"on click increment ^count\" <output _=\"when ^count changes put it into me\">0</output></div>",
|
|
"action": "find('button').click(); find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "always reacts to ^var changes",
|
|
"html": "<div id=\"el\" _=\"init set ^name to 'alice'\"> <button _=\"on click set ^name to 'bob'\">rename</button> <output _=\"live put 'Hello </div>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "multiple children react to same ^var",
|
|
"html": "<div _=\"init set ^color to 'red'\"> <button _=\"on click set ^color to 'blue'\">change</button> <span id=\"a\" _=\"when ^color changes put it into me\"></span> <span id=\"b\" _=\"when ^color changes put it into me\"></span></div>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "sibling subtrees react independently with ^var",
|
|
"html": "<div id=\"a\" _=\"init set ^val to 0\"> <button _=\"on click increment ^val\" <output _=\"when ^val changes put it into me\">0</output></div><div id=\"b\" _=\"init set ^val to 0\"> <button _=\"on click increment ^val\" <output _=\"when ^val changes put it into me\">0</output></div>",
|
|
"action": "find('#a button').click(); find('#a button').click(); find('#b button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "bind works with ^var",
|
|
"html": "<div id=\"el\" _=\"init set ^search to ''\"> <input type=\"text\" _=\"bind ^search and my value\" /> <output _=\"when ^search changes put it into me\"></output></div>",
|
|
"action": "find('input').fill('hello')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "dom-scope",
|
|
"name": "derived ^var chains reactively",
|
|
"html": "<div _=\"init set ^price to 10 then set ^qty to 2 then set ^total to 20\"> <span _=\"when ^price changes set ^total to (^price * ^qty)\"></span> <span _=\"when ^qty changes set ^total to (^price * ^qty)\"></span> <output _=\"when ^total changes put it into me\"></output> <button id=\"price-btn\" _=\"on click set ^price to 25\">set price</button> <button id=\"qty-btn\" _=\"on click set ^qty to 5\">set qty</button></div>",
|
|
"action": "find('#price-btn').click(); find('#qty-btn').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "component",
|
|
"name": "processes _ on inner elements",
|
|
"html": "\n\t\t\t<template component=\"test-inner\" _=\"init set ^count to 0\">\n\t\t\t\t<button _=\"on click increment ^count then put ^count into the next <span/>\">+</button>\n\t\t\t\t<span>0</span>\n\t\t\t</template>\n\t\t\t<test-inner></test-inner>\n\t\t",
|
|
"action": "find('test-inner button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "component",
|
|
"name": "supports multiple independent instances",
|
|
"html": "\n\t\t\t<template component=\"test-multi\" _=\"init set ^count to 0\">\n\t\t\t\t<button _=\"on click increment ^count then put ^count into the next <span/>\">+</button>\n\t\t\t\t<span>0</span>\n\t\t\t</template>\n\t\t\t<test-multi id=\"a\"></test-multi>\n\t\t\t<test-multi id=\"b\"></test-multi>\n\t\t",
|
|
"action": "find('#a button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "component",
|
|
"name": "blocks processing of inner hyperscript until render",
|
|
"html": "\n\t\t\t<template component=\"test-block\" _=\"init set ^msg to 'ready'\">\n\t\t\t\t<span _=\"on click put ^msg into me\">click me</span>\n\t\t\t</template>\n\t\t\t<test-block></test-block>\n\t\t",
|
|
"action": "find('test-block span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "component",
|
|
"name": "does not process slotted _ attributes prematurely",
|
|
"html": "\n\t\t\t<div _=\"init set ^x to 42\">\n\t\t\t\t<template component=\"test-slot-hs\">\n\t\t\t\t\t<div class=\"wrap\"><slot/></div>\n\t\t\t\t</template>\n\t\t\t\t<test-slot-hs>\n\t\t\t\t\t<span _=\"on click put ^x into me\">before</span>\n\t\t\t\t</test-slot-hs>\n\t\t\t</div>\n\t\t",
|
|
"action": "find('test-slot-hs span').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "add",
|
|
"name": "when clause sets result to matched elements",
|
|
"html": "<div id='trigger' _='on click add .foo to .item when it matches .yes then if the result is empty show #none else hide #none'></div><div id='d1' class='item yes'></div><div id='d2' class='item'></div><div id='none' style='display:none'></div>",
|
|
"action": "find('#trigger').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "add",
|
|
"name": "when clause result is empty when nothing matches",
|
|
"html": "<div id='trigger' _='on click add .foo to .item when it matches .nope then if the result is empty remove @hidden from #none'></div><div id='d1' class='item'></div><div id='none' hidden></div>",
|
|
"action": "find('#trigger').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "can default possessive properties",
|
|
"html": "<div id='d1' _=\\\"on click default #d1's foo to 'bar' then put #d1's foo into me\\\"></div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "can default of-expression properties",
|
|
"html": "<div id='d1' _=\\\"on click default foo of me to 'bar' then put my foo into me\\\"></div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "can default array elements",
|
|
"html": "<div id=\"el\" _=\"on click set arr to [null, null] then default arr[0] to 'yes' then put arr[0] into me\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "default array element respects existing value",
|
|
"html": "<div id=\"el\" _=\"on click set arr to ['existing', null] then default arr[0] to 'new' then put arr[0] into me\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "default preserves zero",
|
|
"html": "<div id=\"el\" _='on click set x to 0 then default x to 10 then put x into me'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "default overwrites empty string",
|
|
"html": "<div id=\"el\" _='on click set x to \"\" then default x to \"fallback\" then put x into me'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "default preserves false",
|
|
"html": "<div id=\"el\" _='on click set x to false then default x to true then put x into me'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "can default style ref when unset",
|
|
"html": "<div id=\"el\" _=\"on click default *background-color to 'red'\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "default",
|
|
"name": "default style ref preserves existing value",
|
|
"html": "<div id=\"el\" style=\"color: blue\" _=\"on click default *color to 'red'\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "hide",
|
|
"name": "can filter hide via the when clause",
|
|
"html": "<div id='trigger' _='on click hide <div/> in me when it matches .hideable'> <div id='d1' class='hideable'></div> <div id='d2'></div></div>",
|
|
"action": "find('#trigger').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "increment",
|
|
"name": "can increment an array element",
|
|
"html": "<div id=\"el\" _=\"on click set arr to [10, 20, 30] then increment arr[1] then put arr[1] into me\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "increment",
|
|
"name": "can decrement an array element",
|
|
"html": "<div id=\"el\" _=\"on click set arr to [10, 20, 30] then decrement arr[1] then put arr[1] into me\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "increment",
|
|
"name": "can increment a possessive property",
|
|
"html": "<div id=\"d1\" _=\"on click increment #d1's innerHTML\">5</div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "increment",
|
|
"name": "can increment a property of expression",
|
|
"html": "<div id=\"d1\" _=\"on click increment innerHTML of #d1\">5</div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "increment",
|
|
"name": "can increment a style ref",
|
|
"html": "<div id=\"el\" _=\"on click set my *opacity to 0.5 then increment *opacity by 0.25 then put *opacity into me\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "js",
|
|
"name": "handles rejected promises without hanging",
|
|
"html": "<div id=\"el\" _='on click js return Promise.reject(\\\"boom\\\") end catch e put e into my.innerHTML'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "put",
|
|
"name": "put null into attribute removes it",
|
|
"html": "<div id='d1' foo='bar' _='on click put null into @foo'></div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "remove",
|
|
"name": "can filter class removal via the when clause",
|
|
"html": "<div id='trigger' _='on click remove .highlight from .item when it matches .old'></div><div id='d1' class='item old highlight'></div><div id='d2' class='item highlight'></div>",
|
|
"action": "find('#trigger').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "basic raw for loop with null works",
|
|
"html": "<div id=\"el\" _='on click for x in null put x at end of me end'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "basic property for loop works",
|
|
"html": "<div id=\"el\" _='on click set x to {foo:1, bar:2, baz:3} for prop in x put x[prop] at end of me end'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "bottom-tested repeat until",
|
|
"html": "<div id=\"el\" _='on click set x to 0 repeat set x to until x is 3 end put x into me'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "bottom-tested repeat while",
|
|
"html": "<div id=\"el\" _='on click set x to 0 repeat set x to while x < 3 end put x into me'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "bottom-tested loop always runs at least once",
|
|
"html": "<div id=\"el\" _='on click set x to 0 repeat set x to until true end put x into me'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "break exits a simple repeat loop",
|
|
"html": "<div id=\"el\" _=\"on click\n\t\t\t\tset x to 0\n\t\t\t\trepeat 10 times\n\t\t\t\t\tset x to x + 1\n\t\t\t\t\tif x is 3 break end\n\t\t\t\tend\n\t\t\t\tput x into me\n\t\t\t\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "continue skips rest of iteration in simple repeat loop",
|
|
"html": "<div id=\"el\" _=\"on click\n\t\t\t\trepeat for x in [1, 2, 3, 4, 5]\n\t\t\t\t\tif x is 3 continue end\n\t\t\t\t\tput x at end of me\n\t\t\t\tend\n\t\t\t\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "break exits a for-in loop",
|
|
"html": "<div id=\"el\" _=\"on click\n\t\t\t\trepeat for x in [1, 2, 3, 4, 5]\n\t\t\t\t\tif x is 4 break end\n\t\t\t\t\tput x at end of me\n\t\t\t\tend\n\t\t\t\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "break exits a while loop",
|
|
"html": "<div id=\"el\" _=\"on click\n\t\t\t\tset x to 0\n\t\t\t\trepeat while x < 100\n\t\t\t\t\tset x to x + 1\n\t\t\t\t\tif x is 5 break end\n\t\t\t\tend\n\t\t\t\tput x into me\n\t\t\t\"></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "repeat",
|
|
"name": "for loop over undefined skips without error",
|
|
"html": "<div id=\"el\" _='on click repeat for x in doesNotExist put x at end of me end then put \\\"done\\\" into me'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "settle",
|
|
"name": "can settle a collection of elements",
|
|
"html": "<div class='item'></div><div class='item'></div><div id='trigger' _='on click settle <.item/> then add .done to <.item/>'></div>",
|
|
"action": "find('#trigger').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "show",
|
|
"name": "the result in a when clause refers to previous command result, not element being tested",
|
|
"html": "<div _=\\\"on click get 'found' show <span/> in me when the result is 'found'\\\"><span id='s1' style='display:none'>A</span><span id='s2' style='display:none'>B</span></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "show",
|
|
"name": "the result after show...when is the matched elements",
|
|
"html": "<div _=\\\"on click show <p/> in me when its textContent is 'yes' if the result is empty put 'none' into #out else put 'some' into #out\\\"><p style='display:none'>yes</p><p style='display:none'>no</p><span id='out'>--</span></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "toggle",
|
|
"name": "can toggle visibility",
|
|
"html": "<div id=\"el\" _='on click toggle *visibility'></div>",
|
|
"action": "find('div').dispatchEvent('click'); find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "toggle",
|
|
"name": "can toggle opacity w/ my",
|
|
"html": "<div id=\"el\" _='on click toggle my *opacity'></div>",
|
|
"action": "find('div').dispatchEvent('click'); find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "toggle",
|
|
"name": "can toggle visibility w/ my",
|
|
"html": "<div id=\"el\" _='on click toggle my *visibility'></div>",
|
|
"action": "find('div').dispatchEvent('click'); find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "toggle",
|
|
"name": "can toggle *display between two values",
|
|
"html": "<div id=\"el\" style='display:none' _=\\\"on click toggle *display of me between 'none' and 'flex'\\\"></div>",
|
|
"action": "find('div').dispatchEvent('click'); find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "toggle",
|
|
"name": "can toggle *opacity between three values",
|
|
"html": "<div id=\"el\" style='opacity:0' _=\\\"on click toggle *opacity of me between '0', '0.5' and '1'\\\"></div>",
|
|
"action": "find('div').dispatchEvent('click'); find('div').dispatchEvent('click'); find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"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": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"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": "find('button').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "on",
|
|
"name": "can ignore when target doesn\\'t exist",
|
|
"html": "<div id=\"el\" _=' \ton click from #doesntExist \t\tthrow \\\"bar\\\" \ton click \t\tput \\\"clicked\\\" into me\t'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "parser",
|
|
"name": "can have comments in attributes (triple dash)",
|
|
"html": "<div id=\"el\" _='on click put \\\"clicked\\\" into my.innerHTML ---put some content into the div...'></div>",
|
|
"action": "find('div').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "parser",
|
|
"name": "element-level isolation still works with error recovery",
|
|
"html": "<div><div id='d1' _='on click blargh end on mouseenter also_bad'></div><div id='d2' _='on click put \\\"clicked\\\" into my.innerHTML'></div></div>",
|
|
"action": "find('#d2').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "scoping",
|
|
"name": "element scoped variables span features w/short syntax",
|
|
"html": "<div id='d1' _='on click 1 set :x to 10 on click 2 set @out to :x'></div>",
|
|
"action": "find('#d1').dispatchEvent('click'); find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "closest",
|
|
"name": "closest does not consume a following where clause",
|
|
"html": "<table><tr><td><input type='checkbox' class='cb'><input type='checkbox' class='cb'><input id='master' type='checkbox' _=\\\"set :others to <input[type=checkbox]/> in the closest <table/> where it is not me on click put :others.length into #out\\\"></td></tr></table><div id='out'></div>",
|
|
"action": "find('#master').click()",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "comparisonOperator",
|
|
"name": "is a works with instanceof fallback",
|
|
"html": "<div id='d1' _='on click if I am a Element put \\\"yes\\\" into me'></div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "comparisonOperator",
|
|
"name": "is a Node works via instanceof",
|
|
"html": "<div id='d1' _='on click if I am a Node put \\\"yes\\\" into me'></div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "comparisonOperator",
|
|
"name": "is not a works with instanceof fallback",
|
|
"html": "<div id='d1' _='on click if \\\"hello\\\" is not a Element put \\\"yes\\\" into me'></div>",
|
|
"action": "find('#d1').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "comparisonOperator",
|
|
"name": "I precede works",
|
|
"html": "<div id='a' _=\\\"on click if I precede #b put 'yes' into me\\\"></div><div id='b'></div>",
|
|
"action": "find('#a').dispatchEvent('click')",
|
|
"checks": [],
|
|
"async": true
|
|
},
|
|
{
|
|
"category": "no",
|
|
"name": "no with where on DOM elements",
|
|
"html": "<div id='box'><span class='a'>A</span><span class='b'>B</span></div><button _=\\\"on click if no <span/> in #box where it matches .c then put 'none' into #out else put 'found' into #out\\\">go</button><div id='out'></div>",
|
|
"action": "find('button').click()",
|
|
"checks": [],
|
|
"async": true
|
|
}
|
|
];
|