Commit 3298bb1a authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Commit Bot

[Autofill Assistant] Introduce Selector struct to replace vectors.

Before this CLs, all methods handling selectors took a
std::vector<std::string> as input.

This CL replaces all vectors of strings by a Selector struct, such that
it will be easier to add parameters (like pseudo type) to a selector.

Change-Id: Ic981282db840b02e996c21ceb1072607ff25606e
Reviewed-on: https://chromium-review.googlesource.com/c/1348049
Commit-Queue: Jordan Demeulenaere <jdemeulenaere@chromium.org>
Reviewed-by: default avatarStephane Zermatten <szermatt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610550}
parent 784bd236
......@@ -76,6 +76,8 @@ jumbo_static_library("browser") {
"script_precondition.h",
"script_tracker.cc",
"script_tracker.h",
"selector.cc",
"selector.h",
"service.cc",
"service.h",
"ui_controller.cc",
......
......@@ -40,4 +40,13 @@ std::vector<std::string> Action::ExtractVector(
}
return vector;
}
Selector Action::ExtractSelector(const ElementReferenceProto& element) {
Selector a_selector;
for (const auto& selector : element.selectors()) {
a_selector.selectors.emplace_back(selector);
}
return a_selector;
}
} // namespace autofill_assistant
......@@ -10,6 +10,7 @@
#include <vector>
#include "base/callback_forward.h"
#include "components/autofill_assistant/browser/selector.h"
#include "components/autofill_assistant/browser/service.pb.h"
namespace autofill_assistant {
......@@ -42,6 +43,9 @@ class Action {
static std::vector<std::string> ExtractVector(
const google::protobuf::RepeatedPtrField<std::string>& repeated_strings);
// Returns a Selector from an ElementReferenceProto.
static Selector ExtractSelector(const ElementReferenceProto& element);
void UpdateProcessedAction(ProcessedActionStatusProto status);
const ActionProto proto_;
......
......@@ -11,6 +11,7 @@
#include "base/callback_forward.h"
#include "components/autofill_assistant/browser/batch_element_checker.h"
#include "components/autofill_assistant/browser/selector.h"
#include "third_party/blink/public/mojom/payments/payment_request.mojom.h"
class GURL;
......@@ -53,7 +54,7 @@ class ActionDelegate {
// TODO(crbug.com/806868): Consider embedding that wait right into
// WebController and eliminate double-lookup.
virtual void ShortWaitForElementExist(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) = 0;
// Wait for up to |max_wait_time| for the element |selectors| to be visible on
......@@ -64,11 +65,11 @@ class ActionDelegate {
virtual void WaitForElementVisible(
base::TimeDelta max_wait_time,
bool allow_interrupt,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) = 0;
// Click or tap the element given by |selectors| on the web page.
virtual void ClickOrTapElement(const std::vector<std::string>& selectors,
// Click or tap the element given by |selector| on the web page.
virtual void ClickOrTapElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) = 0;
// Ask user to select one of the given suggestions.
......@@ -99,10 +100,10 @@ class ActionDelegate {
const std::string& title,
const std::vector<std::string>& supported_basic_card_networks) = 0;
// Fill the address form given by |selectors| with the given address
// Fill the address form given by |selector| with the given address
// |profile|. |profile| cannot be nullptr.
virtual void FillAddressForm(const autofill::AutofillProfile* profile,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) = 0;
// Ask user to choose a card in personal data manager. GUID of the chosen card
......@@ -111,21 +112,21 @@ class ActionDelegate {
virtual void ChooseCard(
base::OnceCallback<void(const std::string&)> callback) = 0;
// Fill the card form given by |selectors| with the given |card| and its
// Fill the card form given by |selector| with the given |card| and its
// |cvc|. Return result asynchronously through |callback|.
virtual void FillCardForm(std::unique_ptr<autofill::CreditCard> card,
const base::string16& cvc,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) = 0;
// Select the option given by |selectors| and the value of the option to be
// Select the option given by |selector| and the value of the option to be
// picked.
virtual void SelectOption(const std::vector<std::string>& selectors,
virtual void SelectOption(const Selector& selector,
const std::string& selected_option,
base::OnceCallback<void(bool)> callback) = 0;
// Focus on the element given by |selectors|.
virtual void FocusElement(const std::vector<std::string>& selectors,
// Focus on the element given by |selector|.
virtual void FocusElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) = 0;
// Sets selector of elements that can be manipulated:
......@@ -133,30 +134,30 @@ class ActionDelegate {
// - during the next call to Choose()
// whichever comes first.
virtual void SetTouchableElements(
const std::vector<std::vector<std::string>>& element_selectors) = 0;
const std::vector<Selector>& element_selectors) = 0;
// Highlight the element given by |selectors|.
virtual void HighlightElement(const std::vector<std::string>& selectors,
// Highlight the element given by |selector|.
virtual void HighlightElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) = 0;
// Set the |value| of field |selectors| and return the result through
// Set the |value| of field |selector| and return the result through
// |callback|. If |simulate_key_presses| is true, the value will be set by
// clicking the field and then simulating key presses, otherwise the `value`
// attribute will be set directly.
virtual void SetFieldValue(const std::vector<std::string>& selectors,
virtual void SetFieldValue(const Selector& selector,
const std::string& value,
bool simulate_key_presses,
base::OnceCallback<void(bool)> callback) = 0;
// Set the |value| of the |attribute| of the element given by |selectors|.
virtual void SetAttribute(const std::vector<std::string>& selectors,
// Set the |value| of the |attribute| of the element given by |selector|.
virtual void SetAttribute(const Selector& selector,
const std::vector<std::string>& attribute,
const std::string& value,
base::OnceCallback<void(bool)> callback) = 0;
// Return the outerHTML of an element given by |selectors|.
// Return the outerHTML of an element given by |selector|.
virtual void GetOuterHtml(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool, const std::string&)> callback) = 0;
// Load |url| in the current tab. Returns immediately, before the new page has
......
......@@ -99,8 +99,7 @@ AutofillAction::AutofillAction(const ActionProto& proto)
is_autofill_card_ = false;
prompt_ = proto.use_address().prompt();
name_ = proto.use_address().name();
selectors_ =
ExtractVector(proto.use_address().form_field_element().selectors());
selector_ = ExtractSelector(proto.use_address().form_field_element());
fill_form_message_ = proto.use_address().strings().fill_form();
check_form_message_ = proto.use_address().strings().check_form();
required_fields_value_status_.resize(
......@@ -111,8 +110,7 @@ AutofillAction::AutofillAction(const ActionProto& proto)
is_autofill_card_ = true;
prompt_ = proto.use_card().prompt();
name_ = "";
selectors_ =
ExtractVector(proto.use_card().form_field_element().selectors());
selector_ = ExtractSelector(proto.use_card().form_field_element());
fill_form_message_ = proto.use_card().strings().fill_form();
check_form_message_ = proto.use_card().strings().check_form();
show_overlay_ = proto.use_card().show_overlay();
......@@ -142,7 +140,7 @@ void AutofillAction::InternalProcessAction(
return;
}
if (selectors_.empty()) {
if (selector_.empty()) {
// If there is no selector, finish the action directly.
EndAction(/* successful= */ true);
return;
......@@ -194,7 +192,7 @@ void AutofillAction::OnDataSelected(ActionDelegate* delegate,
std::move(address));
}
if (selectors_.empty()) {
if (selector_.empty()) {
// If there is no selector, finish the action directly. This can be the case
// when we want to trigger the selection of address or card at the beginning
// of the script and use it later.
......@@ -213,9 +211,9 @@ void AutofillAction::OnDataSelected(ActionDelegate* delegate,
void AutofillAction::FillFormWithData(ActionDelegate* delegate) {
delegate->ShortWaitForElementExist(
selectors_, base::BindOnce(&AutofillAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(),
base::Unretained(delegate)));
selector_, base::BindOnce(&AutofillAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(),
base::Unretained(delegate)));
}
void AutofillAction::OnWaitForElement(ActionDelegate* delegate,
......@@ -225,7 +223,7 @@ void AutofillAction::OnWaitForElement(ActionDelegate* delegate,
return;
}
DCHECK(!selectors_.empty());
DCHECK(!selector_.empty());
if (is_autofill_card_) {
// TODO(crbug.com/806868): Consider refactoring SelfDeleteFullCardRequester
// so as to unit test it.
......@@ -242,7 +240,7 @@ void AutofillAction::OnWaitForElement(ActionDelegate* delegate,
delegate->GetClientMemory()->selected_address(name_);
DCHECK(profile);
delegate->FillAddressForm(
profile, selectors_,
profile, selector_,
base::BindOnce(&AutofillAction::OnAddressFormFilled,
weak_ptr_factory_.GetWeakPtr(), delegate));
}
......@@ -258,7 +256,7 @@ void AutofillAction::OnGetFullCard(ActionDelegate* delegate,
return;
}
delegate->FillCardForm(std::move(card), cvc, selectors_,
delegate->FillCardForm(std::move(card), cvc, selector_,
base::BindOnce(&AutofillAction::OnCardFormFilled,
weak_ptr_factory_.GetWeakPtr()));
}
......@@ -294,7 +292,7 @@ void AutofillAction::CheckRequiredFields(ActionDelegate* delegate,
auto& required_address_field = proto_.use_address().required_fields(i);
DCHECK_GT(required_address_field.element().selectors_size(), 0);
batch_element_checker_->AddFieldValueCheck(
ExtractVector(required_address_field.element().selectors()),
ExtractSelector(required_address_field.element()),
base::BindOnce(&AutofillAction::OnGetRequiredFieldValue,
// this instance owns batch_element_checker_
base::Unretained(this), i));
......@@ -401,8 +399,7 @@ void AutofillAction::SetFallbackFieldValuesSequentially(
DCHECK_GT(
required_fields.Get(required_fields_index).element().selectors_size(), 0);
delegate->SetFieldValue(
ExtractVector(
required_fields.Get(required_fields_index).element().selectors()),
ExtractSelector(required_fields.Get(required_fields_index).element()),
fallback_value,
required_fields.Get(required_fields_index).simulate_key_presses(),
base::BindOnce(&AutofillAction::OnSetFallbackFieldValue,
......
......@@ -95,7 +95,7 @@ class AutofillAction : public Action {
// Usage of the autofilled address. Ignored if autofilling a card.
std::string name_;
std::string prompt_;
std::vector<std::string> selectors_;
Selector selector_;
std::string fill_form_message_;
std::string check_form_message_;
......
......@@ -22,14 +22,14 @@ namespace autofill_assistant {
namespace {
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::IsNull;
using ::testing::Not;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::StrNe;
using ::testing::Invoke;
class MockPersonalDataManager : public autofill::PersonalDataManager {
public:
......@@ -225,7 +225,7 @@ TEST_F(AutofillActionTest, ValidationSucceeds) {
// Autofill succeeds.
EXPECT_CALL(mock_action_delegate_,
OnFillAddressForm(NotNull(), ElementsAre(kFakeSelector), _))
OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _))
.WillOnce(RunOnceCallback<2>(true));
// Validation succeeds.
......@@ -254,22 +254,23 @@ TEST_F(AutofillActionTest, FallbackFails) {
// Autofill succeeds.
EXPECT_CALL(mock_action_delegate_,
OnFillAddressForm(NotNull(), ElementsAre(kFakeSelector), _))
OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _))
.WillOnce(RunOnceCallback<2>(true));
// Validation fails when getting FIRST_NAME.
EXPECT_CALL(mock_web_controller_, OnGetFieldValue(ElementsAre("#email"), _))
EXPECT_CALL(mock_web_controller_,
OnGetFieldValue(Eq(Selector({"#email"})), _))
.WillOnce(RunOnceCallback<1>(true, "not empty"));
EXPECT_CALL(mock_web_controller_,
OnGetFieldValue(ElementsAre("#first_name"), _))
OnGetFieldValue(Eq(Selector({"#first_name"})), _))
.WillOnce(RunOnceCallback<1>(true, ""));
EXPECT_CALL(mock_web_controller_,
OnGetFieldValue(ElementsAre("#last_name"), _))
OnGetFieldValue(Eq(Selector({"#last_name"})), _))
.WillOnce(RunOnceCallback<1>(true, "not empty"));
// Fallback fails.
EXPECT_CALL(mock_action_delegate_,
OnSetFieldValue(ElementsAre("#first_name"), kFirstName, _))
OnSetFieldValue(Eq(Selector({"#first_name"})), kFirstName, _))
.WillOnce(RunOnceCallback<2>(false));
ExpectActionToStopScript(action_proto, kCheckForm);
......@@ -294,25 +295,26 @@ TEST_F(AutofillActionTest, FallbackSucceeds) {
// Autofill succeeds.
EXPECT_CALL(mock_action_delegate_,
OnFillAddressForm(NotNull(), ElementsAre(kFakeSelector), _))
OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _))
.WillOnce(RunOnceCallback<2>(true));
{
InSequence seq;
// Validation fails when getting FIRST_NAME.
EXPECT_CALL(mock_web_controller_, OnGetFieldValue(ElementsAre("#email"), _))
EXPECT_CALL(mock_web_controller_,
OnGetFieldValue(Eq(Selector({"#email"})), _))
.WillOnce(RunOnceCallback<1>(true, "not empty"));
EXPECT_CALL(mock_web_controller_,
OnGetFieldValue(ElementsAre("#first_name"), _))
OnGetFieldValue(Eq(Selector({"#first_name"})), _))
.WillOnce(RunOnceCallback<1>(true, ""));
EXPECT_CALL(mock_web_controller_,
OnGetFieldValue(ElementsAre("#last_name"), _))
OnGetFieldValue(Eq(Selector({"#last_name"})), _))
.WillOnce(RunOnceCallback<1>(true, "not empty"));
// Fallback succeeds.
EXPECT_CALL(mock_action_delegate_,
OnSetFieldValue(ElementsAre("#first_name"), kFirstName, _))
OnSetFieldValue(Eq(Selector({"#first_name"})), kFirstName, _))
.WillOnce(RunOnceCallback<2>(true));
// Second validation succeeds.
......
......@@ -23,7 +23,7 @@ void ClickAction::InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) {
DCHECK_GT(proto_.click().element_to_click().selectors_size(), 0);
delegate->ShortWaitForElementExist(
ExtractVector(proto_.click().element_to_click().selectors()),
ExtractSelector(proto_.click().element_to_click()),
base::BindOnce(&ClickAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
......@@ -39,7 +39,7 @@ void ClickAction::OnWaitForElement(ActionDelegate* delegate,
}
delegate->ClickOrTapElement(
ExtractVector(proto_.click().element_to_click().selectors()),
ExtractSelector(proto_.click().element_to_click()),
base::BindOnce(&::autofill_assistant::ClickAction::OnClick,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
......
......@@ -30,7 +30,6 @@ class ClickAction : public Action {
bool element_found);
void OnClick(ProcessActionCallback callback, bool status);
std::vector<std::string> target_element_selectors_;
base::WeakPtrFactory<ClickAction> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ClickAction);
......
......@@ -29,7 +29,7 @@ void FocusElementAction::InternalProcessAction(ActionDelegate* delegate,
delegate->ShowStatusMessage(focus_element.title());
}
delegate->ShortWaitForElementExist(
ExtractVector(focus_element.element().selectors()),
ExtractSelector(focus_element.element()),
base::BindOnce(&FocusElementAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
......@@ -45,7 +45,7 @@ void FocusElementAction::OnWaitForElement(ActionDelegate* delegate,
}
delegate->FocusElement(
ExtractVector(proto_.focus_element().element().selectors()),
ExtractSelector(proto_.focus_element().element()),
base::BindOnce(&FocusElementAction::OnFocusElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
......@@ -54,9 +54,9 @@ void FocusElementAction::OnWaitForElement(ActionDelegate* delegate,
void FocusElementAction::OnFocusElement(ActionDelegate* delegate,
ProcessActionCallback callback,
bool status) {
std::vector<std::vector<std::string>> touchable_elements;
std::vector<Selector> touchable_elements;
for (const auto& ref : proto().focus_element().touchable_element_area()) {
touchable_elements.emplace_back(ExtractVector(ref.selectors()));
touchable_elements.emplace_back(ExtractSelector(ref));
}
if (!touchable_elements.empty())
delegate->SetTouchableElements(touchable_elements);
......
......@@ -24,7 +24,7 @@ void HighlightElementAction::InternalProcessAction(
ProcessActionCallback callback) {
DCHECK_GT(proto_.highlight_element().element().selectors_size(), 0);
delegate->ShortWaitForElementExist(
ExtractVector(proto_.highlight_element().element().selectors()),
ExtractSelector(proto_.highlight_element().element()),
base::BindOnce(&HighlightElementAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
......@@ -40,7 +40,7 @@ void HighlightElementAction::OnWaitForElement(ActionDelegate* delegate,
}
delegate->HighlightElement(
ExtractVector(proto_.highlight_element().element().selectors()),
ExtractSelector(proto_.highlight_element().element()),
base::BindOnce(&HighlightElementAction::OnHighlightElement,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
......
......@@ -25,32 +25,30 @@ class MockActionDelegate : public ActionDelegate {
std::unique_ptr<BatchElementChecker>());
void ShortWaitForElementExist(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override {
OnShortWaitForElementExist(selectors, callback);
OnShortWaitForElementExist(selector, callback);
}
MOCK_METHOD2(OnShortWaitForElementExist,
void(const std::vector<std::string>&,
base::OnceCallback<void(bool)>&));
void(const Selector& selector, base::OnceCallback<void(bool)>&));
void WaitForElementVisible(base::TimeDelta max_wait_time,
bool allow_interrupt,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override {
OnWaitForElementVisible(max_wait_time, allow_interrupt, selectors,
callback);
OnWaitForElementVisible(max_wait_time, allow_interrupt, selector, callback);
}
MOCK_METHOD4(OnWaitForElementVisible,
void(base::TimeDelta,
bool,
const std::vector<std::string>&,
const Selector&,
base::OnceCallback<void(bool)>&));
MOCK_METHOD1(ShowStatusMessage, void(const std::string& message));
MOCK_METHOD2(ClickOrTapElement,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
base::OnceCallback<void(bool)> callback));
void Choose(const std::vector<std::string>& suggestions,
......@@ -73,14 +71,14 @@ class MockActionDelegate : public ActionDelegate {
void(base::OnceCallback<void(const std::string&)>& callback));
void FillAddressForm(const autofill::AutofillProfile* profile,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override {
OnFillAddressForm(profile, selectors, callback);
OnFillAddressForm(profile, selector, callback);
}
MOCK_METHOD3(OnFillAddressForm,
void(const autofill::AutofillProfile* profile,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)>& callback));
void ChooseCard(
......@@ -93,28 +91,27 @@ class MockActionDelegate : public ActionDelegate {
void FillCardForm(std::unique_ptr<autofill::CreditCard> card,
const base::string16& cvc,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override {
OnFillCardForm(card->guid(), selectors, callback);
OnFillCardForm(card->guid(), selector, callback);
}
MOCK_METHOD3(OnFillCardForm,
void(const std::string& guid,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)>& callback));
MOCK_METHOD3(SelectOption,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
const std::string& selected_option,
base::OnceCallback<void(bool)> callback));
MOCK_METHOD2(FocusElement,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
base::OnceCallback<void(bool)> callback));
MOCK_METHOD1(
SetTouchableElements,
void(const std::vector<std::vector<std::string>>& element_selectors));
MOCK_METHOD1(SetTouchableElements,
void(const std::vector<Selector>& element_selectors));
MOCK_METHOD2(HighlightElement,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
base::OnceCallback<void(bool)> callback));
MOCK_METHOD4(
......@@ -125,26 +122,26 @@ class MockActionDelegate : public ActionDelegate {
const std::string& title,
const std::vector<std::string>& supported_basic_card_networks));
void SetFieldValue(const std::vector<std::string>& selectors,
void SetFieldValue(const Selector& selector,
const std::string& value,
bool ignored_simulate_key_presses,
base::OnceCallback<void(bool)> callback) {
OnSetFieldValue(selectors, value, callback);
OnSetFieldValue(selector, value, callback);
}
MOCK_METHOD3(OnSetFieldValue,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
const std::string& value,
base::OnceCallback<void(bool)>& callback));
MOCK_METHOD4(SetAttribute,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
const std::vector<std::string>& attribute,
const std::string& value,
base::OnceCallback<void(bool)> callback));
MOCK_METHOD2(
GetOuterHtml,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
base::OnceCallback<void(bool, const std::string&)> callback));
MOCK_METHOD1(LoadURL, void(const GURL& url));
MOCK_METHOD0(Shutdown, void());
......
......@@ -34,7 +34,7 @@ void PromptAction::InternalProcessAction(ActionDelegate* delegate,
batch_element_checker_ = delegate->CreateBatchElementChecker();
for (const auto& auto_select : proto_.prompt().auto_select()) {
batch_element_checker_->AddElementCheck(
kExistenceCheck, ExtractVector(auto_select.element().selectors()),
kExistenceCheck, ExtractSelector(auto_select.element()),
base::BindOnce(&PromptAction::OnElementExist, base::Unretained(this),
auto_select.result()));
}
......
......@@ -28,7 +28,7 @@ void SelectOptionAction::InternalProcessAction(ActionDelegate* delegate,
DCHECK_GT(select_option.element().selectors_size(), 0);
delegate->ShortWaitForElementExist(
ExtractVector(select_option.element().selectors()),
ExtractSelector(select_option.element()),
base::BindOnce(&SelectOptionAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
......@@ -44,7 +44,7 @@ void SelectOptionAction::OnWaitForElement(ActionDelegate* delegate,
}
delegate->SelectOption(
ExtractVector(proto_.select_option().element().selectors()),
ExtractSelector(proto_.select_option().element()),
proto_.select_option().selected_option(),
base::BindOnce(&::autofill_assistant::SelectOptionAction::OnSelectOption,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
......
......@@ -23,7 +23,7 @@ SetAttributeAction::~SetAttributeAction() {}
void SetAttributeAction::InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) {
delegate->ShortWaitForElementExist(
ExtractVector(proto_.set_attribute().element().selectors()),
ExtractSelector(proto_.set_attribute().element()),
base::BindOnce(&SetAttributeAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
......@@ -39,7 +39,7 @@ void SetAttributeAction::OnWaitForElement(ActionDelegate* delegate,
}
delegate->SetAttribute(
ExtractVector(proto_.set_attribute().element().selectors()),
ExtractSelector(proto_.set_attribute().element()),
ExtractVector(proto_.set_attribute().attribute()),
proto_.set_attribute().value(),
base::BindOnce(&SetAttributeAction::OnSetAttribute,
......
......@@ -26,7 +26,7 @@ void SetFormFieldValueAction::InternalProcessAction(
ActionDelegate* delegate,
ProcessActionCallback callback) {
delegate->ShortWaitForElementExist(
ExtractVector(proto_.set_form_value().element().selectors()),
ExtractSelector(proto_.set_form_value().element()),
base::BindOnce(&SetFormFieldValueAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
......@@ -60,12 +60,10 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate,
}
const auto& key_field = proto_.set_form_value().value(next);
const auto& selectors =
ExtractVector(proto_.set_form_value().element().selectors());
switch (key_field.keypress_case()) {
case SetFormFieldValueProto_KeyPress::kText:
delegate->SetFieldValue(
selectors, key_field.text(),
ExtractSelector(proto_.set_form_value().element()), key_field.text(),
/* simulate_key_presses = */ false,
base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue,
weak_ptr_factory_.GetWeakPtr(), delegate,
......
......@@ -23,7 +23,7 @@ void UploadDomAction::InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) {
DCHECK_GT(proto_.upload_dom().tree_root().selectors_size(), 0);
delegate->ShortWaitForElementExist(
ExtractVector(proto_.upload_dom().tree_root().selectors()),
ExtractSelector(proto_.upload_dom().tree_root()),
base::BindOnce(&UploadDomAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
......@@ -39,7 +39,7 @@ void UploadDomAction::OnWaitForElement(ActionDelegate* delegate,
}
delegate->GetOuterHtml(
ExtractVector(proto_.upload_dom().tree_root().selectors()),
ExtractSelector(proto_.upload_dom().tree_root()),
base::BindOnce(&UploadDomAction::OnGetOuterHtml,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
......
......@@ -28,14 +28,18 @@ WaitForDomAction::~WaitForDomAction() {}
void WaitForDomAction::InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) {
DCHECK_GT(proto_.wait_for_dom().selectors_size(), 0);
Selector a_selector;
for (const auto& selector : proto_.wait_for_dom().selectors()) {
a_selector.selectors.emplace_back(selector);
}
base::TimeDelta max_wait_time = kDefaultCheckDuration;
int timeout_ms = proto_.wait_for_dom().timeout_ms();
if (timeout_ms > 0)
max_wait_time = base::TimeDelta::FromMilliseconds(timeout_ms);
delegate->WaitForElementVisible(
max_wait_time, proto_.wait_for_dom().allow_interrupt(),
ExtractVector(proto_.wait_for_dom().selectors()),
max_wait_time, proto_.wait_for_dom().allow_interrupt(), a_selector,
base::BindOnce(&WaitForDomAction::OnCheckDone,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
......
......@@ -30,22 +30,20 @@ BatchElementChecker::BatchElementChecker(WebController* web_controller)
BatchElementChecker::~BatchElementChecker() {}
void BatchElementChecker::AddElementCheck(
ElementCheckType check_type,
const std::vector<std::string>& selectors,
ElementCheckCallback callback) {
void BatchElementChecker::AddElementCheck(ElementCheckType check_type,
const Selector& selector,
ElementCheckCallback callback) {
DCHECK(!started_);
element_check_callbacks_[std::make_pair(check_type, selectors)].emplace_back(
element_check_callbacks_[std::make_pair(check_type, selector)].emplace_back(
std::move(callback));
}
void BatchElementChecker::AddFieldValueCheck(
const std::vector<std::string>& selectors,
GetFieldValueCallback callback) {
void BatchElementChecker::AddFieldValueCheck(const Selector& selector,
GetFieldValueCallback callback) {
DCHECK(!started_);
get_field_value_callbacks_[selectors].emplace_back(std::move(callback));
get_field_value_callbacks_[selector].emplace_back(std::move(callback));
}
void BatchElementChecker::Run(const base::TimeDelta& duration,
......
......@@ -15,6 +15,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/autofill_assistant/browser/selector.h"
namespace autofill_assistant {
class WebController;
......@@ -64,22 +65,22 @@ class BatchElementChecker {
// Checks an an element.
//
// kElementCheck checks whether at least one element given by |selectors|
// kElementCheck checks whether at least one element given by |selector|
// exists on the web page.
//
// kVisibilityCheck checks whether at least one element given by |selectors|
// kVisibilityCheck checks whether at least one element given by |selector|
// is visible on the page.
//
// New element checks cannot be added once Run has been called.
void AddElementCheck(ElementCheckType check_type,
const std::vector<std::string>& selectors,
const Selector& selector,
ElementCheckCallback callback);
// Gets the value of |selectors| and return the result through |callback|. The
// Gets the value of |selector| and return the result through |callback|. The
// returned value will be the empty string in case of error or empty value.
//
// New field checks cannot be added once Run has been called.
void AddFieldValueCheck(const std::vector<std::string>& selectors,
void AddFieldValueCheck(const Selector& selector,
GetFieldValueCallback callback);
// Runs the checks until all elements exist or for |duration|, whichever one
......@@ -129,15 +130,15 @@ class BatchElementChecker {
WebController* const web_controller_;
// A map of ElementCheck arguments (check_type, selectors) to callbacks that
// A map of ElementCheck arguments (check_type, selector) to callbacks that
// take the result of the check.
std::map<std::pair<ElementCheckType, std::vector<std::string>>,
std::map<std::pair<ElementCheckType, Selector>,
std::vector<ElementCheckCallback>>
element_check_callbacks_;
// A map of GetFieldValue arguments (selectors) to callbacks that take the
// A map of GetFieldValue arguments (selector) to callbacks that take the
// field value.
std::map<std::vector<std::string>, std::vector<GetFieldValueCallback>>
std::map<Selector, std::vector<GetFieldValueCallback>>
get_field_value_callbacks_;
int pending_checks_count_;
bool all_found_;
......
......@@ -94,7 +94,7 @@ content::WebContents* Controller::GetWebContents() {
}
void Controller::SetTouchableElementArea(
const std::vector<std::vector<std::string>>& elements) {
const std::vector<Selector>& elements) {
touchable_element_area_.SetElements(elements);
}
......
......@@ -55,8 +55,7 @@ class Controller : public ScriptExecutorDelegate,
const std::map<std::string, std::string>& GetParameters() override;
autofill::PersonalDataManager* GetPersonalDataManager() override;
content::WebContents* GetWebContents() override;
void SetTouchableElementArea(
const std::vector<std::vector<std::string>>& elements) override;
void SetTouchableElementArea(const std::vector<Selector>& elements) override;
bool IsCookieExperimentEnabled() const;
......
......@@ -28,8 +28,7 @@ ElementArea::ElementArea(WebController* web_controller)
ElementArea::~ElementArea() = default;
void ElementArea::SetElements(
const std::vector<std::vector<std::string>>& elements) {
void ElementArea::SetElements(const std::vector<Selector>& elements) {
element_positions_.clear();
for (const auto& selector : elements) {
......@@ -92,7 +91,7 @@ void ElementArea::KeepUpdatingPositions() {
kCheckDelay);
}
void ElementArea::OnGetElementPosition(const std::vector<std::string>& selector,
void ElementArea::OnGetElementPosition(const Selector& selector,
bool found,
const RectF& rect) {
for (auto& position : element_positions_) {
......
......@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/autofill_assistant/browser/rectf.h"
#include "components/autofill_assistant/browser/selector.h"
namespace autofill_assistant {
class WebController;
......@@ -28,7 +29,7 @@ class ElementArea {
// there are elements to check.
//
// The area is updated asynchronously, so Contains will not work right away.
void SetElements(const std::vector<std::vector<std::string>>& elements);
void SetElements(const std::vector<Selector>& elements);
// Clears the set of elements to check.
void ClearElements() { SetElements({}); }
......@@ -71,7 +72,7 @@ class ElementArea {
// an element. Coordinates are values between 0 and 1, relative to the size of
// the visible viewport.
struct ElementPosition {
std::vector<std::string> selector;
Selector selector;
RectF rect;
ElementPosition();
......@@ -80,7 +81,7 @@ class ElementArea {
};
void KeepUpdatingPositions();
void OnGetElementPosition(const std::vector<std::string>& selector,
void OnGetElementPosition(const Selector& selector,
bool found,
const RectF& rect);
void ReportUpdate();
......
......@@ -11,7 +11,7 @@
#include "testing/gmock/include/gmock/gmock.h"
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Eq;
namespace autofill_assistant {
......@@ -41,17 +41,17 @@ TEST_F(ElementAreaTest, Empty) {
}
TEST_F(ElementAreaTest, ElementNotFound) {
element_area_.SetElements({{"#not_found"}});
element_area_.SetElements({Selector({"#not_found"})});
EXPECT_TRUE(element_area_.IsEmpty());
EXPECT_FALSE(element_area_.Contains(0.5f, 0.5f));
}
TEST_F(ElementAreaTest, OneElement) {
EXPECT_CALL(mock_web_controller_,
OnGetElementPosition(ElementsAre("#found"), _))
OnGetElementPosition(Eq(Selector({"#found"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.25f, 0.25f, 0.75f, 0.75f)));
element_area_.SetElements({{"#found"}});
element_area_.SetElements({Selector({"#found"})});
EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_TRUE(element_area_.Contains(0.5f, 0.5f));
EXPECT_FALSE(element_area_.Contains(0.1f, 0.5f));
......@@ -62,13 +62,14 @@ TEST_F(ElementAreaTest, OneElement) {
TEST_F(ElementAreaTest, TwoElements) {
EXPECT_CALL(mock_web_controller_,
OnGetElementPosition(ElementsAre("#top_left"), _))
OnGetElementPosition(Eq(Selector({"#top_left"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.0f, 0.25f, 0.25f)));
EXPECT_CALL(mock_web_controller_,
OnGetElementPosition(ElementsAre("#bottom_right"), _))
OnGetElementPosition(Eq(Selector({"#bottom_right"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.25f, 0.25f, 1.0f, 1.0f)));
element_area_.SetElements({{"#top_left"}, {"#bottom_right"}});
element_area_.SetElements(
{Selector({"#top_left"}), Selector({"#bottom_right"})});
EXPECT_FALSE(element_area_.IsEmpty());
EXPECT_TRUE(element_area_.Contains(0.1f, 0.1f));
EXPECT_TRUE(element_area_.Contains(0.9f, 0.9f));
......@@ -79,11 +80,11 @@ TEST_F(ElementAreaTest, TwoElements) {
TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
testing::InSequence seq;
EXPECT_CALL(mock_web_controller_,
OnGetElementPosition(ElementsAre("#element"), _))
OnGetElementPosition(Eq(Selector({"#element"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.25f, 1.0f, 0.5f)))
.WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.5f, 1.0f, 0.75f)));
element_area_.SetElements({{"#element"}});
element_area_.SetElements({Selector({"#element"})});
EXPECT_FALSE(element_area_.Contains(0.5f, 0.1f));
EXPECT_TRUE(element_area_.Contains(0.5f, 0.4f));
......@@ -101,11 +102,11 @@ TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
TEST_F(ElementAreaTest, ElementMovesWithTime) {
testing::InSequence seq;
EXPECT_CALL(mock_web_controller_,
OnGetElementPosition(ElementsAre("#element"), _))
OnGetElementPosition(Eq(Selector({"#element"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.25f, 1.0f, 0.5f)))
.WillOnce(RunOnceCallback<1>(true, RectF(0.0f, 0.5f, 1.0f, 0.75f)));
element_area_.SetElements({{"#element"}});
element_area_.SetElements({Selector({"#element"})});
EXPECT_FALSE(element_area_.Contains(0.5f, 0.1f));
EXPECT_TRUE(element_area_.Contains(0.5f, 0.4f));
......
......@@ -24,51 +24,51 @@ class MockWebController : public WebController {
MOCK_METHOD1(LoadURL, void(const GURL&));
void ClickOrTapElement(const std::vector<std::string>& selectors,
void ClickOrTapElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) override {
// Transforming callback into a references allows using RunOnceCallback on
// the argument.
OnClickOrTapElement(selectors, callback);
OnClickOrTapElement(selector, callback);
}
MOCK_METHOD2(OnClickOrTapElement,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
base::OnceCallback<void(bool)>& callback));
void FocusElement(const std::vector<std::string>& selectors,
void FocusElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) override {
OnFocusElement(selectors, callback);
OnFocusElement(selector, callback);
}
MOCK_METHOD2(OnFocusElement,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
base::OnceCallback<void(bool)>& callback));
void ElementCheck(ElementCheckType check_type,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override {
OnElementCheck(check_type, selectors, callback);
OnElementCheck(check_type, selector, callback);
}
MOCK_METHOD3(OnElementCheck,
void(ElementCheckType check_type,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)>& callback));
void GetFieldValue(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool, const std::string&)> callback) override {
OnGetFieldValue(selectors, callback);
OnGetFieldValue(selector, callback);
}
MOCK_METHOD2(
OnGetFieldValue,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
base::OnceCallback<void(bool, const std::string&)>& callback));
void GetElementPosition(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool, const RectF&)> callback) override {
OnGetElementPosition(selectors, callback);
OnGetElementPosition(selector, callback);
}
MOCK_METHOD2(OnGetElementPosition,
void(const std::vector<std::string>& selectors,
void(const Selector& selector,
base::OnceCallback<void(bool, const RectF&)>& callback));
void HasCookie(base::OnceCallback<void(bool)> callback) override {
......
......@@ -78,25 +78,25 @@ ScriptExecutor::CreateBatchElementChecker() {
}
void ScriptExecutor::ShortWaitForElementExist(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) {
WaitForElement(kShortWaitForElementDeadline, kExistenceCheck, selectors,
WaitForElement(kShortWaitForElementDeadline, kExistenceCheck, selector,
std::move(callback));
}
void ScriptExecutor::WaitForElementVisible(
base::TimeDelta max_wait_time,
bool allow_interrupt,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) {
if (!allow_interrupt || ordered_interrupts_->empty()) {
// No interrupts to worry about. Just run normal wait.
WaitForElement(max_wait_time, kVisibilityCheck, selectors,
WaitForElement(max_wait_time, kVisibilityCheck, selector,
std::move(callback));
return;
}
wait_with_interrupts_ = std::make_unique<WaitWithInterrupts>(
this, max_wait_time, kVisibilityCheck, selectors,
this, max_wait_time, kVisibilityCheck, selector,
base::BindOnce(&ScriptExecutor::OnWaitForElementVisible,
base::Unretained(this), std::move(callback)));
wait_with_interrupts_->Run();
......@@ -107,9 +107,9 @@ void ScriptExecutor::ShowStatusMessage(const std::string& message) {
}
void ScriptExecutor::ClickOrTapElement(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) {
delegate_->GetWebController()->ClickOrTapElement(selectors,
delegate_->GetWebController()->ClickOrTapElement(selector,
std::move(callback));
}
......@@ -156,9 +156,9 @@ void ScriptExecutor::ChooseAddress(
}
void ScriptExecutor::FillAddressForm(const autofill::AutofillProfile* profile,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) {
delegate_->GetWebController()->FillAddressForm(profile, selectors,
delegate_->GetWebController()->FillAddressForm(profile, selector,
std::move(callback));
}
......@@ -169,32 +169,32 @@ void ScriptExecutor::ChooseCard(
void ScriptExecutor::FillCardForm(std::unique_ptr<autofill::CreditCard> card,
const base::string16& cvc,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) {
delegate_->GetWebController()->FillCardForm(std::move(card), cvc, selectors,
delegate_->GetWebController()->FillCardForm(std::move(card), cvc, selector,
std::move(callback));
}
void ScriptExecutor::SelectOption(const std::vector<std::string>& selectors,
void ScriptExecutor::SelectOption(const Selector& selector,
const std::string& selected_option,
base::OnceCallback<void(bool)> callback) {
delegate_->GetWebController()->SelectOption(selectors, selected_option,
delegate_->GetWebController()->SelectOption(selector, selected_option,
std::move(callback));
}
void ScriptExecutor::HighlightElement(const std::vector<std::string>& selectors,
void ScriptExecutor::HighlightElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) {
delegate_->GetWebController()->HighlightElement(selectors,
delegate_->GetWebController()->HighlightElement(selector,
std::move(callback));
}
void ScriptExecutor::FocusElement(const std::vector<std::string>& selectors,
void ScriptExecutor::FocusElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) {
delegate_->GetWebController()->FocusElement(selectors, std::move(callback));
delegate_->GetWebController()->FocusElement(selector, std::move(callback));
}
void ScriptExecutor::SetTouchableElements(
const std::vector<std::vector<std::string>>& element_selectors) {
const std::vector<Selector>& element_selectors) {
touchable_elements_ = element_selectors;
}
......@@ -214,26 +214,26 @@ void ScriptExecutor::HideOverlay() {
delegate_->GetUiController()->HideOverlay();
}
void ScriptExecutor::SetFieldValue(const std::vector<std::string>& selectors,
void ScriptExecutor::SetFieldValue(const Selector& selector,
const std::string& value,
bool simulate_key_presses,
base::OnceCallback<void(bool)> callback) {
delegate_->GetWebController()->SetFieldValue(
selectors, value, simulate_key_presses, std::move(callback));
selector, value, simulate_key_presses, std::move(callback));
}
void ScriptExecutor::SetAttribute(const std::vector<std::string>& selectors,
void ScriptExecutor::SetAttribute(const Selector& selector,
const std::vector<std::string>& attribute,
const std::string& value,
base::OnceCallback<void(bool)> callback) {
delegate_->GetWebController()->SetAttribute(selectors, attribute, value,
delegate_->GetWebController()->SetAttribute(selector, attribute, value,
std::move(callback));
}
void ScriptExecutor::GetOuterHtml(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool, const std::string&)> callback) {
delegate_->GetWebController()->GetOuterHtml(selectors, std::move(callback));
delegate_->GetWebController()->GetOuterHtml(selector, std::move(callback));
}
void ScriptExecutor::LoadURL(const GURL& url) {
......@@ -399,10 +399,10 @@ void ScriptExecutor::OnProcessedAction(
void ScriptExecutor::WaitForElement(base::TimeDelta max_wait_time,
ElementCheckType check_type,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) {
std::unique_ptr<BatchElementChecker> checker = CreateBatchElementChecker();
checker->AddElementCheck(check_type, selectors, base::DoNothing());
checker->AddElementCheck(check_type, selector, base::DoNothing());
checker->Run(max_wait_time,
/* try_done= */ base::DoNothing(),
/* all_done= */
......@@ -436,12 +436,12 @@ ScriptExecutor::WaitWithInterrupts::WaitWithInterrupts(
const ScriptExecutor* main_script,
base::TimeDelta max_wait_time,
ElementCheckType check_type,
const std::vector<std::string>& selectors,
const Selector& selector,
WaitWithInterrupts::Callback callback)
: main_script_(main_script),
max_wait_time_(max_wait_time),
check_type_(check_type),
selectors_(selectors),
selector_(selector),
callback_(std::move(callback)),
element_found_(false) {}
......@@ -455,7 +455,7 @@ void ScriptExecutor::WaitWithInterrupts::Run() {
main_script_->delegate_->GetWebController()->CreateBatchElementChecker();
batch_element_checker_->AddElementCheck(
check_type_, selectors_,
check_type_, selector_,
base::BindOnce(&WaitWithInterrupts::OnElementCheckDone,
base::Unretained(this)));
for (const auto* interrupt : *main_script_->ordered_interrupts_) {
......
......@@ -67,7 +67,7 @@ class ScriptExecutor : public ActionDelegate {
struct Result {
bool success = false;
AtEnd at_end = AtEnd::CONTINUE;
std::vector<std::vector<std::string>> touchable_elements;
std::vector<Selector> touchable_elements;
Result();
Result(const Result& other);
......@@ -80,14 +80,14 @@ class ScriptExecutor : public ActionDelegate {
// Override ActionDelegate:
std::unique_ptr<BatchElementChecker> CreateBatchElementChecker() override;
void ShortWaitForElementExist(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override;
void WaitForElementVisible(base::TimeDelta max_wait_time,
bool allow_interrupt,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override;
void ShowStatusMessage(const std::string& message) override;
void ClickOrTapElement(const std::vector<std::string>& selectors,
void ClickOrTapElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) override;
void GetPaymentInformation(
payments::mojom::PaymentOptionsPtr payment_options,
......@@ -100,33 +100,33 @@ class ScriptExecutor : public ActionDelegate {
void ChooseAddress(
base::OnceCallback<void(const std::string&)> callback) override;
void FillAddressForm(const autofill::AutofillProfile* profile,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override;
void ChooseCard(
base::OnceCallback<void(const std::string&)> callback) override;
void FillCardForm(std::unique_ptr<autofill::CreditCard> card,
const base::string16& cvc,
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool)> callback) override;
void SelectOption(const std::vector<std::string>& selectors,
void SelectOption(const Selector& selector,
const std::string& selected_option,
base::OnceCallback<void(bool)> callback) override;
void HighlightElement(const std::vector<std::string>& selectors,
void HighlightElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) override;
void FocusElement(const std::vector<std::string>& selectors,
void FocusElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) override;
void SetTouchableElements(
const std::vector<std::vector<std::string>>& element_selectors) override;
void SetFieldValue(const std::vector<std::string>& selectors,
const std::vector<Selector>& element_selectors) override;
void SetFieldValue(const Selector& selector,
const std::string& value,
bool simulate_key_presses,
base::OnceCallback<void(bool)> callback) override;
void SetAttribute(const std::vector<std::string>& selectors,
void SetAttribute(const Selector& selector,
const std::vector<std::string>& attribute,
const std::string& value,
base::OnceCallback<void(bool)> callback) override;
void GetOuterHtml(
const std::vector<std::string>& selectors,
const Selector& selector,
base::OnceCallback<void(bool, const std::string&)> callback) override;
void LoadURL(const GURL& url) override;
void Shutdown() override;
......@@ -161,7 +161,7 @@ class ScriptExecutor : public ActionDelegate {
WaitWithInterrupts(const ScriptExecutor* main_script,
base::TimeDelta max_wait_time,
ElementCheckType check_type,
const std::vector<std::string>& selectors,
const Selector& selectors,
WaitWithInterrupts::Callback callback);
~WaitWithInterrupts();
......@@ -180,7 +180,7 @@ class ScriptExecutor : public ActionDelegate {
const ScriptExecutor* main_script_;
const base::TimeDelta max_wait_time_;
const ElementCheckType check_type_;
const std::vector<std::string> selectors_;
const Selector selector_;
WaitWithInterrupts::Callback callback_;
std::unique_ptr<BatchElementChecker> batch_element_checker_;
......@@ -207,7 +207,7 @@ class ScriptExecutor : public ActionDelegate {
void OnProcessedAction(std::unique_ptr<ProcessedActionProto> action);
void WaitForElement(base::TimeDelta max_wait_time,
ElementCheckType check_type,
const std::vector<std::string>& selectors,
const Selector& selectors,
base::OnceCallback<void(bool)> callback);
void OnWaitForElementVisible(
base::OnceCallback<void(bool)> element_found_callback,
......@@ -229,7 +229,7 @@ class ScriptExecutor : public ActionDelegate {
bool should_stop_script_;
bool should_clean_contextual_ui_on_finish_;
ActionProto::ActionInfoCase previous_action_type_;
std::vector<std::vector<std::string>> touchable_elements_;
std::vector<Selector> touchable_elements_;
std::map<std::string, ScriptStatusProto>* scripts_state_;
// Set of interrupts that might run during wait for dom actions with
......
......@@ -42,7 +42,7 @@ class ScriptExecutorDelegate {
// Make the area of the screen that correspond to the given elements
// touchable.
virtual void SetTouchableElementArea(
const std::vector<std::vector<std::string>>& elements) = 0;
const std::vector<Selector>& elements) = 0;
// Makes no area of the screen touchable.
void ClearTouchableElementArea() { SetTouchableElementArea({}); }
......
......@@ -26,7 +26,7 @@ using ::testing::_;
using ::testing::AllOf;
using ::testing::Contains;
using ::testing::DoAll;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Invoke;
using ::testing::IsEmpty;
......@@ -85,8 +85,7 @@ class ScriptExecutorTest : public testing::Test,
ClientMemory* GetClientMemory() override { return &memory_; }
void SetTouchableElementArea(
const std::vector<std::vector<std::string>>& elements) {}
void SetTouchableElementArea(const std::vector<Selector>& elements) {}
const std::map<std::string, std::string>& GetParameters() override {
return parameters_;
......@@ -618,10 +617,10 @@ TEST_F(ScriptExecutorTest, DoNotRunInterruptIfPreconditionsDontMatch) {
SetupInterrupt("interrupt", "interrupt_trigger");
EXPECT_CALL(mock_web_controller_,
OnElementCheck(_, ElementsAre("element"), _))
OnElementCheck(_, Eq(Selector({"element"})), _))
.WillRepeatedly(RunOnceCallback<2>(true));
EXPECT_CALL(mock_web_controller_,
OnElementCheck(_, ElementsAre("interrupt_trigger"), _))
OnElementCheck(_, Eq(Selector({"interrupt_trigger"})), _))
.WillRepeatedly(RunOnceCallback<2>(false));
EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
......
......@@ -19,19 +19,22 @@ namespace autofill_assistant {
std::unique_ptr<ScriptPrecondition> ScriptPrecondition::FromProto(
const std::string& script_path,
const ScriptPreconditionProto& script_precondition_proto) {
std::vector<std::vector<std::string>> elements_exist;
std::vector<Selector> elements_exist;
for (const auto& element : script_precondition_proto.elements_exist()) {
std::vector<std::string> selectors;
for (const auto& selector : element.selectors()) {
selectors.emplace_back(selector);
}
if (selectors.empty()) {
// TODO(crbug.com/806868): Check if we shouldn't skip the script when this
// happens.
if (element.selectors_size() == 0) {
DLOG(WARNING)
<< "Empty selectors in script precondition for script path: "
<< script_path << ".";
continue;
}
elements_exist.emplace_back(selectors);
Selector a_selector;
for (const auto& selector : element.selectors()) {
a_selector.selectors.emplace_back(selector);
}
elements_exist.emplace_back(std::move(a_selector));
}
std::set<std::string> domain_match;
......@@ -103,20 +106,19 @@ void ScriptPrecondition::Check(
}
for (const auto& value_match : form_value_match_) {
DCHECK(!value_match.element().selectors().empty());
std::vector<std::string> selectors;
Selector a_selector;
for (const auto& selector : value_match.element().selectors()) {
selectors.emplace_back(selector);
a_selector.selectors.emplace_back(selector);
}
DCHECK(!selectors.empty());
batch_checks->AddFieldValueCheck(
selectors, base::BindOnce(&ScriptPrecondition::OnGetFieldValue,
weak_ptr_factory_.GetWeakPtr()));
a_selector, base::BindOnce(&ScriptPrecondition::OnGetFieldValue,
weak_ptr_factory_.GetWeakPtr()));
}
}
ScriptPrecondition::ScriptPrecondition(
const std::vector<std::vector<std::string>>& elements_exist,
const std::vector<Selector>& elements_exist,
const std::set<std::string>& domain_match,
std::vector<std::unique_ptr<re2::RE2>> path_pattern,
const std::vector<ScriptParameterMatchProto>& parameter_match,
......
......@@ -37,7 +37,7 @@ class ScriptPrecondition {
const ScriptPreconditionProto& script_precondition_proto);
ScriptPrecondition(
const std::vector<std::vector<std::string>>& elements_exist,
const std::vector<Selector>& elements_exist,
const std::set<std::string>& domain_match,
std::vector<std::unique_ptr<re2::RE2>> path_pattern,
const std::vector<ScriptParameterMatchProto>& parameter_match,
......@@ -68,7 +68,7 @@ class ScriptPrecondition {
void OnGetFieldValue(bool exists, const std::string& value);
void ReportCheckResult(bool success);
std::vector<std::vector<std::string>> elements_exist_;
std::vector<Selector> elements_exist_;
// Domain (exact match) excluding the last '/' character.
std::set<std::string> domain_match_;
......
......@@ -20,7 +20,7 @@ namespace autofill_assistant {
namespace {
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Invoke;
// A callback that expects to be called immediately.
......@@ -56,17 +56,18 @@ class ScriptPreconditionTest : public testing::Test {
public:
void SetUp() override {
ON_CALL(mock_web_controller_,
OnElementCheck(kExistenceCheck, ElementsAre("exists"), _))
OnElementCheck(kExistenceCheck, Eq(Selector({"exists"})), _))
.WillByDefault(RunOnceCallback<2>(true));
ON_CALL(mock_web_controller_,
OnElementCheck(kExistenceCheck, ElementsAre("does_not_exist"), _))
ON_CALL(
mock_web_controller_,
OnElementCheck(kExistenceCheck, Eq(Selector({"does_not_exist"})), _))
.WillByDefault(RunOnceCallback<2>(false));
SetUrl("http://www.example.com/path");
ON_CALL(mock_web_controller_, OnGetFieldValue(ElementsAre("exists"), _))
ON_CALL(mock_web_controller_, OnGetFieldValue(Eq(Selector({"exists"})), _))
.WillByDefault(RunOnceCallback<1>(true, "foo"));
ON_CALL(mock_web_controller_,
OnGetFieldValue(ElementsAre("does_not_exist"), _))
OnGetFieldValue(Eq(Selector({"does_not_exist"})), _))
.WillByDefault(RunOnceCallback<1>(false, ""));
}
......@@ -179,7 +180,7 @@ TEST_F(ScriptPreconditionTest, BadPathPattern) {
TEST_F(ScriptPreconditionTest, IgnoreEmptyElementsExist) {
EXPECT_CALL(mock_web_controller_,
OnElementCheck(kExistenceCheck, ElementsAre("exists"), _))
OnElementCheck(kExistenceCheck, Eq(Selector({"exists"})), _))
.WillOnce(RunOnceCallback<2>(true));
ScriptPreconditionProto proto;
......
......@@ -20,6 +20,7 @@
namespace autofill_assistant {
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Field;
using ::testing::IsEmpty;
using ::testing::NiceMock;
......@@ -33,10 +34,11 @@ class ScriptTrackerTest : public testing::Test,
public:
void SetUp() override {
ON_CALL(mock_web_controller_,
OnElementCheck(kExistenceCheck, ElementsAre("exists"), _))
OnElementCheck(kExistenceCheck, Eq(Selector({"exists"})), _))
.WillByDefault(RunOnceCallback<2>(true));
ON_CALL(mock_web_controller_,
OnElementCheck(kExistenceCheck, ElementsAre("does_not_exist"), _))
ON_CALL(
mock_web_controller_,
OnElementCheck(kExistenceCheck, Eq(Selector({"does_not_exist"})), _))
.WillByDefault(RunOnceCallback<2>(false));
ON_CALL(mock_web_controller_, GetUrl()).WillByDefault(ReturnRef(url_));
......@@ -71,7 +73,7 @@ class ScriptTrackerTest : public testing::Test,
content::WebContents* GetWebContents() override { return nullptr; }
virtual void SetTouchableElementArea(
const std::vector<std::vector<std::string>>& elements) override {}
const std::vector<Selector>& elements) override {}
// Overrides ScriptTracker::Listener
void OnRunnableScriptsChanged(
......@@ -297,8 +299,9 @@ TEST_F(ScriptTrackerTest, CheckScriptsAgainAfterScriptEnd) {
}
TEST_F(ScriptTrackerTest, CheckScriptsAfterDOMChange) {
EXPECT_CALL(mock_web_controller_,
OnElementCheck(kExistenceCheck, ElementsAre("maybe_exists"), _))
EXPECT_CALL(
mock_web_controller_,
OnElementCheck(kExistenceCheck, Eq(Selector({"maybe_exists"})), _))
.WillOnce(RunOnceCallback<2>(false));
SupportsScriptResponseProto scripts;
......@@ -309,8 +312,9 @@ TEST_F(ScriptTrackerTest, CheckScriptsAfterDOMChange) {
EXPECT_THAT(runnable_scripts(), IsEmpty());
// DOM has changed; OnElementExists now returns true.
EXPECT_CALL(mock_web_controller_,
OnElementCheck(kExistenceCheck, ElementsAre("maybe_exists"), _))
EXPECT_CALL(
mock_web_controller_,
OnElementCheck(kExistenceCheck, Eq(Selector({"maybe_exists"})), _))
.WillOnce(RunOnceCallback<2>(true));
tracker_.CheckScripts(base::TimeDelta::FromSeconds(0));
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill_assistant/browser/selector.h"
namespace autofill_assistant {
Selector::Selector() = default;
Selector::Selector(std::vector<std::string> s) : selectors(s) {}
Selector::~Selector() = default;
Selector::Selector(Selector&& other) = default;
Selector::Selector(const Selector& other) = default;
Selector& Selector::operator=(const Selector& other) = default;
Selector& Selector::operator=(Selector&& other) = default;
bool Selector::operator<(const Selector& other) const {
return this->selectors < other.selectors;
}
bool Selector::operator==(const Selector& other) const {
return this->selectors == other.selectors;
}
bool Selector::empty() const {
return this->selectors.empty();
}
} // namespace autofill_assistant
\ No newline at end of file
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SELECTOR_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SELECTOR_H_
#include <string>
#include <vector>
#include "base/macros.h"
namespace autofill_assistant {
// A structure to represent a CSS selector.
struct Selector {
// A sequence of CSS selectors. Any non-final CSS selector is expected to
// arrive at a frame or an iframe, i.e. an element that contains another
// document.
std::vector<std::string> selectors;
Selector();
explicit Selector(std::vector<std::string> s);
~Selector();
Selector(Selector&& other);
Selector(const Selector& other);
Selector& operator=(Selector&& other);
Selector& operator=(const Selector& other);
bool operator<(const Selector& other) const;
bool operator==(const Selector& other) const;
// Checks whether this selector is empty.
bool empty() const;
};
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SELECTOR_H_
......@@ -394,6 +394,7 @@ message WaitForDomProto {
optional int32 timeout_ms = 1;
// The element to wait for.
// TODO(crbug.com/806868): Use ElementReferenceProto instead.
repeated string selectors = 2;
// If true, run scripts flagged with 'interrupt=true' as soon as their
......
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