[ChromeDriver] Update sendKeysToElement focus behavior when targeting contenteditable element.
This change updates chromedriver to call focus.js if the element is a non-text element.
This is specifically to fix some cases where browser based text editors use <body contenteditable=true>
to create a text area of sorts.
Before this change, but after https://crrev.com/674640, we were not resetting focus to the body
element as it was considered already focused. This results in sendkeys being lost.
We now call focus on any non-text elements, which still abides by the W3C SendKeys spec change
incoming https://github.com/w3c/webdriver/issues/1430 as carat preservation behavior is only
specified for text-type inputs.
Additionally, this change also updates focus.js javascript to not move carat after a focus.
Which was erroneously not updated in https://crrev.com/674640
Bug: chromedriver:3006
Change-Id: Ie4d4bab3eb45aec64a586cbfa786968601a06189
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1700475
Commit-Queue: Stanley Hon <stahon@microsoft.com>
Reviewed-by: John Chen <johnchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#678908}
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc
index 28e16573..fd52ec7 100644
--- a/chrome/test/chromedriver/element_commands.cc
+++ b/chrome/test/chromedriver/element_commands.cc
@@ -91,9 +91,12 @@
const base::ListValue* key_list) {
// If we were previously focused, we don't need to focus again.
// But also, later we don't move the carat if we were already in focus.
+ // However, non-text elements such as contenteditable elements needs to be
+ // focused to ensure the keys will end up being sent to the correct place.
+ // So in the case of non-text elements, we still focusToElement.
bool wasPreviouslyFocused = false;
IsElementFocused(session, web_view, element_id, &wasPreviouslyFocused);
- if (!wasPreviouslyFocused) {
+ if (!wasPreviouslyFocused || !is_text) {
Status status = FocusToElement(session, web_view, element_id);
if (status.IsError())
return Status(kElementNotInteractable);
@@ -481,8 +484,16 @@
key_list);
}
// If element_type is in textControlTypes, sendKeys should append
- bool is_text = is_input && textControlTypes.find(element_type) !=
- textControlTypes.end();
+ bool is_textControlType = is_input && textControlTypes.find(element_type) !=
+ textControlTypes.end();
+ // If the element is a textarea, sendKeys should also append
+ bool is_textarea = false;
+ status = IsElementAttributeEqualToIgnoreCase(
+ session, web_view, element_id, "tagName", "textarea", &is_textarea);
+ if (status.IsError())
+ return status;
+ bool is_text = is_textControlType || is_textarea;
+
return SendKeysToElement(session, web_view, element_id, is_text, key_list);
}
}
diff --git a/chrome/test/chromedriver/js/focus.js b/chrome/test/chromedriver/js/focus.js
index 7030796b..98f8233 100644
--- a/chrome/test/chromedriver/js/focus.js
+++ b/chrome/test/chromedriver/js/focus.js
@@ -9,9 +9,7 @@
// because this may cause us to lose the current cursor position in the
// element.
// Secondly, we focus the target element.
- // Thirdly, if the target element is newly focused and is a text input, we
- // set the cursor position at the end.
- // Fourthly, we check if the new active element is the target element. If not,
+ // Thirdly, we check if the new active element is the target element. If not,
// we throw an error.
// Additional notes:
// - |document.activeElement| is the currently focused element, or body if
@@ -28,16 +26,6 @@
if (element != prevActiveElement && prevActiveElement)
prevActiveElement.blur();
element.focus();
- if (element != prevActiveElement && element.value &&
- element.value.length && element.setSelectionRange) {
- try {
- element.setSelectionRange(element.value.length, element.value.length);
- } catch (error) {
- if (!(error instanceof TypeError) && !(error instanceof DOMException &&
- error.code == DOMException.INVALID_STATE_ERR))
- throw error;
- }
- }
var activeElement = doc.activeElement;
// If the element is in a shadow DOM, then as far as the document is