Commit d4ee8be6 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Commit Bot

[Autofill Assistant] ElementExists also gets BoxModel.

When checking for presence of an element on a page, we now also compute
the element BoxModel to make sure it is present on the page. This is
necessary because some scripts have conditional actions (e.g. click on
element X if X is on the page) which would fail if the element they act
on has no box model but is still considered on the page.

This makes the check for existence much slower, but for now correctness
is more important than speed.

Bug: 806868
Change-Id: Ibab82898c4ac3dc198b30ba8c10080d3bbebb474
Reviewed-on: https://chromium-review.googlesource.com/c/1280668
Commit-Queue: Jordan Demeulenaere <jdemeulenaere@chromium.org>
Reviewed-by: default avatarGanggui Tang <gogerald@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599916}
parent 579d518c
......@@ -162,11 +162,11 @@ void WebController::OnScrollIntoView(
devtools_client_->GetDOM()->GetBoxModel(
dom::GetBoxModelParams::Builder().SetObjectId(object_id).Build(),
base::BindOnce(&WebController::OnGetBoxModel,
base::BindOnce(&WebController::OnGetBoxModelForClick,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void WebController::OnGetBoxModel(
void WebController::OnGetBoxModelForClick(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<dom::GetBoxModelResult> result) {
if (!result || !result->GetModel() || !result->GetModel()->GetContent()) {
......@@ -188,12 +188,12 @@ void WebController::OnGetBoxModel(
.SetButton(input::DispatchMouseEventButton::LEFT)
.SetType(input::DispatchMouseEventType::MOUSE_PRESSED)
.Build(),
base::BindOnce(&WebController::OnDispatchPressMoustEvent,
base::BindOnce(&WebController::OnDispatchPressMouseEvent,
weak_ptr_factory_.GetWeakPtr(), std::move(callback), x,
y));
}
void WebController::OnDispatchPressMoustEvent(
void WebController::OnDispatchPressMouseEvent(
base::OnceCallback<void(bool)> callback,
double x,
double y,
......@@ -206,11 +206,11 @@ void WebController::OnDispatchPressMoustEvent(
.SetButton(input::DispatchMouseEventButton::LEFT)
.SetType(input::DispatchMouseEventType::MOUSE_RELEASED)
.Build(),
base::BindOnce(&WebController::OnDispatchReleaseMoustEvent,
base::BindOnce(&WebController::OnDispatchReleaseMouseEvent,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void WebController::OnDispatchReleaseMoustEvent(
void WebController::OnDispatchReleaseMouseEvent(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<input::DispatchMouseEventResult> result) {
OnResult(true, std::move(callback));
......@@ -230,7 +230,22 @@ void WebController::ElementExists(const std::vector<std::string>& selectors,
void WebController::OnFindElementForExist(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<FindElementResult> result) {
OnResult(!result->object_id.empty(), std::move(callback));
if (result->object_id.empty()) {
OnResult(false, std::move(callback));
return;
}
devtools_client_->GetDOM()->GetBoxModel(
dom::GetBoxModelParams::Builder().SetObjectId(result->object_id).Build(),
base::BindOnce(&WebController::OnGetBoxModelForExist,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void WebController::OnGetBoxModelForExist(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<dom::GetBoxModelResult> result) {
OnResult(result && result->GetModel() && result->GetModel()->GetContent(),
std::move(callback));
}
void WebController::FindElement(const std::vector<std::string>& selectors,
......
......@@ -68,7 +68,8 @@ class WebController {
base::OnceCallback<void(bool)> callback);
// Check whether at least one element given by |selectors| exists on the web
// page.
// page. The element must have a valid BoxModel (i.e. it must be visible and
// have a size greater than 0).
virtual void ElementExists(const std::vector<std::string>& selectors,
base::OnceCallback<void(bool)> callback);
......@@ -158,18 +159,20 @@ class WebController {
void OnScrollIntoView(base::OnceCallback<void(bool)> callback,
std::string object_id,
std::unique_ptr<runtime::CallFunctionOnResult> result);
void OnGetBoxModel(base::OnceCallback<void(bool)> callback,
std::unique_ptr<dom::GetBoxModelResult> result);
void OnDispatchPressMoustEvent(
void OnGetBoxModelForClick(base::OnceCallback<void(bool)> callback,
std::unique_ptr<dom::GetBoxModelResult> result);
void OnDispatchPressMouseEvent(
base::OnceCallback<void(bool)> callback,
double x,
double y,
std::unique_ptr<input::DispatchMouseEventResult> result);
void OnDispatchReleaseMoustEvent(
void OnDispatchReleaseMouseEvent(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<input::DispatchMouseEventResult> result);
void OnFindElementForExist(base::OnceCallback<void(bool)> callback,
std::unique_ptr<FindElementResult> result);
void OnGetBoxModelForExist(base::OnceCallback<void(bool)> callback,
std::unique_ptr<dom::GetBoxModelResult> result);
// Find the element given by |selectors|. If multiple elements match
// |selectors| and if |strict_mode| is false, return the first one that is
......
......@@ -275,6 +275,11 @@ IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, IsElementExists) {
IsElementExists(selectors, true);
selectors.emplace_back("#whatever");
IsElementExists(selectors, false);
// Hidden element.
selectors.clear();
selectors.emplace_back("#hidden");
IsElementExists(selectors, false);
}
IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, ClickElement) {
......
......@@ -55,6 +55,8 @@ found in the LICENSE file.
<div id="testOuterHtml"><span>Span</span><p>Paragraph</p></div>
<div id="hidden" style="display: none;">This text is hidden</div>
<iframe id="iframe" name="test_iframe" width="100%" height="500" src=
"autofill_assistant_target_website_iframe_one.html"></iframe>
</body>
......
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