[Autofill Assistant] Allow setting top padding for FocusAction.
The top padding can be specified either by the Pixels or ratio
relative to the height of the window.
This is the M-76 merge for http://crrev/c/1640408.
(cherry picked from commit e0949be5a94d0ad61a816563160feb94c638e9c4)
Bug: 973043
Bug: 806868
Bug: b/132758584
Change-Id: I2d3f77b04a9ca319634fe2ec1325d24c0052d100
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1631607
Reviewed-by: Stephane Zermatten <szermatt@chromium.org>
Commit-Queue: Lukasz Suder <lsuder@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#665878}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1657896
Reviewed-by: Lukasz Suder <lsuder@chromium.org>
Cr-Commit-Position: refs/branch-heads/3809@{#283}
Cr-Branched-From: d82dec1a818f378c464ba307ddd9c92133eac355-refs/heads/master@{#665002}
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn
index c0b1614..855e5a3 100644
--- a/components/autofill_assistant/browser/BUILD.gn
+++ b/components/autofill_assistant/browser/BUILD.gn
@@ -131,6 +131,8 @@
"state.h",
"string_conversions_util.cc",
"string_conversions_util.h",
+ "top_padding.cc",
+ "top_padding.h",
"trigger_context.cc",
"trigger_context.h",
"ui_controller.cc",
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h
index 0d985f2..a0eec45 100644
--- a/components/autofill_assistant/browser/actions/action_delegate.h
+++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -15,6 +15,7 @@
#include "components/autofill_assistant/browser/details.h"
#include "components/autofill_assistant/browser/info_box.h"
#include "components/autofill_assistant/browser/selector.h"
+#include "components/autofill_assistant/browser/top_padding.h"
#include "components/autofill_assistant/browser/ui_controller.h"
#include "third_party/blink/public/mojom/payments/payment_request.mojom.h"
#include "third_party/icu/source/common/unicode/umachine.h"
@@ -129,9 +130,11 @@
const std::string& selected_option,
base::OnceCallback<void(const ClientStatus&)> callback) = 0;
- // Focus on the element given by |selector|.
+ // Focus on element given by |selector|. |top_padding| specifies the padding
+ // between focused element and the top.
virtual void FocusElement(
const Selector& selector,
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback) = 0;
// Sets selector of areas that can be manipulated:
diff --git a/components/autofill_assistant/browser/actions/focus_element_action.cc b/components/autofill_assistant/browser/actions/focus_element_action.cc
index ca8c8819..5792e60 100644
--- a/components/autofill_assistant/browser/actions/focus_element_action.cc
+++ b/components/autofill_assistant/browser/actions/focus_element_action.cc
@@ -34,16 +34,35 @@
std::move(callback).Run(std::move(processed_action_proto_));
return;
}
+
+ // Default value of 25%. This value should always be overriden
+ // by backend.
+ TopPadding top_padding{0.25, TopPadding::Unit::RATIO};
+ switch (focus_element.top_padding().top_padding_case()) {
+ case FocusElementProto::TopPadding::kPixels:
+ top_padding = TopPadding(focus_element.top_padding().pixels(),
+ TopPadding::Unit::PIXELS);
+ break;
+ case FocusElementProto::TopPadding::kRatio:
+ top_padding = TopPadding(focus_element.top_padding().ratio(),
+ TopPadding::Unit::RATIO);
+ break;
+ case FocusElementProto::TopPadding::TOP_PADDING_NOT_SET:
+ // Default value set before switch.
+ break;
+ }
+
delegate->ShortWaitForElement(
selector,
base::BindOnce(&FocusElementAction::OnWaitForElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
- std::move(callback), selector));
+ std::move(callback), selector, top_padding));
}
void FocusElementAction::OnWaitForElement(ActionDelegate* delegate,
ProcessActionCallback callback,
const Selector& selector,
+ const TopPadding& top_padding,
bool element_found) {
if (!element_found) {
UpdateProcessedAction(ELEMENT_RESOLUTION_FAILED);
@@ -52,7 +71,7 @@
}
delegate->FocusElement(
- selector,
+ selector, top_padding,
base::BindOnce(&FocusElementAction::OnFocusElement,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(delegate),
std::move(callback)));
diff --git a/components/autofill_assistant/browser/actions/focus_element_action.h b/components/autofill_assistant/browser/actions/focus_element_action.h
index ff9ff0c..2f707bb 100644
--- a/components/autofill_assistant/browser/actions/focus_element_action.h
+++ b/components/autofill_assistant/browser/actions/focus_element_action.h
@@ -6,6 +6,7 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_FOCUS_ELEMENT_ACTION_H_
#include "components/autofill_assistant/browser/actions/action.h"
+#include "components/autofill_assistant/browser/top_padding.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
@@ -26,6 +27,7 @@
void OnWaitForElement(ActionDelegate* delegate,
ProcessActionCallback callback,
const Selector& selector,
+ const TopPadding& top_padding,
bool element_found);
void OnFocusElement(ActionDelegate* delegate,
ProcessActionCallback callback,
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h
index a446f28b..365b965 100644
--- a/components/autofill_assistant/browser/actions/mock_action_delegate.h
+++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -14,6 +14,7 @@
#include "components/autofill_assistant/browser/actions/action_delegate.h"
#include "components/autofill_assistant/browser/client_settings.h"
#include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/top_padding.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace autofill_assistant {
@@ -89,8 +90,9 @@
void(const Selector& selector,
const std::string& selected_option,
base::OnceCallback<void(const ClientStatus&)> callback));
- MOCK_METHOD2(FocusElement,
+ MOCK_METHOD3(FocusElement,
void(const Selector& selector,
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback));
MOCK_METHOD1(SetTouchableElementArea,
void(const ElementAreaProto& touchable_element_area));
diff --git a/components/autofill_assistant/browser/mock_web_controller.h b/components/autofill_assistant/browser/mock_web_controller.h
index a725fd8d..e96b8e73 100644
--- a/components/autofill_assistant/browser/mock_web_controller.h
+++ b/components/autofill_assistant/browser/mock_web_controller.h
@@ -10,6 +10,7 @@
#include "base/callback.h"
#include "components/autofill_assistant/browser/actions/click_action.h"
+#include "components/autofill_assistant/browser/top_padding.h"
#include "components/autofill_assistant/browser/web_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -37,11 +38,13 @@
void FocusElement(
const Selector& selector,
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback) override {
- OnFocusElement(selector, callback);
+ OnFocusElement(selector, top_padding, callback);
}
- MOCK_METHOD2(OnFocusElement,
+ MOCK_METHOD3(OnFocusElement,
void(const Selector& selector,
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)>& callback));
void ElementCheck(const Selector& selector,
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc
index 678f3dd..62beb8c2 100644
--- a/components/autofill_assistant/browser/script_executor.cc
+++ b/components/autofill_assistant/browser/script_executor.cc
@@ -314,9 +314,12 @@
void ScriptExecutor::FocusElement(
const Selector& selector,
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback) {
last_focused_element_selector_ = selector;
- delegate_->GetWebController()->FocusElement(selector, std::move(callback));
+ last_focused_element_top_padding_ = top_padding;
+ delegate_->GetWebController()->FocusElement(selector, top_padding,
+ std::move(callback));
}
void ScriptExecutor::SetTouchableElementArea(
@@ -886,7 +889,8 @@
if (!main_script_->last_focused_element_selector_.empty()) {
delegate_->GetWebController()->FocusElement(
- main_script_->last_focused_element_selector_, base::DoNothing());
+ main_script_->last_focused_element_selector_,
+ main_script_->last_focused_element_top_padding_, base::DoNothing());
}
}
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h
index f3bcedb2..05faccc8 100644
--- a/components/autofill_assistant/browser/script_executor.h
+++ b/components/autofill_assistant/browser/script_executor.h
@@ -25,6 +25,7 @@
#include "components/autofill_assistant/browser/script.h"
#include "components/autofill_assistant/browser/script_executor_delegate.h"
#include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/top_padding.h"
namespace autofill_assistant {
// Class to execute an assistant script.
@@ -137,6 +138,7 @@
base::OnceCallback<void(const ClientStatus&)> callback) override;
void FocusElement(
const Selector& selector,
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback) override;
void SetTouchableElementArea(
const ElementAreaProto& touchable_element_area) override;
@@ -342,6 +344,7 @@
bool should_clean_contextual_ui_on_finish_;
ActionProto::ActionInfoCase previous_action_type_;
Selector last_focused_element_selector_;
+ TopPadding last_focused_element_top_padding_;
std::unique_ptr<ElementAreaProto> touchable_element_area_;
std::map<std::string, ScriptStatusProto>* scripts_state_;
std::unique_ptr<BatchElementChecker> batch_element_checker_;
diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc
index 3aebc40..819580b 100644
--- a/components/autofill_assistant/browser/script_executor_unittest.cc
+++ b/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -67,8 +67,8 @@
ON_CALL(mock_web_controller_, OnElementCheck(_, _))
.WillByDefault(RunOnceCallback<1>(true));
- ON_CALL(mock_web_controller_, OnFocusElement(_, _))
- .WillByDefault(RunOnceCallback<1>(OkClientStatus()));
+ ON_CALL(mock_web_controller_, OnFocusElement(_, _, _))
+ .WillByDefault(RunOnceCallback<2>(OkClientStatus()));
}
protected:
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index e2cf26c1..1ac036ca1 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -713,6 +713,14 @@
// Contain all arguments to focus on an element.
message FocusElementProto {
+ message TopPadding {
+ oneof top_padding {
+ // Padding in CSS pixels. Eg. 20.
+ int32 pixels = 1;
+ // Ratio in relation to the window.innerHeight. Eg. 0.25.
+ float ratio = 2;
+ }
+ }
// Element to focus on.
optional ElementReferenceProto element = 1;
@@ -727,6 +735,9 @@
// Restrict interaction to a series of rectangular areas.
optional ElementAreaProto touchable_element_area = 6;
+
+ // The padding that will be added between the focused element and the top.
+ optional TopPadding top_padding = 7;
}
// An area made up of rectangles whole border are made defined by the position
diff --git a/components/autofill_assistant/browser/top_padding.cc b/components/autofill_assistant/browser/top_padding.cc
new file mode 100644
index 0000000..7415810
--- /dev/null
+++ b/components/autofill_assistant/browser/top_padding.cc
@@ -0,0 +1,27 @@
+// 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/top_padding.h"
+
+namespace autofill_assistant {
+
+TopPadding::TopPadding() {}
+
+TopPadding::TopPadding(float val, Unit u) : value_(val), unit_(u) {}
+
+float TopPadding::pixels() const {
+ if (unit_ == TopPadding::Unit::PIXELS) {
+ return value_;
+ }
+ return 0;
+}
+
+float TopPadding::ratio() const {
+ if (unit_ == TopPadding::Unit::RATIO) {
+ return value_;
+ }
+ return 0;
+}
+
+} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/top_padding.h b/components/autofill_assistant/browser/top_padding.h
new file mode 100644
index 0000000..472c4c5
--- /dev/null
+++ b/components/autofill_assistant/browser/top_padding.h
@@ -0,0 +1,38 @@
+// Copyright 2019 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_TOP_PADDING_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_TOP_PADDING_H_
+
+namespace autofill_assistant {
+
+// A simple structure that holds information about the top padding.
+// This structure is used by WebController.FocusElement.
+//
+// Only one type of value can be set (pixels or ratio). If one is
+// set, other returns 0.
+struct TopPadding {
+ enum class Unit {
+ // Css Pixels.
+ PIXELS = 0,
+ // Ratio in relation to window.innerHeight.
+ RATIO = 1
+ };
+
+ TopPadding();
+ TopPadding(float value, Unit unit);
+
+ // Returns 0 if value set in Ratio.
+ float pixels() const;
+ // Returns 0 if value set in CSS Pixels.
+ float ratio() const;
+
+ private:
+ float value_ = 0;
+ Unit unit_ = Unit::PIXELS;
+};
+
+} // namespace autofill_assistant
+
+#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_TOP_PADDING_H_
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc
index 9f9963b..fd54c95 100644
--- a/components/autofill_assistant/browser/web_controller.cc
+++ b/components/autofill_assistant/browser/web_controller.cc
@@ -60,15 +60,17 @@
v.width,
v.height] })";
-const char* const kScrollIntoViewScript =
- R"(function(node) {
+// Scrolls to the specified node with top padding. The top padding can
+// be specified through pixels or ratio. Pixels take precedence.
+const char* const kScrollIntoViewWithPaddingScript =
+ R"(function(node, topPaddingPixels, topPaddingRatio) {
node.scrollIntoViewIfNeeded();
const rect = node.getBoundingClientRect();
- if (rect.height < window.innerHeight) {
- window.scrollBy({top: rect.top - window.innerHeight * 0.25});
- } else {
- window.scrollBy({top: rect.top});
+ let topPadding = topPaddingPixels;
+ if (!topPadding){
+ topPadding = window.innerHeight * topPaddingRatio;
}
+ window.scrollBy({top: rect.top - topPadding});
})";
const char* const kScrollIntoViewIfNeededScript =
@@ -1209,6 +1211,7 @@
}
void WebController::OnFindElementForFocusElement(
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& status,
std::unique_ptr<FindElementResult> element_result) {
@@ -1223,11 +1226,12 @@
settings_->document_ready_check_count, element_object_id,
base::BindOnce(
&WebController::OnWaitDocumentToBecomeInteractiveForFocusElement,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+ weak_ptr_factory_.GetWeakPtr(), top_padding, std::move(callback),
std::move(element_result)));
}
void WebController::OnWaitDocumentToBecomeInteractiveForFocusElement(
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback,
std::unique_ptr<FindElementResult> target_element,
bool result) {
@@ -1236,15 +1240,23 @@
return;
}
- std::vector<std::unique_ptr<runtime::CallArgument>> argument;
- argument.emplace_back(runtime::CallArgument::Builder()
- .SetObjectId(target_element->object_id)
- .Build());
+ std::vector<std::unique_ptr<runtime::CallArgument>> arguments;
+ arguments.emplace_back(runtime::CallArgument::Builder()
+ .SetObjectId(target_element->object_id)
+ .Build());
+ arguments.emplace_back(runtime::CallArgument::Builder()
+ .SetValue(base::Value::ToUniquePtrValue(
+ base::Value(top_padding.pixels())))
+ .Build());
+ arguments.emplace_back(runtime::CallArgument::Builder()
+ .SetValue(base::Value::ToUniquePtrValue(
+ base::Value(top_padding.ratio())))
+ .Build());
devtools_client_->GetRuntime()->CallFunctionOn(
runtime::CallFunctionOnParams::Builder()
.SetObjectId(target_element->object_id)
- .SetArguments(std::move(argument))
- .SetFunctionDeclaration(std::string(kScrollIntoViewScript))
+ .SetArguments(std::move(arguments))
+ .SetFunctionDeclaration(std::string(kScrollIntoViewWithPaddingScript))
.SetReturnByValue(true)
.Build(),
base::BindOnce(&WebController::OnFocusElement,
@@ -1459,14 +1471,15 @@
void WebController::FocusElement(
const Selector& selector,
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback) {
DVLOG(3) << __func__ << " " << selector;
DCHECK(!selector.empty());
- FindElement(
- selector,
- /* strict_mode= */ false,
- base::BindOnce(&WebController::OnFindElementForFocusElement,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+ FindElement(selector,
+ /* strict_mode= */ false,
+ base::BindOnce(&WebController::OnFindElementForFocusElement,
+ weak_ptr_factory_.GetWeakPtr(), top_padding,
+ std::move(callback)));
}
void WebController::GetFieldValue(
diff --git a/components/autofill_assistant/browser/web_controller.h b/components/autofill_assistant/browser/web_controller.h
index e63a379..8ea31c7 100644
--- a/components/autofill_assistant/browser/web_controller.h
+++ b/components/autofill_assistant/browser/web_controller.h
@@ -23,6 +23,7 @@
#include "components/autofill_assistant/browser/devtools/devtools_client.h"
#include "components/autofill_assistant/browser/rectf.h"
#include "components/autofill_assistant/browser/selector.h"
+#include "components/autofill_assistant/browser/top_padding.h"
#include "third_party/icu/source/common/unicode/umachine.h"
#include "url/gurl.h"
@@ -105,9 +106,11 @@
const Selector& selector,
base::OnceCallback<void(const ClientStatus&)> callback);
- // Focus on element given by |selector|.
+ // Focus on element given by |selector|. |top_padding| specifies the padding
+ // between focused element and the top.
virtual void FocusElement(
const Selector& selector,
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback);
// Get the value of |selector| and return the result through |callback|. The
@@ -321,10 +324,12 @@
const autofill::FormData& form_data,
const autofill::FormFieldData& form_field);
void OnFindElementForFocusElement(
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback,
const ClientStatus& status,
std::unique_ptr<FindElementResult> element_result);
void OnWaitDocumentToBecomeInteractiveForFocusElement(
+ const TopPadding& top_padding,
base::OnceCallback<void(const ClientStatus&)> callback,
std::unique_ptr<FindElementResult> target_element,
bool result);
diff --git a/components/autofill_assistant/browser/web_controller_browsertest.cc b/components/autofill_assistant/browser/web_controller_browsertest.cc
index e123e5aae..2fc512a 100644
--- a/components/autofill_assistant/browser/web_controller_browsertest.cc
+++ b/components/autofill_assistant/browser/web_controller_browsertest.cc
@@ -4,10 +4,12 @@
#include "base/bind.h"
#include "base/memory/ref_counted.h"
+#include "base/strings/strcat.h"
#include "components/autofill_assistant/browser/actions/click_action.h"
#include "components/autofill_assistant/browser/client_settings.h"
#include "components/autofill_assistant/browser/service.pb.h"
#include "components/autofill_assistant/browser/string_conversions_util.h"
+#include "components/autofill_assistant/browser/top_padding.h"
#include "components/autofill_assistant/browser/web_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
@@ -149,10 +151,10 @@
}
}
- void FocusElement(const Selector& selector) {
+ void FocusElement(const Selector& selector, const TopPadding top_padding) {
base::RunLoop run_loop;
web_controller_->FocusElement(
- selector,
+ selector, top_padding,
base::BindOnce(&WebControllerBrowserTest::OnFocusElement,
base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run();
@@ -420,7 +422,8 @@
Selector selector;
selector.selectors.emplace_back("#scroll_item_5");
- FocusElement(selector);
+ TopPadding top_padding{0.25, TopPadding::Unit::RATIO};
+ FocusElement(selector, top_padding);
base::ListValue eval_result = content::EvalJs(shell(), R"(
let item = document.querySelector("#scroll_item_5");
let itemRect = item.getBoundingClientRect();
@@ -853,7 +856,8 @@
iframeRect.y + divRect.y < window.innerHeight;
)";
EXPECT_EQ(false, content::EvalJs(shell(), checkVisibleScript));
- FocusElement(selector);
+ TopPadding top_padding;
+ FocusElement(selector, top_padding);
EXPECT_EQ(true, content::EvalJs(shell(), checkVisibleScript));
}
@@ -869,6 +873,68 @@
/* initial_container_scroll_y=*/200);
}
+IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest,
+ FocusElement_WithPaddingInPixels) {
+ Selector selector;
+ selector.selectors.emplace_back("#scroll-me");
+
+ const std::string checkScrollDifferentThanTargetScript = R"(
+ window.scrollTo(0, 0);
+ let scrollTarget = document.querySelector("#scroll-me");
+ let scrollTargetRect = scrollTarget.getBoundingClientRect();
+ scrollTargetRect.y > 360;
+ )";
+
+ EXPECT_EQ(true,
+ content::EvalJs(shell(), checkScrollDifferentThanTargetScript));
+
+ // Scroll 360px from the top.
+ TopPadding top_padding{/* value= */ 360, TopPadding::Unit::PIXELS};
+ FocusElement(selector, top_padding);
+
+ double eval_result = content::EvalJs(shell(), R"(
+ let scrollTarget = document.querySelector("#scroll-me");
+ let scrollTargetRect = scrollTarget.getBoundingClientRect();
+ scrollTargetRect.top;
+ )")
+ .ExtractDouble();
+
+ EXPECT_NEAR(360, eval_result, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest,
+ FocusElement_WithPaddingInRatio) {
+ Selector selector;
+ selector.selectors.emplace_back("#scroll-me");
+
+ const std::string checkScrollDifferentThanTargetScript = R"(
+ window.scrollTo(0, 0);
+ let scrollTarget = document.querySelector("#scroll-me");
+ let scrollTargetRect = scrollTarget.getBoundingClientRect();
+ let targetScrollY = window.innerHeight * 0.7;
+ scrollTargetRect.y > targetScrollY;
+ )";
+
+ EXPECT_EQ(true,
+ content::EvalJs(shell(), checkScrollDifferentThanTargetScript));
+
+ // Scroll 70% from the top.
+ TopPadding top_padding{/* value= */ 0.7, TopPadding::Unit::RATIO};
+ FocusElement(selector, top_padding);
+
+ base::ListValue eval_result = content::EvalJs(shell(), R"(
+ let scrollTarget = document.querySelector("#scroll-me");
+ let scrollTargetRect = scrollTarget.getBoundingClientRect();
+ [scrollTargetRect.top, window.innerHeight]
+ )")
+ .ExtractList();
+
+ double top = eval_result.GetList()[0].GetDouble();
+ double window_inner_height = eval_result.GetList()[1].GetDouble();
+
+ EXPECT_NEAR(top, window_inner_height * 0.7, 1);
+}
+
IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, SelectOption) {
Selector selector;
selector.selectors.emplace_back("#select");
diff --git a/components/test/data/autofill_assistant/autofill_assistant_target_website.html b/components/test/data/autofill_assistant/autofill_assistant_target_website.html
index ee4ca7d..b831945 100644
--- a/components/test/data/autofill_assistant/autofill_assistant_target_website.html
+++ b/components/test/data/autofill_assistant/autofill_assistant_target_website.html
@@ -231,6 +231,8 @@
<div id="hidden" style="display: none;">This text is hidden</div>
+ <div id="scroll-me" style="background-color: green; height: 40px; width: 100%;"></div>
+
<iframe id="iframe" name="test_iframe" width="100%" height="500" src=
"autofill_assistant_target_website_iframe_one.html"></iframe>