Commit 55ba59a0 authored by Stephane Zermatten's avatar Stephane Zermatten Committed by Commit Bot

Allow prompt action to react to element disappearing.

Before this change, it was possible to make prompt end when element
appeared, but not when they disappeared. Yet, prompt is often used in
interrupt to deal with dialog box and it is useful to detect when such a
dialog box is gone.

With this change, scripts can just ask for prompt to end when a specific
element is gone.

Bug: b/146311363
Change-Id: Ie52fe2b0216533ce92f298fd3b6369ac4af01716
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1969578
Commit-Queue: Stephane Zermatten <szermatt@chromium.org>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726359}
parent 9a0342b7
...@@ -72,14 +72,27 @@ void PromptAction::RegisterChecks( ...@@ -72,14 +72,27 @@ void PromptAction::RegisterChecks(
auto_select_choice_index_ = -1; auto_select_choice_index_ = -1;
for (int i = 0; i < proto_.prompt().choices_size(); i++) { for (int i = 0; i < proto_.prompt().choices_size(); i++) {
Selector selector = const PromptProto::Choice& choice = proto_.prompt().choices(i);
Selector(proto_.prompt().choices(i).auto_select_if_element_exists()); switch (choice.auto_select_case()) {
if (selector.empty()) case PromptProto::Choice::kAutoSelectIfElementExists:
continue; checker->AddElementCheck(
Selector(choice.auto_select_if_element_exists()),
checker->AddElementCheck( base::BindOnce(&PromptAction::OnAutoSelectElementExists,
selector, base::BindOnce(&PromptAction::OnAutoSelectElementExists, weak_ptr_factory_.GetWeakPtr(), i,
weak_ptr_factory_.GetWeakPtr(), i)); /* must_exist= */ true));
break;
case PromptProto::Choice::kAutoSelectIfElementDisappears:
checker->AddElementCheck(
Selector(choice.auto_select_if_element_disappears()),
base::BindOnce(&PromptAction::OnAutoSelectElementExists,
weak_ptr_factory_.GetWeakPtr(), i,
/* must_exist= */ false));
break;
case PromptProto::Choice::AUTO_SELECT_NOT_SET:
break;
}
} }
checker->AddAllDoneCallback(base::BindOnce(&PromptAction::OnElementChecksDone, checker->AddAllDoneCallback(base::BindOnce(&PromptAction::OnElementChecksDone,
...@@ -141,19 +154,23 @@ void PromptAction::UpdateUserActions() { ...@@ -141,19 +154,23 @@ void PromptAction::UpdateUserActions() {
bool PromptAction::HasAutoSelect() { bool PromptAction::HasAutoSelect() {
for (int i = 0; i < proto_.prompt().choices_size(); i++) { for (int i = 0; i < proto_.prompt().choices_size(); i++) {
Selector selector = if (proto_.prompt().choices(i).auto_select_case() !=
Selector(proto_.prompt().choices(i).auto_select_if_element_exists()); PromptProto::Choice::AUTO_SELECT_NOT_SET) {
if (!selector.empty())
return true; return true;
}
} }
return false; return false;
} }
void PromptAction::OnAutoSelectElementExists( void PromptAction::OnAutoSelectElementExists(
int choice_index, int choice_index,
bool must_exist,
const ClientStatus& element_status) { const ClientStatus& element_status) {
if (element_status.ok()) if ((must_exist && element_status.ok()) ||
(!must_exist &&
element_status.proto_status() == ELEMENT_RESOLUTION_FAILED)) {
auto_select_choice_index_ = choice_index; auto_select_choice_index_ = choice_index;
}
// Calling OnSuggestionChosen() is delayed until try_done, as it indirectly // Calling OnSuggestionChosen() is delayed until try_done, as it indirectly
// deletes the batch element checker, which isn't supported from an element // deletes the batch element checker, which isn't supported from an element
......
...@@ -39,6 +39,7 @@ class PromptAction : public Action { ...@@ -39,6 +39,7 @@ class PromptAction : public Action {
void UpdateUserActions(); void UpdateUserActions();
bool HasAutoSelect(); bool HasAutoSelect();
void OnAutoSelectElementExists(int choice_index, void OnAutoSelectElementExists(int choice_index,
bool must_exist,
const ClientStatus& element_status); const ClientStatus& element_status);
void OnElementChecksDone( void OnElementChecksDone(
base::OnceCallback<void(const ClientStatus&)> wait_for_dom_callback); base::OnceCallback<void(const ClientStatus&)> wait_for_dom_callback);
......
...@@ -271,6 +271,36 @@ TEST_F(PromptActionTest, AutoSelectWhenElementExists) { ...@@ -271,6 +271,36 @@ TEST_F(PromptActionTest, AutoSelectWhenElementExists) {
task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1)); task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1));
} }
TEST_F(PromptActionTest, AutoSelectWhenElementDisappears) {
auto* choice_proto = prompt_proto_->add_choices();
choice_proto->set_server_payload("auto-select");
choice_proto->mutable_auto_select_if_element_disappears()->add_selectors(
"element");
PromptAction action(&mock_action_delegate_, proto_);
action.ProcessAction(callback_.Get());
EXPECT_THAT(user_actions_, Pointee(SizeIs(0)));
EXPECT_CALL(mock_web_controller_,
OnElementCheck(Eq(Selector({"element"})), _))
.WillOnce(RunOnceCallback<1>(OkClientStatus()))
.WillRepeatedly(
RunOnceCallback<1>(ClientStatus(ELEMENT_RESOLUTION_FAILED)));
// First round of element checks: element exists.
task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1));
// Second round of element checks: element has gone.
EXPECT_CALL(mock_action_delegate_, CancelPrompt());
EXPECT_CALL(
callback_,
Run(Pointee(AllOf(Property(&ProcessedActionProto::status, ACTION_APPLIED),
Property(&ProcessedActionProto::prompt_choice,
Property(&PromptProto::Choice::server_payload,
"auto-select"))))));
task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1));
}
TEST_F(PromptActionTest, AutoSelectWithButton) { TEST_F(PromptActionTest, AutoSelectWithButton) {
auto* ok_proto = prompt_proto_->add_choices(); auto* ok_proto = prompt_proto_->add_choices();
ok_proto->mutable_chip()->set_text("Ok"); ok_proto->mutable_chip()->set_text("Ok");
......
...@@ -1188,8 +1188,13 @@ message PromptProto { ...@@ -1188,8 +1188,13 @@ message PromptProto {
// Map this choice to a direct action. // Map this choice to a direct action.
optional DirectActionProto direct_action = 12; optional DirectActionProto direct_action = 12;
// Auto-select this choice if the given element exist. oneof auto_select {
optional ElementReferenceProto auto_select_if_element_exists = 4; // Auto-select this choice if the given element exist.
ElementReferenceProto auto_select_if_element_exists = 4;
// Auto-select this choice if the given element disappears.
ElementReferenceProto auto_select_if_element_disappears = 14;
}
// The chip is only visible or enabled if all the given element exists. // The chip is only visible or enabled if all the given element exists.
repeated ElementReferenceProto show_only_if_element_exists = 6; repeated ElementReferenceProto show_only_if_element_exists = 6;
......
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