Commit 58e39354 authored by Hui(Andy) Wu's avatar Hui(Andy) Wu Committed by Commit Bot

Reland "[autofill assistant] Introduce small delay between key presses."

This is a reland of 012bea0a, with flacky
test deleted.

Original change's description:
> [autofill assistant] Introduce small delay between key presses.
>
> Introduce a small delay between key presses while simulate_key_presses
> is true. This hopefully will allow any JS from the website to have time
> to process the events.
>
> Bug: b/124505757
> Change-Id: I3ab90bde3434043ae9988a9e0b7ff43fdf6e86fb
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1567920
> Commit-Queue: Hui Wu <wuandy@chromium.org>
> Reviewed-by: Clemens Arbesser <arbesser@google.com>
> Cr-Commit-Position: refs/heads/master@{#652013}

Bug: b/124505757
Change-Id: Ieb9153190ec7c80fc4debde93b3159df6f70ce88
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1573642Reviewed-by: default avatarClemens Arbesser <arbesser@google.com>
Commit-Queue: Hui Wu <wuandy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#652249}
parent e24dc38a
...@@ -169,6 +169,7 @@ class ActionDelegate { ...@@ -169,6 +169,7 @@ class ActionDelegate {
const Selector& selector, const Selector& selector,
const std::string& value, const std::string& value,
bool simulate_key_presses, bool simulate_key_presses,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) = 0; base::OnceCallback<void(const ClientStatus&)> callback) = 0;
// Set the |value| of the |attribute| of the element given by |selector|. // Set the |value| of the |attribute| of the element given by |selector|.
...@@ -183,6 +184,7 @@ class ActionDelegate { ...@@ -183,6 +184,7 @@ class ActionDelegate {
virtual void SendKeyboardInput( virtual void SendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) = 0; base::OnceCallback<void(const ClientStatus&)> callback) = 0;
// Return the outerHTML of an element given by |selector|. // Return the outerHTML of an element given by |selector|.
......
...@@ -252,6 +252,7 @@ void AutofillAction::SetFallbackFieldValuesSequentially( ...@@ -252,6 +252,7 @@ void AutofillAction::SetFallbackFieldValuesSequentially(
Selector(required_fields.Get(required_fields_index).element()), Selector(required_fields.Get(required_fields_index).element()),
fallback_value, fallback_value,
required_fields.Get(required_fields_index).simulate_key_presses(), required_fields.Get(required_fields_index).simulate_key_presses(),
required_fields.Get(required_fields_index).delay_in_millisecond(),
base::BindOnce(&AutofillAction::OnSetFallbackFieldValue, base::BindOnce(&AutofillAction::OnSetFallbackFieldValue,
weak_ptr_factory_.GetWeakPtr(), delegate, weak_ptr_factory_.GetWeakPtr(), delegate,
required_fields_index)); required_fields_index));
......
...@@ -116,6 +116,7 @@ class MockActionDelegate : public ActionDelegate { ...@@ -116,6 +116,7 @@ class MockActionDelegate : public ActionDelegate {
void SetFieldValue(const Selector& selector, void SetFieldValue(const Selector& selector,
const std::string& value, const std::string& value,
bool ignored_simulate_key_presses, bool ignored_simulate_key_presses,
int ignored_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) { base::OnceCallback<void(const ClientStatus&)> callback) {
OnSetFieldValue(selector, value, callback); OnSetFieldValue(selector, value, callback);
} }
...@@ -131,9 +132,10 @@ class MockActionDelegate : public ActionDelegate { ...@@ -131,9 +132,10 @@ class MockActionDelegate : public ActionDelegate {
const std::string& value, const std::string& value,
base::OnceCallback<void(const ClientStatus&)> callback)); base::OnceCallback<void(const ClientStatus&)> callback));
MOCK_METHOD3(SendKeyboardInput, MOCK_METHOD4(SendKeyboardInput,
void(const Selector& selector, void(const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback)); base::OnceCallback<void(const ClientStatus&)> callback));
MOCK_METHOD2(GetOuterHtml, MOCK_METHOD2(GetOuterHtml,
void(const Selector& selector, void(const Selector& selector,
......
...@@ -69,6 +69,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate, ...@@ -69,6 +69,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate,
const auto& key_field = proto_.set_form_value().value(next); const auto& key_field = proto_.set_form_value().value(next);
bool simulate_key_presses = proto_.set_form_value().simulate_key_presses(); bool simulate_key_presses = proto_.set_form_value().simulate_key_presses();
int delay_in_millisecond = proto_.set_form_value().delay_in_millisecond();
switch (key_field.keypress_case()) { switch (key_field.keypress_case()) {
case SetFormFieldValueProto_KeyPress::kText: case SetFormFieldValueProto_KeyPress::kText:
if (simulate_key_presses || key_field.text().empty()) { if (simulate_key_presses || key_field.text().empty()) {
...@@ -77,6 +78,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate, ...@@ -77,6 +78,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate,
// to next value after |SetFieldValue| is done. // to next value after |SetFieldValue| is done.
delegate->SetFieldValue( delegate->SetFieldValue(
selector, key_field.text(), simulate_key_presses, selector, key_field.text(), simulate_key_presses,
delay_in_millisecond,
base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue,
weak_ptr_factory_.GetWeakPtr(), delegate, weak_ptr_factory_.GetWeakPtr(), delegate,
std::move(callback), selector, std::move(callback), selector,
...@@ -85,6 +87,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate, ...@@ -85,6 +87,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate,
// Trigger a check for keyboard fallback when |SetFieldValue| is done. // Trigger a check for keyboard fallback when |SetFieldValue| is done.
delegate->SetFieldValue( delegate->SetFieldValue(
selector, key_field.text(), simulate_key_presses, selector, key_field.text(), simulate_key_presses,
delay_in_millisecond,
base::BindOnce( base::BindOnce(
&SetFormFieldValueAction::OnSetFieldValueAndCheckFallback, &SetFormFieldValueAction::OnSetFieldValueAndCheckFallback,
weak_ptr_factory_.GetWeakPtr(), delegate, std::move(callback), weak_ptr_factory_.GetWeakPtr(), delegate, std::move(callback),
...@@ -98,7 +101,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate, ...@@ -98,7 +101,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate,
// You should use the `keyboard_input' field instead. // You should use the `keyboard_input' field instead.
if (key_field.keycode() < 128) { // US-ASCII if (key_field.keycode() < 128) { // US-ASCII
delegate->SendKeyboardInput( delegate->SendKeyboardInput(
selector, {key_field.keycode()}, selector, {key_field.keycode()}, delay_in_millisecond,
base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue,
weak_ptr_factory_.GetWeakPtr(), delegate, weak_ptr_factory_.GetWeakPtr(), delegate,
std::move(callback), selector, std::move(callback), selector,
...@@ -115,6 +118,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate, ...@@ -115,6 +118,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate,
case SetFormFieldValueProto_KeyPress::kKeyboardInput: case SetFormFieldValueProto_KeyPress::kKeyboardInput:
delegate->SendKeyboardInput( delegate->SendKeyboardInput(
selector, UTF8ToUnicode(key_field.keyboard_input()), selector, UTF8ToUnicode(key_field.keyboard_input()),
delay_in_millisecond,
base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue,
weak_ptr_factory_.GetWeakPtr(), delegate, weak_ptr_factory_.GetWeakPtr(), delegate,
std::move(callback), selector, std::move(callback), selector,
...@@ -171,6 +175,7 @@ void SetFormFieldValueAction::OnGetFieldValue(ActionDelegate* delegate, ...@@ -171,6 +175,7 @@ void SetFormFieldValueAction::OnGetFieldValue(ActionDelegate* delegate,
// afterwards. // afterwards.
delegate->SetFieldValue( delegate->SetFieldValue(
selector, key_field.text(), /*simulate_key_presses = */ true, selector, key_field.text(), /*simulate_key_presses = */ true,
proto_.set_form_value().delay_in_millisecond(),
base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue,
weak_ptr_factory_.GetWeakPtr(), delegate, weak_ptr_factory_.GetWeakPtr(), delegate,
std::move(callback), selector, std::move(callback), selector,
......
...@@ -349,9 +349,11 @@ void ScriptExecutor::SetFieldValue( ...@@ -349,9 +349,11 @@ void ScriptExecutor::SetFieldValue(
const Selector& selector, const Selector& selector,
const std::string& value, const std::string& value,
bool simulate_key_presses, bool simulate_key_presses,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) { base::OnceCallback<void(const ClientStatus&)> callback) {
delegate_->GetWebController()->SetFieldValue( delegate_->GetWebController()->SetFieldValue(
selector, value, simulate_key_presses, std::move(callback)); selector, value, simulate_key_presses, key_press_delay_in_millisecond,
std::move(callback));
} }
void ScriptExecutor::SetAttribute( void ScriptExecutor::SetAttribute(
...@@ -366,8 +368,10 @@ void ScriptExecutor::SetAttribute( ...@@ -366,8 +368,10 @@ void ScriptExecutor::SetAttribute(
void ScriptExecutor::SendKeyboardInput( void ScriptExecutor::SendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) { base::OnceCallback<void(const ClientStatus&)> callback) {
delegate_->GetWebController()->SendKeyboardInput(selector, codepoints, delegate_->GetWebController()->SendKeyboardInput(
selector, codepoints, key_press_delay_in_millisecond,
std::move(callback)); std::move(callback));
} }
......
...@@ -144,6 +144,7 @@ class ScriptExecutor : public ActionDelegate, ...@@ -144,6 +144,7 @@ class ScriptExecutor : public ActionDelegate,
const Selector& selector, const Selector& selector,
const std::string& value, const std::string& value,
bool simulate_key_presses, bool simulate_key_presses,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) override; base::OnceCallback<void(const ClientStatus&)> callback) override;
void SetAttribute( void SetAttribute(
const Selector& selector, const Selector& selector,
...@@ -153,6 +154,7 @@ class ScriptExecutor : public ActionDelegate, ...@@ -153,6 +154,7 @@ class ScriptExecutor : public ActionDelegate,
void SendKeyboardInput( void SendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) override; base::OnceCallback<void(const ClientStatus&)> callback) override;
void GetOuterHtml( void GetOuterHtml(
const Selector& selector, const Selector& selector,
......
...@@ -691,6 +691,9 @@ message UseAddressProto { ...@@ -691,6 +691,9 @@ message UseAddressProto {
// Whether we should simulate actual key presses when filling |element| with // Whether we should simulate actual key presses when filling |element| with
// its corresponding value. // its corresponding value.
optional bool simulate_key_presses = 3; optional bool simulate_key_presses = 3;
// Delay between two key presses when simlulating.
optional int32 delay_in_millisecond = 4 [default = 20];
} }
// An optional name to allow to handle multiple addresses selection (for // An optional name to allow to handle multiple addresses selection (for
...@@ -1027,6 +1030,9 @@ message SetFormFieldValueProto { ...@@ -1027,6 +1030,9 @@ message SetFormFieldValueProto {
// Whether to send key press events when setting values to HTML fields. // Whether to send key press events when setting values to HTML fields.
optional bool simulate_key_presses = 5; optional bool simulate_key_presses = 5;
// Delay between two key presses when simlulating.
optional int32 delay_in_millisecond = 6 [default = 20];
} }
// Set an element attribute to a specific value. // Set an element attribute to a specific value.
......
...@@ -1450,6 +1450,7 @@ void WebController::SetFieldValue( ...@@ -1450,6 +1450,7 @@ void WebController::SetFieldValue(
const Selector& selector, const Selector& selector,
const std::string& value, const std::string& value,
bool simulate_key_presses, bool simulate_key_presses,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) { base::OnceCallback<void(const ClientStatus&)> callback) {
DVLOG(3) << __func__ << " " << selector << ", value=" << value DVLOG(3) << __func__ << " " << selector << ", value=" << value
<< ", simulate_key_presses=" << simulate_key_presses; << ", simulate_key_presses=" << simulate_key_presses;
...@@ -1461,7 +1462,8 @@ void WebController::SetFieldValue( ...@@ -1461,7 +1462,8 @@ void WebController::SetFieldValue(
selector, "", selector, "",
base::BindOnce(&WebController::OnClearFieldForSendKeyboardInput, base::BindOnce(&WebController::OnClearFieldForSendKeyboardInput,
weak_ptr_factory_.GetWeakPtr(), selector, weak_ptr_factory_.GetWeakPtr(), selector,
UTF8ToUnicode(value), std::move(callback))); UTF8ToUnicode(value), key_press_delay_in_millisecond,
std::move(callback)));
return; return;
} }
InternalSetFieldValue(selector, value, std::move(callback)); InternalSetFieldValue(selector, value, std::move(callback));
...@@ -1481,47 +1483,65 @@ void WebController::InternalSetFieldValue( ...@@ -1481,47 +1483,65 @@ void WebController::InternalSetFieldValue(
void WebController::OnClearFieldForSendKeyboardInput( void WebController::OnClearFieldForSendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& clear_status) { const ClientStatus& clear_status) {
if (!clear_status.ok()) { if (!clear_status.ok()) {
std::move(callback).Run(clear_status); std::move(callback).Run(clear_status);
return; return;
} }
SendKeyboardInput(selector, codepoints, std::move(callback)); SendKeyboardInput(selector, codepoints, key_press_delay_in_millisecond,
std::move(callback));
} }
void WebController::OnClickElementForSendKeyboardInput( void WebController::OnClickElementForSendKeyboardInput(
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& click_status) { const ClientStatus& click_status) {
if (!click_status.ok()) { if (!click_status.ok()) {
std::move(callback).Run(click_status); std::move(callback).Run(click_status);
return; return;
} }
DispatchKeyboardTextDownEvent(codepoints, 0, std::move(callback)); DispatchKeyboardTextDownEvent(codepoints, 0, /*delay=*/false,
delay_in_millisecond, std::move(callback));
} }
void WebController::DispatchKeyboardTextDownEvent( void WebController::DispatchKeyboardTextDownEvent(
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
size_t index, size_t index,
bool delay,
int delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) { base::OnceCallback<void(const ClientStatus&)> callback) {
if (index >= codepoints.size()) { if (index >= codepoints.size()) {
std::move(callback).Run(OkClientStatus()); std::move(callback).Run(OkClientStatus());
return; return;
} }
if (delay && delay_in_millisecond > 0) {
base::PostDelayedTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&WebController::DispatchKeyboardTextDownEvent,
weak_ptr_factory_.GetWeakPtr(), codepoints, index,
/*delay=*/false, delay_in_millisecond,
std::move(callback)),
base::TimeDelta::FromMilliseconds(delay_in_millisecond));
return;
}
devtools_client_->GetInput()->DispatchKeyEvent( devtools_client_->GetInput()->DispatchKeyEvent(
CreateKeyEventParamsForCharacter( CreateKeyEventParamsForCharacter(
autofill_assistant::input::DispatchKeyEventType::KEY_DOWN, autofill_assistant::input::DispatchKeyEventType::KEY_DOWN,
codepoints[index]), codepoints[index]),
base::BindOnce(&WebController::DispatchKeyboardTextUpEvent, base::BindOnce(&WebController::DispatchKeyboardTextUpEvent,
weak_ptr_factory_.GetWeakPtr(), codepoints, index, weak_ptr_factory_.GetWeakPtr(), codepoints, index,
std::move(callback))); delay_in_millisecond, std::move(callback)));
} }
void WebController::DispatchKeyboardTextUpEvent( void WebController::DispatchKeyboardTextUpEvent(
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
size_t index, size_t index,
int delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) { base::OnceCallback<void(const ClientStatus&)> callback) {
DCHECK_LT(index, codepoints.size()); DCHECK_LT(index, codepoints.size());
devtools_client_->GetInput()->DispatchKeyEvent( devtools_client_->GetInput()->DispatchKeyEvent(
...@@ -1530,6 +1550,7 @@ void WebController::DispatchKeyboardTextUpEvent( ...@@ -1530,6 +1550,7 @@ void WebController::DispatchKeyboardTextUpEvent(
codepoints[index]), codepoints[index]),
base::BindOnce(&WebController::DispatchKeyboardTextDownEvent, base::BindOnce(&WebController::DispatchKeyboardTextDownEvent,
weak_ptr_factory_.GetWeakPtr(), codepoints, index + 1, weak_ptr_factory_.GetWeakPtr(), codepoints, index + 1,
/*delay=*/true, delay_in_millisecond,
std::move(callback))); std::move(callback)));
} }
...@@ -1651,6 +1672,7 @@ void WebController::OnSetAttribute( ...@@ -1651,6 +1672,7 @@ void WebController::OnSetAttribute(
void WebController::SendKeyboardInput( void WebController::SendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
const int delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback) { base::OnceCallback<void(const ClientStatus&)> callback) {
if (VLOG_IS_ON(3)) { if (VLOG_IS_ON(3)) {
std::string input_str; std::string input_str;
...@@ -1661,16 +1683,18 @@ void WebController::SendKeyboardInput( ...@@ -1661,16 +1683,18 @@ void WebController::SendKeyboardInput(
} }
DCHECK(!selector.empty()); DCHECK(!selector.empty());
FindElement(selector, FindElement(
selector,
/* strict_mode= */ true, /* strict_mode= */ true,
base::BindOnce(&WebController::OnFindElementForSendKeyboardInput, base::BindOnce(&WebController::OnFindElementForSendKeyboardInput,
weak_ptr_factory_.GetWeakPtr(), selector, weak_ptr_factory_.GetWeakPtr(), selector, codepoints,
codepoints, std::move(callback))); delay_in_millisecond, std::move(callback)));
} }
void WebController::OnFindElementForSendKeyboardInput( void WebController::OnFindElementForSendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
const int delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& status, const ClientStatus& status,
std::unique_ptr<FindElementResult> element_result) { std::unique_ptr<FindElementResult> element_result) {
...@@ -1681,7 +1705,7 @@ void WebController::OnFindElementForSendKeyboardInput( ...@@ -1681,7 +1705,7 @@ void WebController::OnFindElementForSendKeyboardInput(
ClickElement(selector, base::BindOnce( ClickElement(selector, base::BindOnce(
&WebController::OnClickElementForSendKeyboardInput, &WebController::OnClickElementForSendKeyboardInput,
weak_ptr_factory_.GetWeakPtr(), codepoints, weak_ptr_factory_.GetWeakPtr(), codepoints,
std::move(callback))); delay_in_millisecond, std::move(callback)));
} }
void WebController::GetOuterHtml( void WebController::GetOuterHtml(
......
...@@ -121,6 +121,7 @@ class WebController { ...@@ -121,6 +121,7 @@ class WebController {
const Selector& selector, const Selector& selector,
const std::string& value, const std::string& value,
bool simulate_key_presses, bool simulate_key_presses,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback); base::OnceCallback<void(const ClientStatus&)> callback);
// Set the |value| of the |attribute| of the element given by |selector|. // Set the |value| of the |attribute| of the element given by |selector|.
...@@ -131,11 +132,13 @@ class WebController { ...@@ -131,11 +132,13 @@ class WebController {
base::OnceCallback<void(const ClientStatus&)> callback); base::OnceCallback<void(const ClientStatus&)> callback);
// Sets the keyboard focus to |selector| and inputs |codepoints|, one // Sets the keyboard focus to |selector| and inputs |codepoints|, one
// character at a time. // character at a time. Key presses will have a delay of |delay_in_milli|
// between them.
// Returns the result through |callback|. // Returns the result through |callback|.
virtual void SendKeyboardInput( virtual void SendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int delay_in_milli,
base::OnceCallback<void(const ClientStatus&)> callback); base::OnceCallback<void(const ClientStatus&)> callback);
// Return the outerHTML of |selector|. // Return the outerHTML of |selector|.
...@@ -345,19 +348,24 @@ class WebController { ...@@ -345,19 +348,24 @@ class WebController {
void OnClearFieldForSendKeyboardInput( void OnClearFieldForSendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int key_press_delay_in_millisecond,
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& status); const ClientStatus& status);
void OnClickElementForSendKeyboardInput( void OnClickElementForSendKeyboardInput(
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int delay_in_milli,
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& click_status); const ClientStatus& click_status);
void DispatchKeyboardTextDownEvent( void DispatchKeyboardTextDownEvent(
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
size_t index, size_t index,
bool delay,
int delay_in_milli,
base::OnceCallback<void(const ClientStatus&)> callback); base::OnceCallback<void(const ClientStatus&)> callback);
void DispatchKeyboardTextUpEvent( void DispatchKeyboardTextUpEvent(
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
size_t index, size_t index,
int delay_in_milli,
base::OnceCallback<void(const ClientStatus&)> callback); base::OnceCallback<void(const ClientStatus&)> callback);
void OnFindElementForSetAttribute( void OnFindElementForSetAttribute(
const std::vector<std::string>& attribute, const std::vector<std::string>& attribute,
...@@ -370,6 +378,7 @@ class WebController { ...@@ -370,6 +378,7 @@ class WebController {
void OnFindElementForSendKeyboardInput( void OnFindElementForSendKeyboardInput(
const Selector& selector, const Selector& selector,
const std::vector<UChar32>& codepoints, const std::vector<UChar32>& codepoints,
int delay_in_milli,
base::OnceCallback<void(const ClientStatus&)> callback, base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& status, const ClientStatus& status,
std::unique_ptr<FindElementResult> element_result); std::unique_ptr<FindElementResult> element_result);
......
...@@ -332,7 +332,7 @@ class WebControllerBrowserTest : public content::ContentBrowserTest, ...@@ -332,7 +332,7 @@ class WebControllerBrowserTest : public content::ContentBrowserTest,
base::RunLoop run_loop; base::RunLoop run_loop;
ClientStatus result; ClientStatus result;
web_controller_->SetFieldValue( web_controller_->SetFieldValue(
selector, value, simulate_key_presses, selector, value, simulate_key_presses, 0,
base::BindOnce(&WebControllerBrowserTest::OnSetFieldValue, base::BindOnce(&WebControllerBrowserTest::OnSetFieldValue,
base::Unretained(this), run_loop.QuitClosure(), base::Unretained(this), run_loop.QuitClosure(),
&result)); &result));
...@@ -348,11 +348,12 @@ class WebControllerBrowserTest : public content::ContentBrowserTest, ...@@ -348,11 +348,12 @@ class WebControllerBrowserTest : public content::ContentBrowserTest,
} }
ClientStatus SendKeyboardInput(const Selector& selector, ClientStatus SendKeyboardInput(const Selector& selector,
const std::vector<UChar32>& codepoints) { const std::vector<UChar32>& codepoints,
int delay_in_milli) {
base::RunLoop run_loop; base::RunLoop run_loop;
ClientStatus result; ClientStatus result;
web_controller_->SendKeyboardInput( web_controller_->SendKeyboardInput(
selector, codepoints, selector, codepoints, delay_in_milli,
base::BindOnce(&WebControllerBrowserTest::OnSendKeyboardInput, base::BindOnce(&WebControllerBrowserTest::OnSendKeyboardInput,
base::Unretained(this), run_loop.QuitClosure(), base::Unretained(this), run_loop.QuitClosure(),
&result)); &result));
...@@ -360,6 +361,11 @@ class WebControllerBrowserTest : public content::ContentBrowserTest, ...@@ -360,6 +361,11 @@ class WebControllerBrowserTest : public content::ContentBrowserTest,
return result; return result;
} }
ClientStatus SendKeyboardInput(const Selector& selector,
const std::vector<UChar32>& codepoints) {
return SendKeyboardInput(selector, codepoints, -1);
}
void OnSendKeyboardInput(const base::Closure& done_callback, void OnSendKeyboardInput(const base::Closure& done_callback,
ClientStatus* result_output, ClientStatus* result_output,
const ClientStatus& status) { const ClientStatus& status) {
...@@ -928,6 +934,25 @@ IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, ...@@ -928,6 +934,25 @@ IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest,
GetFieldsValue(selectors, {expected_output}); GetFieldsValue(selectors, {expected_output});
} }
IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest,
SendKeyboardInputSetsKeyPropertyWithTimeout) {
// Sends input keys to a field where JS will intercept KeyDown and
// at index 3 it will set a timeout whick inserts an space after the
// timeout. If key press delay is enabled, it should handle this
// correctly.
auto input = UTF8ToUnicode("012345");
std::string expected_output = "012 345";
std::vector<Selector> selectors;
Selector a_selector;
a_selector.selectors.emplace_back("#input_js_event_with_timeout");
selectors.emplace_back(a_selector);
EXPECT_EQ(ACTION_APPLIED,
SendKeyboardInput(a_selector, input, /*delay_in_milli*/ 100)
.proto_status());
GetFieldsValue(selectors, {expected_output});
}
IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, SetAttribute) { IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, SetAttribute) {
Selector selector; Selector selector;
std::vector<std::string> attribute; std::vector<std::string> attribute;
......
...@@ -174,6 +174,21 @@ found in the LICENSE file. ...@@ -174,6 +174,21 @@ found in the LICENSE file.
</script> </script>
</div> </div>
<div>
<input id="input_js_event_with_timeout" type="text">
<!-- Uses the 'key' property of a keydown event. -->
<script>
var t = document.getElementById("input_js_event_with_timeout");
t.addEventListener('keydown', e => {
var value = e.target.value;
if (value.length === 3) {
e.preventDefault();
setTimeout(() => {e.target.value = value + ' ' + e.key}, 10);
}
});
</script>
</div>
<div id="testOuterHtml"><span>Span</span><p>Paragraph</p></div> <div id="testOuterHtml"><span>Span</span><p>Paragraph</p></div>
<div id="hidden" style="display: none;">This text is hidden</div> <div id="hidden" style="display: none;">This text is hidden</div>
......
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