Commit 9c037b6b authored by Shengfa Lin's avatar Shengfa Lin Committed by Commit Bot

[chromedriver] Modify sendkeys for contenteditable

Webdriver standard has updated handling for contenteditable,
specifically, only for element that was not focuses would
we move the caret to the end of children.

Modified test to reflect

Bug: chromedriver:3214
Change-Id: I123a7cb3569ad82c3c30d180abfdeaa3b0c8204c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2203288Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Commit-Queue: Shengfa Lin <shengfa@google.com>
Cr-Commit-Position: refs/heads/master@{#770330}
parent b186a4a1
......@@ -524,22 +524,33 @@ Status ExecuteSendKeysToElement(Session* session,
args, &get_content_editable);
if (status.IsError())
return status;
// If element_type is in textControlTypes, sendKeys should append
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;
bool is_content_editable;
if (get_content_editable->GetAsBoolean(&is_content_editable) &&
is_content_editable) {
// If element is contentEditable, will move caret
// at end of element text. W3C mandates that the
// caret be moved "after any child content"
// If element is contentEditable
// check if element is focused
bool is_focused = false;
status = IsElementFocused(session, web_view, element_id, &is_focused);
if (status.IsError())
return status;
// Get top level contentEditable element
std::unique_ptr<base::Value> result;
status = web_view->CallFunction(
session->GetCurrentFrameId(),
"function(element) {"
"var range = document.createRange();"
"range.selectNodeContents(element);"
"range.collapse();"
"var sel = window.getSelection();"
"sel.removeAllRanges();"
"sel.addRange(range);"
"while (element.parentElement && "
"element.parentElement.isContentEditable) {"
" element = element.parentElement;"
......@@ -550,24 +561,44 @@ Status ExecuteSendKeysToElement(Session* session,
if (status.IsError())
return status;
const base::DictionaryValue* element_dict;
std::string target_element_id;
std::string top_element_id;
if (!result->GetAsDictionary(&element_dict) ||
!element_dict->GetString(GetElementKey(), &target_element_id))
!element_dict->GetString(GetElementKey(), &top_element_id))
return Status(kUnknownError, "no element reference returned by script");
return SendKeysToElement(session, web_view, target_element_id, false,
key_list);
}
// If element_type is in textControlTypes, sendKeys should append
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;
// check if top level contentEditable element is focused
bool is_top_focused = false;
status =
IsElementFocused(session, web_view, top_element_id, &is_top_focused);
if (status.IsError())
return status;
// If is_text we want to send keys to the element
// Otherwise, send keys to the top element
if ((is_text && !is_focused) || (!is_text && !is_top_focused)) {
// If element does not currentley have focus
// will move caret
// at end of element text. W3C mandates that the
// caret be moved "after any child content"
// Set selection using the element itself
std::unique_ptr<base::Value> unused;
status = web_view->CallFunction(session->GetCurrentFrameId(),
"function(element) {"
"var range = document.createRange();"
"range.selectNodeContents(element);"
"range.collapse();"
"var sel = window.getSelection();"
"sel.removeAllRanges();"
"sel.addRange(range);"
"}",
args, &unused);
if (status.IsError())
return status;
}
// Use top level element id for the purpose of focusing
if (!is_text)
return SendKeysToElement(session, web_view, top_element_id, is_text,
key_list);
}
return SendKeysToElement(session, web_view, element_id, is_text, key_list);
}
}
......
......@@ -2843,7 +2843,6 @@ class ChromeDriverW3cTest(ChromeDriverBaseTestWithWebServer):
'\'<p contentEditable="true"> <i>hello-></i> '
'<b>send_this_value </b> </p>\';'
'var input = document.getElementsByTagName("i")[0];'
'input.focus();'
'return input;')
element.SendKeys('hello')
self.assertEquals(u'hello->hello', element.GetText())
......@@ -2858,7 +2857,7 @@ class ChromeDriverW3cTest(ChromeDriverBaseTestWithWebServer):
'input.focus();'
'return input;')
element.SendKeys('hello')
self.assertEquals(u'hello ->hello', element.GetText())
self.assertEquals(u'hellohello ->', element.GetText())
def testUnexpectedAlertOpenExceptionMessage(self):
self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html'))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment