1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_TEST_BASE_INTERACTIVE_TEST_UTILS_H_
#define CHROME_TEST_BASE_INTERACTIVE_TEST_UTILS_H_
#include <utility>
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/view_ids.h"
#include "ui/base/test/ui_controls.h"
#include "ui/display/display.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/widget/widget_observer.h"
namespace display {
class Screen;
} // namespace display
#if defined(TOOLKIT_VIEWS)
namespace views {
class View;
class Widget;
}
#endif
namespace ui_test_utils {
// Use in browser interactive uitests to wait until a browser is set to active.
// To use, create and call WaitForActivation(). Since on some platforms, the
// active browser list kept in |BrowserList| is updated before the actual
// activation (see |BrowserView::Show()| for details), observe the widget
// directly and wait for it to actually get activated.
class BrowserActivationWaiter : public views::WidgetObserver {
public:
explicit BrowserActivationWaiter(const Browser* browser);
BrowserActivationWaiter(const BrowserActivationWaiter&) = delete;
BrowserActivationWaiter& operator=(const BrowserActivationWaiter&) = delete;
~BrowserActivationWaiter() override;
// Runs a message loop until the widget associated to |browser| supplied to
// the constructor is activated, or returns immediately if |browser| has
// already active. Should only be called once.
void WaitForActivation();
// views::WidgetObserver
void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
private:
bool observed_ = false;
base::RunLoop run_loop_;
};
// Use in browser interactive uitests to wait until a browser is deactivated.
// To use, create and call WaitForDeactivation().
class BrowserDeactivationWaiter : public BrowserListObserver {
public:
explicit BrowserDeactivationWaiter(const Browser* browser);
BrowserDeactivationWaiter(const BrowserDeactivationWaiter&) = delete;
BrowserDeactivationWaiter& operator=(const BrowserDeactivationWaiter&) =
delete;
~BrowserDeactivationWaiter() override;
// Runs a message loop until the |browser_| supplied to the constructor is
// deactivated, or returns immediately if |browser_| has already become
// inactive.
// Should only be called once.
void WaitForDeactivation();
private:
// BrowserListObserver:
void OnBrowserNoLongerActive(Browser* browser) override;
const base::WeakPtr<const Browser> browser_;
bool observed_ = false;
base::RunLoop run_loop_;
};
// Brings the native window for |browser| to the foreground and waits until the
// browser is active.
[[nodiscard]] bool BringBrowserWindowToFront(const Browser* browser);
// Returns true if the View is focused.
bool IsViewFocused(const Browser* browser, ViewID vid);
// Simulates a mouse click on a View in the browser.
void ClickOnView(views::View* view);
void ClickOnView(const Browser* browser, ViewID vid);
// Makes focus shift to the given View without clicking it.
void FocusView(const Browser* browser, ViewID vid);
// A collection of utilities that are used from interactive_ui_tests. These are
// separated from ui_test_utils.h to ensure that browser_tests don't use them,
// since they depend on focus which isn't possible for sharded test.
// Hide a native window.
void HideNativeWindow(gfx::NativeWindow window);
// Show and focus a native window. Returns true on success.
[[nodiscard]] bool ShowAndFocusNativeWindow(gfx::NativeWindow window);
// Sends key press and release events to a `browser` or `window`. Waits until at
// least the key release (or key press, depending on `wait_for`) events have
// been dispatched, or the test times out. It's useful to wait for key press
// instead of key release when the target may be deleted in response to key
// press. This may wait for key release even if `wait_for` is `kKeyPress` on
// platforms where it's possible to confirm that key release has been dispatched
// on a deleted target. This uses `ui_controls::SendKeyPress`, see it for
// details. Returns true if the event was successfully dispatched.
[[nodiscard]] bool SendKeyPressSync(
const Browser* browser,
ui::KeyboardCode key,
bool control,
bool shift,
bool alt,
bool command,
ui_controls::KeyEventType wait_for = ui_controls::kKeyRelease);
[[nodiscard]] bool SendKeyPressToWindowSync(
const gfx::NativeWindow window,
ui::KeyboardCode key,
bool control,
bool shift,
bool alt,
bool command,
ui_controls::KeyEventType wait_for = ui_controls::kKeyRelease);
// Sends a move event blocking until received. Returns true if the event was
// successfully received. This uses ui_controls::SendMouse***NotifyWhenDone,
// see it for details.
[[nodiscard]] bool SendMouseMoveSync(
const gfx::Point& location,
gfx::NativeWindow window_hint = gfx::NativeWindow());
[[nodiscard]] bool SendMouseEventsSync(
ui_controls::MouseButton type,
int button_state,
gfx::NativeWindow window_hint = gfx::NativeWindow());
// A combination of SendMouseMove to the middle of the view followed by
// SendMouseEvents. Only exposed for toolkit-views.
// Alternatives: ClickOnView() and ui::test::EventGenerator.
#if defined(TOOLKIT_VIEWS)
void MoveMouseToCenterAndClick(
views::View* view,
ui_controls::MouseButton button,
int button_state,
base::OnceClosure task,
int accelerator_state = ui_controls::kNoAccelerator);
void MoveMouseToCenterWithOffsetAndClick(
views::View* view,
const gfx::Vector2d& offset,
ui_controls::MouseButton button,
int button_state,
base::OnceClosure task,
int accelerator_state = ui_controls::kNoAccelerator);
// Returns the center of |view| in screen coordinates.
gfx::Point GetCenterInScreenCoordinates(const views::View* view);
// Blocks until the given view is focused (or not focused, depending on
// |focused|). Returns immediately if the state is already correct.
void WaitForViewFocus(Browser* browser, ViewID vid, bool focused);
void WaitForViewFocus(Browser* browser, views::View* view, bool focused);
#endif
#if BUILDFLAG(IS_MAC)
// Clear pressed modifier keys and report true if any key modifiers were down.
bool ClearKeyEventModifiers();
// Ensures that if no key window is set (can happen in apps that are not
// frontmost), we simulate the frontmost window becoming key, which triggers
// any logic that would normally run in this case.
void HandleMissingKeyWindow();
#endif
namespace internal {
// A utility function to send a mouse click event in a closure. It's shared by
// ui_controls_linux.cc and ui_controls_mac.cc
void ClickTask(ui_controls::MouseButton button,
int button_state,
base::OnceClosure followup,
int accelerator_state = ui_controls::kNoAccelerator);
} // namespace internal
// Returns the secondary display from the screen. DCHECKs if there is no such
// display.
display::Display GetSecondaryDisplay(display::Screen* screen);
// Returns the pair of displays -- the first one is the primary display and the
// second one is the other display.
std::pair<display::Display, display::Display> GetDisplays(
display::Screen* screen);
} // namespace ui_test_utils
#endif // CHROME_TEST_BASE_INTERACTIVE_TEST_UTILS_H_
|