Bug 1433463 - WebDriver:ElementSendKeys should not run unfocussing steps. r?automatedtester
According to the WebDriver standard the Element Send Keys command
should not run the unfocussing steps. Not blurring the element
causes the DOM "change" event not to fire, but the specification
only expects the "input" event to fire.
The standard does, however, expect the Element Clear command to
run the unfocussing steps and to blur the element for historical reasons.
MozReview-Commit-ID: FHD1whho0jT
--- a/testing/marionette/interaction.js
+++ b/testing/marionette/interaction.js
@@ -572,18 +572,16 @@ async function webdriverSendKeysToElemen
if (el.type == "file") {
await interaction.uploadFile(el, value);
} else if ((el.type == "date" || el.type == "time") &&
Preferences.get("dom.forms.datetime")) {
interaction.setFormControlValue(el, value);
} else {
event.sendKeysToElement(value, el, win);
}
-
- el.blur();
}
async function legacySendKeysToElement(el, value, a11y) {
const win = getWindow(el);
if (el.type == "file") {
await interaction.uploadFile(el, value);
} else if ((el.type == "date" || el.type == "time") &&
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -584736,17 +584736,17 @@
"bea28e051bc747d863dad9d1fd4ef8ffce432b54",
"testharness"
],
"service-workers/service-worker/state.https.html": [
"ecb0e2fd22e7c92a98ae612a2032a92edf8520d9",
"testharness"
],
"service-workers/service-worker/svg-target-reftest.https.html": [
- "c8d97ffed68ca40b4154bde36d9a0ca65d2e3816",
+ "9eb665d5cd1f62f2591130e372fd6dc1e9c61f64",
"reftest"
],
"service-workers/service-worker/synced-state.https.html": [
"c6a3d6e8aa7a70e1bc670f89192240bac081bfe9",
"testharness"
],
"service-workers/service-worker/uncontrolled-page.https.html": [
"881f51c7f9c64f6d69746e1e195c11cf6e29fb3e",
@@ -592480,21 +592480,21 @@
"7d40a7641dbf04cd78f1dba630afa2e8d80dad13",
"wdspec"
],
"webdriver/tests/element_send_keys/__init__.py": [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webdriver/tests/element_send_keys/form_controls.py": [
- "7c4a249f9575a69268b5f2970a5623fc1724e6e1",
+ "a1ade96c599a336684ee5a46dbc1716aac8ed9ae",
"wdspec"
],
"webdriver/tests/element_send_keys/interactability.py": [
- "bd5d26173017dc3cbdc282809028639a7b4a214a",
+ "197bf11c6cae354d9f3cc07f836a857345046e1c",
"wdspec"
],
"webdriver/tests/element_send_keys/scroll_into_view.py": [
"fb192d5d1d93aa729b07cadcadfa630587bd0b39",
"wdspec"
],
"webdriver/tests/execute_async_script/__init__.py": [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
@@ -598772,17 +598772,17 @@
"b0e679dd7720701364abeaca6870d94db5d7ee74",
"support"
],
"workers/support/iframe_sw_dataUrl.html": [
"2cd66112b612e7b861af00af5ccc26cc7c5a76f8",
"support"
],
"workers/support/name-as-accidental-global.js": [
- "530670268fae610b60066773ee475743b8498b53",
+ "5f75e855287f1a8b391498a3c567b68c75f56416",
"support"
],
"workers/support/name.js": [
"27fa41f445888125f84dab8a57ca62b41c09e506",
"support"
],
"workers/support/nosiniff-error-worker.py": [
"aa81cbafc77ccc9407cba3ac0bd4498e5076bf2b",
--- a/testing/web-platform/tests/webdriver/tests/element_send_keys/form_controls.py
+++ b/testing/web-platform/tests/webdriver/tests/element_send_keys/form_controls.py
@@ -1,53 +1,60 @@
import pytest
-from tests.support.asserts import assert_error, assert_same_element, assert_success
+from tests.support.asserts import (
+ assert_element_has_focus,
+ assert_error,
+ assert_same_element,
+ assert_success,
+)
from tests.support.inline import inline
def element_send_keys(session, element, text):
return session.transport.send(
"POST",
"/session/{session_id}/element/{element_id}/value".format(
session_id=session.session_id,
element_id=element.id),
{"text": text})
def add_event_listeners(element):
element.session.execute_script("""
let [target] = arguments;
window.events = [];
- for (let expected of ["focus", "blur", "change", "keypress", "keydown", "keyup", "input"]) {
+ for (let expected of ["focus", "change", "keypress", "keydown", "keyup", "input"]) {
target.addEventListener(expected, ({type}) => window.events.push(type));
}
""", args=(element,))
def get_events(session):
return session.execute_script("return window.events")
def test_input(session):
session.url = inline("<input>")
element = session.find.css("input", all=False)
assert element.property("value") == ""
element_send_keys(session, element, "foo")
assert element.property("value") == "foo"
+ assert_element_has_focus(element)
def test_textarea(session):
session.url = inline("<textarea>")
element = session.find.css("textarea", all=False)
assert element.property("value") == ""
element_send_keys(session, element, "foo")
assert element.property("value") == "foo"
+ assert_element_has_focus(element)
def test_input_append(session):
session.url = inline("<input value=a>")
element = session.find.css("input", all=False)
assert element.property("value") == "a"
element_send_keys(session, element, "b")
@@ -84,11 +91,18 @@ def test_events(session, tag):
"keyup",
"keydown",
"keypress",
"input",
"keyup",
"keydown",
"keypress",
"input",
- "keyup",
- "change",
- "blur"]
+ "keyup"]
+
+
+@pytest.mark.parametrize("tag", ["input", "textarea"])
+def test_not_blurred(session, tag):
+ session.url = inline("<%s>" % tag)
+ element = session.find.css(tag, all=False)
+
+ element_send_keys(session, element, "")
+ assert_element_has_focus(element)
--- a/testing/web-platform/tests/webdriver/tests/element_send_keys/interactability.py
+++ b/testing/web-platform/tests/webdriver/tests/element_send_keys/interactability.py
@@ -1,86 +1,86 @@
-from tests.support.asserts import assert_error, assert_same_element, assert_success
+from tests.support.asserts import assert_error, assert_success
from tests.support.inline import iframe, inline
def send_keys_to_element(session, element, text):
return session.transport.send(
"POST",
"/session/{session_id}/element/{element_id}/value".format(
session_id=session.session_id,
element_id=element.id),
{"text": text})
def test_body_is_interactable(session):
session.url = inline("""
- <body onkeypress="document.getElementById('result').value += event.key">
- <input type="text" id="result"/>
+ <body onkeypress="document.querySelector('input').value += event.key">
+ <input>
</body>
""")
element = session.find.css("body", all=False)
result = session.find.css("input", all=False)
# By default body is the active element
- assert_same_element(session, element, session.active_element)
+ assert session.active_element is element
response = send_keys_to_element(session, element, "foo")
assert_success(response)
- assert_same_element(session, element, session.active_element)
+ assert session.active_element is element
assert result.property("value") == "foo"
def test_document_element_is_interactable(session):
session.url = inline("""
- <html onkeypress="document.getElementById('result').value += event.key">
- <input type="text" id="result"/>
+ <html onkeypress="document.querySelector('input').value += event.key">
+ <input>
</html>
""")
body = session.find.css("body", all=False)
element = session.find.css(":root", all=False)
result = session.find.css("input", all=False)
# By default body is the active element
- assert_same_element(session, body, session.active_element)
+ assert session.active_element is body
response = send_keys_to_element(session, element, "foo")
assert_success(response)
- assert_same_element(session, body, session.active_element)
+ assert session.active_element is element
assert result.property("value") == "foo"
def test_iframe_is_interactable(session):
session.url = inline(iframe("""
- <body onkeypress="document.getElementById('result').value += event.key">
- <input type="text" id="result"/>
+ <body onkeypress="document.querySelector('input').value += event.key">
+ <input>
</body>
"""))
body = session.find.css("body", all=False)
frame = session.find.css("iframe", all=False)
# By default the body has the focus
- assert_same_element(session, body, session.active_element)
+ assert session.active_element is body
response = send_keys_to_element(session, frame, "foo")
assert_success(response)
- assert_same_element(session, body, session.active_element)
+ assert session.active_element is frame
# Any key events are immediately routed to the nested
# browsing context's active document.
session.switch_frame(frame)
result = session.find.css("input", all=False)
assert result.property("value") == "foo"
def test_transparent_element(session):
- session.url = inline("<input style=\"opacity: 0;\">")
+ session.url = inline("""<input style="opacity: 0">""")
element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo")
assert_success(response)
assert element.property("value") == "foo"
def test_readonly_element(session):
@@ -89,18 +89,18 @@ def test_readonly_element(session):
response = send_keys_to_element(session, element, "foo")
assert_success(response)
assert element.property("value") == ""
def test_obscured_element(session):
session.url = inline("""
- <input type="text" />
- <div style="position: relative; top: -3em; height: 5em; background-color: blue"></div>
+ <input>
+ <div style="position: relative; top: -3em; height: 5em; background: blue;"></div>
""")
element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo")
assert_success(response)
assert element.property("value") == "foo"
@@ -108,29 +108,29 @@ def test_not_a_focusable_element(session
session.url = inline("<div>foo</div>")
element = session.find.css("div", all=False)
response = send_keys_to_element(session, element, "foo")
assert_error(response, "element not interactable")
def test_not_displayed_element(session):
- session.url = inline("<input style=\"display: none\">")
+ session.url = inline("""<input style="display: none">""")
element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo")
assert_error(response, "element not interactable")
def test_hidden_element(session):
- session.url = inline("<input style=\"visibility: hidden\">")
+ session.url = inline("""<input style="visibility: hidden">""")
element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo")
assert_error(response, "element not interactable")
def test_disabled_element(session):
- session.url = inline("<input disabled=\"false\">")
+ session.url = inline("""<input disabled>""")
element = session.find.css("input", all=False)
response = send_keys_to_element(session, element, "foo")
assert_error(response, "element not interactable")