Commit 36290865 authored by sandromaggi's avatar sandromaggi Committed by Commit Bot

[Autofill Assistant] Provide more debug information for autofill.

When the AA autofill action fails, we now send more information. These
include:
* Missing fallback values
* Errors in finding or filling field

Bug: b/128592689
Change-Id: I9872fc08fa5917ca9964bc176ffed8c6a93e77cc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2019104
Commit-Queue: Sandro Maggi <sandromaggi@google.com>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735889}
parent e56c255a
......@@ -192,6 +192,7 @@ source_set("unit_tests") {
"actions/mock_action_delegate.h",
"actions/popup_message_action_unittest.cc",
"actions/prompt_action_unittest.cc",
"actions/required_fields_fallback_handler_unittest.cc",
"actions/set_form_field_value_action_unittest.cc",
"actions/show_details_action_unittest.cc",
"actions/tell_action_unittest.cc",
......
......@@ -15,6 +15,36 @@
#include "components/autofill_assistant/browser/client_status.h"
namespace autofill_assistant {
namespace {
AutofillErrorInfoProto::AutofillFieldError* AddAutofillError(
const RequiredFieldsFallbackHandler::RequiredField& required_field,
ClientStatus* client_status) {
auto* field_error = client_status->mutable_details()
->mutable_autofill_error_info()
->add_autofill_field_error();
*field_error->mutable_field() =
required_field.selector.ToElementReferenceProto();
field_error->set_field_key(required_field.fallback_key);
return field_error;
}
void FillStatusDetailsWithMissingFallbackData(
const RequiredFieldsFallbackHandler::RequiredField& required_field,
ClientStatus* client_status) {
auto* field_error = AddAutofillError(required_field, client_status);
field_error->set_no_fallback_value(true);
}
void FillStatusDetailsWithError(
const RequiredFieldsFallbackHandler::RequiredField& required_field,
ProcessedActionStatusProto error_status,
ClientStatus* client_status) {
auto* field_error = AddAutofillError(required_field, client_status);
field_error->set_status(error_status);
}
} // namespace
RequiredFieldsFallbackHandler::RequiredFieldsFallbackHandler(
const std::vector<RequiredField>& required_fields,
......@@ -44,7 +74,9 @@ void RequiredFieldsFallbackHandler::CheckAndFallbackRequiredFields(
base::OnceCallback<void(const ClientStatus&,
const base::Optional<ClientStatus>&)>
status_update_callback) {
initial_autofill_status_ = initial_autofill_status;
DCHECK(fallback_data != nullptr);
client_status_ = initial_autofill_status;
status_update_callback_ = std::move(status_update_callback);
if (required_fields_.empty()) {
......@@ -66,7 +98,10 @@ void RequiredFieldsFallbackHandler::CheckAllRequiredFields(
DCHECK(!batch_element_checker_);
batch_element_checker_ = std::make_unique<BatchElementChecker>();
for (size_t i = 0; i < required_fields_.size(); i++) {
if (required_fields_[i].forced) {
// First run (with fallback data) we skip checking forced fields, since
// we overwrite them anyway. Second run (without fallback data) forced
// fields should be checked.
if (required_fields_[i].forced && fallback_data != nullptr) {
continue;
}
......@@ -106,14 +141,14 @@ void RequiredFieldsFallbackHandler::OnCheckRequiredFieldsDone(
if (!should_fallback) {
std::move(status_update_callback_)
.Run(ClientStatus(ACTION_APPLIED), initial_autofill_status_);
.Run(ClientStatus(ACTION_APPLIED), client_status_);
return;
}
if (!fallback_data) {
if (fallback_data == nullptr) {
// Validation failed and we don't want to try the fallback.
std::move(status_update_callback_)
.Run(ClientStatus(MANUAL_FALLBACK), initial_autofill_status_);
.Run(ClientStatus(MANUAL_FALLBACK), client_status_);
return;
}
......@@ -127,11 +162,13 @@ void RequiredFieldsFallbackHandler::OnCheckRequiredFieldsDone(
if (fallback_data->GetValue(required_field.fallback_key).has_value()) {
has_fallbacks = true;
} else {
FillStatusDetailsWithMissingFallbackData(required_field, &client_status_);
}
}
if (!has_fallbacks) {
std::move(status_update_callback_)
.Run(ClientStatus(MANUAL_FALLBACK), initial_autofill_status_);
.Run(ClientStatus(MANUAL_FALLBACK), client_status_);
return;
}
......@@ -182,7 +219,13 @@ void RequiredFieldsFallbackHandler::OnGetFallbackFieldTag(
std::move(fallback_data));
}
DVLOG(3) << "Setting fallback value for " << required_field.selector;
if (!element_tag_status.ok()) {
DVLOG(3) << "Status for element tag was "
<< element_tag_status.proto_status();
}
DVLOG(3) << "Setting fallback value for " << required_field.selector << " ("
<< element_tag << ")";
if (element_tag == "SELECT") {
action_delegate_->SelectOption(
required_field.selector, fallback_value.value(),
......@@ -205,9 +248,13 @@ void RequiredFieldsFallbackHandler::OnSetFallbackFieldValue(
std::unique_ptr<FallbackData> fallback_data,
const ClientStatus& set_field_status) {
if (!set_field_status.ok()) {
// Fallback failed: we stop the script without checking the fields.
FillStatusDetailsWithError(required_fields_[required_fields_index],
set_field_status.proto_status(),
&client_status_);
// Fallback failed: we stop the script without checking the other fields.
std::move(status_update_callback_)
.Run(ClientStatus(MANUAL_FALLBACK), initial_autofill_status_);
.Run(ClientStatus(MANUAL_FALLBACK), client_status_);
return;
}
......
......@@ -112,7 +112,7 @@ class RequiredFieldsFallbackHandler {
std::unique_ptr<FallbackData> fallback_data,
const ClientStatus& status);
ClientStatus initial_autofill_status_;
ClientStatus client_status_;
std::vector<RequiredField> required_fields_;
base::OnceCallback<void(const ClientStatus&,
......
......@@ -20,6 +20,20 @@ Selector::Selector(const ElementReferenceProto& proto) {
pseudo_type = proto.pseudo_type();
}
ElementReferenceProto Selector::ToElementReferenceProto() const {
ElementReferenceProto proto;
for (const auto& selector : selectors) {
proto.add_selectors(selector);
}
if (must_be_visible) {
proto.set_visibility_requirement(MUST_BE_VISIBLE);
}
proto.set_inner_text_pattern(inner_text_pattern);
proto.set_value_pattern(value_pattern);
proto.set_pseudo_type(pseudo_type);
return proto;
}
Selector::Selector(std::vector<std::string> s)
: selectors(s), pseudo_type(PseudoType::UNDEFINED) {}
Selector::Selector(std::vector<std::string> s, PseudoType p)
......
......@@ -45,6 +45,8 @@ struct Selector {
Selector(std::vector<std::string> s, PseudoType p);
~Selector();
ElementReferenceProto ToElementReferenceProto() const;
Selector(Selector&& other);
Selector(const Selector& other);
Selector& operator=(Selector&& other);
......
......@@ -28,6 +28,23 @@ TEST(SelectorTest, FromProto) {
EXPECT_EQ(PseudoType::BEFORE, selector.pseudo_type);
}
TEST(SelectorTest, ToProto) {
Selector selector;
selector.selectors.emplace_back("a");
selector.selectors.emplace_back("b");
selector.inner_text_pattern = "c";
selector.value_pattern = "d";
selector.must_be_visible = true;
selector.pseudo_type = PseudoType::BEFORE;
ElementReferenceProto proto = selector.ToElementReferenceProto();
EXPECT_THAT(proto.selectors(), testing::ElementsAre("a", "b"));
EXPECT_EQ("c", proto.inner_text_pattern());
EXPECT_EQ("d", proto.value_pattern());
EXPECT_EQ(MUST_BE_VISIBLE, proto.visibility_requirement());
EXPECT_EQ(PseudoType::BEFORE, proto.pseudo_type());
}
TEST(SelectorTest, Comparison) {
EXPECT_FALSE(Selector({"a"}) == Selector({"b"}));
EXPECT_LT(Selector({"a"}), Selector({"b"}));
......
......@@ -630,6 +630,22 @@ message UnexpectedErrorInfoProto {
// Message to report autofill related errors for debugging purposes.
message AutofillErrorInfoProto {
message AutofillFieldError {
// The field the error occurred for.
optional ElementReferenceProto field = 1;
// The key of the fallback field. Matches the RequiredField::X enum entry.
optional int32 field_key = 2;
oneof error_type {
// No fallback value for this field.
bool no_fallback_value = 3;
// The status of the action.
ProcessedActionStatusProto status = 4;
}
}
// Comma separated list of address keys in the client memory when the
// unexpected error occurred. Memory values are never reported this way since
// they may contain PII. Only the address key names!
......@@ -644,6 +660,9 @@ message AutofillErrorInfoProto {
// Error status of the Chrome autofill attempt.
optional ProcessedActionStatusProto autofill_error_status = 4;
// Errors that occurred during fallback filling of autofill fields.
repeated AutofillFieldError autofill_field_error = 5;
}
// Next: 22
......
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