summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/uievents
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/uievents')
-rw-r--r--testing/web-platform/tests/uievents/idlharness.window.js1
-rw-r--r--testing/web-platform/tests/uievents/textInput/api.html88
-rw-r--r--testing/web-platform/tests/uievents/textInput/backspace.html16
-rw-r--r--testing/web-platform/tests/uievents/textInput/basic.html16
-rw-r--r--testing/web-platform/tests/uievents/textInput/delete-selection.html16
-rw-r--r--testing/web-platform/tests/uievents/textInput/delete.html16
-rw-r--r--testing/web-platform/tests/uievents/textInput/enter-input.html14
-rw-r--r--testing/web-platform/tests/uievents/textInput/enter-textarea-contenteditable.html15
-rw-r--r--testing/web-platform/tests/uievents/textInput/smiley-manual.html17
-rw-r--r--testing/web-platform/tests/uievents/textInput/support/basic.sub.js49
-rw-r--r--testing/web-platform/tests/uievents/textInput/support/common.js38
-rw-r--r--testing/web-platform/tests/uievents/textInput/support/no-textInput.sub.js29
12 files changed, 315 insertions, 0 deletions
diff --git a/testing/web-platform/tests/uievents/idlharness.window.js b/testing/web-platform/tests/uievents/idlharness.window.js
index c3919e3558..ca8d23e4f6 100644
--- a/testing/web-platform/tests/uievents/idlharness.window.js
+++ b/testing/web-platform/tests/uievents/idlharness.window.js
@@ -16,6 +16,7 @@ idl_test(
CompositionEvent: ['new CompositionEvent("event")'],
UIEvent: ['new UIEvent("event")'],
InputEvent: ['new InputEvent("event")'],
+ TextEvent: ['(() => { const ev = document.createEvent("TextEvent"); ev.initTextEvent("event"); return ev; })()'],
});
}
);
diff --git a/testing/web-platform/tests/uievents/textInput/api.html b/testing/web-platform/tests/uievents/textInput/api.html
new file mode 100644
index 0000000000..a88184e500
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/api.html
@@ -0,0 +1,88 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>textInput: API</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<input class=test-el>
+<textarea class=test-el></textarea>
+<div contenteditable class=test-el></div>
+<script src="support/common.js"></script>
+<script>
+test(() => {
+ assert_throws_js(TypeError, () => {
+ new TextEvent('textInput');
+ });
+}, "No constructor");
+
+test(() => {
+ const e = document.createEvent('TextEvent');
+ assert_equals(Object.getPrototypeOf(e), window.TextEvent.prototype);
+ assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(e)), window.UIEvent.prototype);
+ assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(e))), window.Event.prototype);
+}, "document.CreateEvent('TextEvent') prototype chain");
+
+test(() => {
+ const e = document.createEvent('TextEvent');
+ assert_throws_js(TypeError, () => { e.initTextEvent(); });
+}, "initTextEvent() no arguments");
+
+test(() => {
+ const e = document.createEvent('TextEvent');
+ e.initTextEvent('foo');
+ assert_equals(e.type, 'foo');
+ assert_equals(e.bubbles, false);
+ assert_equals(e.cancelable, false);
+ assert_equals(e.view, null);
+ assert_equals(e.data, 'undefined');
+}, "initTextEvent('foo')");
+
+test(() => {
+ const e = document.createEvent('TextEvent');
+ e.initTextEvent('foo', true, true, window, 'bar');
+ assert_equals(e.type, 'foo');
+ assert_equals(e.bubbles, true);
+ assert_equals(e.cancelable, true);
+ assert_equals(e.view, window);
+ assert_equals(e.data, 'bar');
+}, "initTextEvent('foo', true, true, window, 'bar')");
+
+test(() => {
+ const div = document.createElement('div');
+ let textinputCount = 0;
+ let textInputCount = 0;
+ div.addEventListener('textinput', e => {
+ assert_equals(e.type, 'textinput');
+ textinputCount++;
+ });
+ div.addEventListener('textInput', e => {
+ assert_equals(e.type, 'textInput');
+ textInputCount++;
+ });
+ const textinputEvent = document.createEvent('TextEvent');
+ textinputEvent.initTextEvent('textinput');
+ div.dispatchEvent(textinputEvent);
+
+ const textInputEvent = document.createEvent('TextEvent');
+ textInputEvent.initTextEvent('textInput');
+ div.dispatchEvent(textInputEvent);
+
+ assert_equals(textinputCount, 1);
+ assert_equals(textInputCount, 1);
+}, "case sensitivity: textInput vs textinput");
+
+const els = document.querySelectorAll('.test-el');
+for (const el of els) {
+ promise_test(t => {
+ return new Promise((resolve, reject) => {
+ el.addEventListener('textInput', reject);
+ el.addEventListener('input', t.step_func(e => {
+ const actualValue = 'value' in el ? el.value : el.textContent;
+ assert_equals(actualValue, 'a');
+ resolve();
+ }));
+ el.focus();
+ document.execCommand('insertText', false, 'a');
+ });
+ }, `execCommand('insertText', false, 'a'), ${elDesc(el)}` );
+}
+</script>
diff --git a/testing/web-platform/tests/uievents/textInput/backspace.html b/testing/web-platform/tests/uievents/textInput/backspace.html
new file mode 100644
index 0000000000..c9b2f8bee4
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/backspace.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>textInput: backspace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<style>
+[contenteditable] { border: thin inset silver; }
+</style>
+<p>Press Backspace in each text field below.</p>
+<input class=test-el value=abc>
+<textarea class=test-el>abc</textarea>
+<div contenteditable=true class=test-el>abc</div>
+<script src="support/common.js"></script>
+<script src="support/no-textInput.sub.js?key=Backspace&selectionStart=2&selectionEnd=2&expectedValue=ac"></script>
diff --git a/testing/web-platform/tests/uievents/textInput/basic.html b/testing/web-platform/tests/uievents/textInput/basic.html
new file mode 100644
index 0000000000..6335167faa
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/basic.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>textInput: basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<style>
+[contenteditable] { border: thin inset silver; }
+</style>
+<p>Type "a" into each text field below.</p>
+<input class=test-el>
+<textarea class=test-el></textarea>
+<div contenteditable=true class=test-el></div>
+<script src="support/common.js"></script>
+<script src="support/basic.sub.js?key=a&selectionStart=0&selectionEnd=0&expectedValue=a"></script>
diff --git a/testing/web-platform/tests/uievents/textInput/delete-selection.html b/testing/web-platform/tests/uievents/textInput/delete-selection.html
new file mode 100644
index 0000000000..f77e8c6e98
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/delete-selection.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>textInput: delete selection</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<style>
+[contenteditable] { border: thin inset silver; }
+</style>
+<p>Press Delete (Fn+Backspace for macOS) in each text field below.</p>
+<input class=test-el value=abc>
+<textarea class=test-el>abc</textarea>
+<div contenteditable=true class=test-el>abc</div>
+<script src="support/common.js"></script>
+<script src="support/no-textInput.sub.js?key=Delete&selectionStart=1&selectionEnd=2&expectedValue=ac"></script>
diff --git a/testing/web-platform/tests/uievents/textInput/delete.html b/testing/web-platform/tests/uievents/textInput/delete.html
new file mode 100644
index 0000000000..2d696fba71
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/delete.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>textInput: delete</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<style>
+[contenteditable] { border: thin inset silver; }
+</style>
+<p>Press Delete (Fn+Backspace for macOS) in each text field below.</p>
+<input class=test-el value=abc>
+<textarea class=test-el>abc</textarea>
+<div contenteditable=true class=test-el>abc</div>
+<script src="support/common.js"></script>
+<script src="support/no-textInput.sub.js?key=Delete&selectionStart=1&selectionEnd=1&expectedValue=ac"></script>
diff --git a/testing/web-platform/tests/uievents/textInput/enter-input.html b/testing/web-platform/tests/uievents/textInput/enter-input.html
new file mode 100644
index 0000000000..032503694d
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/enter-input.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>textInput: Enter key for input element</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<style>
+[contenteditable] { border: thin inset silver; }
+</style>
+<p>Press Enter in the text field below.</p>
+<input class=test-el>
+<script src="support/common.js"></script>
+<script src="support/no-textInput.sub.js?key=Enter&selectionStart=0&selectionEnd=0&expectedValue="></script>
diff --git a/testing/web-platform/tests/uievents/textInput/enter-textarea-contenteditable.html b/testing/web-platform/tests/uievents/textInput/enter-textarea-contenteditable.html
new file mode 100644
index 0000000000..60891df982
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/enter-textarea-contenteditable.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>textInput: Enter key for textarea and contenteditable</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<style>
+[contenteditable] { border: thin inset silver; }
+</style>
+<p>Press Enter in each text field below.</p>
+<textarea class=test-el></textarea>
+<div contenteditable=true class=test-el></div>
+<script src="support/common.js"></script>
+<script src="support/basic.sub.js?key=Enter&selectionStart=0&selectionEnd=0&expectedValue=\n"></script>
diff --git a/testing/web-platform/tests/uievents/textInput/smiley-manual.html b/testing/web-platform/tests/uievents/textInput/smiley-manual.html
new file mode 100644
index 0000000000..7781f6e1b0
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/smiley-manual.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>textInput: smiley (manual)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+[contenteditable] { border: thin inset silver; }
+</style>
+<p>Type "🙂" into each text field below.</p>
+<input class=test-el>
+<textarea class=test-el></textarea>
+<div contenteditable=true class=test-el></div>
+<script>
+setup({ explicit_timeout: true });
+</script>
+<script src="support/common.js"></script>
+<script src="support/basic.sub.js?key=🙂&selectionStart=0&selectionEnd=0&expectedValue=🙂"></script>
diff --git a/testing/web-platform/tests/uievents/textInput/support/basic.sub.js b/testing/web-platform/tests/uievents/textInput/support/basic.sub.js
new file mode 100644
index 0000000000..55d2f0d1e6
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/support/basic.sub.js
@@ -0,0 +1,49 @@
+const els = document.querySelectorAll('.test-el');
+const key = "{{GET[key]}}";
+const keyRaw = keyMapping[key] || key;
+const expectedData = key === "Enter" ? "\n" : key;
+const selectionStart = {{GET[selectionStart]}};
+const selectionEnd = {{GET[selectionEnd]}};
+const expectedValue = "{{GET[expectedValue]}}";
+
+for (const el of els) {
+ promise_test(t => {
+ return new Promise((resolve, reject) => {
+ let beforeinputEvents = 0;
+ let textInputEvents = 0;
+ el.addEventListener('beforeinput', t.step_func(e => {
+ beforeinputEvents++;
+ }));
+ el.addEventListener('textInput', t.step_func(e => {
+ textInputEvents++;
+ assert_equals(beforeinputEvents, 1);
+ assert_equals(e.data, expectedData);
+ assert_true(e.bubbles);
+ assert_true(e.cancelable);
+ assert_equals(e.view, window);
+ assert_equals(e.detail, 0);
+ assert_true(e instanceof window.TextEvent);
+ }));
+ el.addEventListener('input', t.step_func(e => {
+ assert_equals(textInputEvents, 1);
+ if (expectedValue === "\n" && !(el instanceof HTMLInputElement) && !(el instanceof HTMLTextAreaElement)) {
+ // New paragraph in contenteditable during editing is weird.
+ // innerHTML is <div><br></div><div><br></div>
+ // ...but later changes to <br>
+ // So, check that there's at least one <br>.
+ assert_true(getValue(el).indexOf('<br>') > -1);
+ } else {
+ assert_equals(getValue(el), expectedValue);
+ }
+ resolve();
+ }));
+ el.onfocus = t.step_func(e => {
+ if (window.test_driver) {
+ test_driver.send_keys(el, keyRaw);
+ }
+ });
+ el.focus();
+ setSelection(el, selectionStart, selectionEnd);
+ });
+ }, `${document.title}, ${elDesc(el)}`);
+}
diff --git a/testing/web-platform/tests/uievents/textInput/support/common.js b/testing/web-platform/tests/uievents/textInput/support/common.js
new file mode 100644
index 0000000000..25c39da3e2
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/support/common.js
@@ -0,0 +1,38 @@
+function elDesc(el) {
+ let rv = `<${el.localName}`;
+ if (el.hasAttribute('contenteditable')) {
+ rv += ` contenteditable="${el.getAttribute('contenteditable')}"`;
+ }
+ if (el.hasAttribute('type')) {
+ rv += ` type="${el.getAttribute('type')}"`;
+ }
+ rv += `>`;
+ return rv;
+}
+
+function setSelection(el, selectionStart, selectionEnd) {
+ if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
+ el.selectionStart = selectionStart;
+ el.selectionEnd = selectionEnd;
+ } else {
+ const s = getSelection();
+ s.removeAllRanges();
+ const r = new Range();
+ r.setStart(el.firstChild || el, selectionStart);
+ r.setEnd(el.firstChild || el, selectionEnd);
+ s.addRange(r);
+ }
+}
+
+function getValue(el) {
+ if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
+ return el.value;
+ }
+ return el.innerHTML;
+}
+
+const keyMapping = {
+ "Enter": "\uE006",
+ "Backspace": "\uE003",
+ "Delete": "\uE017",
+};
diff --git a/testing/web-platform/tests/uievents/textInput/support/no-textInput.sub.js b/testing/web-platform/tests/uievents/textInput/support/no-textInput.sub.js
new file mode 100644
index 0000000000..332cbf08f2
--- /dev/null
+++ b/testing/web-platform/tests/uievents/textInput/support/no-textInput.sub.js
@@ -0,0 +1,29 @@
+const els = document.querySelectorAll('.test-el');
+const key = "{{GET[key]}}";
+const keyRaw = keyMapping[key] || key;
+const expectedData = key === "Enter" ? "\n" : key;
+const selectionStart = {{GET[selectionStart]}};
+const selectionEnd = {{GET[selectionEnd]}};
+const expectedValue = "{{GET[expectedValue]}}";
+
+for (const el of els) {
+ promise_test(t => {
+ return new Promise((resolve, reject) => {
+ el.addEventListener('textInput', reject);
+ el.addEventListener('keyup', t.step_func(e => {
+ if (e.key !== key) {
+ return;
+ }
+ assert_equals(getValue(el), expectedValue);
+ resolve();
+ }));
+ el.onfocus = t.step_func(e => {
+ if (window.test_driver) {
+ test_driver.send_keys(el, keyRaw);
+ }
+ });
+ el.focus();
+ setSelection(el, selectionStart, selectionEnd);
+ });
+ }, `${document.title}, ${elDesc(el)}`);
+}