Bug 1447239 - Make WPT for InputEvent.inputType of each execCommand should test each call separately r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 07 Jan 2019 10:09:51 +0000
changeset 509795 f8237a1e70b899fb91131718054f2d9e53bc082c
parent 509794 658f77e5e78bf4efa3dce011f4aae33139206f7e
child 509796 cd0f006ea4b311f6223c6d151f09aa9758c7ad92
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1447239
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1447239 - Make WPT for InputEvent.inputType of each execCommand should test each call separately r=smaug The WPT for InputEvent.inputType of each execCommand runs all tests in a test function. Therefore, even if there is an unexpected result, it won't test other part. Additionally, it tests execCommand's result of the DOM tree in the contenteditable so that it's not useful for checking InputEvent.inputType for now. Therefore, this patch makes the test returns error for each result of each call of execCommand. Additionally, it sets contenteditable attribute to a <p> element which cannot store other block elements like <ul>, <ol>, <div>, etc. Therefore, some of the execCommand won't work on Gecko since Gecko's editor does not create invalid child elements as far as possible. Therefore, this patch makes it a <div> element. And also adding "insertHorizontalRule", "backColor", "foreColor", "hilightColor", "fontName", "createLink", "unlink". inputType values for those commands are defined by current spec. So, if they'd be changed, we could detect it quickly. Differential Revision: https://phabricator.services.mozilla.com/D14123
testing/web-platform/meta/input-events/input-events-exec-command.html.ini
testing/web-platform/tests/input-events/input-events-exec-command.html
--- a/testing/web-platform/meta/input-events/input-events-exec-command.html.ini
+++ b/testing/web-platform/meta/input-events/input-events-exec-command.html.ini
@@ -1,4 +1,117 @@
 [input-events-exec-command.html]
-  [execCommand() should only trigger 'input']
+  [Calling execCommand("insertText", false, a)]
+    expected: FAIL
+
+  [Calling execCommand("insertText", false, bc)]
+    expected: FAIL
+
+  [Calling execCommand("insertOrderedList", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("insertUnorderedList", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("insertLineBreak", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("insertParagraph", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("insertHorizontalRule", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("bold", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("italic", false, null)]
+    expected: FAIL
+
+  [execCommand("italic") should wrap selected text with <i> element]
+    expected: FAIL
+
+  [Calling execCommand("underline", false, null)]
+    expected: FAIL
+
+  [execCommand("underline") should wrap selected text with <u> element]
+    expected: FAIL
+
+  [Calling execCommand("strikeThrough", false, null)]
+    expected: FAIL
+
+  [execCommand("strikeThrough") should wrap selected text with <strike> element]
+    expected: FAIL
+
+  [Calling execCommand("superscript", false, null)]
+    expected: FAIL
+
+  [execCommand("superscript") should wrap selected text with <sup> element]
+    expected: FAIL
+
+  [Calling execCommand("subscript", false, null)]
+    expected: FAIL
+
+  [execCommand("subscript") should wrap selected text with <sub> element]
+    expected: FAIL
+
+  [Calling execCommand("backColor", false, #000000)]
     expected: FAIL
 
+  [Calling execCommand("foreColor", false, #FFFFFF)]
+    expected: FAIL
+
+  [Calling execCommand("hiliteColor", false, #FFFF00)]
+    expected: FAIL
+
+  [Calling execCommand("fontName", false, monospace)]
+    expected: FAIL
+
+  [Calling execCommand("justifyCenter", false, null)]
+    expected: FAIL
+
+  [execCommand("justifyCenter") should wrap the text with <div> element whose text-align is center]
+    expected: FAIL
+
+  [Calling execCommand("justifyFull", false, null)]
+    expected: FAIL
+
+  [execCommand("justifyFull") should wrap the text with <div> element whose text-align is justify]
+    expected: FAIL
+
+  [Calling execCommand("justifyRight", false, null)]
+    expected: FAIL
+
+  [execCommand("justifyRight") should wrap the text with <div> element whose text-align is right]
+    expected: FAIL
+
+  [Calling execCommand("justifyLeft", false, null)]
+    expected: FAIL
+
+  [execCommand("justifyLeft") should wrap the text with <div> element whose text-align is left]
+    expected: FAIL
+
+  [Calling execCommand("removeFormat", false, null)]
+    expected: FAIL
+
+  [execCommand("removeFormat") should remove the style of current block]
+    expected: FAIL
+
+  [Calling execCommand("indent", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("outdent", false, null)]
+    expected: FAIL
+
+  [Set of execCommand("indent") and execCommand("outdent") should keep same DOM tree]
+    expected: FAIL
+
+  [Calling execCommand("cut", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("paste", false, null)]
+    expected: FAIL
+
+  [Calling execCommand("createLink", false, https://example.com/)]
+    expected: FAIL
+
+  [Calling execCommand("unlink", false, null)]
+    expected: FAIL
--- a/testing/web-platform/tests/input-events/input-events-exec-command.html
+++ b/testing/web-platform/tests/input-events/input-events-exec-command.html
@@ -1,86 +1,147 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
 <title>execCommand() should only trigger 'input'</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<p id="txt" contenteditable></p>
+<div id="txt" contenteditable></div>
 <script>
-test(function() {
+(function() {
     let lastBeforeInputType = '';
     let lastInputType = '';
     const txt = document.getElementById('txt');
     txt.addEventListener('beforeinput', function(event) {
         assert_true(event instanceof InputEvent);
         assert_false(event.isComposing);
         lastBeforeInputType = event.inputType;
     });
     txt.addEventListener('input', function(event) {
         assert_true(event instanceof InputEvent);
         assert_false(event.isComposing);
         lastInputType = event.inputType;
     });
 
     const NO_INPUT_EVENT_FIRED = 'NO_INPUT_EVENT_FIRED';
     function testExecCommandInputType(command, args, inputType) {
-        lastBeforeInputType = NO_INPUT_EVENT_FIRED;
-        lastInputType = NO_INPUT_EVENT_FIRED;
-        document.execCommand(command, false, args);
-        assert_equals(lastBeforeInputType, NO_INPUT_EVENT_FIRED, `execCommand(${command}, false, ${args}) shouldn't fire beforeinput`);
-        assert_equals(lastInputType, inputType, `execCommand(${command}, false, ${args}) should produce inputType: ${inputType}`);
+        const description = `Calling execCommand("${command}", false, ${args})`;
+        test(function() {
+            lastBeforeInputType = NO_INPUT_EVENT_FIRED;
+            lastInputType = NO_INPUT_EVENT_FIRED;
+            try {
+                document.execCommand(command, false, args);
+            } catch (e) {
+                assert(false, `execCommand shouldn't cause any exception: ${e}`);
+            }
+            assert_equals(lastBeforeInputType, NO_INPUT_EVENT_FIRED,
+                          `${description} shouldn't fire beforeinput`);
+            assert_equals(lastInputType, inputType,
+                          `${description} should produce inputType: ${inputType}`);
+        }, description);
     }
 
     txt.focus();
     // InsertText
     testExecCommandInputType('insertText', 'a', 'insertText');
     testExecCommandInputType('insertText', 'bc', 'insertText');
-    assert_equals(txt.innerHTML, 'abc');
+    test(function() {
+        assert_equals(txt.innerHTML, 'abc');
+    }, "execCommand(\"insertText\") should insert \"abc\" into the editor");
     testExecCommandInputType('insertOrderedList', null, 'insertOrderedList');
-    assert_equals(txt.innerHTML, '<ol><li>abc</li></ol>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<ol><li>abc</li></ol>');
+    }, "execCommand(\"insertOrderedList\") should make <ol> and wrap the text with it");
     testExecCommandInputType('insertUnorderedList', null, 'insertUnorderedList');
-    assert_equals(txt.innerHTML, '<ul><li>abc</li></ul>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<ul><li>abc</li></ul>');
+    }, "execCommand(\"insertUnorderedList\") should make <ul> and wrap the text with it");
     testExecCommandInputType('insertLineBreak', null, 'insertLineBreak');
     testExecCommandInputType('insertParagraph', null, 'insertParagraph');
+    txt.innerHTML = '';
+    testExecCommandInputType('insertHorizontalRule', null, 'insertHorizontalRule');
 
     // Styling
     txt.innerHTML = 'abc';
     var selection = window.getSelection();
     selection.collapse(txt, 0);
     selection.extend(txt, 1);
     testExecCommandInputType('bold', null, 'formatBold');
-    assert_equals(txt.innerHTML, '<b>abc</b>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<b>abc</b>');
+    }, "execCommand(\"bold\") should wrap selected text with <b> element");
     testExecCommandInputType('italic', null, 'formatItalic');
-    assert_equals(txt.innerHTML, '<b><i>abc</i></b>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<b><i>abc</i></b>');
+    }, "execCommand(\"italic\") should wrap selected text with <i> element");
     testExecCommandInputType('underline', null, 'formatUnderline');
-    assert_equals(txt.innerHTML, '<b><i><u>abc</u></i></b>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<b><i><u>abc</u></i></b>');
+    }, "execCommand(\"underline\") should wrap selected text with <u> element");
     testExecCommandInputType('strikeThrough', null, 'formatStrikeThrough');
-    assert_equals(txt.innerHTML, '<b><i><u><strike>abc</strike></u></i></b>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<b><i><u><strike>abc</strike></u></i></b>');
+    }, "execCommand(\"strikeThrough\") should wrap selected text with <strike> element");
     testExecCommandInputType('superscript', null, 'formatSuperscript');
-    assert_equals(txt.innerHTML, '<b><i><u><strike><sup>abc</sup></strike></u></i></b>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<b><i><u><strike><sup>abc</sup></strike></u></i></b>');
+    }, "execCommand(\"superscript\") should wrap selected text with <sup> element");
     testExecCommandInputType('subscript', null, 'formatSubscript');
-    assert_equals(txt.innerHTML, '<b><i><u><strike><sub>abc</sub></strike></u></i></b>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<b><i><u><strike><sub>abc</sub></strike></u></i></b>');
+    }, "execCommand(\"subscript\") should wrap selected text with <sub> element");
+    txt.innerHTML = 'abc';
+    selection.collapse(txt, 0);
+    selection.extend(txt, 1);
+    testExecCommandInputType('backColor', '#000000', 'formatBackColor');
+    testExecCommandInputType('foreColor', '#FFFFFF', 'formatFontColor');
+    testExecCommandInputType('hiliteColor', '#FFFF00', 'formatBackColor');
+    testExecCommandInputType('fontName', 'monospace', 'formatFontName');
 
     // Formating
     txt.innerHTML = 'abc';
     testExecCommandInputType('justifyCenter', null, 'formatJustifyCenter');
-    assert_equals(txt.innerHTML, '<div style="text-align: center;">abc</div>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<div style="text-align: center;">abc</div>');
+    }, "execCommand(\"justifyCenter\") should wrap the text with <div> element whose text-align is center");
     testExecCommandInputType('justifyFull', null, 'formatJustifyFull');
-    assert_equals(txt.innerHTML, '<div style="text-align: justify;">abc</div>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<div style="text-align: justify;">abc</div>');
+    }, "execCommand(\"justifyFull\") should wrap the text with <div> element whose text-align is justify");
     testExecCommandInputType('justifyRight', null, 'formatJustifyRight');
-    assert_equals(txt.innerHTML, '<div style="text-align: right;">abc</div>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<div style="text-align: right;">abc</div>');
+    }, "execCommand(\"justifyRight\") should wrap the text with <div> element whose text-align is right");
     testExecCommandInputType('justifyLeft', null, 'formatJustifyLeft');
-    assert_equals(txt.innerHTML, '<div style="text-align: left;">abc</div>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<div style="text-align: left;">abc</div>');
+    }, "execCommand(\"justifyLeft\") should wrap the text with <div> element whose text-align is left");
     selection.collapse(txt, 0);
     selection.extend(txt, 1);
     testExecCommandInputType('removeFormat', null, 'formatRemove');
-    assert_equals(txt.innerHTML, '<div style="">abc</div>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<div style="">abc</div>');
+    }, "execCommand(\"removeFormat\") should remove the style of current block");
     testExecCommandInputType('indent', null, 'formatIndent');
     testExecCommandInputType('outdent', null, 'formatOutdent');
-    assert_equals(txt.innerHTML, '<div style="">abc</div>');
+    test(function() {
+        assert_equals(txt.innerHTML, '<div style="">abc</div>');
+    }, "Set of execCommand(\"indent\") and execCommand(\"outdent\") should keep same DOM tree");
 
     // Copy shouldn't fire 'input'.
     testExecCommandInputType('copy', null, NO_INPUT_EVENT_FIRED);
     // Cut/Paste should fire 'input'.
     testExecCommandInputType('cut', null, 'deleteByCut');
     testExecCommandInputType('paste', null, 'insertFromPaste');
-});
+
+    // Link and Unlink
+    txt.innerHTML = 'abc';
+    selection.collapse(txt.firstChild, 1);
+    selection.extend(txt.firstChild, 2);
+    testExecCommandInputType('createLink', 'https://example.com/', 'insertLink');
+    test(function() {
+        assert_equals(txt.innerHTML, 'a<a href="https://example.com/">b</a>c');
+    }, "execCommand(\"createLink\") should create a link");
+    testExecCommandInputType('unlink', null, '');
+    test(function() {
+        assert_equals(txt.innerHTML, 'abc');
+    }, "execCommand(\"createLink\") should remove the link");
+})();
 </script>