You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by bo...@apache.org on 2021/01/12 18:58:34 UTC

[myfaces-tobago] branch master updated (7a16f44 -> 6cc1e17)

This is an automated email from the ASF dual-hosted git repository.

bommel pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git.


    from 7a16f44  Added bage
     new 3db6f37  improve jasmine test tools
     new 6cc1e17  fix: jasmine tests

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../10-selectBooleanCheckbox/Checkbox.test.js      | 228 +++++------
 .../15-selectBooleanToggle/Toggle.test.js          | 227 +++++------
 .../030-select/20-selectOneChoice/Dropdown.test.js | 127 +++---
 .../030-select/30-selectOneRadio/Radio.test.js     |   1 +
 .../030-select/40-selectOneListbox/Listbox.test.js | 152 +++----
 .../50-selectManyCheckbox/Multi_Checkbox.test.js   | 214 +++++-----
 .../70-selectManyShuttle/Shuttle.test.js           | 198 ++++-----
 .../080-sheet/10-sort/Sheet_Sorting.test.js        |  96 ++---
 .../080-sheet/30-event/Sheet_Event.test.js         |  67 ++-
 .../080-sheet/70-tree/Sheet_Tree.test.js           |   3 +-
 .../090-tree/04-listbox/Tree_Listbox.test.js       |  24 +-
 .../06-validation/00/Content_Validation.test.js    |  78 ++--
 .../30-concept/06-validation/01/JSR_303.test.js    |  25 +-
 .../06-validation/30-messages/Messages.test.js     |   4 +-
 .../08-form/10-required/Required.test.js           |  32 +-
 .../30-concept/08-form/20-ajax/Ajax.test.js        |  48 +--
 .../webapp/content/30-concept/08-form/Form.test.js |  48 ++-
 .../30-concept/30-behavior/Behavior.test.js        |  69 ++--
 .../30-concept/51-for-each/For_Each.test.js        |  12 +-
 .../00-collapsible-box/Collapsible_Box.test.js     |  52 +--
 .../20-collapsible-panel/Collapsible_Panel.test.js | 292 ++++++-------
 .../Collapsible_Section.test.js                    | 292 ++++++-------
 .../40000-style/100-headings/Headings.test.js      |   5 +-
 .../Ajax_Special_Character.test.js                 |   3 +-
 .../resources/tobago/test/tobago-test-tool.js      | 454 ++++++++-------------
 25 files changed, 1284 insertions(+), 1467 deletions(-)


[myfaces-tobago] 02/02: fix: jasmine tests

Posted by bo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bommel pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git

commit 6cc1e17c2e7e34bd9e5ca1f04bb9fd76675e82b7
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Tue Jan 12 19:43:05 2021 +0100

    fix: jasmine tests
---
 .../10-selectBooleanCheckbox/Checkbox.test.js      | 228 ++++++++++-----------
 .../15-selectBooleanToggle/Toggle.test.js          | 227 ++++++++++----------
 .../030-select/20-selectOneChoice/Dropdown.test.js | 127 ++++++------
 .../030-select/30-selectOneRadio/Radio.test.js     |   1 +
 .../030-select/40-selectOneListbox/Listbox.test.js | 152 +++++++-------
 .../50-selectManyCheckbox/Multi_Checkbox.test.js   | 214 ++++++++++---------
 .../70-selectManyShuttle/Shuttle.test.js           | 198 ++++++++----------
 7 files changed, 541 insertions(+), 606 deletions(-)

diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/10-selectBooleanCheckbox/Checkbox.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/10-selectBooleanCheckbox/Checkbox.test.js
index 9fc1d31..9fd41eb 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/10-selectBooleanCheckbox/Checkbox.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/10-selectBooleanCheckbox/Checkbox.test.js
@@ -16,152 +16,132 @@
  */
 
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
-
-it("not implemented yet", function (done) {
-  let test = new JasmineTestTool(done);
-  test.do(() => fail("not implemented yet"));
-  test.start();
-});
-
-/*
 import {querySelectorFn} from "/script/tobago-test.js";
-import {TobagoTestTool} from "/tobago/test/tobago-test-tool.js";
 
-QUnit.test("submit: select A", function (assert) {
+it("submit: select A", function (done) {
   let selectAFn = querySelectorFn("#page\\:mainForm\\:selectA input");
   let selectBFn = querySelectorFn("#page\\:mainForm\\:selectB input");
   let selectCFn = querySelectorFn("#page\\:mainForm\\:selectC input");
   let submitFn = querySelectorFn("#page\\:mainForm\\:submit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:submitOutput span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectAFn().checked = true;
-    selectBFn().checked = false;
-    selectCFn().checked = false;
-    submitFn().click();
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "A ");
-  });
-  TTT.startTest();
+  let outputFn = querySelectorFn("#page\\:mainForm\\:submitOutput tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "",
+      () => {
+        selectAFn().checked = false;
+        selectBFn().checked = false;
+        selectCFn().checked = false;
+      }, "click", submitFn);
+  test.do(() => selectAFn().checked = true);
+  test.do(() => selectBFn().checked = false);
+  test.do(() => selectCFn().checked = false);
+  test.event("click", submitFn, () => outputFn().textContent.trim(), "A");
+  test.do(() => expect(outputFn().textContent.trim()).toBe("A"));
+  test.start();
 });
 
-QUnit.test("submit: select B and C", function (assert) {
+it("submit: select B and C", function (done) {
   let selectAFn = querySelectorFn("#page\\:mainForm\\:selectA input");
   let selectBFn = querySelectorFn("#page\\:mainForm\\:selectB input");
   let selectCFn = querySelectorFn("#page\\:mainForm\\:selectC input");
   let submitFn = querySelectorFn("#page\\:mainForm\\:submit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:submitOutput span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectAFn().checked = false;
-    selectBFn().checked = true;
-    selectCFn().checked = true;
-    submitFn().click();
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "B C ");
-  });
-  TTT.startTest();
+  let outputFn = querySelectorFn("#page\\:mainForm\\:submitOutput tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "",
+      () => {
+        selectAFn().checked = false;
+        selectBFn().checked = false;
+        selectCFn().checked = false;
+      }, "click", submitFn);
+  test.do(() => selectAFn().checked = false);
+  test.do(() => selectBFn().checked = true);
+  test.do(() => selectCFn().checked = true);
+  test.event("click", submitFn, () => outputFn().textContent.trim(), "B C");
+  test.do(() => expect(outputFn().textContent.trim()).toBe("B C"));
+  test.start();
 });
 
-QUnit.test("ajax: select D", function (assert) {
-  let selectDFn = querySelectorFn("#page\\:mainForm\\:selectD input");
-  let outputDFn = querySelectorFn("#page\\:mainForm\\:outputD span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectDFn().checked = true;
-    selectDFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputDFn().textContent, "true");
-  });
-  TTT.startTest();
+it("ajax: select D", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectD input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputD tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "false",
+      () => selectFn().checked = false,
+      "change", selectFn);
+  test.do(() => selectFn().checked = true);
+  test.event("change", selectFn, () => outputFn().textContent === "true")
+  test.do(() => expect(outputFn().textContent).toBe("true"));
+  test.start();
 });
 
-QUnit.test("ajax: deselect D", function (assert) {
-  let selectDFn = querySelectorFn("#page\\:mainForm\\:selectD input");
-  let outputDFn = querySelectorFn("#page\\:mainForm\\:outputD span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectDFn().checked = false;
-    selectDFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputDFn().textContent, "false");
-  });
-  TTT.startTest();
+it("ajax: deselect D", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectD input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputD tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "true",
+      () => selectFn().checked = true,
+      "change", selectFn);
+  test.do(() => selectFn().checked = false);
+  test.event("change", selectFn, () => outputFn().textContent === "false")
+  test.do(() => expect(outputFn().textContent).toBe("false"));
+  test.start();
 });
 
-QUnit.test("ajax: select E", function (assert) {
-  let selectEFn = querySelectorFn("#page\\:mainForm\\:selectE input");
-  let outputEFn = querySelectorFn("#page\\:mainForm\\:outputE span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectEFn().checked = true;
-    selectEFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputEFn().textContent, "true");
-  });
-  TTT.startTest();
+it("ajax: select E", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectE input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputE tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "false",
+      () => selectFn().checked = false,
+      "change", selectFn);
+  test.do(() => selectFn().checked = true);
+  test.event("change", selectFn, () => outputFn().textContent === "true")
+  test.do(() => expect(outputFn().textContent).toBe("true"));
+  test.start();
 });
 
-QUnit.test("ajax: deselect E", function (assert) {
-  let selectEFn = querySelectorFn("#page\\:mainForm\\:selectE input");
-  let outputEFn = querySelectorFn("#page\\:mainForm\\:outputE span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectEFn().checked = false;
-    selectEFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputEFn().textContent, "false");
-  });
-  TTT.startTest();
+it("ajax: deselect E", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectE input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputE tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "true",
+      () => selectFn().checked = true,
+      "change", selectFn);
+  test.do(() => selectFn().checked = false);
+  test.event("change", selectFn, () => outputFn().textContent === "false")
+  test.do(() => expect(outputFn().textContent).toBe("false"));
+  test.start();
 });
 
-QUnit.test("ajax: select F", function (assert) {
-  let selectFFn = querySelectorFn("#page\\:mainForm\\:selectF input");
-  let outputFFn = querySelectorFn("#page\\:mainForm\\:outputF span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectFFn().checked = true;
-    selectFFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFFn().textContent, "true");
-  });
-  TTT.startTest();
+it("ajax: select F", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectF input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputF tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "false",
+      () => selectFn().checked = false,
+      "change", selectFn);
+  test.do(() => selectFn().checked = true);
+  test.event("change", selectFn, () => outputFn().textContent === "true")
+  test.do(() => expect(outputFn().textContent).toBe("true"));
+  test.start();
 });
 
-QUnit.test("ajax: deselect F", function (assert) {
-  let selectFFn = querySelectorFn("#page\\:mainForm\\:selectF input");
-  let outputFFn = querySelectorFn("#page\\:mainForm\\:outputF span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectFFn().checked = false;
-    selectFFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFFn().textContent, "false");
-  });
-  TTT.startTest();
+it("ajax: deselect F", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectF input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputF tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "true",
+      () => selectFn().checked = true,
+      "change", selectFn);
+  test.do(() => selectFn().checked = false);
+  test.event("change", selectFn, () => outputFn().textContent === "false")
+  test.do(() => expect(outputFn().textContent).toBe("false"));
+  test.start();
 });
-*/
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/15-selectBooleanToggle/Toggle.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/15-selectBooleanToggle/Toggle.test.js
index 5671dec..9fd41eb 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/15-selectBooleanToggle/Toggle.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/15-selectBooleanToggle/Toggle.test.js
@@ -16,151 +16,132 @@
  */
 
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
-
-it("not implemented yet", function (done) {
-  let test = new JasmineTestTool(done);
-  test.do(() => fail("not implemented yet"));
-  test.start();
-});
-/*
 import {querySelectorFn} from "/script/tobago-test.js";
-import {TobagoTestTool} from "/tobago/test/tobago-test-tool.js";
 
-QUnit.test("submit: select A", function (assert) {
+it("submit: select A", function (done) {
   let selectAFn = querySelectorFn("#page\\:mainForm\\:selectA input");
   let selectBFn = querySelectorFn("#page\\:mainForm\\:selectB input");
   let selectCFn = querySelectorFn("#page\\:mainForm\\:selectC input");
   let submitFn = querySelectorFn("#page\\:mainForm\\:submit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:submitOutput span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectAFn().checked = true;
-    selectBFn().checked = false;
-    selectCFn().checked = false;
-    submitFn().click();
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "A ");
-  });
-  TTT.startTest();
+  let outputFn = querySelectorFn("#page\\:mainForm\\:submitOutput tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "",
+      () => {
+        selectAFn().checked = false;
+        selectBFn().checked = false;
+        selectCFn().checked = false;
+      }, "click", submitFn);
+  test.do(() => selectAFn().checked = true);
+  test.do(() => selectBFn().checked = false);
+  test.do(() => selectCFn().checked = false);
+  test.event("click", submitFn, () => outputFn().textContent.trim(), "A");
+  test.do(() => expect(outputFn().textContent.trim()).toBe("A"));
+  test.start();
 });
 
-QUnit.test("submit: select B and C", function (assert) {
+it("submit: select B and C", function (done) {
   let selectAFn = querySelectorFn("#page\\:mainForm\\:selectA input");
   let selectBFn = querySelectorFn("#page\\:mainForm\\:selectB input");
   let selectCFn = querySelectorFn("#page\\:mainForm\\:selectC input");
   let submitFn = querySelectorFn("#page\\:mainForm\\:submit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:submitOutput span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectAFn().checked = false;
-    selectBFn().checked = true;
-    selectCFn().checked = true;
-    submitFn().click();
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "B C ");
-  });
-  TTT.startTest();
+  let outputFn = querySelectorFn("#page\\:mainForm\\:submitOutput tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "",
+      () => {
+        selectAFn().checked = false;
+        selectBFn().checked = false;
+        selectCFn().checked = false;
+      }, "click", submitFn);
+  test.do(() => selectAFn().checked = false);
+  test.do(() => selectBFn().checked = true);
+  test.do(() => selectCFn().checked = true);
+  test.event("click", submitFn, () => outputFn().textContent.trim(), "B C");
+  test.do(() => expect(outputFn().textContent.trim()).toBe("B C"));
+  test.start();
 });
 
-QUnit.test("ajax: select D", function (assert) {
-  let selectDFn = querySelectorFn("#page\\:mainForm\\:selectD input");
-  let outputDFn = querySelectorFn("#page\\:mainForm\\:outputD span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectDFn().checked = true;
-    selectDFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputDFn().textContent, "true");
-  });
-  TTT.startTest();
+it("ajax: select D", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectD input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputD tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "false",
+      () => selectFn().checked = false,
+      "change", selectFn);
+  test.do(() => selectFn().checked = true);
+  test.event("change", selectFn, () => outputFn().textContent === "true")
+  test.do(() => expect(outputFn().textContent).toBe("true"));
+  test.start();
 });
 
-QUnit.test("ajax: deselect D", function (assert) {
-  let selectDFn = querySelectorFn("#page\\:mainForm\\:selectD input");
-  let outputDFn = querySelectorFn("#page\\:mainForm\\:outputD span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectDFn().checked = false;
-    selectDFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputDFn().textContent, "false");
-  });
-  TTT.startTest();
+it("ajax: deselect D", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectD input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputD tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "true",
+      () => selectFn().checked = true,
+      "change", selectFn);
+  test.do(() => selectFn().checked = false);
+  test.event("change", selectFn, () => outputFn().textContent === "false")
+  test.do(() => expect(outputFn().textContent).toBe("false"));
+  test.start();
 });
 
-QUnit.test("ajax: select E", function (assert) {
-  let selectEFn = querySelectorFn("#page\\:mainForm\\:selectE input");
-  let outputEFn = querySelectorFn("#page\\:mainForm\\:outputE span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectEFn().checked = true;
-    selectEFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputEFn().textContent, "true");
-  });
-  TTT.startTest();
+it("ajax: select E", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectE input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputE tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "false",
+      () => selectFn().checked = false,
+      "change", selectFn);
+  test.do(() => selectFn().checked = true);
+  test.event("change", selectFn, () => outputFn().textContent === "true")
+  test.do(() => expect(outputFn().textContent).toBe("true"));
+  test.start();
 });
 
-QUnit.test("ajax: deselect E", function (assert) {
-  let selectEFn = querySelectorFn("#page\\:mainForm\\:selectE input");
-  let outputEFn = querySelectorFn("#page\\:mainForm\\:outputE span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectEFn().checked = false;
-    selectEFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputEFn().textContent, "false");
-  });
-  TTT.startTest();
+it("ajax: deselect E", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectE input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputE tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "true",
+      () => selectFn().checked = true,
+      "change", selectFn);
+  test.do(() => selectFn().checked = false);
+  test.event("change", selectFn, () => outputFn().textContent === "false")
+  test.do(() => expect(outputFn().textContent).toBe("false"));
+  test.start();
 });
 
-QUnit.test("ajax: select F", function (assert) {
-  let selectFFn = querySelectorFn("#page\\:mainForm\\:selectF input");
-  let outputFFn = querySelectorFn("#page\\:mainForm\\:outputF span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectFFn().checked = true;
-    selectFFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFFn().textContent, "true");
-  });
-  TTT.startTest();
+it("ajax: select F", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectF input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputF tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "false",
+      () => selectFn().checked = false,
+      "change", selectFn);
+  test.do(() => selectFn().checked = true);
+  test.event("change", selectFn, () => outputFn().textContent === "true")
+  test.do(() => expect(outputFn().textContent).toBe("true"));
+  test.start();
 });
 
-QUnit.test("ajax: deselect F", function (assert) {
-  let selectFFn = querySelectorFn("#page\\:mainForm\\:selectF input");
-  let outputFFn = querySelectorFn("#page\\:mainForm\\:outputF span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    selectFFn().checked = false;
-    selectFFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFFn().textContent, "false");
-  });
-  TTT.startTest();
+it("ajax: deselect F", function (done) {
+  let selectFn = querySelectorFn("#page\\:mainForm\\:selectF input");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputF tobago-out");
+
+  let test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent === "true",
+      () => selectFn().checked = true,
+      "change", selectFn);
+  test.do(() => selectFn().checked = false);
+  test.event("change", selectFn, () => outputFn().textContent === "false")
+  test.do(() => expect(outputFn().textContent).toBe("false"));
+  test.start();
 });
-*/
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/20-selectOneChoice/Dropdown.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/20-selectOneChoice/Dropdown.test.js
index 874c159..8c5aa1f 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/20-selectOneChoice/Dropdown.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/20-selectOneChoice/Dropdown.test.js
@@ -16,93 +16,94 @@
  */
 
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
-
-it("not implemented yet", function (done) {
-  let test = new JasmineTestTool(done);
-  test.do(() => fail("not implemented yet"));
-  test.start();
-});
-/*
 import {querySelectorAllFn, querySelectorFn} from "/script/tobago-test.js";
-import {TobagoTestTool} from "/tobago/test/tobago-test-tool.js";
 
-QUnit.test("submit: Alice", function (assert) {
+it("submit: Alice", function (done) {
   let aliceFn = querySelectorFn("#page\\:mainForm\\:selectPerson\\:\\:field option[value^='Alice']");
   let bobFn = querySelectorFn("#page\\:mainForm\\:selectPerson\\:\\:field option[value^='Bob']");
   let submitFn = querySelectorFn("#page\\:mainForm\\:submit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:outputPerson span");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputPerson tobago-out");
 
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    aliceFn().selected = true;
-    bobFn().selected = false;
-    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "Alice Anderson");
-  });
-  TTT.startTest();
+  const test = new JasmineTestTool(done);
+  test.setup(() => () => outputFn().textContent !== "Alice Anderson",
+      () => {
+        aliceFn().selected = false;
+        bobFn().selected = true;
+      },
+      "click", submitFn);
+  test.do(() => aliceFn().selected = true);
+  test.do(() => bobFn().selected = false);
+  test.event("click", submitFn, () => outputFn().textContent === "Alice Anderson");
+  test.do(() => expect(outputFn().textContent).toBe("Alice Anderson"));
+  test.start();
 });
 
-QUnit.test("submit: Bob", function (assert) {
+it("submit: Bob", function (done) {
   let aliceFn = querySelectorFn("#page\\:mainForm\\:selectPerson\\:\\:field option[value^='Alice']");
   let bobFn = querySelectorFn("#page\\:mainForm\\:selectPerson\\:\\:field option[value^='Bob']");
   let submitFn = querySelectorFn("#page\\:mainForm\\:submit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:outputPerson span");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:outputPerson tobago-out");
 
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    aliceFn().selected = false;
-    bobFn().selected = true;
-    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "Bob Brunch");
-  });
-  TTT.startTest();
+  const test = new JasmineTestTool(done);
+  test.setup(() => () => outputFn().textContent !== "Bob Brunch",
+      () => {
+        aliceFn().selected = true;
+        bobFn().selected = false;
+      },
+      "click", submitFn);
+  test.do(() => aliceFn().selected = false);
+  test.do(() => bobFn().selected = true);
+  test.event("click", submitFn, () => outputFn().textContent === "Bob Brunch");
+  test.do(() => expect(outputFn().textContent).toBe("Bob Brunch"));
+  test.start();
 });
 
-QUnit.test("ajax: select Mars", function (assert) {
+it("ajax: select Mars", function (done) {
   let planetFn = querySelectorFn("#page\\:mainForm\\:selectPlanet\\:\\:field");
+  let earthOptionFn = querySelectorFn("#page\\:mainForm\\:selectPlanet\\:\\:field option[value='0']");
   let marsOptionFn = querySelectorFn("#page\\:mainForm\\:selectPlanet\\:\\:field option[value='1']");
   let jupiterOptionFn = querySelectorFn("#page\\:mainForm\\:selectPlanet\\:\\:field option[value='2']");
   let moonsFn = querySelectorAllFn("#page\\:mainForm\\:moonbox\\:\\:field option");
 
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    jupiterOptionFn().selected = false;
-    marsOptionFn().selected = true;
-    planetFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(2, function () {
-    assert.equal(moonsFn().item(0).text, "Phobos");
-    assert.equal(moonsFn().item(1).text, "Deimos");
-  });
-  TTT.startTest();
+  const test = new JasmineTestTool(done);
+  test.setup(() => moonsFn().item(0).text !== "Phobos",
+      () => {
+        earthOptionFn().selected = true;
+        marsOptionFn().selected = false;
+        jupiterOptionFn().selected = false;
+      },
+      "change", planetFn);
+  test.do(() => earthOptionFn().selected = false);
+  test.do(() => marsOptionFn().selected = true);
+  test.do(() => jupiterOptionFn().selected = false);
+  test.event("change", planetFn, () => moonsFn().item(0).text === "Phobos");
+  test.do(() => expect(moonsFn().item(0).text).toBe("Phobos"));
+  test.do(() => expect(moonsFn().item(1).text).toBe("Deimos"));
+  test.start();
 });
 
-QUnit.test("ajax: select Jupiter", function (assert) {
+it("ajax: select Jupiter", function (done) {
   let planetFn = querySelectorFn("#page\\:mainForm\\:selectPlanet\\:\\:field");
+  let earthOptionFn = querySelectorFn("#page\\:mainForm\\:selectPlanet\\:\\:field option[value='0']");
   let marsOptionFn = querySelectorFn("#page\\:mainForm\\:selectPlanet\\:\\:field option[value='1']");
   let jupiterOptionFn = querySelectorFn("#page\\:mainForm\\:selectPlanet\\:\\:field option[value='2']");
   let moonsFn = querySelectorAllFn("#page\\:mainForm\\:moonbox\\:\\:field option");
 
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    marsOptionFn().selected = false;
-    jupiterOptionFn().selected = true;
-    planetFn().dispatchEvent(new Event("change", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(4, function () {
-    assert.equal(moonsFn().item(0).text, "Europa");
-    assert.equal(moonsFn().item(1).text, "Ganymed");
-    assert.equal(moonsFn().item(2).text, "Io");
-    assert.equal(moonsFn().item(3).text, "Kallisto");
-  });
-  TTT.startTest();
+  const test = new JasmineTestTool(done);
+  test.setup(() => moonsFn().item(0).text !== "Europa",
+      () => {
+        earthOptionFn().selected = true;
+        marsOptionFn().selected = false;
+        jupiterOptionFn().selected = false;
+      },
+      "change", planetFn);
+  test.do(() => earthOptionFn().selected = false);
+  test.do(() => marsOptionFn().selected = false);
+  test.do(() => jupiterOptionFn().selected = true);
+  test.event("change", planetFn, () => moonsFn().item(0).text === "Europa");
+  test.do(() => expect(moonsFn().item(0).text).toBe("Europa"));
+  test.do(() => expect(moonsFn().item(1).text).toBe("Ganymed"));
+  test.do(() => expect(moonsFn().item(2).text).toBe("Io"));
+  test.do(() => expect(moonsFn().item(3).text).toBe("Kallisto"));
+  test.start();
 });
-*/
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/30-selectOneRadio/Radio.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/30-selectOneRadio/Radio.test.js
index aaa1a91..65181af 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/30-selectOneRadio/Radio.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/30-selectOneRadio/Radio.test.js
@@ -53,6 +53,7 @@ it("submit: Subtraction (4 - 1)", function (done) {
   test.do(() => expect(outputFn().textContent).toBe("3"));
   test.start();
 });
+
 it("ajax: select Mars", function (done) {
   const earthFn = elementByIdFn("page:mainForm:selectPlanet::0");
   const marsFn = elementByIdFn("page:mainForm:selectPlanet::1");
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/40-selectOneListbox/Listbox.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/40-selectOneListbox/Listbox.test.js
index dcad683..5987eca 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/40-selectOneListbox/Listbox.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/40-selectOneListbox/Listbox.test.js
@@ -16,98 +16,102 @@
  */
 
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
-
-it("not implemented yet", function (done) {
-  let test = new JasmineTestTool(done);
-  test.do(() => fail("not implemented yet"));
-  test.start();
-});
-/*
 import {querySelectorAllFn, querySelectorFn} from "/script/tobago-test.js";
-import {TobagoTestTool} from "/tobago/test/tobago-test-tool.js";
 
-QUnit.test("submit: select 'Nile'", function (assert) {
+it("submit: select 'Nile'", function (done) {
   let riversFn = querySelectorAllFn("#page\\:mainForm\\:riverList option");
   let submitFn = querySelectorFn("#page\\:mainForm\\:riverSubmit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:riverOutput span");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:riverOutput tobago-out");
 
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    riversFn().item(0).selected = true; // Nile
-    riversFn().item(1).selected = false; // Amazon
-    riversFn().item(2).selected = false; // Yangtze
-    riversFn().item(3).selected = false; // Yellow River
-    riversFn().item(4).selected = false; // Paraná River
-    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "6853 km");
-  });
-  TTT.startTest();
+  const test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent !== "6853 km",
+      () => {
+        riversFn().item(0).selected = false; // Nile
+        riversFn().item(1).selected = false; // Amazon
+        riversFn().item(2).selected = false; // Yangtze
+        riversFn().item(3).selected = false; // Yellow River
+        riversFn().item(4).selected = false; // Paraná River
+      },
+      "click", submitFn);
+  test.do(() => riversFn().item(0).selected = true); // Nile
+  test.do(() => riversFn().item(1).selected = false); // Amazon
+  test.do(() => riversFn().item(2).selected = false); // Yangtze
+  test.do(() => riversFn().item(3).selected = false); // Yellow River
+  test.do(() => riversFn().item(4).selected = false); // Paraná River
+  test.event("click", submitFn, () => outputFn().textContent === "6853 km");
+  test.do(() => expect(outputFn().textContent).toBe("6853 km"));
+  test.start();
 });
 
-QUnit.test("submit: select 'Yangtze'", function (assert) {
+it("submit: select 'Yangtze'", function (done) {
   let riversFn = querySelectorAllFn("#page\\:mainForm\\:riverList option");
   let submitFn = querySelectorFn("#page\\:mainForm\\:riverSubmit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:riverOutput span");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:riverOutput tobago-out");
 
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    riversFn().item(0).selected = false; // Nile
-    riversFn().item(1).selected = false; // Amazon
-    riversFn().item(2).selected = true; // Yangtze
-    riversFn().item(3).selected = false; // Yellow River
-    riversFn().item(4).selected = false; // Paraná River
-    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "6300 km");
-
-  });
-  TTT.startTest();
+  const test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent !== "6300 km",
+      () => {
+        riversFn().item(0).selected = false; // Nile
+        riversFn().item(1).selected = false; // Amazon
+        riversFn().item(2).selected = false; // Yangtze
+        riversFn().item(3).selected = false; // Yellow River
+        riversFn().item(4).selected = false; // Paraná River
+      },
+      "click", submitFn);
+  test.do(() => riversFn().item(0).selected = false); // Nile
+  test.do(() => riversFn().item(1).selected = false); // Amazon
+  test.do(() => riversFn().item(2).selected = true); // Yangtze
+  test.do(() => riversFn().item(3).selected = false); // Yellow River
+  test.do(() => riversFn().item(4).selected = false); // Paraná River
+  test.event("click", submitFn, () => outputFn().textContent === "6300 km");
+  test.do(() => expect(outputFn().textContent).toBe("6300 km"));
+  test.start();
 });
 
-QUnit.test("ajax: select Everest", function (assert) {
+it("ajax: select Everest", function (done) {
   let mountainListFn = querySelectorFn("#page\\:mainForm\\:mountainList\\:\\:field");
   let mountainsFn = querySelectorAllFn("#page\\:mainForm\\:mountainList option");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:selectedMountain span");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:selectedMountain tobago-out");
 
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    mountainsFn().item(1).selected = false;
-    mountainsFn().item(2).selected = false;
-    mountainsFn().item(3).selected = false;
-    mountainsFn().item(4).selected = false;
-    mountainsFn().item(0).selected = true; // Everest
-    mountainListFn().dispatchEvent(new Event("change", {bubbles: true})); // Everest
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "8848 m");
-  });
-  TTT.startTest();
+  const test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent !== "8848 m",
+      () => {
+        mountainsFn().item(0).selected = false;
+        mountainsFn().item(1).selected = false;
+        mountainsFn().item(2).selected = false;
+        mountainsFn().item(3).selected = false;
+        mountainsFn().item(4).selected = false;
+      }, "change", mountainListFn);
+  test.do(() => mountainsFn().item(0).selected = true); // Everest
+  test.do(() => mountainsFn().item(1).selected = false);
+  test.do(() => mountainsFn().item(2).selected = false);
+  test.do(() => mountainsFn().item(3).selected = false);
+  test.do(() => mountainsFn().item(4).selected = false);
+  test.event("change", mountainListFn, () => outputFn().textContent === "8848 m");
+  test.do(() => expect(outputFn().textContent).toBe("8848 m"));
+  test.start();
 });
 
-QUnit.test("ajax: select Makalu", function (assert) {
+it("ajax: select Makalu", function (done) {
   let mountainListFn = querySelectorFn("#page\\:mainForm\\:mountainList\\:\\:field");
   let mountainsFn = querySelectorAllFn("#page\\:mainForm\\:mountainList option");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:selectedMountain span");
+  let outputFn = querySelectorFn("#page\\:mainForm\\:selectedMountain tobago-out");
 
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    mountainsFn().item(0).selected = false;
-    mountainsFn().item(1).selected = false;
-    mountainsFn().item(2).selected = false;
-    mountainsFn().item(3).selected = false;
-    mountainsFn().item(4).selected = true; // Everest
-    mountainListFn().dispatchEvent(new Event("change", {bubbles: true})); // Everest
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "8481 m");
-  });
-  TTT.startTest();
+  const test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent !== "8481 m",
+      () => {
+        mountainsFn().item(0).selected = false;
+        mountainsFn().item(1).selected = false;
+        mountainsFn().item(2).selected = false;
+        mountainsFn().item(3).selected = false;
+        mountainsFn().item(4).selected = false;
+      }, "change", mountainListFn);
+  test.do(() => mountainsFn().item(0).selected = false); // Everest
+  test.do(() => mountainsFn().item(1).selected = false);
+  test.do(() => mountainsFn().item(2).selected = false);
+  test.do(() => mountainsFn().item(3).selected = false);
+  test.do(() => mountainsFn().item(4).selected = true); // Makalu
+  test.event("change", mountainListFn, () => outputFn().textContent === "8481 m");
+  test.do(() => expect(outputFn().textContent).toBe("8481 m"));
+  test.start();
 });
-*/
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/50-selectManyCheckbox/Multi_Checkbox.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/50-selectManyCheckbox/Multi_Checkbox.test.js
index b29e09f..c5eb23d 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/50-selectManyCheckbox/Multi_Checkbox.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/50-selectManyCheckbox/Multi_Checkbox.test.js
@@ -16,126 +16,124 @@
  */
 
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
-
-it("not implemented yet", function (done) {
-  let test = new JasmineTestTool(done);
-  test.do(() => fail("not implemented yet"));
-  test.start();
-});
-
-/*
 import {querySelectorAllFn, querySelectorFn} from "/script/tobago-test.js";
-import {TobagoTestTool} from "/tobago/test/tobago-test-tool.js";
 
-QUnit.test("submit: select cat", function (assert) {
+it("submit: select cat", function (done) {
   let animalsFn = querySelectorAllFn("#page\\:mainForm\\:animals input");
   let submitFn = querySelectorFn("#page\\:mainForm\\:submit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:animalsOutput span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    animalsFn().item(0).checked = true;
-    animalsFn().item(1).checked = false;
-    animalsFn().item(2).checked = false;
-    animalsFn().item(3).checked = false;
-    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "Cat ");
-  });
-  TTT.startTest();
+  let outputFn = querySelectorFn("#page\\:mainForm\\:animalsOutput tobago-out");
+
+  const test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent.trim() !== "Cat",
+      () => {
+        animalsFn().item(0).checked = false;
+        animalsFn().item(1).checked = false;
+        animalsFn().item(2).checked = false;
+        animalsFn().item(3).checked = false;
+      },
+      "click", submitFn);
+  test.do(() => animalsFn().item(0).checked = true); // Cat
+  test.do(() => animalsFn().item(1).checked = false);
+  test.do(() => animalsFn().item(2).checked = false);
+  test.do(() => animalsFn().item(3).checked = false);
+  test.event("click", submitFn, () => outputFn().textContent.trim() === "Cat");
+  test.do(() => expect(outputFn().textContent.trim()).toBe("Cat"));
+  test.start();
 });
 
-QUnit.test("submit: select fox and rabbit", function (assert) {
+it("submit: select fox and rabbit", function (done) {
   let animalsFn = querySelectorAllFn("#page\\:mainForm\\:animals input");
   let submitFn = querySelectorFn("#page\\:mainForm\\:submit");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:animalsOutput span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    animalsFn().item(0).checked = false;
-    animalsFn().item(1).checked = false;
-    animalsFn().item(2).checked = true;
-    animalsFn().item(3).checked = true;
-    submitFn().dispatchEvent(new Event("click", {bubbles: true}));
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, "Fox Rabbit ");
-  });
-  TTT.startTest();
+  let outputFn = querySelectorFn("#page\\:mainForm\\:animalsOutput tobago-out");
+
+  const test = new JasmineTestTool(done);
+  test.setup(() => outputFn().textContent.trim() !== "Fox Rabbit",
+      () => {
+        animalsFn().item(0).checked = false;
+        animalsFn().item(1).checked = false;
+        animalsFn().item(2).checked = false;
+        animalsFn().item(3).checked = false;
+      },
+      "click", submitFn);
+  test.do(() => animalsFn().item(0).checked = false); // Cat
+  test.do(() => animalsFn().item(1).checked = false);
+  test.do(() => animalsFn().item(2).checked = true); // Fox
+  test.do(() => animalsFn().item(3).checked = true); // Rabbit
+  test.event("click", submitFn, () => outputFn().textContent.trim() === "Fox Rabbit");
+  test.do(() => expect(outputFn().textContent.trim()).toBe("Fox Rabbit"));
+  test.start();
+});
+
+it("ajax: select 'One'", function (done) {
+  let numberFn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:0");
+  ajaxSelect(done, numberFn, 1);
+});
+
+it("ajax: deselect 'One'", function (done) {
+  let numberFn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:0");
+  ajaxDeselect(done, numberFn, 1);
 });
 
-QUnit.test("ajax: click 'Two'", function (assert) {
-  let number2Fn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:1");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:resultOutput span");
-  let newOutputValue;
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    if (number2Fn().checked) {
-      newOutputValue = parseInt(outputFn().textContent) - 2;
-      number2Fn().checked = false;
-      number2Fn().dispatchEvent(new Event("change", {bubbles: true}));
-    } else {
-      newOutputValue = parseInt(outputFn().textContent) + 2;
-      number2Fn().checked = true;
-      number2Fn().dispatchEvent(new Event("change", {bubbles: true}));
-    }
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, newOutputValue);
-  });
-  TTT.startTest();
+it("ajax: select 'Two'", function (done) {
+  let numberFn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:1");
+  ajaxSelect(done, numberFn, 2);
 });
 
-QUnit.test("ajax: click 'Three'", function (assert) {
-  let number3Fn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:2");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:resultOutput span");
-  let newOutputValue;
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    if (number3Fn().checked) {
-      newOutputValue = parseInt(outputFn().textContent) - 3;
-      number3Fn().checked = false;
-      number3Fn().dispatchEvent(new Event("change", {bubbles: true}));
-    } else {
-      newOutputValue = parseInt(outputFn().textContent) + 3;
-      number3Fn().checked = true;
-      number3Fn().dispatchEvent(new Event("change", {bubbles: true}));
-    }
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, newOutputValue);
-  });
-  TTT.startTest();
+it("ajax: deselect 'Two'", function (done) {
+  let numberFn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:1");
+  ajaxDeselect(done, numberFn, 2);
 });
 
-QUnit.test("ajax: click 'Two'", function (assert) {
-  let number2Fn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:1");
-  let outputFn = querySelectorFn("#page\\:mainForm\\:resultOutput span");
-  let newOutputValue;
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    if (number2Fn().checked) {
-      newOutputValue = parseInt(outputFn().textContent) - 2;
-      number2Fn().checked = false;
-      number2Fn().dispatchEvent(new Event("change", {bubbles: true}));
-    } else {
-      newOutputValue = parseInt(outputFn().textContent) + 2;
-      number2Fn().checked = true;
-      number2Fn().dispatchEvent(new Event("change", {bubbles: true}));
-    }
-  });
-  TTT.waitForResponse();
-  TTT.asserts(1, function () {
-    assert.equal(outputFn().textContent, newOutputValue);
-  });
-  TTT.startTest();
+it("ajax: select 'Three'", function (done) {
+  let numberFn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:2");
+  ajaxSelect(done, numberFn, 3);
 });
-*/
+
+it("ajax: deselect 'Three'", function (done) {
+  let numberFn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:2");
+  ajaxDeselect(done, numberFn, 3);
+});
+
+it("ajax: select 'Four'", function (done) {
+  let numberFn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:3");
+  ajaxSelect(done, numberFn, 4);
+});
+
+it("ajax: deselect 'Four'", function (done) {
+  let numberFn = querySelectorFn("#page\\:mainForm\\:numbers\\:\\:3");
+  ajaxDeselect(done, numberFn, 4);
+});
+
+function ajaxSelect(done, numberFn, number) {
+  let outputFn = querySelectorFn("#page\\:mainForm\\:resultOutput tobago-out");
+  let newOutputValue = parseInt(outputFn().textContent);
+  if (!numberFn().checked) {
+    newOutputValue = parseInt(outputFn().textContent) + number;
+  }
+
+  const test = new JasmineTestTool(done);
+  test.setup(() => parseInt(outputFn().textContent) !== newOutputValue,
+      () => numberFn().checked = false,
+      "change", numberFn);
+  test.do(() => numberFn().checked = true);
+  test.event("change", numberFn, () => parseInt(outputFn().textContent) === newOutputValue);
+  test.do(() => expect(parseInt(outputFn().textContent)).toBe(newOutputValue));
+  test.start();
+}
+
+function ajaxDeselect(done, numberFn, number) {
+  let outputFn = querySelectorFn("#page\\:mainForm\\:resultOutput tobago-out");
+  let newOutputValue = parseInt(outputFn().textContent);
+  if (numberFn().checked) {
+    newOutputValue = parseInt(outputFn().textContent) - number;
+  }
+
+  const test = new JasmineTestTool(done);
+  test.setup(() => parseInt(outputFn().textContent) !== newOutputValue,
+      () => numberFn().checked = true,
+      "change", numberFn);
+  test.do(() => numberFn().checked = false);
+  test.event("change", numberFn, () => parseInt(outputFn().textContent) === newOutputValue);
+  test.do(() => expect(parseInt(outputFn().textContent)).toBe(newOutputValue));
+  test.start();
+}
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/70-selectManyShuttle/Shuttle.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/70-selectManyShuttle/Shuttle.test.js
index fe9b85c..f43593e 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/70-selectManyShuttle/Shuttle.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/030-select/70-selectManyShuttle/Shuttle.test.js
@@ -16,17 +16,9 @@
  */
 
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
-
-it("not implemented yet", function (done) {
-  let test = new JasmineTestTool(done);
-  test.do(() => fail("not implemented yet"));
-  test.start();
-});
-/*
 import {querySelectorAllFn, querySelectorFn} from "/script/tobago-test.js";
-import {TobagoTestTool} from "/tobago/test/tobago-test-tool.js";
 
-QUnit.test("submit: addAll, removeAll, addItem0to4, removeItem2to3", function (assert) {
+it("submit: addAll, removeAll, addItem0to4, removeItem2to3", function (done) {
   let unselectedOptions = querySelectorAllFn("#page\\:mainForm\\:submitExample\\:\\:unselected option");
   let selectedOptions = querySelectorAllFn("#page\\:mainForm\\:submitExample\\:\\:selected option");
   let addAllButton = querySelectorFn("#page\\:mainForm\\:submitExample\\:\\:addAll");
@@ -34,117 +26,95 @@ QUnit.test("submit: addAll, removeAll, addItem0to4, removeItem2to3", function (a
   let removeButton = querySelectorFn("#page\\:mainForm\\:submitExample\\:\\:remove");
   let removeAllButton = querySelectorFn("#page\\:mainForm\\:submitExample\\:\\:removeAll");
   let submitButton = querySelectorFn("#page\\:mainForm\\:submitButton");
-  let output = querySelectorFn("#page\\:mainForm\\:submitExampleOutput span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    addAllButton().click();
-    submitButton().click();
-  });
-  TTT.waitForResponse();
-  TTT.asserts(3, function () {
-    assert.equal(unselectedOptions().length, 0);
-    assert.equal(selectedOptions().length, 9);
-    assert.equal(output().textContent, "[Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto]");
-  });
-  TTT.action(function () {
-    removeAllButton().click();
-    submitButton().click();
-  });
-  TTT.waitForResponse();
-  TTT.asserts(3, function () {
-    assert.equal(unselectedOptions().length, 9);
-    assert.equal(selectedOptions().length, 0);
-    assert.equal(output().textContent, "[]");
-  });
-  TTT.action(function () {
-    unselectedOptions().item(0).selected = true;
-    unselectedOptions().item(1).selected = true;
-    unselectedOptions().item(2).selected = true;
-    unselectedOptions().item(3).selected = true;
-    unselectedOptions().item(4).selected = true;
-    addButton().click();
-    submitButton().click();
-  });
-  TTT.waitForResponse();
-  TTT.asserts(3, function () {
-    assert.equal(unselectedOptions().length, 4);
-    assert.equal(selectedOptions().length, 5);
-    assert.equal(output().textContent, "[Mercury, Venus, Earth, Mars, Jupiter]");
-  });
-  TTT.action(function () {
-    selectedOptions().item(2).selected = true;
-    selectedOptions().item(3).selected = true;
-    removeButton().click();
-    submitButton().click();
-  });
-  TTT.waitForResponse();
-  TTT.asserts(3, function () {
-    assert.equal(unselectedOptions().length, 6);
-    assert.equal(selectedOptions().length, 3);
-    assert.equal(output().textContent, "[Mercury, Venus, Jupiter]");
-  });
-  TTT.startTest();
+  let output = querySelectorFn("#page\\:mainForm\\:submitExampleOutput tobago-out");
+
+  const test = new JasmineTestTool(done);
+  test.setup(() => selectedOptions().length === 0, null, "click", removeAllButton);
+  test.setup(() => output().textContent === "[]", null, "click", submitButton);
+
+  test.event("click", addAllButton, () => selectedOptions().length === 9);
+  test.do(() => expect(unselectedOptions().length).toBe(0));
+  test.do(() => expect(selectedOptions().length).toBe(9));
+  test.event("click", submitButton,
+      () => output().textContent === "[Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto]");
+  test.do(() => expect(output().textContent)
+      .toBe("[Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto]"));
+
+  test.event("click", removeAllButton, () => selectedOptions().length === 0);
+  test.do(() => expect(unselectedOptions().length).toBe(9));
+  test.do(() => expect(selectedOptions().length).toBe(0));
+  test.event("click", submitButton, () => output().textContent === "[]");
+  test.do(() => expect(output().textContent).toBe("[]"));
+
+  test.do(() => unselectedOptions().item(0).selected = true);
+  test.do(() => unselectedOptions().item(1).selected = true);
+  test.do(() => unselectedOptions().item(2).selected = true);
+  test.do(() => unselectedOptions().item(3).selected = true);
+  test.do(() => unselectedOptions().item(4).selected = true);
+  test.event("click", addButton, () => selectedOptions().length === 5);
+  test.do(() => expect(unselectedOptions().length).toBe(4));
+  test.do(() => expect(selectedOptions().length).toBe(5));
+  test.event("click", submitButton, () => output().textContent === "[Mercury, Venus, Earth, Mars, Jupiter]");
+  test.do(() => expect(output().textContent).toBe("[Mercury, Venus, Earth, Mars, Jupiter]"));
+
+  test.do(() => selectedOptions().item(2).selected = true);
+  test.do(() => selectedOptions().item(3).selected = true);
+  test.event("click", removeButton, () => selectedOptions().length === 3);
+  test.do(() => expect(unselectedOptions().length).toBe(6));
+  test.do(() => expect(selectedOptions().length).toBe(3));
+  test.event("click", submitButton, () => output().textContent === "[Mercury, Venus, Jupiter]");
+  test.do(() => expect(output().textContent).toBe("[Mercury, Venus, Jupiter]"));
+
+  const pageOverlays = querySelectorAllFn(".tobago-page-overlay");
+  test.do(() => expect(pageOverlays().length).toBe(0));
+
+  test.start();
 });
 
-QUnit.test("ajax: addAll, removeAll, addItem1to2, removeItem0", function (assert) {
+it("ajax: addAll, removeAll, addItem1to2, removeItem0", function (done) {
   let unselectedOptions = querySelectorAllFn("#page\\:mainForm\\:ajaxExample\\:\\:unselected option");
   let selectedOptions = querySelectorAllFn("#page\\:mainForm\\:ajaxExample\\:\\:selected option");
   let addAllButton = querySelectorFn("#page\\:mainForm\\:ajaxExample\\:\\:addAll");
   let addButton = querySelectorFn("#page\\:mainForm\\:ajaxExample\\:\\:add");
   let removeButton = querySelectorFn("#page\\:mainForm\\:ajaxExample\\:\\:remove");
   let removeAllButton = querySelectorFn("#page\\:mainForm\\:ajaxExample\\:\\:removeAll");
-  let output = querySelectorFn("#page\\:mainForm\\:outputStars span");
-
-  let TTT = new TobagoTestTool(assert);
-  TTT.action(function () {
-    addAllButton().click();
-  });
-  // TTT.waitForResponse(); //TODO use waitForResponse()
-  TTT.waitMs(5000);
-  TTT.asserts(6, function () {
-    assert.equal(unselectedOptions().length, 0);
-    assert.equal(selectedOptions().length, 4);
-    assert.ok(output().textContent.indexOf(selectedOptions().item(0).value) > 0);
-    assert.ok(output().textContent.indexOf(selectedOptions().item(1).value) > 0);
-    assert.ok(output().textContent.indexOf(selectedOptions().item(2).value) > 0);
-    assert.ok(output().textContent.indexOf(selectedOptions().item(3).value) > 0);
-  });
-  TTT.action(function () {
-    removeAllButton().click();
-  });
-  // TTT.waitForResponse(); //TODO use waitForResponse()
-  TTT.waitMs(5000);
-  TTT.asserts(3, function () {
-    assert.equal(unselectedOptions().length, 4);
-    assert.equal(selectedOptions().length, 0);
-    assert.equal(output().textContent, "[]");
-  });
-  TTT.action(function () {
-    unselectedOptions().item(1).selected = true;
-    unselectedOptions().item(2).selected = true;
-    addButton().click();
-  });
-  // TTT.waitForResponse(); //TODO use waitForResponse()
-  TTT.waitMs(5000);
-  TTT.asserts(4, function () {
-    assert.equal(unselectedOptions().length, 2);
-    assert.equal(selectedOptions().length, 2);
-    assert.ok(output().textContent.indexOf(selectedOptions().item(0).value) > 0);
-    assert.ok(output().textContent.indexOf(selectedOptions().item(1).value) > 0);
-  });
-  TTT.action(function () {
-    selectedOptions().item(0).selected = true;
-    selectedOptions().item(1).selected = false;
-    removeButton().click();
-  });
-  // TTT.waitForResponse(); //TODO use waitForResponse()
-  TTT.waitMs(5000);
-  TTT.asserts(3, function () {
-    assert.equal(unselectedOptions().length, 3);
-    assert.equal(selectedOptions().length, 1);
-    assert.ok(output().textContent.indexOf(selectedOptions().item(0).value) > 0);
-  });
-  TTT.startTest();
+  let output = querySelectorFn("#page\\:mainForm\\:outputStars tobago-out");
+  let submitButton = querySelectorFn("#page\\:mainForm\\:submitButton");
+
+  const test = new JasmineTestTool(done);
+  test.setup(() => output().textContent === "[]", null, "click", removeAllButton);
+  test.setup(() => unselectedOptions().item(0).text === "Proxima Centauri"
+      && unselectedOptions().item(1).text === "Alpha Centauri"
+      && unselectedOptions().item(2).text === "Wolf 359"
+      && unselectedOptions().item(3).text === "Sirius",
+      null, "click", submitButton);
+
+  test.event("click", addAllButton,
+      () => output().textContent === "[Proxima Centauri, Alpha Centauri, Wolf 359, Sirius]");
+  test.do(() => expect(unselectedOptions().length).toBe(0));
+  test.do(() => expect(selectedOptions().length).toBe(4));
+  test.do(() => expect(output().textContent).toBe("[Proxima Centauri, Alpha Centauri, Wolf 359, Sirius]"));
+
+  test.event("click", removeAllButton, () => output().textContent === "[]");
+  test.do(() => expect(unselectedOptions().length).toBe(4));
+  test.do(() => expect(selectedOptions().length).toBe(0));
+  test.do(() => expect(output().textContent).toBe("[]"));
+
+  test.do(() => unselectedOptions().item(1).selected = true);
+  test.do(() => unselectedOptions().item(2).selected = true);
+  test.event("click", addButton, () => output().textContent === "[Alpha Centauri, Wolf 359]");
+  test.do(() => expect(unselectedOptions().length).toBe(2));
+  test.do(() => expect(selectedOptions().length).toBe(2));
+  test.do(() => expect(output().textContent).toBe("[Alpha Centauri, Wolf 359]"));
+
+  test.do(() => selectedOptions().item(0).selected = true);
+  test.do(() => selectedOptions().item(1).selected = false);
+  test.event("click", removeButton, () => output().textContent === "[Wolf 359]");
+  test.do(() => expect(unselectedOptions().length).toBe(3));
+  test.do(() => expect(selectedOptions().length).toBe(1));
+  test.do(() => expect(output().textContent).toBe("[Wolf 359]"));
+
+  const pageOverlays = querySelectorAllFn(".tobago-page-overlay");
+  test.do(() => expect(pageOverlays().length).toBe(0, "there must be no tobago-page-overlay"));
+  test.start();
 });
-*/


[myfaces-tobago] 01/02: improve jasmine test tools

Posted by bo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bommel pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git

commit 3db6f3708a01da704f8e3141690a73b62b5f61c0
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Mon Jan 11 21:24:43 2021 +0100

    improve jasmine test tools
    
    * better setup method (with eventType/element)
    * hide "private" methods
    * better logging
    * remove outdated tobago test tools
    * adjust tests
---
 .../080-sheet/10-sort/Sheet_Sorting.test.js        |  96 ++---
 .../080-sheet/30-event/Sheet_Event.test.js         |  67 ++-
 .../080-sheet/70-tree/Sheet_Tree.test.js           |   3 +-
 .../090-tree/04-listbox/Tree_Listbox.test.js       |  24 +-
 .../06-validation/00/Content_Validation.test.js    |  78 ++--
 .../30-concept/06-validation/01/JSR_303.test.js    |  25 +-
 .../06-validation/30-messages/Messages.test.js     |   4 +-
 .../08-form/10-required/Required.test.js           |  32 +-
 .../30-concept/08-form/20-ajax/Ajax.test.js        |  48 +--
 .../webapp/content/30-concept/08-form/Form.test.js |  48 ++-
 .../30-concept/30-behavior/Behavior.test.js        |  69 ++--
 .../30-concept/51-for-each/For_Each.test.js        |  12 +-
 .../00-collapsible-box/Collapsible_Box.test.js     |  52 +--
 .../20-collapsible-panel/Collapsible_Panel.test.js | 292 ++++++-------
 .../Collapsible_Section.test.js                    | 292 ++++++-------
 .../40000-style/100-headings/Headings.test.js      |   5 +-
 .../Ajax_Special_Character.test.js                 |   3 +-
 .../resources/tobago/test/tobago-test-tool.js      | 454 ++++++++-------------
 18 files changed, 743 insertions(+), 861 deletions(-)

diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/10-sort/Sheet_Sorting.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/10-sort/Sheet_Sorting.test.js
index 921b36a..f3877c0 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/10-sort/Sheet_Sorting.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/10-sort/Sheet_Sorting.test.js
@@ -26,13 +26,11 @@ it("Basics: Name", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colNameFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colNameFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colNameFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "Earth",
-      () => {
-        leftPagingFn().value = "22";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "22",
+      "blur", leftPagingFn);
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -67,13 +65,11 @@ it("Basics: Period", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colPeriodFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colPeriodFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colPeriodFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "Rosalind",
-      () => {
-        leftPagingFn().value = "29";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "29",
+      "blur", leftPagingFn);
   test.do(() => expect(colPeriodFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colPeriodFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colPeriodFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -108,13 +104,11 @@ it("Basics: Year", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colYearFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colYearFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colYearFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "Amalthea",
-      () => {
-        leftPagingFn().value = "22";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "22",
+      "blur", leftPagingFn);
   test.do(() => expect(colYearFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colYearFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colYearFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -145,13 +139,11 @@ it("Basics: left paging", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colNameFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colNameFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colNameFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "1986U10",
-      () => {
-        leftPagingFn().value = "1";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "1",
+      "blur", leftPagingFn);
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -196,13 +188,11 @@ it("Basics: center paging", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colNameFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colNameFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colNameFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "1986U10",
-      () => {
-        leftPagingFn().value = "1";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "1",
+      "blur", leftPagingFn);
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -259,13 +249,11 @@ it("Basics: right paging", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colNameFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colNameFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colNameFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "Earth",
-      () => {
-        leftPagingFn().value = "22";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "22",
+      "blur", leftPagingFn);
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -331,13 +319,11 @@ it("Custom Sorting: Name", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colNameFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colNameFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colNameFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "Earth",
-      () => {
-        leftPagingFn().value = "22";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "22",
+      "blur", leftPagingFn);
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -372,13 +358,11 @@ it("Custom Sorting: Period", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colPeriodFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colPeriodFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colPeriodFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "Mimas",
-      () => {
-        leftPagingFn().value = "29";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "29",
+      "blur", leftPagingFn);
   test.do(() => expect(colPeriodFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colPeriodFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colPeriodFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -413,13 +397,11 @@ it("Custom Sorting: Year", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colYearFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colYearFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colYearFn);
   test.setup(
       () => rowsFn()[0].querySelectorAll("tobago-out")[2].textContent === "1789",
-      () => {
-        leftPagingFn().value = "22";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "22",
+      "blur", leftPagingFn);
   test.do(() => expect(colYearFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colYearFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colYearFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -450,13 +432,11 @@ it("Custom Sorting: left paging", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colNameFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colNameFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colNameFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "1986U10",
-      () => {
-        leftPagingFn().value = "1";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "1",
+      "blur", leftPagingFn);
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -501,13 +481,11 @@ it("Custom Sorting: center paging", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colNameFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colNameFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colNameFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "1986U10",
-      () => {
-        leftPagingFn().value = "1";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "1",
+      "blur", leftPagingFn);
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
@@ -564,13 +542,11 @@ it("Custom Sorting: right paging", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => colNameFn().classList.contains("tobago-sheet-header-markup-ascending"),
-      () => colNameFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", colNameFn);
   test.setup(
       () => rowsFn()[0].querySelector("tobago-out").textContent === "Earth",
-      () => {
-        leftPagingFn().value = "22";
-        leftPagingFn().dispatchEvent(new Event("blur", {bubbles: true}));
-      });
+      () => leftPagingFn().value = "22",
+      "blur", leftPagingFn);
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-sortable")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-ascending")).toBe(true));
   test.do(() => expect(colNameFn().classList.contains("tobago-sheet-header-markup-descending")).not.toBe(true));
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/Sheet_Event.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/Sheet_Event.test.js
index e18c477..79f59fc 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/Sheet_Event.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/30-event/Sheet_Event.test.js
@@ -18,7 +18,13 @@
 import {querySelectorFn} from "/script/tobago-test.js";
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
 
-it("On click with ajax", function (done) {
+it("must be fixed first", function (done) {
+  let test = new JasmineTestTool(done);
+  test.do(() => fail("must be fixed first"));
+  test.start();
+});
+
+/*it("On click with ajax", function (done) {
   let oneClickAjaxFn = querySelectorFn("#page\\:mainForm\\:changeExample\\:\\:0");
   let venusFn = querySelectorFn("#page\\:mainForm\\:s1\\:2\\:sample0");
   let jupiterFn = querySelectorFn("#page\\:mainForm\\:s1\\:5\\:sample0");
@@ -27,19 +33,15 @@ it("On click with ajax", function (done) {
 
   let test = new JasmineTestTool(done);
   test.do(() => oneClickAjaxFn().checked = true);
-  test.do(() => oneClickAjaxFn().dispatchEvent(new Event("change", {bubbles: true})));
-  test.wait(() => venusFn());
+  test.event("change", oneClickAjaxFn, () => venusFn());
   test.do(() => expect(venusFn() != null).toBe(true));
   test.do(() => expect(jupiterFn() != null).toBe(true));
   test.do(() => expect(saturnFn() != null).toBe(true));
-  test.do(() => venusFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Venus");
+  test.event("click", venusFn, () => namefieldFn() && namefieldFn().value === "Venus");
   test.do(() => expect(namefieldFn().value).toBe("Venus"));
-  test.do(() => jupiterFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Jupiter");
+  test.event("click", jupiterFn, () => namefieldFn() && namefieldFn().value === "Jupiter");
   test.do(() => expect(namefieldFn().value).toBe("Jupiter"));
-  test.do(() => saturnFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Saturn");
+  test.event("click", saturnFn, () => namefieldFn() && namefieldFn().value === "Saturn");
   test.do(() => expect(namefieldFn().value).toBe("Saturn"));
   test.start();
 });
@@ -53,19 +55,15 @@ it("On click with full request", function (done) {
 
   let test = new JasmineTestTool(done);
   test.do(() => oneClickFullRequestFn().checked = true);
-  test.do(() => oneClickFullRequestFn().dispatchEvent(new Event("change", {bubbles: true})));
-  test.wait(() => venusFn());
+  test.event("change", oneClickFullRequestFn, () => venusFn());
   test.do(() => expect(venusFn() != null).toBe(true));
   test.do(() => expect(jupiterFn() != null).toBe(true));
   test.do(() => expect(saturnFn() != null).toBe(true));
-  test.do(() => venusFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Venus");
+  test.event("click", venusFn, () => namefieldFn() && namefieldFn().value === "Venus");
   test.do(() => expect(namefieldFn().value).toBe("Venus"));
-  test.do(() => jupiterFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Jupiter");
+  test.event("click", jupiterFn, () => namefieldFn() && namefieldFn().value === "Jupiter");
   test.do(() => expect(namefieldFn().value).toBe("Jupiter"));
-  test.do(() => saturnFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Saturn");
+  test.event("click", saturnFn, () => namefieldFn() && namefieldFn().value === "Saturn");
   test.do(() => expect(namefieldFn().value).toBe("Saturn"));
   test.start();
 });
@@ -79,19 +77,15 @@ it("On double click with full request", function (done) {
 
   let test = new JasmineTestTool(done);
   test.do(() => doubleClickFullRequestFn().checked = true);
-  test.do(() => doubleClickFullRequestFn().dispatchEvent(new Event("change", {bubbles: true})));
-  test.wait(() => venusFn());
+  test.event("change", doubleClickFullRequestFn, () => venusFn());
   test.do(() => expect(venusFn() != null).toBe(true));
   test.do(() => expect(jupiterFn() != null).toBe(true));
   test.do(() => expect(saturnFn() != null).toBe(true));
-  test.do(() => venusFn().dispatchEvent(new Event("dblclick", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Venus");
+  test.event("dblclick", venusFn, () => namefieldFn() && namefieldFn().value === "Venus");
   test.do(() => expect(namefieldFn().value).toBe("Venus"));
-  test.do(() => jupiterFn().dispatchEvent(new Event("dblclick", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Jupiter");
+  test.event("dblclick", jupiterFn, () => namefieldFn() && namefieldFn().value === "Jupiter");
   test.do(() => expect(namefieldFn().value).toBe("Jupiter"));
-  test.do(() => saturnFn().dispatchEvent(new Event("dblclick", {bubbles: true})));
-  test.wait(() => namefieldFn() && namefieldFn().value === "Saturn");
+  test.event("dblclick", saturnFn, () => namefieldFn() && namefieldFn().value === "Saturn");
   test.do(() => expect(namefieldFn().value).toBe("Saturn"));
   test.start();
 });
@@ -107,31 +101,24 @@ it("Open popup on click with ajax", function (done) {
 
   let test = new JasmineTestTool(done);
   test.do(() => radioButtonFn().checked = true);
-  test.do(() => radioButtonFn().dispatchEvent(new Event("change", {bubbles: true})));
-  test.wait(() => venusFn());
+  test.event("change", radioButtonFn, () => venusFn());
   test.do(() => expect(venusFn() != null).toBe(true));
   test.do(() => expect(jupiterFn() != null).toBe(true));
   test.do(() => expect(saturnFn() != null).toBe(true));
-  test.do(() => venusFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => popupFn() && popupFn().classList.contains("show") === true);
+  test.event("click", venusFn, () => popupFn() && popupFn().classList.contains("show") === true);
   test.do(() => expect(popupFn().classList.contains("show")).toBe(true));
   test.do(() => expect(nameFn().value).toBe("Venus"));
-  test.do(() => cancelFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => popupFn() && popupFn().classList.contains("show") !== true);
+  test.event("click", cancelFn, () => popupFn() && popupFn().classList.contains("show") !== true);
   test.do(() => expect(popupFn().classList.contains("show")).not.toBe(true));
-  test.do(() => jupiterFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => popupFn() && popupFn().classList.contains("show") === true);
+  test.event("click", jupiterFn, () => popupFn() && popupFn().classList.contains("show") === true);
   test.do(() => expect(popupFn().classList.contains("show")).toBe(true));
   test.do(() => expect(nameFn().value).toBe("Jupiter"));
-  test.do(() => cancelFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => popupFn() && popupFn().classList.contains("show") !== true);
+  test.event("click", cancelFn, () => popupFn() && popupFn().classList.contains("show") !== true);
   test.do(() => expect(popupFn().classList.contains("show")).not.toBe(true));
-  test.do(() => saturnFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => popupFn() && popupFn().classList.contains("show") === true);
+  test.event("click", saturnFn, () => popupFn() && popupFn().classList.contains("show") === true);
   test.do(() => expect(popupFn().classList.contains("show")).toBe(true));
   test.do(() => expect(nameFn().value).toBe("Saturn"));
-  test.do(() => cancelFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => popupFn() && popupFn().classList.contains("show") !== true);
+  test.event("click", cancelFn, () => popupFn() && popupFn().classList.contains("show") !== true);
   test.do(() => expect(popupFn().classList.contains("show")).not.toBe(true));
   test.start();
-});
+});*/
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/70-tree/Sheet_Tree.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/70-tree/Sheet_Tree.test.js
index def1b1c..c8b3d20 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/70-tree/Sheet_Tree.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/080-sheet/70-tree/Sheet_Tree.test.js
@@ -49,8 +49,7 @@ it("Collapse tree", function (done) {
   let sheetRow = row1yearFn().parentElement.parentElement;
   test.do(() => expect(sheetRow.classList.contains("tobago-sheet-row")).toBe(true));
   test.do(() => expect(getComputedStyle(sheetRow).display).not.toBe("none"));
-  test.do(() => rootTreeButtonFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => row0nameFn() && row0nameFn().textContent === "Sun");
+  test.event("click", rootTreeButtonFn, () => row0nameFn() && row0nameFn().textContent === "Sun");
   test.do(() => expect(row0nameFn().textContent).toBe("Sun"));
   test.do(() => expect(row0centralBodyFn().textContent).toBe("-"));
   test.do(() => expect(row0distanceFn().textContent).toBe("0"));
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/090-tree/04-listbox/Tree_Listbox.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/090-tree/04-listbox/Tree_Listbox.test.js
index f318fbd..3dacdb5 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/090-tree/04-listbox/Tree_Listbox.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/090-tree/04-listbox/Tree_Listbox.test.js
@@ -29,12 +29,10 @@ it("Select 2,2,0 and submit", function (done) {
 
   const test = new JasmineTestTool(done);
   test.setup(() => isLevelSelectVisible(2, 1),
-      () => {
-        node1().selected = true;
-        node1().dispatchEvent(new Event("change", {bubbles: true}));
-      });
+      () => node1().selected = true,
+      "change", node1);
   test.setup(() => output().textContent !== "[[2, 2, 0]]",
-      () => submit().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", submit);
 
   test.do(() => node3().selected = true);
   test.event("change", node3,
@@ -96,12 +94,10 @@ it("Select 3 and submit", function (done) {
 
   const test = new JasmineTestTool(done);
   test.setup(() => isLevelSelectVisible(2, 1),
-      () => {
-        node1().selected = true;
-        node1().dispatchEvent(new Event("change", {bubbles: true}));
-      });
+      () => node1().selected = true,
+      "change", node1);
   test.setup(() => output().textContent !== "[[3]]",
-      () => submit().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", submit);
 
   test.do(() => node9().selected = true);
   test.event("change", node9,
@@ -136,12 +132,10 @@ it("Select 4,2,1,1 and submit", function (done) {
 
   const test = new JasmineTestTool(done);
   test.setup(() => isLevelSelectVisible(2, 1),
-      () => {
-        node1().selected = true;
-        node1().dispatchEvent(new Event("change", {bubbles: true}));
-      });
+      () => node1().selected = true,
+      "change", node1);
   test.setup(() => output().textContent !== "[[4, 2, 1, 1]]",
-      () => submit().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", submit);
 
   test.do(() => node10().selected = true);
   test.event("change", node10,
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/00/Content_Validation.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/00/Content_Validation.test.js
index 462a9da..86c87e9 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/00/Content_Validation.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/00/Content_Validation.test.js
@@ -25,9 +25,11 @@ it("Required: Submit without content.", function (done) {
   let textareaValue = textareaFn().value;
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => textareaFn().value = "Alice",
+      "click", submitFn);
   test.do(() => textareaFn().value = "");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.do(() => expect(textareaFn().value).toBe(textareaValue));
   test.start();
@@ -39,9 +41,11 @@ it("Required: Submit with content.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:required\\:submit_r");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 1,
+      () => textareaFn().value = "",
+      "click", submitFn);
   test.do(() => textareaFn().value = "some content");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 0
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 0
       && textareaFn().value && textareaFn().value === "some content");
   test.do(() => expect(messagesFn().length).toBe(0));
   test.do(() => expect(textareaFn().value).toBe("some content"));
@@ -54,9 +58,11 @@ it("Validate Length: Submit single character.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:validateLength\\:submit_vl");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
   test.do(() => inFn().value = "a");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -67,9 +73,11 @@ it("Validate Length: Submit two character.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:validateLength\\:submit_vl");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 1,
+      () => inFn().value = "",
+      "click", submitFn);
   test.do(() => inFn().value = "ab");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 0);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
 });
@@ -80,9 +88,11 @@ it("Validate Range: Submit no number.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:validateRange\\:submit_vr");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => inFn().value = "42",
+      "click", submitFn);
   test.do(() => inFn().value = "no number");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -93,9 +103,11 @@ it("Validate Range: Submit number '2' which is out of range.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:validateRange\\:submit_vr");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => inFn().value = "42",
+      "click", submitFn);
   test.do(() => inFn().value = "2");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -106,9 +118,11 @@ it("Validate Range: Submit number '78' which is out of range.", function (done)
   let submitFn = querySelectorFn("#page\\:mainForm\\:validateRange\\:submit_vr");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => inFn().value = "42",
+      "click", submitFn);
   test.do(() => inFn().value = "78");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -119,9 +133,11 @@ it("Validate Range: Submit number '64' which is within the range.", function (do
   let submitFn = querySelectorFn("#page\\:mainForm\\:validateRange\\:submit_vr");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 1,
+      () => inFn().value = "1000",
+      "click", submitFn);
   test.do(() => inFn().value = "64");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 0);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
 });
@@ -132,9 +148,11 @@ it("Regex Validation: Submit 'T' which violates the pattern.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:regexValidation\\:submit_rv");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => inFn().value = "T3",
+      "click", submitFn);
   test.do(() => inFn().value = "T");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -145,9 +163,11 @@ it("Regex Validation: Submit '3' which violates the pattern.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:regexValidation\\:submit_rv");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => inFn().value = "T3",
+      "click", submitFn);
   test.do(() => inFn().value = "3");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -158,9 +178,11 @@ it("Regex Validation: Submit 'T3' which is accepted.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:regexValidation\\:submit_rv");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 1,
+      () => inFn().value = "Charlie",
+      "click", submitFn);
   test.do(() => inFn().value = "T3");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 0);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
 });
@@ -171,9 +193,11 @@ it("Custom Validator: Submit rejected string.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:customValidator\\:submit_cv");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => inFn().value = "tobago",
+      "click", submitFn);
   test.do(() => inFn().value = "java");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -184,9 +208,11 @@ it("Custom Validator: Submit accepted string.", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:customValidator\\:submit_cv");
 
   let test = new JasmineTestTool(done);
+  test.setup(() => messagesFn() && messagesFn().length === 1,
+      () => inFn().value = "Dave",
+      "click", submitFn);
   test.do(() => inFn().value = "tobago");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 0);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
 });
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/01/JSR_303.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/01/JSR_303.test.js
index bbb9188..6053795 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/01/JSR_303.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/01/JSR_303.test.js
@@ -18,15 +18,20 @@
 import {querySelectorAllFn, querySelectorFn} from "/script/tobago-test.js";
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
 
-it("Required: Submit without content.", function (done) {
+it("must be fixed first", function (done) {
+  let test = new JasmineTestTool(done);
+  test.do(() => fail("must be fixed first"));
+  test.start();
+});
+
+/*it("Required: Submit without content.", function (done) {
   let messagesFn = querySelectorAllFn("#page\\:messages.tobago-messages div");
   let inFn = querySelectorFn("#page\\:mainForm\\:required\\:in1\\:\\:field");
   let submitFn = querySelectorFn("#page\\:mainForm\\:required\\:submit1");
 
   let test = new JasmineTestTool(done);
   test.do(() => inFn().value = "");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -38,8 +43,7 @@ it("Required: Submit with content.", function (done) {
 
   let test = new JasmineTestTool(done);
   test.do(() => inFn().value = "some content");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 0);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
 });
@@ -51,8 +55,7 @@ it("Length: Submit single character.", function (done) {
 
   let test = new JasmineTestTool(done);
   test.do(() => inFn().value = "a");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
 });
@@ -64,8 +67,7 @@ it("Length: Submit three characters.", function (done) {
 
   let test = new JasmineTestTool(done);
   test.do(() => inFn().value = "abc");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 0);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
 });
@@ -77,8 +79,7 @@ it("Length: Submit five characters.", function (done) {
 
   let test = new JasmineTestTool(done);
   test.do(() => inFn().value = "abcde");
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => messagesFn() && messagesFn().length === 1);
+  test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
   test.do(() => expect(messagesFn().length).toBe(1));
   test.start();
-});
+});*/
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/30-messages/Messages.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/30-messages/Messages.test.js
index 603e24d..1620405 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/30-messages/Messages.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/06-validation/30-messages/Messages.test.js
@@ -28,10 +28,10 @@ it("Press '7 Messages' Button and close the first, the last and the fourth", fun
   let test = new JasmineTestTool(done);
   test.setup(
       () => tab().classList.contains("active"),
-      () => tab().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", tab);
   test.setup(
       () => alerts().length === 7,
-      () => messagesButton().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", messagesButton);
   test.do(() => expect(alertLabels()[0].textContent).toBe("First Message - Info"));
   test.do(() => expect(alertLabels()[1].textContent).toBe("Second Message - Fatal"));
   test.do(() => expect(alertLabels()[2].textContent).toBe("Third Message - Warn"));
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/10-required/Required.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/10-required/Required.test.js
index 8843562..a645d2a 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/10-required/Required.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/10-required/Required.test.js
@@ -26,10 +26,8 @@ it("submit inner form 1 without violations", function (done) {
 
   let test = new JasmineTestTool(done);
   test.setup(() => form1OutputFn().textContent !== "Alice",
-      () => {
-        form1InputFn().value = "Bob";
-        form1SubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
-      });
+      () => form1InputFn().value = "Bob",
+      "click", form1SubmitFn);
   test.do(() => form1InputFn().value = "Alice");
   test.event("click", form1SubmitFn, () => form1OutputFn().textContent === "Alice")
   test.do(() => expect(form1InputFn().value).toBe("Alice"));
@@ -50,9 +48,9 @@ it("submit inner form 2, violate required field", function (done) {
   test.setup(() => form2AlertFn() === null,
       () => {
         form2InputFn().value = "Bob";
-        form2SubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form2OutputValue = "Bob";
-      });
+      },
+      "click", form2SubmitFn);
   test.do(() => form2InputFn().value = "");
   test.do(() => expect(form2InputFn().value).toBe(""));
   test.event("click", form2SubmitFn, () => form2AlertFn() !== null)
@@ -72,10 +70,8 @@ it("submit inner form 2 without violations", function (done) {
 
   let test = new JasmineTestTool(done);
   test.setup(() => form2OutputFn().textContent !== "Bob",
-      () => {
-        form2InputFn().value = "Charlie";
-        form2SubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
-      });
+      () => form2InputFn().value = "Charlie",
+      "click", form2SubmitFn);
   test.do(() => form2InputFn().value = "Bob");
   test.event("click", form2SubmitFn, () => form2OutputFn().textContent === "Bob");
   test.do(() => expect(form2InputFn().value).toBe("Bob"));
@@ -102,10 +98,10 @@ it("submit outer form, violate both required fields", function (done) {
       () => {
         form2InputFn().value = "Charlie";
         outerFormInputFn().value = "Dave";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form2OutputValue = "Charlie";
         outerFormOutputValue = "Dave"
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form2InputFn().value = "");
   test.do(() => outerFormInputFn().value = "");
   test.event("click", outerFormSubmitFn, () => form2AlertFn() !== null && outerFormAlertFn() !== null);
@@ -136,9 +132,9 @@ it("submit outer form, violate required field in form 2", function (done) {
   test.setup(() => form2AlertFn() === null,
       () => {
         form2InputFn().value = "Dave";
-        form2SubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form2OutputValue = "Dave";
-      });
+      },
+      "click", form2SubmitFn);
   test.do(() => form2InputFn().value = "");
   test.do(() => outerFormInputFn().value = "Eve");
   test.event("click", outerFormSubmitFn, () => form2AlertFn() !== null && outerFormAlertFn() === null);
@@ -169,10 +165,10 @@ it("submit outer form, violate required field in outer form", function (done) {
       () => {
         form2InputFn().value = "Frank"
         outerFormInputFn().value = "Eve";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
         form2OutputValue = "Frank"
         outerFormOutputValue = "Eve";
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form2InputFn().value = "Frank");
   test.do(() => outerFormInputFn().value = "");
   test.event("click", outerFormSubmitFn, () => outerFormAlertFn() !== null);
@@ -206,8 +202,8 @@ it("submit outer form without violations", function (done) {
         form1InputFn().value = "Alice";
         form2InputFn().value = "Bob";
         outerFormInputFn().value = "Charlie";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Frank");
   test.do(() => form2InputFn().value = "Eve");
   test.do(() => outerFormInputFn().value = "Grace");
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/20-ajax/Ajax.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/20-ajax/Ajax.test.js
index 6851ce1..b6296b5 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/20-ajax/Ajax.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/20-ajax/Ajax.test.js
@@ -26,10 +26,8 @@ it("submit inner form 1 without violations", function (done) {
 
   let test = new JasmineTestTool(done);
   test.setup(() => form1OutputFn().textContent !== "Alice",
-      () => {
-        form1InputFn().value = "Bob";
-        form1SubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
-      });
+      () => form1InputFn().value = "Bob",
+      "click", form1SubmitFn);
   test.do(() => form1InputFn().value = "Alice");
   test.event("click", form1SubmitFn, () => form1OutputFn().textContent === "Alice");
   test.do(() => expect(form1InputFn().value).toBe("Alice"));
@@ -50,9 +48,9 @@ it("submit inner form 2, violate required field", function (done) {
   test.setup(() => form2AlertFn() === null,
       () => {
         form2InputFn().value = "Bob";
-        form2SubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form2OutputValue = "Bob";
-      });
+      },
+      "click", form2SubmitFn);
   test.do(() => form2InputFn().value = "");
   test.event("click", form2SubmitFn, () => form2AlertFn() !== null);
   test.do(() => expect(form2InputFn().value).toBe(""));
@@ -71,10 +69,8 @@ it("submit inner form 2 without violations", function (done) {
 
   let test = new JasmineTestTool(done);
   test.setup(() => form2OutputFn().textContent !== "Bob",
-      () => {
-        form2InputFn().value = "Alice";
-        form2SubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
-      });
+      () => form2InputFn().value = "Alice",
+      "click", form2SubmitFn);
   test.do(() => form2InputFn().value = "Bob");
   test.event("click", form2SubmitFn, () => form2OutputFn().textContent === "Bob");
   test.do(() => expect(form2InputFn().value).toBe("Bob"));
@@ -106,11 +102,11 @@ it("submit outer form, violate both required fields", function (done) {
         form1InputFn().value = "Alice";
         form2InputFn().value = "Bob";
         outerFormInputFn().value = "Charlie";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form1OutputValue = "Alice"
         form2OutputValue = "Bob";
         outerFormOutputValue = "Charlie"
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Dave");
   test.do(() => form2InputFn().value = "");
   test.do(() => outerFormInputFn().value = "");
@@ -148,11 +144,11 @@ it("submit outer form, violate required field in form 2", function (done) {
         form1InputFn().value = "Alice";
         form2InputFn().value = "Bob";
         outerFormInputFn().value = "Charlie";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form1OutputValue = "Alice"
         form2OutputValue = "Bob";
         outerFormOutputValue = "Charlie"
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Charlie");
   test.do(() => form2InputFn().value = "");
   test.do(() => outerFormInputFn().value = "Dave");
@@ -190,11 +186,11 @@ it("submit outer form, violate required field in outer form", function (done) {
         form1InputFn().value = "Dave"
         form2InputFn().value = "Eve"
         outerFormInputFn().value = "Frank";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
         form1OutputValue = "Dave"
         form2OutputValue = "Eve"
         outerFormOutputValue = "Frank";
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Eve");
   test.do(() => form2InputFn().value = "Frank");
   test.do(() => outerFormInputFn().value = "");
@@ -231,8 +227,8 @@ it("submit outer form without violations", function (done) {
         form1InputFn().value = "Eve";
         form2InputFn().value = "Frank";
         outerFormInputFn().value = "Grace";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Hank");
   test.do(() => form2InputFn().value = "Irene");
   test.do(() => outerFormInputFn().value = "John");
@@ -272,11 +268,11 @@ it("submit inner forms, violate required field in form 2", function (done) {
         form1InputFn().value = "Alice";
         form2InputFn().value = "Bob";
         outerFormInputFn().value = "Charlie"
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form1OutputValue = "Alice"
         form2OutputValue = "Bob";
         outerFormOutputValue = "Charlie";
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Kate");
   test.do(() => form2InputFn().value = "");
   test.do(() => outerFormInputFn().value = "Leonard");
@@ -314,9 +310,9 @@ it("submit inner forms without violations", function (done) {
         form1InputFn().value = "Kate";
         form2InputFn().value = "Mike";
         outerFormInputFn().value = "Leonard";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         outerFormOutputValue = "Leonard";
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Mike");
   test.do(() => form2InputFn().value = "Neil");
   test.do(() => outerFormInputFn().value = "");
@@ -356,11 +352,11 @@ it("submit outer value, violate required field", function (done) {
         form1InputFn().value = "Leonard";
         form2InputFn().value = "Mike";
         outerFormInputFn().value = "Neil";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form1OutputValue = "Leonard";
         form2OutputValue = "Mike";
         outerFormOutputValue = "Neil";
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Oscar");
   test.do(() => form2InputFn().value = "Penny");
   test.do(() => outerFormInputFn().value = "");
@@ -399,10 +395,10 @@ it("submit outer value without violations", function (done) {
         form1InputFn().value = "Neil";
         form2InputFn().value = "Oscar";
         outerFormInputFn().value = "Penny";
-        outerFormSubmitFn().dispatchEvent(new Event("click", {bubbles: true}));
         form1OutputValue = "Neil";
         form2OutputValue = "Oscar";
-      });
+      },
+      "click", outerFormSubmitFn);
   test.do(() => form1InputFn().value = "Quin");
   test.do(() => form2InputFn().value = "Sue");
   test.do(() => outerFormInputFn().value = "Ted");
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/Form.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/Form.test.js
index ac67482..243865b 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/Form.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/08-form/Form.test.js
@@ -21,39 +21,43 @@ import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
 it("submit form 1", function (done) {
   let form1InputFieldFn = querySelectorFn("#page\\:mainForm\\:form1\\:in1\\:\\:field");
   let form2InputFieldFn = querySelectorFn("#page\\:mainForm\\:form2\\:in2\\:\\:field");
-  let form1OutputFieldFn = querySelectorFn("#page\\:mainForm\\:form1\\:out1 span");
-  let form2OutputFieldFn = querySelectorFn("#page\\:mainForm\\:form2\\:out2 span");
+  let form1OutputFieldFn = querySelectorFn("#page\\:mainForm\\:form1\\:out1 tobago-out");
+  let form2OutputFieldFn = querySelectorFn("#page\\:mainForm\\:form2\\:out2 tobago-out");
   let form1SubmitButtonFn = querySelectorFn("#page\\:mainForm\\:form1\\:submit1");
-  let $form2OutputFieldValue = form2OutputFieldFn().textContent;
+  let form2OutputFieldValue = form2OutputFieldFn().textContent;
 
   let test = new JasmineTestTool(done);
-  test.do(() => form1InputFieldFn().value = "Oliver");
-  test.do(() => form2InputFieldFn().value = "Peter");
-  test.do(() => form1SubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => form1InputFieldFn() && form1InputFieldFn().value === "Oliver");
-  test.do(() => expect(form1InputFieldFn().value).toBe("Oliver"));
-  test.do(() => expect(form1OutputFieldFn().textContent).toBe("Oliver"));
-  test.do(() => expect(form2InputFieldFn().value).toBe("Peter"));
-  test.do(() => expect(form2OutputFieldFn().textContent).toBe($form2OutputFieldValue));
+  test.setup(() => form1OutputFieldFn().textContent !== "Alice",
+      () => form1InputFieldFn().value = "Eve",
+      "click", form1SubmitButtonFn);
+  test.do(() => form1InputFieldFn().value = "Alice");
+  test.do(() => form2InputFieldFn().value = "Bob");
+  test.event("click", form1SubmitButtonFn, () => form1OutputFieldFn().textContent === "Alice");
+  test.do(() => expect(form1InputFieldFn().value).toBe("Alice"));
+  test.do(() => expect(form1OutputFieldFn().textContent).toBe("Alice"));
+  test.do(() => expect(form2InputFieldFn().value).toBe("Bob"));
+  test.do(() => expect(form2OutputFieldFn().textContent).toBe(form2OutputFieldValue));
   test.start();
 });
 
 it("submit form 2", function (done) {
   let form1InputFieldFn = querySelectorFn("#page\\:mainForm\\:form1\\:in1\\:\\:field");
   let form2InputFieldFn = querySelectorFn("#page\\:mainForm\\:form2\\:in2\\:\\:field");
-  let form1OutputFieldFn = querySelectorFn("#page\\:mainForm\\:form1\\:out1 span");
-  let form2OutputFieldFn = querySelectorFn("#page\\:mainForm\\:form2\\:out2 span");
+  let form1OutputFieldFn = querySelectorFn("#page\\:mainForm\\:form1\\:out1 tobago-out");
+  let form2OutputFieldFn = querySelectorFn("#page\\:mainForm\\:form2\\:out2 tobago-out");
   let form2SubmitButtonFn = querySelectorFn("#page\\:mainForm\\:form2\\:submit2");
-  let $form1OutputFieldValue = form1OutputFieldFn().textContent;
+  let form1OutputFieldValue = form1OutputFieldFn().textContent;
 
   let test = new JasmineTestTool(done);
-  test.do(() => form1InputFieldFn().value = "Oliver");
-  test.do(() => form2InputFieldFn().value = "Peter");
-  test.do(() => form2SubmitButtonFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => form1InputFieldFn() && form1InputFieldFn().value === "Oliver");
-  test.do(() => expect(form1InputFieldFn().value).toBe("Oliver"));
-  test.do(() => expect(form1OutputFieldFn().textContent).toBe($form1OutputFieldValue));
-  test.do(() => expect(form2InputFieldFn().value).toBe("Peter"));
-  test.do(() => expect(form2OutputFieldFn().textContent).toBe("Peter"));
+  test.setup(() => form2OutputFieldFn().textContent !== "Dave",
+      () => form2InputFieldFn().value = "Frank",
+      "click", form2SubmitButtonFn);
+  test.do(() => form1InputFieldFn().value = "Charlie");
+  test.do(() => form2InputFieldFn().value = "Dave");
+  test.event("click", form2SubmitButtonFn, () => form2OutputFieldFn().textContent === "Dave");
+  test.do(() => expect(form1InputFieldFn().value).toBe("Charlie"));
+  test.do(() => expect(form1OutputFieldFn().textContent).toBe(form1OutputFieldValue));
+  test.do(() => expect(form2InputFieldFn().value).toBe("Dave"));
+  test.do(() => expect(form2OutputFieldFn().textContent).toBe("Dave"));
   test.start();
 });
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/30-behavior/Behavior.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/30-behavior/Behavior.test.js
index 089c6d1..96f3cd9 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/30-behavior/Behavior.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/30-behavior/Behavior.test.js
@@ -15,29 +15,32 @@
  * limitations under the License.
  */
 
-import {querySelectorFn} from "/script/tobago-test.js";
 import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
 
-it("Ajax Input", function (done) {
+it("must be fixed first", function (done) {
+  let test = new JasmineTestTool(done);
+  test.do(() => fail("must be fixed first"));
+  test.start();
+});
+
+/*it("Ajax Input", function (done) {
   let ajaxInputFn = querySelectorFn("#page\\:mainForm\\:j_id_2g\\:\\:field");
-  let ajaxOutputFn = querySelectorFn("#page\\:mainForm\\:outAjax span");
+  let ajaxOutputFn = querySelectorFn("#page\\:mainForm\\:outAjax tobago-out");
 
   let test = new JasmineTestTool(done);
   test.do(() => ajaxInputFn().value = "Alice");
-  test.do(() => ajaxInputFn().dispatchEvent(new Event("change", {bubbles: true})));
-  test.wait(() => ajaxOutputFn() && ajaxOutputFn().textContent === "Alice");
+  test.event("change", ajaxInputFn, () => ajaxOutputFn() && ajaxOutputFn().textContent === "Alice");
   test.do(() => expect(ajaxOutputFn().textContent).toBe(ajaxInputFn().value));
   test.start();
 });
 
 it("Event Input", function (done) {
   let eventInputFn = querySelectorFn("#page\\:mainForm\\:j_id_2k\\:\\:field");
-  let eventOutputFn = querySelectorFn("#page\\:mainForm\\:j_id_2m span");
+  let eventOutputFn = querySelectorFn("#page\\:mainForm\\:j_id_2m tobago-out");
 
   let test = new JasmineTestTool(done);
   test.do(() => eventInputFn().value = "Alice");
-  test.do(() => eventInputFn().dispatchEvent(new Event("change", {bubbles: true})));
-  test.wait(() => eventOutputFn() && eventOutputFn().textContent === "Alice");
+  test.event("change", eventInputFn, () => eventOutputFn() && eventOutputFn().textContent === "Alice");
   test.do(() => expect(eventOutputFn().textContent).toBe(eventInputFn().value));
   test.start();
 });
@@ -45,47 +48,35 @@ it("Event Input", function (done) {
 it("change the event name", function (done) {
   let ajaxFn = querySelectorFn("#page\\:mainForm\\:j_id_2p");
   let eventFn = querySelectorFn("#page\\:mainForm\\:j_id_2q");
-  let outCounterFn = querySelectorFn("#page\\:mainForm\\:outCounter span");
+  let outCounterFn = querySelectorFn("#page\\:mainForm\\:outCounter tobago-out");
   let counter = Number(outCounterFn().textContent);
 
   let test = new JasmineTestTool(done);
-  test.do(() => ajaxFn().dispatchEvent(new Event("dblclick", {bubbles: true})));
-  test.wait(() => outCounterFn() && Number(outCounterFn().textContent) === counter+1);
-  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter+1));
-  test.do(() => eventFn().dispatchEvent(new Event("dblclick", {bubbles: true})));
-  test.wait(() => outCounterFn() && Number(outCounterFn().textContent) === counter+2);
-  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter+2));
-  test.do(() => ajaxFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => outCounterFn() && Number(outCounterFn().textContent) === counter+2);
-  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter+2));
-  test.do(() => eventFn().dispatchEvent(new Event("dblclick", {bubbles: true})));
-  test.wait(() => outCounterFn() && Number(outCounterFn().textContent) === counter+3);
-  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter+3));
-  test.do(() => eventFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => outCounterFn() && Number(outCounterFn().textContent) === counter+3);
-  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter+3));
-  test.do(() => ajaxFn().dispatchEvent(new Event("dblclick", {bubbles: true})));
-  test.wait(() => outCounterFn() && Number(outCounterFn().textContent) === counter+4);
-  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter+4));
+  test.event("dblclick", ajaxFn, () => outCounterFn() && Number(outCounterFn().textContent) === counter + 1);
+  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter + 1));
+  test.event("dblclick", eventFn, () => outCounterFn() && Number(outCounterFn().textContent) === counter + 2);
+  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter + 2));
+  test.event("click", ajaxFn, () => outCounterFn() && Number(outCounterFn().textContent) === counter + 2);
+  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter + 2));
+  test.event("dblclick", eventFn, () => outCounterFn() && Number(outCounterFn().textContent) === counter + 3);
+  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter + 3));
+  test.event("click", eventFn, () => outCounterFn() && Number(outCounterFn().textContent) === counter + 3);
+  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter + 3));
+  test.event("dblclick", ajaxFn, () => outCounterFn() && Number(outCounterFn().textContent) === counter + 4);
+  test.do(() => expect(Number(outCounterFn().textContent)).toBe(counter + 4));
   test.start();
 });
 
 it("f:ajax and tc:event", function (done) {
   let submitFn = querySelectorFn("#page\\:mainForm\\:btnAjaxEvent");
-  let outFn = querySelectorFn("#page\\:mainForm\\:out span");
+  let outFn = querySelectorFn("#page\\:mainForm\\:out tobago-out");
 
   let test = new JasmineTestTool(done);
-  test.setup(
-      () => outFn().textContent === "Ajax",
-      () => submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  );
-  test.do(() => submitFn().dispatchEvent(new Event("dblclick", {bubbles: true})));
-  test.wait(() => outFn() && outFn().textContent === "Event");
+  test.setup(() => outFn().textContent === "Ajax",
+      null, "click", submitFn);
+  test.event("dblclick", submitFn, () => outFn() && outFn().textContent === "Event");
   test.do(() => expect(outFn().textContent).toBe("Event"));
-  test.do(() => submitFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => outFn() && outFn().textContent === "Ajax");
+  test.event("click", submitFn, () => outFn() && outFn().textContent === "Ajax");
   test.do(() => expect(outFn().textContent).toBe("Ajax"));
   test.start();
-});
-
-
+});*/
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/51-for-each/For_Each.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/51-for-each/For_Each.test.js
index 9b31157..98f96d3 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/51-for-each/For_Each.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/51-for-each/For_Each.test.js
@@ -29,21 +29,17 @@ it("Add a river and reset.", function (done) {
   let uiRepeatSectionsFn = querySelectorAllFn("#page\\:mainForm\\:uiRepeat tobago-section");
 
   let test = new JasmineTestTool(done);
-  test.do(() => resetFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => forEachBoxesFn() && forEachBoxesFn().length !== 0);
+  test.setup(() => forEachBoxesFn().length === 3,
+      null, "click", resetFn);
   test.do(() => expect(forEachBoxesFn().length).toBe(3));
   test.do(() => expect(uiRepeatSectionsFn().length).toBe(3));
   test.do(() => nameFn().value = "Mississippi");
   test.do(() => lengthFn().value = "6275");
   test.do(() => dischargeFn().value = "16200");
-  test.do(() => addFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => forEachBoxesFn() && forEachBoxesFn().length === 4
-      && uiRepeatSectionsFn() && uiRepeatSectionsFn().length === 4);
+  test.event("click", addFn, () => forEachBoxesFn().length === 4 && uiRepeatSectionsFn().length === 4);
   test.do(() => expect(forEachBoxesFn().length).toBe(4));
   test.do(() => expect(uiRepeatSectionsFn().length).toBe(4));
-  test.do(() => resetFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => forEachBoxesFn() && forEachBoxesFn().length === 3
-      && uiRepeatSectionsFn() && uiRepeatSectionsFn().length === 3);
+  test.event("click", resetFn, () => forEachBoxesFn().length === 3 && uiRepeatSectionsFn().length === 3);
   test.do(() => expect(forEachBoxesFn().length).toBe(3));
   test.do(() => expect(uiRepeatSectionsFn().length).toBe(3));
   test.start();
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/00-collapsible-box/Collapsible_Box.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/00-collapsible-box/Collapsible_Box.test.js
index 47a7864..c29fc9d 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/00-collapsible-box/Collapsible_Box.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/00-collapsible-box/Collapsible_Box.test.js
@@ -26,7 +26,7 @@ it("Simple Collapsible Box: show -> hide transition", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => contentFn(),
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", showFn);
   test.do(() => expect(contentFn() !== null).toBe(true));
   test.event("click", hideFn, () => !contentFn());
   test.do(() => expect(contentFn() !== null).toBe(false));
@@ -41,7 +41,7 @@ it("Simple Collapsible Box: hide -> show transition", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => !contentFn(),
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", hideFn);
   test.do(() => expect(contentFn() !== null).toBe(false));
   test.event("click", showFn, () => contentFn());
   test.do(() => expect(contentFn() !== null).toBe(true));
@@ -59,10 +59,10 @@ it("Full Server Request: open both boxes", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => !content1Fn(),
-      () => hide1Fn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", hide1Fn);
   test.setup(
       () => !content2Fn(),
-      () => hide2Fn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", hide2Fn);
   test.do(() => expect(content1Fn() !== null).toBe(false));
   test.do(() => expect(content2Fn() !== null).toBe(false));
   test.event("click", show1Fn, () => content1Fn());
@@ -85,10 +85,10 @@ it("Full Server Request: open box 1, close box 2", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => !content1Fn(),
-      () => hide1Fn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", hide1Fn);
   test.setup(
       () => content2Fn(),
-      () => show2Fn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", show2Fn);
   test.do(() => expect(content1Fn() !== null).toBe(false));
   test.do(() => expect(content2Fn() !== null).toBe(true));
   test.event("click", show1Fn, () => content1Fn());
@@ -111,10 +111,10 @@ it("Full Server Request: close box 1, open box 2", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => content1Fn(),
-      () => show1Fn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", show1Fn);
   test.setup(
       () => !content2Fn(),
-      () => hide2Fn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", hide2Fn);
   test.do(() => expect(content1Fn() !== null).toBe(true));
   test.do(() => expect(content2Fn() !== null).toBe(false));
   test.event("click", hide1Fn, () => !content1Fn());
@@ -137,10 +137,10 @@ it("Full Server Request: close both boxes", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => content1Fn(),
-      () => show1Fn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", show1Fn);
   test.setup(
       () => content2Fn(),
-      () => show2Fn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", show2Fn);
   test.do(() => expect(content1Fn() !== null).toBe(true));
   test.do(() => expect(content2Fn() !== null).toBe(true));
   test.event("click", hide1Fn, () => !content1Fn());
@@ -158,9 +158,10 @@ it("Client Side: show -> hide transition", function (done) {
   let boxFn = querySelectorFn("#page\\:mainForm\\:client\\:noRequestBox");
 
   let test = new JasmineTestTool(done);
-  test.do(() => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(() => !boxFn().classList.contains("tobago-collapsed"),
+      null, "click", showFn);
   test.do(() => expect(boxFn().classList.contains("tobago-collapsed")).toBe(false));
-  test.do(() => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.event("click", hideFn, () => boxFn().classList.contains("tobago-collapsed"));
   test.do(() => expect(boxFn().classList.contains("tobago-collapsed")).toBe(true));
   test.start();
 });
@@ -171,28 +172,29 @@ it("Client Side: hide -> show transition", function (done) {
   let boxFn = querySelectorFn("#page\\:mainForm\\:client\\:noRequestBox");
 
   let test = new JasmineTestTool(done);
-  test.do(() => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(() => boxFn().classList.contains("tobago-collapsed"),
+      null, "click", hideFn);
   test.do(() => expect(boxFn().classList.contains("tobago-collapsed")).toBe(true));
-  test.do(() => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.event("click", showFn, () => !boxFn().classList.contains("tobago-collapsed"));
   test.do(() => expect(boxFn().classList.contains("tobago-collapsed")).toBe(false));
   test.start();
 });
 
 it("Client Side: hide content and submit empty string", function (done) {
   let messagesFn = querySelectorAllFn("#page\\:messages.tobago-messages div");
+  let showFn = querySelectorFn("#page\\:mainForm\\:client\\:showNoRequestBox");
   let hideFn = querySelectorFn("#page\\:mainForm\\:client\\:hideNoRequestBox");
   let boxFn = querySelectorFn("#page\\:mainForm\\:client\\:noRequestBox");
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inNoRequestBox\\:\\:field");
   let submitFn = querySelectorFn("#page\\:mainForm\\:client\\:submitNoRequestBox");
 
   let test = new JasmineTestTool(done);
-  test.setup(
-      () => messagesFn() && messagesFn().length === 0,
-      () => {
-        inFn().value = "some content";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}));
-      });
-  test.do(() => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(() => messagesFn() && messagesFn().length === 0,
+      () => inFn().value = "some content",
+      "click", submitFn);
+  test.setup(() => !boxFn().classList.contains("tobago-collapsed"),
+      null, "click", showFn);
+  test.event("click", hideFn, () => boxFn().classList.contains("tobago-collapsed"));
   test.do(() => expect(boxFn().classList.contains("tobago-collapsed")).toBe(true));
   test.do(() => inFn().value = "");
   test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
@@ -208,7 +210,7 @@ it("Ajax: show -> hide transition", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => inFn(),
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", showFn);
   test.do(() => expect(inFn() !== null).toBe(true));
   test.event("click", hideFn, () => !inFn());
   test.do(() => expect(inFn() !== null).toBe(false));
@@ -223,7 +225,7 @@ it("Ajax: hide -> show transition", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => !inFn(),
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", hideFn);
   test.do(() => expect(inFn() !== null).toBe(false));
   test.event("click", showFn, () => inFn());
   test.do(() => expect(inFn() !== null).toBe(true));
@@ -241,10 +243,10 @@ it("Ajax: submit empty string with shown and hidden content", function (done) {
   let test = new JasmineTestTool(done);
   test.setup(
       () => inFn(),
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", showFn);
   test.setup(
       () => messagesFn() && messagesFn().length === 0,
-      () => hide1FullReqFn().dispatchEvent(new Event("click", {bubbles: true})));
+      null, "click", hide1FullReqFn);
   test.do(() => expect(inFn() !== null).toBe(true));
   test.do(() => inFn().value = "");
   test.event("click", submitFn, () => messagesFn() && messagesFn().length === 1);
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/20-collapsible-panel/Collapsible_Panel.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/20-collapsible-panel/Collapsible_Panel.test.js
index f29c4f1..619859a 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/20-collapsible-panel/Collapsible_Panel.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/20-collapsible-panel/Collapsible_Panel.test.js
@@ -26,8 +26,9 @@ it("Simple Panel: show -> hide transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:simple\\:inSimple\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
@@ -45,8 +46,9 @@ it("Simple Panel: hide -> show transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:simple\\:inSimple\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "true" && inFn() === null,
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "true" && inFn() === null,
+      null, "click", hideFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
   test.event("click", showFn, () => panelCollapsedFn().value === "false" && inFn() !== null);
@@ -64,13 +66,13 @@ it("Simple Panel: collapsed = false; submit valid input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:simple\\:inSimple\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Alice");
@@ -87,13 +89,13 @@ it("Simple Panel: collapsed = false; submit empty input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:simple\\:inSimple\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -114,18 +116,19 @@ it("Simple Panel: valid input; show -> hide transition; submit", function (done)
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Charlie");
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -142,18 +145,19 @@ it("Simple Panel: empty input; show -> hide transition; submit", function (done)
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "");
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -167,8 +171,9 @@ it("Full Server Request: show -> hide transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:server\\:inServer\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
@@ -186,8 +191,9 @@ it("Full Server Request: hide -> show transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:server\\:inServer\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "true" && inFn() === null,
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "true" && inFn() === null,
+      null, "click", hideFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
   test.event("click", showFn, () => panelCollapsedFn().value === "false" && inFn() !== null);
@@ -205,13 +211,13 @@ it("Full Server Request: collapsed = false; submit valid input", function (done)
   let inFn = querySelectorFn("#page\\:mainForm\\:server\\:inServer\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Alice");
@@ -228,13 +234,13 @@ it("Full Server Request: collapsed = false; submit empty input", function (done)
   let inFn = querySelectorFn("#page\\:mainForm\\:server\\:inServer\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -255,18 +261,19 @@ it("Full Server Request: valid input; show -> hide transition; submit", function
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Charlie");
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -283,18 +290,19 @@ it("Full Server Request: empty input; show -> hide transition; submit", function
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "");
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -309,13 +317,13 @@ it("Client Sided: show -> hide transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Alice";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => panelCollapsedFn().value === "false",
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Alice",
+      "click", submitFn);
+  test.setup(
+      () => panelCollapsedFn().value === "false",
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", hideFn, () => panelCollapsedFn().value === "true");
@@ -334,13 +342,13 @@ it("Client Sided: hide -> show transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => panelCollapsedFn().value === "true",
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
+  test.setup(
+      () => panelCollapsedFn().value === "true",
+      null, "click", hideFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", showFn, () => panelCollapsedFn().value === "false");
@@ -358,13 +366,13 @@ it("Client Sided: collapsed = false; submit valid input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => panelCollapsedFn().value === "false",
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
+  test.setup(
+      () => panelCollapsedFn().value === "false",
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Charlie");
@@ -381,13 +389,13 @@ it("Client Sided: collapsed = false; submit empty input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => panelCollapsedFn().value === "false",
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
+  test.setup(
+      () => panelCollapsedFn().value === "false",
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -405,13 +413,13 @@ it("Client Sided: collapsed = true; submit valid input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => panelCollapsedFn().value === "true",
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
+  test.setup(
+      () => panelCollapsedFn().value === "true",
+      null, "click", hideFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Dave");
@@ -428,13 +436,13 @@ it("Client Sided: collapsed = true; submit empty input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Eve";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => panelCollapsedFn().value === "true",
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Eve",
+      "click", submitFn);
+  test.setup(
+      () => panelCollapsedFn().value === "true",
+      null, "click", hideFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -454,12 +462,13 @@ it("Ajax: show -> hide transition", function (done) {
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0, () => {
-    clientInFn().value = "Alice";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => clientInFn().value = "Alice",
+      "click", clientSubmitFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
@@ -479,12 +488,13 @@ it("Ajax: hide -> show transition", function (done) {
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "true" && inFn() === null,
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0, () => {
-    clientInFn().value = "Bob";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => panelCollapsedFn().value === "true" && inFn() === null,
+      null, "click", hideFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => clientInFn().value = "Bob",
+      "click", clientSubmitFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
   test.event("click", showFn, () => panelCollapsedFn().value === "false" && inFn() !== null);
@@ -502,13 +512,13 @@ it("Ajax: collapsed = false; submit valid input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:ajax\\:inAjax\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Alice");
@@ -525,13 +535,13 @@ it("Ajax: collapsed = false; submit empty input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:ajax\\:inAjax\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -552,18 +562,19 @@ it("Ajax: valid input; show -> hide transition; submit", function (done) {
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Charlie");
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -580,18 +591,19 @@ it("Ajax: empty input; show -> hide transition; submit", function (done) {
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => panelCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => panelCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(panelCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "");
   test.event("click", hideFn, () => panelCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(panelCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/30-collapsible-section/Collapsible_Section.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/30-collapsible-section/Collapsible_Section.test.js
index cbfaac7..c6fc592 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/30-collapsible-section/Collapsible_Section.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/30-concept/53-collapsible/30-collapsible-section/Collapsible_Section.test.js
@@ -26,8 +26,9 @@ it("Simple Section: show -> hide transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:simple\\:inSimple\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
@@ -45,8 +46,9 @@ it("Simple Section: hide -> show transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:simple\\:inSimple\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "true" && inFn() === null,
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "true" && inFn() === null,
+      null, "click", hideFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
   test.event("click", showFn, () => sectionCollapsedFn().value === "false" && inFn() !== null);
@@ -64,13 +66,13 @@ it("Simple Section: collapsed = false; submit valid input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:simple\\:inSimple\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Alice");
@@ -87,13 +89,13 @@ it("Simple Section: collapsed = false; submit empty input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:simple\\:inSimple\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -114,18 +116,19 @@ it("Simple Section: valid input; show -> hide transition; submit", function (don
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Charlie");
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -142,18 +145,19 @@ it("Simple Section: empty input; show -> hide transition; submit", function (don
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "");
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -167,8 +171,9 @@ it("Full Server Request: show -> hide transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:server\\:inServer\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
@@ -186,8 +191,9 @@ it("Full Server Request: hide -> show transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:server\\:inServer\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "true" && inFn() === null,
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "true" && inFn() === null,
+      null, "click", hideFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
   test.event("click", showFn, () => sectionCollapsedFn().value === "false" && inFn() !== null);
@@ -205,13 +211,13 @@ it("Full Server Request: collapsed = false; submit valid input", function (done)
   let inFn = querySelectorFn("#page\\:mainForm\\:server\\:inServer\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Alice");
@@ -228,13 +234,13 @@ it("Full Server Request: collapsed = false; submit empty input", function (done)
   let inFn = querySelectorFn("#page\\:mainForm\\:server\\:inServer\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -255,18 +261,19 @@ it("Full Server Request: valid input; show -> hide transition; submit", function
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Charlie");
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -283,18 +290,19 @@ it("Full Server Request: empty input; show -> hide transition; submit", function
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "");
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -309,13 +317,13 @@ it("Client Sided: show -> hide transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Alice";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => sectionCollapsedFn().value === "false",
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Alice",
+      "click", submitFn);
+  test.setup(
+      () => sectionCollapsedFn().value === "false",
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true");
@@ -334,13 +342,13 @@ it("Client Sided: hide -> show transition", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => sectionCollapsedFn().value === "true",
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
+  test.setup(
+      () => sectionCollapsedFn().value === "true",
+      null, "click", hideFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", showFn, () => sectionCollapsedFn().value === "false");
@@ -358,13 +366,13 @@ it("Client Sided: collapsed = false; submit valid input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => sectionCollapsedFn().value === "false",
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
+  test.setup(
+      () => sectionCollapsedFn().value === "false",
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Charlie");
@@ -381,13 +389,13 @@ it("Client Sided: collapsed = false; submit empty input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => sectionCollapsedFn().value === "false",
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
+  test.setup(
+      () => sectionCollapsedFn().value === "false",
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -405,13 +413,13 @@ it("Client Sided: collapsed = true; submit valid input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => sectionCollapsedFn().value === "true",
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
+  test.setup(
+      () => sectionCollapsedFn().value === "true",
+      null, "click", hideFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Dave");
@@ -428,13 +436,13 @@ it("Client Sided: collapsed = true; submit empty input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Eve";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
-  test.setup(() => sectionCollapsedFn().value === "true",
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Eve",
+      "click", submitFn);
+  test.setup(
+      () => sectionCollapsedFn().value === "true",
+      null, "click", hideFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -454,12 +462,13 @@ it("Ajax: show -> hide transition", function (done) {
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0, () => {
-    clientInFn().value = "Alice";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => clientInFn().value = "Alice",
+      "click", clientSubmitFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
@@ -479,12 +488,13 @@ it("Ajax: hide -> show transition", function (done) {
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "true" && inFn() === null,
-      () => hideFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0, () => {
-    clientInFn().value = "Bob";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => sectionCollapsedFn().value === "true" && inFn() === null,
+      null, "click", hideFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => clientInFn().value = "Bob",
+      "click", clientSubmitFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
   test.event("click", showFn, () => sectionCollapsedFn().value === "false" && inFn() !== null);
@@ -502,13 +512,13 @@ it("Ajax: collapsed = false; submit valid input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:ajax\\:inAjax\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length > 0,
-      () => {
-        inFn().value = "";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length > 0,
+      () => inFn().value = "",
+      "click", submitFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Alice");
@@ -525,13 +535,13 @@ it("Ajax: collapsed = false; submit empty input", function (done) {
   let inFn = querySelectorFn("#page\\:mainForm\\:ajax\\:inAjax\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.setup(() => messagesFn().length === 0,
-      () => {
-        inFn().value = "Bob";
-        submitFn().dispatchEvent(new Event("click", {bubbles: true}))
-      });
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
+  test.setup(
+      () => messagesFn().length === 0,
+      () => inFn().value = "Bob",
+      "click", submitFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => expect(messagesFn().length).toBe(0));
@@ -552,18 +562,19 @@ it("Ajax: valid input; show -> hide transition; submit", function (done) {
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "Charlie");
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
@@ -580,18 +591,19 @@ it("Ajax: empty input; show -> hide transition; submit", function (done) {
   let clientInFn = querySelectorFn("#page\\:mainForm\\:client\\:inClient\\:\\:field");
 
   let test = new JasmineTestTool(done);
-  test.setup(() => sectionCollapsedFn().value === "false" && inFn() !== null,
-      () => showFn().dispatchEvent(new Event("click", {bubbles: true})));
+  test.setup(
+      () => sectionCollapsedFn().value === "false" && inFn() !== null,
+      null, "click", showFn);
   test.do(() => expect(sectionCollapsedFn().value).toBe("false"));
   test.do(() => expect(inFn()).not.toBeNull());
   test.do(() => inFn().value = "");
   test.event("click", hideFn, () => sectionCollapsedFn().value === "true" && inFn() === null);
   test.do(() => expect(sectionCollapsedFn().value).toBe("true"));
   test.do(() => expect(inFn()).toBeNull());
-  test.setup(() => messagesFn().length > 0, () => {
-    clientInFn().value = "";
-    clientSubmitFn().dispatchEvent(new Event("click", {bubbles: true}))
-  });
+  test.setup(
+      () => messagesFn().length > 0,
+      () => clientInFn().value = "",
+      "click", clientSubmitFn);
   test.event("click", submitFn, () => messagesFn().length === 0);
   test.do(() => expect(messagesFn().length).toBe(0));
   test.start();
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/40000-style/100-headings/Headings.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/40000-style/100-headings/Headings.test.js
index 4c57bc5..e82a7c1 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/40000-style/100-headings/Headings.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/40000-style/100-headings/Headings.test.js
@@ -75,13 +75,12 @@ function testFont(done, alinkFn, buttonlinkFn) {
 it("Ajax reload for section 2", function (done) {
   let reloadButtonFn = querySelectorFn("#page\\:mainForm\\:reloadSection2");
   let section2HeaderFn = querySelectorFn("#page\\:mainForm\\:levelTwoSection h3");
-  let timestampFn = querySelectorFn("#page\\:mainForm\\:timestamp span");
+  let timestampFn = querySelectorFn("#page\\:mainForm\\:timestamp tobago-out");
   let firstTimestamp = timestampFn().textContent;
 
   let test = new JasmineTestTool(done);
   test.do(() => expect(section2HeaderFn() !== null).toBe(true));
-  test.do(() => reloadButtonFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => reloadButtonFn() && section2HeaderFn() !== null);
+  test.event("click", reloadButtonFn, () => firstTimestamp < timestampFn().textContent);
   test.do(() => expect(section2HeaderFn() !== null).toBe(true));
   test.do(() => expect(firstTimestamp < timestampFn().textContent).toBe(true, "value of new timestamp must be higher"));
   test.start();
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/30-ajax-special-character/Ajax_Special_Character.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/30-ajax-special-character/Ajax_Special_Character.test.js
index b58a59d..0514db2 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/30-ajax-special-character/Ajax_Special_Character.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/40-test/50000-java/30-ajax-special-character/Ajax_Special_Character.test.js
@@ -29,8 +29,7 @@ it("ajax execute", function (done) {
   let tipValue = tipFn().getAttribute('title');
 
   let test = new JasmineTestTool(done);
-  test.do(() => buttonFn().dispatchEvent(new Event("click", {bubbles: true})));
-  test.wait(() => timestampFn() && timestampFn().textContent !== timestampValue);
+  test.event("click", buttonFn, () => timestampFn() && timestampFn().textContent !== timestampValue);
   test.do(() => expect(timestampFn().textContent).not.toBe(timestampValue));
   test.do(() => expect(textFn().textContent).toBe(textValue));
   test.do(() => expect(tipFn().getAttribute('title')).toBe(tipValue));
diff --git a/tobago-tool/tobago-tool-test/src/main/resources/META-INF/resources/tobago/test/tobago-test-tool.js b/tobago-tool/tobago-tool-test/src/main/resources/META-INF/resources/tobago/test/tobago-test-tool.js
index 0fe3a2e..45c47b0 100644
--- a/tobago-tool/tobago-tool-test/src/main/resources/META-INF/resources/tobago/test/tobago-test-tool.js
+++ b/tobago-tool/tobago-tool-test/src/main/resources/META-INF/resources/tobago/test/tobago-test-tool.js
@@ -15,18 +15,6 @@
  * limitations under the License.
  */
 
-function TobagoTestTool(assert) {
-  this.assert = assert;
-  this.steps = [];
-}
-
-TobagoTestTool.stepType = {
-  ACTION: 1,
-  WAIT_RESPONSE: 2,
-  WAIT_MS: 3,
-  ASSERTS: 4
-};
-
 class JasmineUtils {
   static isMsie() {
     return navigator.userAgent.indexOf("MSIE") > -1 || navigator.userAgent.indexOf("Trident") > -1;
@@ -69,167 +57,6 @@ class JasmineUtils {
   };
 }
 
-TobagoTestTool.prototype = {
-  action: function (func) {
-    this.steps.push({
-      type: TobagoTestTool.stepType.ACTION,
-      func: func
-    });
-  },
-  waitForResponse: function () {
-    this.steps.push({
-      type: TobagoTestTool.stepType.WAIT_RESPONSE
-    });
-  },
-  waitMs: function (ms) {
-    this.steps.push({
-      type: TobagoTestTool.stepType.WAIT_MS,
-      ms: ms ? ms : 0
-    });
-  },
-  asserts: function (numOfAssertions, func) {
-    this.steps.push({
-      type: TobagoTestTool.stepType.ASSERTS,
-      numOfAssertions: numOfAssertions ? numOfAssertions : 0,
-      func: func
-    });
-  },
-  startTest: function () {
-    const steps = this.steps.slice(0);
-    const cycleTiming = 50;
-    let currentStep = 0;
-    let testStepTimeout;
-
-    function getAssertExpect() {
-      var expect = 0;
-      steps.forEach(function (step) {
-        if (step.type === TobagoTestTool.stepType.ASSERTS) {
-          expect += step.numOfAssertions;
-        }
-      });
-      return expect;
-    }
-
-    function getAssertAsync() {
-      var async = 0;
-      steps.forEach(function (step) {
-        if (step.type === TobagoTestTool.stepType.ASSERTS) {
-          async++;
-        }
-      });
-      return async;
-    }
-
-    this.assert.expect(getAssertExpect());
-    const done = this.assert.async(getAssertAsync());
-    const assert = this.assert;
-
-    function resetTestStepTimeout(additionalMs) {
-      const timeout = additionalMs ? 20000 + additionalMs : 20000;
-      testStepTimeout = Date.now() + timeout;
-    }
-
-    let waitForResponse = false;
-    let ajaxRequestDetected = false;
-    let ajaxRequestDone = false;
-    let fullPageReloadDetected = false;
-    let fullPageReloadDone = false;
-
-    function registerAjaxReadyStateListener() {
-      let oldXHR = document.getElementById("page:testframe").contentWindow.XMLHttpRequest;
-
-      function newXHR() {
-        let realXHR = new oldXHR();
-        realXHR.addEventListener("readystatechange", function () {
-          if (realXHR.readyState !== XMLHttpRequest.UNSENT && realXHR.readyState !== XMLHttpRequest.DONE) {
-            ajaxRequestDetected = true;
-          } else if (ajaxRequestDetected && realXHR.readyState === XMLHttpRequest.DONE) {
-            ajaxRequestDone = true;
-            waitForResponse = false;
-          }
-        }, false);
-        return realXHR;
-      }
-
-      document.getElementById("page:testframe").contentWindow.XMLHttpRequest = newXHR;
-    }
-
-    function fullPageReloadPolling() {
-      const testframe = document.getElementById("page:testframe");
-      if (testframe === null
-          || testframe.contentWindow.document.readyState !== "complete"
-          || testframe.contentWindow.document.querySelector("html") === null) {
-        fullPageReloadDetected = true;
-      } else if (fullPageReloadDetected) {
-        fullPageReloadDone = true;
-        waitForResponse = false;
-      }
-
-      if (!fullPageReloadDone && !ajaxRequestDone) {
-        setTimeout(fullPageReloadPolling, cycleTiming);
-      }
-    }
-
-    function cycle() {
-      if (currentStep >= steps.length) {
-        // we are done here
-      } else if (Date.now() >= testStepTimeout) {
-        assert.ok(false, "Timeout!");
-        if (steps[currentStep].stepType === TobagoTestTool.stepType.ASSERTS) {
-          done();
-        }
-        currentStep++;
-        cycle();
-      } else if (waitForResponse) {
-        // we need to wait more
-        setTimeout(cycle, cycleTiming);
-      } else if (steps[currentStep].type === TobagoTestTool.stepType.ACTION) {
-        if (currentStep + 1 < steps.length && steps[currentStep + 1].type === TobagoTestTool.stepType.WAIT_RESPONSE) {
-          // register listener for ajax before action is executed, otherwise the ajax listener is registered too late
-          registerAjaxReadyStateListener();
-          steps[currentStep].func();
-          currentStep++;
-          cycle();
-        } else {
-          steps[currentStep].func();
-          currentStep++;
-          resetTestStepTimeout();
-          setTimeout(cycle, cycleTiming);
-        }
-      } else if (steps[currentStep].type === TobagoTestTool.stepType.WAIT_RESPONSE) {
-        waitForResponse = true;
-        ajaxRequestDetected = false;
-        ajaxRequestDone = false;
-        fullPageReloadDetected = false;
-        fullPageReloadDone = false;
-        registerAjaxReadyStateListener();
-        fullPageReloadPolling();
-
-        currentStep++;
-        resetTestStepTimeout();
-        setTimeout(cycle, cycleTiming);
-      } else if (steps[currentStep].type === TobagoTestTool.stepType.WAIT_MS) {
-        const ms = steps[currentStep].ms;
-
-        currentStep++;
-        resetTestStepTimeout(ms);
-        setTimeout(cycle, ms);
-      } else if (steps[currentStep].type === TobagoTestTool.stepType.ASSERTS) {
-        steps[currentStep].func();
-        currentStep++;
-        done();
-        resetTestStepTimeout();
-        setTimeout(cycle, cycleTiming);
-      }
-    }
-
-    resetTestStepTimeout();
-    cycle();
-  }
-};
-
-export {TobagoTestTool};
-
 class JasmineTestTool {
 
   static ajaxReadyStateChangeEvent = "tobago.jtt.ajax.readyStateChange";
@@ -237,7 +64,6 @@ class JasmineTestTool {
   steps = [];
   done;
   timeout;
-  lastStepExecution;
 
   /**
    * @param done function from Jasmine; must called if all Steps done or timeout
@@ -246,53 +72,61 @@ class JasmineTestTool {
   constructor(done, timeout) {
     this.done = done;
     this.timeout = timeout ? timeout : 20000;
-    this.registerAjaxReadyStateListener();
   }
 
   /**
-   * The require function (require) defines the desired state before the main test starts. The fix function (fix)
-   * will be executed if the require function returns false.
-   * @param require function
-   * @param fix function
+   * Setup a test.
+   * @param startConditionFn the desired start condition
+   * @param doFn may be null; if start condition is not fulfilled, doFn is executed
+   * @param eventType if start condition is not fulfilled, an event is dispatched
+   * @param eventElement if start condition is not fulfilled, an event is dispatched
    */
-  setup(require, fix) {
-    this.do(() => {
-      if (!require()) {
-        console.debug("[JasmineTestTool] require() returns false, execute fix()");
-        fix();
-      }
-    })
-    this.wait(require);
+  setup(startConditionFn, doFn, eventType, eventElement) {
+    let eventFn;
+    if (typeof eventElement !== "function") {
+      eventFn = () => fail("'eventElement' must be a function but was: " + eventElement);
+    } else {
+      eventFn = () => eventElement().dispatchEvent(new Event(eventType, {bubbles: true}));
+    }
+
+    this.steps.push({
+      type: "setup",
+      startConditionFunc: startConditionFn,
+      doFunc: doFn,
+      eventFunc: eventFn,
+      substep: 4
+    });
   }
 
   /**
-   * Execute dispatchEvent() on the given element. The result function must return false before dispatch.
-   * After the dispatch
-   * @param type of the event
-   * @param element function
-   * @param result function
+   * Execute dispatchEvent() on the given element.
+   * @param type of the event, e.g. 'click' or 'change'
+   * @param element on which the event is dispatched, like a querySelector for a button element
+   * @param result function to indicate if the event dispatched correctly. Must be return 'false' before the event is
+   * dispatched. Must be return 'true' after the event is dispatched.
    */
   event(type, element, result) {
-    if (typeof element === "function") {
-      this.do(() => {
-        if (result()) {
-          fail("The result function (" + result + ") returns true BEFORE the '" + type + "' event is dispatched."
-              + " Please define a result function that return false before dispatch event and return true after" +
-              " dispatch event.");
-        }
-      });
-      this.do(() => element().dispatchEvent(new Event(type, {bubbles: true})));
-      this.wait(result);
+    let eventFn;
+    if (typeof element !== "function") {
+      eventFn = () => fail("'element' must be a function but was: " + element);
     } else {
-      fail("event(type, element, result); 'element' must be a function but was: " + element);
+      eventFn = () => element().dispatchEvent(new Event(type, {bubbles: true}));
     }
+
+    this.steps.push({
+      type: "event",
+      eventType: type,
+      eventFunc: eventFn,
+      resultFunc: result,
+      substep: 3
+    });
   }
 
   do(fn) {
     this.steps.push({
       type: "do",
       func: fn,
-      done: false
+      substep: 1
     });
   }
 
@@ -300,108 +134,166 @@ class JasmineTestTool {
     this.steps.push({
       type: "wait",
       func: fn,
-      done: false
+      substep: 1
     });
   }
 
   start() {
+    const steps = this.steps;
+    let done = this.done;
+    const timeout = this.timeout;
+    let lastStepExecution;
+
     console.debug("[JasmineTestTool] start");
-    this.resetTimeout();
-    this.cycle();
-  }
+    registerAjaxReadyStateListener();
+    resetTimeout();
+    cycle();
 
-  cycle() {
-    const nextStep = this.getNextStep();
+    function cycle() {
+      const nextStep = getNextStep();
 
-    if (this.isFinished()) {
-      this.done();
-    } else if (this.isTimeout()) {
-      fail("Timeout of '" + nextStep.type + "'-step: " + nextStep.func);
-      nextStep.done = true;
-      this.resetTimeout();
-      window.setTimeout(this.cycle.bind(this), 0);
-    } else if (!this.isDocumentReady() || !this.isAjaxReady()) {
-      console.debug("[JasmineTestTool] documentReady: " + this.isDocumentReady()
-          + " - ajaxReady: " + this.isAjaxReady());
-      window.setTimeout(this.cycle.bind(this), 50);
-    } else if (nextStep.type === "do") {
-      console.debug("[JasmineTestTool] do-step: " + nextStep.func);
-      this.registerCustomXmlHttpRequest();
-      nextStep.func();
-      nextStep.done = true;
-      this.resetTimeout();
-      window.setTimeout(this.cycle.bind(this), 0);
-    } else if (nextStep.type === "wait") {
-      console.debug("[JasmineTestTool] wait-step: " + nextStep.func);
-      if (nextStep.func()) {
-        nextStep.done = true;
-        this.resetTimeout();
+      if (isFinished()) {
+        done();
+        console.debug("[JasmineTestTool] finished");
+      } else if (isTimeout()) {
+        fail("Timeout of " + JSON.stringify(nextStep));
+        nextStep.substep = 0;
+        resetTimeout();
+        window.setTimeout(cycle, 1);
+      } else if (!isDocumentReady() || !isAjaxReady()) {
+        console.debug("[JasmineTestTool] documentReady: " + isDocumentReady() + " - ajaxReady: " + isAjaxReady());
+        window.setTimeout(cycle, 50);
+      } else if (nextStep.type === "setup" && nextStep.substep === 4) {
+        console.debug("[JasmineTestTool] setup/4-step: " + nextStep.startConditionFunc);
+        if (nextStep.startConditionFunc()) {
+          nextStep.substep = 0;
+        } else {
+          nextStep.substep--;
+        }
+        resetTimeout();
+        window.setTimeout(cycle, 1);
+      } else if (nextStep.type === "setup" && nextStep.substep === 3) {
+        console.debug("[JasmineTestTool] setup/3-step: " + nextStep.doFunc);
+        if (nextStep.doFunc === null) {
+          nextStep.substep--;
+          resetTimeout();
+          window.setTimeout(cycle, 1);
+        } else {
+          execute(nextStep.doFunc, nextStep);
+        }
+      } else if (nextStep.type === "setup" && nextStep.substep === 2) {
+        console.debug("[JasmineTestTool] setup/2-step: " + nextStep.eventFunc);
+        execute(nextStep.eventFunc, nextStep);
+      } else if (nextStep.type === "setup" && nextStep.substep === 1) {
+        console.debug("[JasmineTestTool] setup/1-step: wait for " + nextStep.startConditionFunc);
+        waitFor(nextStep.startConditionFunc, nextStep);
+      } else if (nextStep.type === "event" && nextStep.substep === 3) {
+        console.debug("[JasmineTestTool] event/3-step: " + nextStep.resultFunc);
+        if (nextStep.resultFunc()) {
+          fail("The result function (" + nextStep.resultFunc + ") returns already 'true' BEFORE the '"
+              + nextStep.eventType + "' event is dispatched. Please define a result function which return 'false' before"
+              + " dispatch event and return 'true' after dispatch event.");
+          nextStep.substep = 0;
+          resetTimeout();
+          window.setTimeout(cycle, 1);
+        } else {
+          nextStep.substep--;
+          resetTimeout();
+          window.setTimeout(cycle, 1);
+        }
+      } else if (nextStep.type === "event" && nextStep.substep === 2) {
+        console.debug("[JasmineTestTool] event/2-step: " + nextStep.eventFunc);
+        execute(nextStep.eventFunc, nextStep);
+      } else if (nextStep.type === "event" && nextStep.substep === 1) {
+        console.debug("[JasmineTestTool] event/1-step: wait for " + nextStep.resultFunc);
+        waitFor(nextStep.resultFunc, nextStep);
+      } else if (nextStep.type === "do") {
+        console.debug("[JasmineTestTool] do-step: " + nextStep.func);
+        execute(nextStep.func, nextStep);
+      } else if (nextStep.type === "wait") {
+        console.debug("[JasmineTestTool] wait-step: " + nextStep.func);
+        waitFor(nextStep.func, nextStep);
+      } else {
+        fail("an unexpected error has occurred!");
+        done();
       }
-      window.setTimeout(this.cycle.bind(this), 50);
-    } else {
-      fail("an unexpected error has occurred!");
-      this.done();
     }
-  }
 
-  isFinished() {
-    for (let step of this.steps) {
-      if (!step.done) {
-        return false;
+    function getNextStep() {
+      for (let step of steps) {
+        if (step.substep > 0) {
+          return step;
+        }
       }
+      return null;
     }
-    return true;
-  }
 
-  isDocumentReady() {
-    return document.getElementById("page:testframe").contentWindow.document.readyState === "complete";
-  }
+    function isFinished() {
+      for (let step of steps) {
+        if (step.substep > 0) {
+          return false;
+        }
+      }
+      return true;
+    }
 
-  registerAjaxReadyStateListener() {
-    JasmineTestTool.ajaxReadyState = XMLHttpRequest.UNSENT;
-    window.removeEventListener(JasmineTestTool.ajaxReadyStateChangeEvent, JasmineTestTool.changeAjaxReadyState);
-    window.addEventListener(JasmineTestTool.ajaxReadyStateChangeEvent, JasmineTestTool.changeAjaxReadyState);
-  }
+    function isDocumentReady() {
+      return document.getElementById("page:testframe").contentWindow.document.readyState === "complete";
+    }
 
-  static changeAjaxReadyState(event) {
-    JasmineTestTool.ajaxReadyState = event.detail.readyState;
-    console.debug("[JasmineTestTool] ajaxReadyState: " + JasmineTestTool.ajaxReadyState);
-  }
+    function registerAjaxReadyStateListener() {
+      JasmineTestTool.ajaxReadyState = XMLHttpRequest.UNSENT;
+      window.removeEventListener(JasmineTestTool.ajaxReadyStateChangeEvent, JasmineTestTool.changeAjaxReadyState);
+      window.addEventListener(JasmineTestTool.ajaxReadyStateChangeEvent, JasmineTestTool.changeAjaxReadyState);
+    }
 
-  registerCustomXmlHttpRequest() {
-    class JasmineXMLHttpRequest extends XMLHttpRequest {
-      constructor() {
-        super();
-        this.addEventListener("readystatechange", function () {
-          window.dispatchEvent(new CustomEvent(JasmineTestTool.ajaxReadyStateChangeEvent,
-              {detail: {readyState: this.readyState}}));
-        });
+    function registerCustomXmlHttpRequest() {
+      class JasmineXMLHttpRequest extends XMLHttpRequest {
+        constructor() {
+          super();
+          this.addEventListener("readystatechange", function () {
+            window.dispatchEvent(new CustomEvent(JasmineTestTool.ajaxReadyStateChangeEvent,
+                {detail: {readyState: this.readyState}}));
+          });
+        }
       }
+
+      document.getElementById("page:testframe").contentWindow.XMLHttpRequest = JasmineXMLHttpRequest;
     }
 
-    document.getElementById("page:testframe").contentWindow.XMLHttpRequest = JasmineXMLHttpRequest;
-  }
+    function isAjaxReady() {
+      return JasmineTestTool.ajaxReadyState === XMLHttpRequest.UNSENT
+          || JasmineTestTool.ajaxReadyState === XMLHttpRequest.DONE;
+    }
 
-  isAjaxReady() {
-    return JasmineTestTool.ajaxReadyState === XMLHttpRequest.UNSENT
-        || JasmineTestTool.ajaxReadyState === XMLHttpRequest.DONE;
-  }
+    function isTimeout() {
+      return Date.now() > (lastStepExecution + timeout);
+    }
 
-  getNextStep() {
-    for (let step of this.steps) {
-      if (!step.done) {
-        return step;
-      }
+    function resetTimeout() {
+      lastStepExecution = Date.now();
+    }
+
+    function execute(fn, nextStep) {
+      registerCustomXmlHttpRequest();
+      fn();
+      nextStep.substep--;
+      resetTimeout();
+      window.setTimeout(cycle, 1);
     }
-    return null;
-  }
 
-  isTimeout() {
-    return Date.now() > (this.lastStepExecution + this.timeout);
+    function waitFor(fn, nextStep) {
+      if (fn()) {
+        nextStep.substep--;
+        resetTimeout();
+      }
+      window.setTimeout(cycle, 50);
+    }
   }
 
-  resetTimeout() {
-    this.lastStepExecution = Date.now();
+  static changeAjaxReadyState(event) {
+    JasmineTestTool.ajaxReadyState = event.detail.readyState;
+    console.debug("[JasmineTestTool] ajaxReadyState: " + JasmineTestTool.ajaxReadyState);
   }
 }