part 0: Update `exec-command-with-text-editor.tentative.html` for testing the following patches more

Differential Revision: https://phabricator.services.mozilla.com/D108566

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1220696
gecko-commit: 2ebe50bc549887f7af6fcbfd9e6f96e62a244f26
gecko-reviewers: smaug
diff --git a/editing/other/exec-command-with-text-editor.tentative.html b/editing/other/exec-command-with-text-editor.tentative.html
index e500c76..f9e6094 100644
--- a/editing/other/exec-command-with-text-editor.tentative.html
+++ b/editing/other/exec-command-with-text-editor.tentative.html
@@ -17,14 +17,14 @@
  */
 function runTests() {
   let container = document.getElementById("container");
-  container.innerHTML = "<input id=\"target\">";
+  container.innerHTML = "Here <b>is</b> Text: <input id=\"target\">";
   runTest(document.getElementById("target"), "In <input>");
-  container.innerHTML = "<textarea id=\"target\"></textarea>";
+  container.innerHTML = "Here <b>is</b> Text: <textarea id=\"target\"></textarea>";
   runTest(document.getElementById("target"), "In <textarea>");
   container.setAttribute("contenteditable", "true");
-  container.innerHTML = "<input id=\"target\">";
+  container.innerHTML = "Here <b>is</b> Text: <input id=\"target\">";
   runTest(document.getElementById("target"), "In <input> in contenteditable");
-  container.innerHTML = "<textarea id=\"target\"></textarea>";
+  container.innerHTML = "Here <b>is</b> Text: <textarea id=\"target\"></textarea>";
   runTest(document.getElementById("target"), "In <textarea> in contenteditable");
 
   done();
@@ -42,93 +42,163 @@
      *                execCommand() with command and param.  must have a
      *                pair of "[" and "]" for specifying selection range.
      * expectedExecCommandResult: expected bool result of execCommand().
+     * expectedCommandSupported: expected bool result of queryCommandSupported().
+     * expectedCommandEnabled: expected bool result of queryCommandEnabled().
      * beforeinputExpected: if "beforeinput" event shouldn't be fired, set
-     *                      false.  otherwise, expected inputType value.
-     * inputExpected: if "input" event shouldn't be fired, set false.
-     *                otherwise, expected inputType value.
+     *                      null.  otherwise, expected inputType value and
+     *                      target element.
+     * inputExpected: if "input" event shouldn't be fired, set null.
+     *                otherwise, expected inputType value and target element.
      */
+    {command: "getHTML", param: null,
+     value: "a[b]c", expectedValue: "a[b]c",
+     expectedExecCommandResult: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null, inputExpected: null,
+     additionalCheckFunc: aDescription => {
+       test(
+         () => assert_equals(document.queryCommandValue("getHTML"), "b"),
+         `${aDescription}: getHTML value should be "b" when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } has focus`
+       );
+       aTarget.blur();
+       container.focus();
+       getSelection().setBaseAndExtent(
+         container.firstChild,
+         1,
+         container.querySelector("b").nextSibling,
+         2
+       );
+       test(
+         () => assert_equals(document.queryCommandValue("getHTML"), "ere <b>is</b> T"),
+         `${aDescription}: getHTML value should be "ere <b>is</b> T" when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } does not have focus`
+        );
+      },
+    },
     {command: "bold", param: "bold",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "italic", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "underline", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "strikethrough", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "superscript", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     // Should return true for web apps implementing custom editor.
     {command: "cut", param: null,
      value: "ab[]c", expectedValue: "ab[]c",
-     expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: false,
+     expectedExecCommandResult: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "cut", param: null,
      value: "a[b]c", expectedValue: "a[]c",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "deleteByCut",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "deleteByCut", target: aTarget },
     },
     // Should return true for web apps implementing custom editor.
     {command: "copy", param: null,
      value: "abc[]d", expectedValue: "abc[]d",
-     expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: false,
+     expectedExecCommandResult: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "copy", param: null,
      value: "a[bc]d", expectedValue: "a[bc]d",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "paste", param: null,
      value: "a[]c", expectedValue: "a[bc]c",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "insertFromPaste",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "insertFromPaste", target: aTarget },
     },
     {command: "delete", param: null,
      value: "ab[]c", expectedValue: "a[]c",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "deleteContentBackward",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "deleteContentBackward", target: aTarget },
     },
     {command: "delete", param: null,
      value: "a[b]c", expectedValue: "a[]c",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "deleteContentBackward",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "deleteContentBackward", target: aTarget },
     },
     {command: "forwarddelete", param: null,
      value: "a[b]c", expectedValue: "a[]c",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "deleteContentForward",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "deleteContentForward", target: aTarget },
     },
     {command: "forwarddelete", param: null,
      value: "a[]bc", expectedValue: "a[]c",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "deleteContentForward",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "deleteContentForward", target: aTarget },
     },
     {command: "selectall", param: null,
      value: "a[b]c", expectedValue: "[abc]",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null, inputExpected: null,
     },
     // Setting value should forget any transactions.
     {command: "undo", param: null,
      value: "[a]bc", expectedValue: "[a]bc",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "undo", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
@@ -136,13 +206,18 @@
        document.execCommand("delete", false, null);
      },
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "historyUndo",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "historyUndo", target: aTarget },
     },
     // Setting value should forget any transactions.
     {command: "redo", param: null,
      value: "[a]bc", expectedValue: "[a]bc",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "redo", param: null,
      value: "a[b]c", expectedValue: "a[]c",
@@ -151,186 +226,428 @@
        document.execCommand("undo", false, null);
      },
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "historyRedo",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "historyRedo", target: aTarget },
     },
     {command: "indent", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "outdent", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "backcolor", param: "#000000",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "forecolor", param: "#000000",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "hilitecolor", param: "#000000",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "fontname", param: "DummyFont",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "fontsize", param: "5",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "increasefontsize", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "decreasefontsize", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "inserthorizontalrule", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "createlink", param: "foo.html",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "insertimage", param: "no-image.png",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "inserthtml", param: "<b>inserted</b>",
      value: "a[b]c", expectedValue: "ainserted[]c",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "insertText",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "insertText", target: aTarget },
     },
     {command: "inserttext", param: "**inserted**",
      value: "a[b]c", expectedValue: "a**inserted**[]c",
      expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "insertText",
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null,
+     inputExpected: { inputType: "insertText", target: aTarget },
     },
     {command: "justifyleft", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "justifyright", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "justifycenter", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "justifyfull", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "removeformat", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "unlink", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "insertorderedlist", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "insertunorderedlist", param: null,
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "insertparagraph", param: null,
      value: "a[b]c", expectedValue: kIsTextArea ? "a\n[]c" : "a[b]c",
-     expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "insertParagraph",
+     expectedExecCommandResult: kIsTextArea,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: kIsTextArea,
+     beforeinputExpected: null,
+     inputExpected: kIsTextArea ? { inputType: "insertParagraph", target: aTarget } : null,
     },
     {command: "insertlinebreak", param: null,
      value: "a[b]c", expectedValue: kIsTextArea ? "a\n[]c" : "a[b]c",
-     expectedExecCommandResult: true,
-     beforeinputExpected: false, inputExpected: "insertLineBreak",
+     expectedExecCommandResult: kIsTextArea,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: kIsTextArea,
+     beforeinputExpected: null,
+     inputExpected: kIsTextArea ? { inputType: "insertLineBreak", target: aTarget } : null,
     },
     {command: "formatblock", param: "div",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
     },
     {command: "heading", param: "h1",
      value: "a[b]c", expectedValue: "a[b]c",
      expectedExecCommandResult: false,
-     beforeinputExpected: false, inputExpected: false,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: false,
+     beforeinputExpected: null, inputExpected: null,
+    },
+    {command: "styleWithCSS", param: "true",
+     value: "a[b]c", expectedValue: "a[b]c",
+     expectedExecCommandResult: container.isContentEditable,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: container.isContentEditable,
+     beforeinputExpected: null, inputExpected: null,
+     additionalCheckFunc: aDescription => {
+       test(
+         () => assert_equals(document.queryCommandState("styleWithCSS"), container.isContentEditable),
+         `${aDescription}: styleWithCSS state should be ${container.isContentEditable} when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } has focus`
+       );
+       aTarget.blur();
+       container.focus();
+       getSelection().collapse(container, 0);
+       test(
+         () => assert_equals(document.queryCommandState("styleWithCSS"), container.isContentEditable),
+         `${aDescription}: styleWithCSS state should be ${container.isContentEditable} when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } does not have focus`
+        );
+      },
+    },
+    {command: "styleWithCSS", param: "false",
+     value: "a[b]c", expectedValue: "a[b]c",
+     expectedExecCommandResult: container.isContentEditable,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: container.isContentEditable,
+     beforeinputExpected: null, inputExpected: null,
+     additionalCheckFunc: aDescription => {
+       test(
+         () => assert_equals(document.queryCommandState("styleWithCSS"), false),
+         `${aDescription}: styleWithCSS state should be false when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } has focus`
+       );
+       aTarget.blur();
+       container.focus();
+       getSelection().collapse(container, 0);
+       test(
+         () => assert_equals(document.queryCommandState("styleWithCSS"), false),
+         `${aDescription}: styleWithCSS state should be false when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } does not have focus`
+        );
+      },
+    },
+    {command: "contentReadOnly", param: "true",
+     value: "a[b]c", expectedValue: "a[b]c",
+     expectedExecCommandResult: true,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null, inputExpected: null,
+     additionalCheckFunc: aDescription => {
+       test(
+         () => assert_equals(document.queryCommandState("contentReadOnly"), true),
+         `${aDescription}: contentReadOnly state should be true when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } has focus`
+       );
+       test(
+         () => assert_equals(aTarget.readOnly, true),
+         `${aDescription}: readonly property should be true`
+       );
+       aTarget.blur();
+       container.focus();
+       getSelection().collapse(container, 0);
+       test(
+         () => assert_equals(document.queryCommandState("contentReadOnly"), false),
+         `${aDescription}: contentReadOnly state should be false when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } does not have focus`
+        );
+      },
+    },
+    {command: "contentReadOnly", param: "false",
+     value: "a[b]c", expectedValue: "a[b]c",
+     expectedExecCommandResult: true,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: true,
+     beforeinputExpected: null, inputExpected: null,
+     additionalCheckFunc: aDescription => {
+       test(
+         () => assert_equals(document.queryCommandState("contentReadOnly"), false),
+         `${aDescription}: contentReadOnly state should be false when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } has focus`
+       );
+       test(
+         () => assert_equals(aTarget.readOnly, false),
+         `${aDescription}: readonly property should be false`
+       );
+       aTarget.blur();
+       container.focus();
+       getSelection().collapse(container, 0);
+       test(
+         () => assert_equals(document.queryCommandState("contentReadOnly"), false),
+         `${aDescription}: contentReadOnly state should be false when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } does not have focus`
+        );
+      },
+    },
+    {command: "defaultParagraphSeparator", param: "p",
+     value: "a[b]c", expectedValue: "a[b]c",
+     expectedExecCommandResult: container.isContentEditable,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: container.isContentEditable,
+     beforeinputExpected: null, inputExpected: null,
+     additionalCheckFunc: aDescription => {
+       test(
+         () =>
+           assert_equals(
+             document.queryCommandValue("defaultParagraphSeparator"),
+             container.isContentEditable ? "p" : "div"
+           )
+         ,
+         `${aDescription}: defaultParagraphSeparator value should be "p" when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } has focus`
+       );
+       aTarget.blur();
+       container.focus();
+       getSelection().collapse(container, 0);
+       test(
+         () =>
+           assert_equals(
+             document.queryCommandValue("defaultParagraphSeparator"),
+             container.isContentEditable ? "p" : "div"
+           ),
+         `${aDescription}: defaultParagraphSeparator value should be "p" when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } does not have focus`
+        );
+      },
+    },
+    {command: "defaultParagraphSeparator", param: "div",
+     value: "a[b]c", expectedValue: "a[b]c",
+     expectedExecCommandResult: container.isContentEditable,
+     expectedCommandSupported: true,
+     expectedCommandEnabled: container.isContentEditable,
+     beforeinputExpected: null, inputExpected: null,
+     additionalCheckFunc: aDescription => {
+       test(
+         () => assert_equals(document.queryCommandValue("defaultParagraphSeparator"), "div"),
+         `${aDescription}: defaultParagraphSeparator value should be "div" when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } has focus`
+       );
+       aTarget.blur();
+       container.focus();
+       getSelection().collapse(container, 0);
+       test(
+         () => assert_equals(document.queryCommandValue("defaultParagraphSeparator"), "div"),
+         `${aDescription}: defaultParagraphSeparator value should be "div" when ${
+           kIsTextArea ? "<textarea>" : "<input>"
+         } does not have focus`
+        );
+      },
     },
   ];
 
   for (const kTest of kTests) {
     const kDescription =
         `${aDescription}, execCommand("${kTest.command}", false, ${kTest.param}), ${kTest.value})`;
-    if (!document.queryCommandSupported(kTest.command)) {
-      continue;
-    }
+    aTarget.value = "dummy value to ensure the following value setting clear the undo history";
     let value = kTest.value.replace(/[\[\]]/g, "");
     aTarget.value = value;
     aTarget.focus();
     aTarget.selectionStart = kTest.value.indexOf("[");
     aTarget.selectionEnd = kTest.value.indexOf("]") - 1;
 
+    test(
+      () => assert_equals(document.queryCommandSupported(kTest.command), kTest.expectedCommandSupported),
+      `${kDescription}: The command should ${
+        kTest.expectedCommandSupported ? "be" : "not be"
+      } supported`
+    );
+    test(
+      () => assert_equals(document.queryCommandEnabled(kTest.command), kTest.expectedCommandEnabled),
+      `${kDescription}: The command should ${
+        kTest.expectedCommandEnabled ? "be" : "not be"
+      } enabled`
+    );
+
+    if (!document.queryCommandSupported(kTest.command)) {
+      continue;
+    }
+
     if (kTest.initFunc) {
       kTest.initFunc();
     }
 
-    let beforeinput = false;
+    let beforeinput = null;
     function onBeforeinput(event) {
-      beforeinput = event.inputType;
+      beforeinput = event;
     }
     window.addEventListener("beforeinput", onBeforeinput, {capture: true});
-    let input = false;
+    let input = null;
     function onInput(event) {
-      input = event.inputType;
+      input = event;
     }
     window.addEventListener("input", onInput, {capture: true});
     let ret;
     test(function () {
       ret = document.execCommand(kTest.command, false, kTest.param);
       assert_equals(ret, kTest.expectedExecCommandResult);
-    }, `${kDescription}: calling execCommand()`);
-    if (ret == kTest.expectedExecCommandResult) {
-      test(function () {
-        let value = aTarget.value.substring(0, aTarget.selectionStart) +
-                        "[" +
-                        aTarget.value.substring(aTarget.selectionStart, aTarget.selectionEnd) +
-                        "]" +
-                        aTarget.value.substring(aTarget.selectionEnd);
-        assert_equals(value, kTest.expectedValue);
-      }, `${kDescription}: checking value and selection after execCommand()`);
-      test(function () {
-        assert_equals(beforeinput, kTest.beforeinputExpected);
-      }, `${kDescription}: checking beforeinput event`);
-      test(function () {
-        assert_equals(input, kTest.inputExpected);
-      }, `${kDescription}: checking input event`);
+    }, `${kDescription}: execCommand() should return ${kTest.expectedExecCommandResult}`);
+    test(function () {
+      let value = aTarget.value.substring(0, aTarget.selectionStart) +
+                      "[" +
+                      aTarget.value.substring(aTarget.selectionStart, aTarget.selectionEnd) +
+                      "]" +
+                      aTarget.value.substring(aTarget.selectionEnd);
+      assert_equals(value, kTest.expectedValue);
+    }, `${kDescription}: ${kIsTextArea ? "<textarea>" : "<input>"}.value should be "${kTest.expectedValue}"`);
+    test(function () {
+      assert_equals(beforeinput?.inputType, kTest.beforeinputExpected?.inputType);
+    }, `${kDescription}: beforeinput.inputType should be ${kTest.beforeinputExpected?.inputType}`);
+    test(function () {
+      assert_equals(beforeinput?.target, kTest.beforeinputExpected?.target);
+    }, `${kDescription}: beforeinput.target should be ${kTest.beforeinputExpected?.target}`);
+    test(function () {
+      assert_equals(input?.inputType, kTest.inputExpected?.inputType);
+    }, `${kDescription}: input.inputType should be ${kTest.inputExpected?.inputType}`);
+    test(function () {
+      assert_equals(input?.target, kTest.inputExpected?.target);
+    }, `${kDescription}: input.target should be ${kTest.inputExpected?.target}`);
+    if (kTest.additionalCheckFunc) {
+      kTest.additionalCheckFunc(kDescription);
     }
     window.removeEventListener("beforeinput", onBeforeinput, {capture: true});
     window.removeEventListener("input", onInput, {capture: true});