Commit fc4d56bb authored by Stephane Zermatten's avatar Stephane Zermatten Committed by Commit Bot

[Autofill Assistant] Make ConfigureBottomSheetAction wait for resize to

happen.

Before this change, ConfigureBottomSheetAction would return immediately
after asking for the viewport to be resized. Depending on how quickly
that happened, a Focus action following ConfigureBottomSheetAction might
see the window height before the resize and not be able to focus.

The current workaround for that is to wait after resizing the viewport
before focusing on an element, but the time it takes varies a lot.

With this change, ConfigureBottomSheetAction waits until the viewport
resize has been seen from the Javascript side, so we don't wait longer
than strictly necessary. A maximum wait time avoids scripts getting
stuck in this action.

Bug: b/133665079
Change-Id: Ia37076710634542bb4f15c77f30275c234383cb4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1640408
Commit-Queue: Stephane Zermatten <szermatt@chromium.org>
Reviewed-by: default avatarJordan Demeulenaere <jdemeulenaere@chromium.org>
Cr-Commit-Position: refs/heads/master@{#665557}
parent 3dca3271
......@@ -161,6 +161,7 @@ source_set("unit_tests") {
testonly = true
sources = [
"actions/autofill_action_unittest.cc",
"actions/configure_bottom_sheet_action_unittest.cc",
"actions/mock_action_delegate.cc",
"actions/mock_action_delegate.h",
"actions/prompt_action_unittest.cc",
......
......@@ -246,9 +246,19 @@ class ActionDelegate {
// Set whether the viewport should be resized.
virtual void SetResizeViewport(bool resize_viewport) = 0;
// Checks whether the viewport should be resized.
virtual bool GetResizeViewport() = 0;
// Set the peek mode.
virtual void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) = 0;
// Checks the current peek mode.
virtual ConfigureBottomSheetProto::PeekMode GetPeekMode() = 0;
// Calls the callback once the main document window has been resized.
virtual void WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback) = 0;
// Returns the current client settings.
virtual const ClientSettings& GetSettings() = 0;
......
......@@ -4,33 +4,89 @@
#include "components/autofill_assistant/browser/actions/configure_bottom_sheet_action.h"
#include "base/bind.h"
#include "base/callback.h"
#include "components/autofill_assistant/browser/actions/action_delegate.h"
#include "components/autofill_assistant/browser/client_status.h"
namespace autofill_assistant {
ConfigureBottomSheetAction::ConfigureBottomSheetAction(const ActionProto& proto)
: Action(proto) {}
: Action(proto), weak_ptr_factory_(this) {}
ConfigureBottomSheetAction::~ConfigureBottomSheetAction() {}
void ConfigureBottomSheetAction::InternalProcessAction(
ActionDelegate* delegate,
ProcessActionCallback callback) {
if (proto_.configure_bottom_sheet().viewport_resizing() ==
ConfigureBottomSheetProto::RESIZE) {
const ConfigureBottomSheetProto& proto = proto_.configure_bottom_sheet();
if (proto.resize_timeout_ms() > 0) {
// When a window resize is expected, we want to wait for the size change to
// be visible to Javascript before moving on to another action. To do that,
// this action registers a callback *before* making any change and waits for
// a 'resize' event in the Javascript side.
bool resize = delegate->GetResizeViewport();
bool expect_resize =
(!resize &&
proto.viewport_resizing() == ConfigureBottomSheetProto::RESIZE) ||
(resize &&
(proto.viewport_resizing() == ConfigureBottomSheetProto::NO_RESIZE ||
(proto.peek_mode() !=
ConfigureBottomSheetProto::UNDEFINED_PEEK_MODE &&
proto.peek_mode() != delegate->GetPeekMode())));
if (expect_resize) {
callback_ = std::move(callback);
timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(proto.resize_timeout_ms()),
base::BindOnce(&ConfigureBottomSheetAction::OnTimeout,
weak_ptr_factory_.GetWeakPtr()));
delegate->WaitForWindowHeightChange(
base::BindOnce(&ConfigureBottomSheetAction::OnWindowHeightChange,
weak_ptr_factory_.GetWeakPtr()));
}
}
if (proto.viewport_resizing() == ConfigureBottomSheetProto::RESIZE) {
delegate->SetResizeViewport(true);
} else if (proto_.configure_bottom_sheet().viewport_resizing() ==
} else if (proto.viewport_resizing() ==
ConfigureBottomSheetProto::NO_RESIZE) {
delegate->SetResizeViewport(false);
}
if (proto_.configure_bottom_sheet().peek_mode() !=
ConfigureBottomSheetProto::UNDEFINED_PEEK_MODE) {
delegate->SetPeekMode(proto_.configure_bottom_sheet().peek_mode());
if (proto.peek_mode() != ConfigureBottomSheetProto::UNDEFINED_PEEK_MODE) {
delegate->SetPeekMode(proto.peek_mode());
}
if (callback) {
UpdateProcessedAction(OkClientStatus());
std::move(callback).Run(std::move(processed_action_proto_));
}
}
void ConfigureBottomSheetAction::OnWindowHeightChange(
const ClientStatus& status) {
if (!callback_)
return;
timer_.Stop();
UpdateProcessedAction(status);
std::move(callback_).Run(std::move(processed_action_proto_));
}
void ConfigureBottomSheetAction::OnTimeout() {
if (!callback_)
return;
UpdateProcessedAction(ACTION_APPLIED);
std::move(callback).Run(std::move(processed_action_proto_));
DVLOG(2)
<< __func__
<< " Timed out waiting for window height change. Continuing anyways.";
UpdateProcessedAction(OkClientStatus());
processed_action_proto_->mutable_status_details()->set_original_status(
ProcessedActionStatusProto::TIMED_OUT);
std::move(callback_).Run(std::move(processed_action_proto_));
}
} // namespace autofill_assistant
......@@ -6,6 +6,8 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_CONFIGURE_BOTTOM_SHEET_ACTION_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "components/autofill_assistant/browser/actions/action.h"
namespace autofill_assistant {
......@@ -21,6 +23,12 @@ class ConfigureBottomSheetAction : public Action {
void InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) override;
void OnWindowHeightChange(const ClientStatus& status);
void OnTimeout();
ProcessActionCallback callback_;
base::OneShotTimer timer_;
base::WeakPtrFactory<ConfigureBottomSheetAction> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ConfigureBottomSheetAction);
};
......
// 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.
#include "components/autofill_assistant/browser/actions/configure_bottom_sheet_action.h"
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "components/autofill_assistant/browser/actions/mock_action_delegate.h"
#include "components/autofill_assistant/browser/mock_run_once_callback.h"
#include "components/autofill_assistant/browser/mock_web_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace autofill_assistant {
namespace {
using ::testing::_;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::IsEmpty;
using ::testing::IsNull;
using ::testing::Pointee;
using ::testing::Property;
using ::testing::SizeIs;
class ConfigureBottomSheetActionTest : public testing::Test {
public:
ConfigureBottomSheetActionTest()
: task_env_(
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {}
void SetUp() override {
ON_CALL(mock_action_delegate_, GetResizeViewport())
.WillByDefault(Invoke([this]() { return resize_viewport_; }));
ON_CALL(mock_action_delegate_, SetResizeViewport(_))
.WillByDefault(
Invoke([this](bool value) { resize_viewport_ = value; }));
ON_CALL(mock_action_delegate_, GetPeekMode())
.WillByDefault(Invoke([this]() { return peek_mode_; }));
ON_CALL(mock_action_delegate_, SetPeekMode(_))
.WillByDefault(
Invoke([this](ConfigureBottomSheetProto::PeekMode peek_mode) {
peek_mode_ = peek_mode;
}));
ON_CALL(mock_action_delegate_, OnWaitForWindowHeightChange(_))
.WillByDefault(Invoke(
[this](base::OnceCallback<void(const ClientStatus&)>& callback) {
on_resize_cb_ = std::move(callback);
}));
}
protected:
// Runs the action defined in |proto_| and reports the result to |callback_|.
//
// Once it has run, the result of the action is available in
// |processed_action_|. Before the action has run, |processed_action_| status
// is UNKNOWN_ACTION_STATUS.
void Run() {
ActionProto action_proto;
*action_proto.mutable_configure_bottom_sheet() = proto_;
action_ = std::make_unique<ConfigureBottomSheetAction>(action_proto);
action_->ProcessAction(
&mock_action_delegate_,
base::BindOnce(base::BindLambdaForTesting(
[&](std::unique_ptr<ProcessedActionProto> result) {
processed_action_ = *result;
})));
}
// Runs an action that waits for a resize.
void RunWithTimeout() {
proto_.set_resize_timeout_ms(100);
Run();
}
// Fast forward time enough for an action created by RunWithTimeout() to time
// out.
void ForceTimeout() {
task_env_.FastForwardBy(base::TimeDelta::FromMilliseconds(100));
task_env_.FastForwardBy(base::TimeDelta::FromMilliseconds(100));
}
// task_env_ must be first to guarantee other field
// creation run in that environment.
base::test::ScopedTaskEnvironment task_env_;
MockActionDelegate mock_action_delegate_;
MockWebController mock_web_controller_;
ConfigureBottomSheetProto proto_;
bool resize_viewport_ = false;
base::OnceCallback<void(const ClientStatus&)> on_resize_cb_;
ConfigureBottomSheetProto::PeekMode peek_mode_ =
ConfigureBottomSheetProto::HANDLE;
std::unique_ptr<ConfigureBottomSheetAction> action_;
ProcessedActionProto processed_action_;
};
TEST_F(ConfigureBottomSheetActionTest, NoOp) {
Run();
EXPECT_EQ(ACTION_APPLIED, processed_action_.status());
EXPECT_FALSE(resize_viewport_);
EXPECT_EQ(ConfigureBottomSheetProto::HANDLE, peek_mode_);
}
TEST_F(ConfigureBottomSheetActionTest, ChangePeekMode) {
proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER);
Run();
EXPECT_EQ(ACTION_APPLIED, processed_action_.status());
EXPECT_FALSE(resize_viewport_);
EXPECT_EQ(ConfigureBottomSheetProto::HANDLE_HEADER, peek_mode_);
}
TEST_F(ConfigureBottomSheetActionTest, EnableResize) {
proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE);
Run();
EXPECT_EQ(ACTION_APPLIED, processed_action_.status());
EXPECT_TRUE(resize_viewport_);
EXPECT_EQ(ConfigureBottomSheetProto::HANDLE, peek_mode_);
}
TEST_F(ConfigureBottomSheetActionTest, EnableResizeWithPeekMode) {
proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE);
proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER);
Run();
EXPECT_EQ(ACTION_APPLIED, processed_action_.status());
EXPECT_TRUE(resize_viewport_);
EXPECT_EQ(ConfigureBottomSheetProto::HANDLE_HEADER, peek_mode_);
}
TEST_F(ConfigureBottomSheetActionTest, WaitAfterSettingResize) {
proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE);
RunWithTimeout();
EXPECT_TRUE(resize_viewport_);
ASSERT_TRUE(on_resize_cb_);
std::move(on_resize_cb_).Run(OkClientStatus());
EXPECT_EQ(ACTION_APPLIED, processed_action_.status());
}
TEST_F(ConfigureBottomSheetActionTest, WaitFailsAfterSettingResize) {
proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE);
RunWithTimeout();
ASSERT_TRUE(on_resize_cb_);
std::move(on_resize_cb_).Run(ClientStatus(OTHER_ACTION_STATUS));
EXPECT_EQ(OTHER_ACTION_STATUS, processed_action_.status());
}
TEST_F(ConfigureBottomSheetActionTest, WaitTimesOut) {
proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE);
RunWithTimeout();
ASSERT_TRUE(on_resize_cb_);
ForceTimeout();
EXPECT_EQ(ACTION_APPLIED, processed_action_.status());
EXPECT_EQ(TIMED_OUT, processed_action_.status_details().original_status());
}
TEST_F(ConfigureBottomSheetActionTest, TimesOutAfterWindowResized) {
proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE);
RunWithTimeout();
ASSERT_TRUE(on_resize_cb_);
std::move(on_resize_cb_).Run(OkClientStatus());
ForceTimeout();
EXPECT_EQ(ACTION_APPLIED, processed_action_.status());
EXPECT_TRUE(resize_viewport_);
}
TEST_F(ConfigureBottomSheetActionTest, WindowResizedAfterTimeout) {
proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE);
RunWithTimeout();
ASSERT_TRUE(on_resize_cb_);
ForceTimeout();
std::move(on_resize_cb_).Run(OkClientStatus());
EXPECT_EQ(ACTION_APPLIED, processed_action_.status());
}
TEST_F(ConfigureBottomSheetActionTest, WaitAfterUnsettingResize) {
resize_viewport_ = true;
proto_.set_viewport_resizing(ConfigureBottomSheetProto::NO_RESIZE);
RunWithTimeout();
ASSERT_TRUE(on_resize_cb_);
}
TEST_F(ConfigureBottomSheetActionTest, WaitAfterChangingPeekModeInResizeMode) {
resize_viewport_ = true;
proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER);
RunWithTimeout();
EXPECT_EQ(ConfigureBottomSheetProto::HANDLE_HEADER, peek_mode_);
ASSERT_TRUE(on_resize_cb_);
}
TEST_F(ConfigureBottomSheetActionTest, DontWaitAfterChangingPeekIfNoResize) {
proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE_HEADER);
RunWithTimeout();
ASSERT_FALSE(on_resize_cb_);
}
TEST_F(ConfigureBottomSheetActionTest, DontWaitIfPeekModeNotChanged) {
resize_viewport_ = true;
proto_.set_peek_mode(ConfigureBottomSheetProto::HANDLE);
RunWithTimeout();
ASSERT_FALSE(on_resize_cb_);
}
TEST_F(ConfigureBottomSheetActionTest, DontWaitIfResizeModeNotChanged) {
resize_viewport_ = true;
proto_.set_viewport_resizing(ConfigureBottomSheetProto::RESIZE);
RunWithTimeout();
ASSERT_FALSE(on_resize_cb_);
}
} // namespace
} // namespace autofill_assistant
......@@ -161,13 +161,23 @@ class MockActionDelegate : public ActionDelegate {
MOCK_METHOD1(SetProgressVisible, void(bool visible));
MOCK_METHOD1(SetChips, void(std::unique_ptr<std::vector<Chip>> chips));
MOCK_METHOD1(SetResizeViewport, void(bool resize_viewport));
MOCK_METHOD0(GetResizeViewport, bool());
MOCK_METHOD1(SetPeekMode,
void(ConfigureBottomSheetProto::PeekMode peek_mode));
MOCK_METHOD0(GetPeekMode, ConfigureBottomSheetProto::PeekMode());
MOCK_METHOD2(
SetForm,
bool(std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback));
void WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback) {
OnWaitForWindowHeightChange(callback);
}
MOCK_METHOD1(OnWaitForWindowHeightChange,
void(base::OnceCallback<void(const ClientStatus&)>& callback));
const ClientSettings& GetSettings() override { return client_settings_; }
ClientSettings client_settings_;
......
......@@ -93,10 +93,22 @@ void FakeScriptExecutorDelegate::SetPaymentRequestOptions(
payment_request_options_ = std::move(options);
}
void FakeScriptExecutorDelegate::SetResizeViewport(bool resize_viewport) {}
void FakeScriptExecutorDelegate::SetResizeViewport(bool resize_viewport) {
resize_viewport_ = resize_viewport;
}
bool FakeScriptExecutorDelegate::GetResizeViewport() {
return resize_viewport_;
}
void FakeScriptExecutorDelegate::SetPeekMode(
ConfigureBottomSheetProto::PeekMode peek_mode) {}
ConfigureBottomSheetProto::PeekMode peek_mode) {
peek_mode_ = peek_mode;
}
ConfigureBottomSheetProto::PeekMode FakeScriptExecutorDelegate::GetPeekMode() {
return peek_mode_;
}
bool FakeScriptExecutorDelegate::HasNavigationError() {
return navigation_error_;
......
......@@ -48,7 +48,9 @@ class FakeScriptExecutorDelegate : public ScriptExecutorDelegate {
void SetPaymentRequestOptions(
std::unique_ptr<PaymentRequestOptions> options) override;
void SetResizeViewport(bool resize_viewport) override;
bool GetResizeViewport() override;
void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override;
ConfigureBottomSheetProto::PeekMode GetPeekMode() override;
bool SetForm(std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback)
override;
......@@ -113,6 +115,9 @@ class FakeScriptExecutorDelegate : public ScriptExecutorDelegate {
bool navigating_to_new_document_ = false;
bool navigation_error_ = false;
std::set<ScriptExecutorDelegate::Listener*> listeners_;
bool resize_viewport_ = false;
ConfigureBottomSheetProto::PeekMode peek_mode_ =
ConfigureBottomSheetProto::HANDLE;
DISALLOW_COPY_AND_ASSIGN(FakeScriptExecutorDelegate);
};
......
......@@ -89,6 +89,14 @@ class MockWebController : public WebController {
}
MOCK_METHOD0(ClearCookie, void());
void WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback) {
OnWaitForWindowHeightChange(callback);
}
MOCK_METHOD1(OnWaitForWindowHeightChange,
void(base::OnceCallback<void(const ClientStatus&)>& callback));
};
} // namespace autofill_assistant
......
......@@ -456,11 +456,24 @@ void ScriptExecutor::SetResizeViewport(bool resize_viewport) {
delegate_->SetResizeViewport(resize_viewport);
}
bool ScriptExecutor::GetResizeViewport() {
return delegate_->GetResizeViewport();
}
void ScriptExecutor::SetPeekMode(
ConfigureBottomSheetProto::PeekMode peek_mode) {
delegate_->SetPeekMode(peek_mode);
}
ConfigureBottomSheetProto::PeekMode ScriptExecutor::GetPeekMode() {
return delegate_->GetPeekMode();
}
void ScriptExecutor::WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback) {
delegate_->GetWebController()->WaitForWindowHeightChange(std::move(callback));
}
const ClientSettings& ScriptExecutor::GetSettings() {
return delegate_->GetSettings();
}
......
......@@ -179,7 +179,11 @@ class ScriptExecutor : public ActionDelegate,
void SetProgress(int progress) override;
void SetProgressVisible(bool visible) override;
void SetResizeViewport(bool resize_viewport) override;
bool GetResizeViewport() override;
void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override;
ConfigureBottomSheetProto::PeekMode GetPeekMode() override;
void WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback) override;
const ClientSettings& GetSettings() override;
bool SetForm(std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback)
......
......@@ -68,8 +68,10 @@ class ScriptExecutorDelegate {
virtual void SetProgress(int progress) = 0;
virtual void SetProgressVisible(bool visible) = 0;
virtual void SetChips(std::unique_ptr<std::vector<Chip>> chips) = 0;
virtual bool GetResizeViewport() = 0;
virtual void SetResizeViewport(bool resize_viewport) = 0;
virtual void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) = 0;
virtual ConfigureBottomSheetProto::PeekMode GetPeekMode() = 0;
virtual bool SetForm(
std::unique_ptr<FormProto> form,
base::RepeatingCallback<void(const FormProto::Result*)> callback) = 0;
......
......@@ -1231,6 +1231,10 @@ message ConfigureBottomSheetProto {
// resize_viewport is true or was set to true by a previous actions, the
// viewport will be resized to match the new peek height.
optional PeekMode peek_mode = 2;
// Maximum time to wait for the window to resize before continuing with the
// script. If 0 or unset, the action doesn't wait.
optional int32 resize_timeout_ms = 3;
}
// Allow scripts to display a form with multiple inputs.
......
......@@ -23,6 +23,7 @@
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill_assistant/browser/client_settings.h"
#include "components/autofill_assistant/browser/client_status.h"
#include "components/autofill_assistant/browser/rectf.h"
#include "components/autofill_assistant/browser/string_conversions_util.h"
#include "content/public/browser/browser_task_traits.h"
......@@ -197,6 +198,26 @@ const char* const kClickElement =
selector.click();
})";
// Javascript code that returns a promise that will succeed once the main
// document window has changed height.
//
// This ignores width changes, to filter out resizes caused by changes to the
// screen orientation.
const char* const kWaitForWindowHeightChange = R"(
new Promise((fulfill, reject) => {
var lastWidth = window.innerWidth;
var handler = function(event) {
if (window.innerWidth != lastWidth) {
lastWidth = window.innerWidth;
return
}
window.removeEventListener('resize', handler)
fulfill(true)
}
window.addEventListener('resize', handler)
})
)";
bool ConvertPseudoType(const PseudoType pseudo_type,
dom::PseudoType* pseudo_type_output) {
switch (pseudo_type) {
......@@ -1149,6 +1170,24 @@ void WebController::OnFindElementForCheck(
std::move(callback).Run(status.ok());
}
void WebController::WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback) {
devtools_client_->GetRuntime()->Evaluate(
runtime::EvaluateParams::Builder()
.SetExpression(kWaitForWindowHeightChange)
.SetAwaitPromise(true)
.Build(),
base::BindOnce(&WebController::OnWaitForWindowHeightChange,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void WebController::OnWaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback,
std::unique_ptr<runtime::EvaluateResult> result) {
std::move(callback).Run(
CheckJavaScriptResult(result.get(), __FILE__, __LINE__));
}
void WebController::FindElement(const Selector& selector,
bool strict_mode,
FindElementCallback callback) {
......
......@@ -186,6 +186,10 @@ class WebController {
bool strict,
base::OnceCallback<void(bool)> callback);
// Calls the callback once the main document window has been resized.
virtual void WaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback);
private:
friend class WebControllerBrowserTest;
......@@ -290,6 +294,9 @@ class WebController {
void OnFindElementForCheck(base::OnceCallback<void(bool)> callback,
const ClientStatus& status,
std::unique_ptr<FindElementResult> result);
void OnWaitForWindowHeightChange(
base::OnceCallback<void(const ClientStatus&)> callback,
std::unique_ptr<runtime::EvaluateResult> result);
// Find the element given by |selector|. If multiple elements match
// |selector| and if |strict_mode| is false, return the first one that is
......
......@@ -170,14 +170,14 @@ class WebControllerBrowserTest : public content::ContentBrowserTest,
ClientStatus result;
web_controller_->SelectOption(
selector, option,
base::BindOnce(&WebControllerBrowserTest::OnSelectOption,
base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
base::Unretained(this), run_loop.QuitClosure(),
&result));
run_loop.Run();
return result;
}
void OnSelectOption(base::Closure done_callback,
void OnClientStatus(base::Closure done_callback,
ClientStatus* result_output,
const ClientStatus& status) {
*result_output = status;
......@@ -188,20 +188,13 @@ class WebControllerBrowserTest : public content::ContentBrowserTest,
base::RunLoop run_loop;
ClientStatus result;
web_controller_->HighlightElement(
selector, base::BindOnce(&WebControllerBrowserTest::OnHighlightElement,
selector, base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
base::Unretained(this), run_loop.QuitClosure(),
&result));
run_loop.Run();
return result;
}
void OnHighlightElement(base::Closure done_callback,
ClientStatus* result_output,
const ClientStatus& status) {
*result_output = status;
std::move(done_callback).Run();
}
ClientStatus GetOuterHtml(const Selector& selector,
std::string* html_output) {
base::RunLoop run_loop;
......@@ -1089,4 +1082,17 @@ IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, GetAndSetCookie) {
EXPECT_TRUE(SetCookie());
}
IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, WaitForHeightChange) {
base::RunLoop run_loop;
ClientStatus result;
web_controller_->WaitForWindowHeightChange(
base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
base::Unretained(this), run_loop.QuitClosure(), &result));
EXPECT_TRUE(
content::ExecJs(shell(), "window.dispatchEvent(new Event('resize'))"));
run_loop.Run();
EXPECT_EQ(ACTION_APPLIED, result.proto_status());
}
} // namespace
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