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
|
// Copyright 2022 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_INTERACTION_INTERACTIVE_BROWSER_TEST_H_
#define CHROME_TEST_INTERACTION_INTERACTIVE_BROWSER_TEST_H_
#include <concepts>
#include <utility>
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/test/interaction/interactive_browser_window_test.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/views/interaction/interactive_views_test.h"
// Provides interactive test functionality for desktop browsers.
//
// Interactive tests use InteractionSequence, ElementTracker, and
// InteractionTestUtil to provide a common library of concise test methods. This
// convenience API is nicknamed "Kombucha" (see README.md for more information).
//
// This class is not a test fixture; it is a mixin that can be added to an
// existing browser test class using `InteractiveBrowserTestMixin<T>` - or just
// use `InteractiveBrowserTest`, which *is* a test fixture (preferred; see
// below).
class InteractiveBrowserTestApi
: virtual public views::test::InteractiveViewsTestApi,
virtual public InteractiveBrowserWindowTestApi {
public:
// These methods have multiple implementations in base classes; include them
// all in the class namespace.
using InteractiveBrowserWindowTestApi::EnsureNotPresent;
using InteractiveBrowserWindowTestApi::EnsurePresent;
using InteractiveBrowserWindowTestApi::ScrollIntoView;
using InteractiveViewsTestApi::EnsureNotPresent;
using InteractiveViewsTestApi::EnsurePresent;
using InteractiveViewsTestApi::ScrollIntoView;
// Instruments the WebContents held by `web_view` as `id`. Will wait for the
// WebView to become visible if it is not.
//
// If `wait_for_ready` is true (default), the step will not complete until the
// current page in the WebContents is fully loaded. (Note that this may not
// cover dynamic loading of data; you may need to do a WaitForStateChange() to
// be sure dynamic content is loaded).
[[nodiscard]] MultiStep InstrumentNonTabWebView(ui::ElementIdentifier id,
ElementSpecifier web_view,
bool wait_for_ready = true);
[[nodiscard]] MultiStep InstrumentNonTabWebView(
ui::ElementIdentifier id,
AbsoluteViewSpecifier web_view,
bool wait_for_ready = true);
// These are required so the following overloads don't hide the base class
// variations.
using InteractiveViewsTestApi::DragMouseTo;
using InteractiveViewsTestApi::MoveMouseTo;
// Find the DOM element at the given path in the reference element, which
// should be an instrumented WebContents; see Instrument*(). Move the mouse to
// the element's center point in screen coordinates.
//
// If the DOM element may be scrolled outside of the current viewport,
// consider using ScrollIntoView(web_contents, where) before this verb.
[[nodiscard]] MultiStep MoveMouseTo(ui::ElementIdentifier web_contents,
const DeepQuery& where);
// Find the DOM element at the given path in the reference element, which
// should be an instrumented WebContents; see Instrument*(). Perform a drag
// from the mouse's current location to the element's center point in screen
// coordinates, and then if `release` is true, releases the mouse button.
//
// If the DOM element may be scrolled outside of the current viewport,
// consider using ScrollIntoView(web_contents, where) before this verb.
[[nodiscard]] MultiStep DragMouseTo(ui::ElementIdentifier web_contents,
const DeepQuery& where,
bool release = true);
};
// Template for adding InteractiveBrowserTestApi to any test fixture which is
// derived from InProcessBrowserTest.
//
// If you don't need to derive from some existing test class, prefer to use
// InteractiveBrowserTest.
//
// Note that this test fixture attempts to set the context widget from the
// created `browser()` during `SetUpOnMainThread()`. If your derived test
// fixture does not create a browser during set up, you will need to manually
// `SetContextWidget()` before calling `RunTestSequence()`, or use
// `RunTestTestSequenceInContext()` instead.
//
// See README.md for usage.
template <typename T>
requires std::derived_from<T, InProcessBrowserTest>
class InteractiveBrowserTestMixin : public T, public InteractiveBrowserTestApi {
public:
template <typename... Args>
explicit InteractiveBrowserTestMixin(Args&&... args)
: T(std::forward<Args>(args)...) {}
~InteractiveBrowserTestMixin() override = default;
protected:
void SetUpOnMainThread() override {
T::SetUpOnMainThread();
private_test_impl().DoTestSetUp();
if (Browser* browser = T::browser()) {
SetContextWidget(
BrowserView::GetBrowserViewForBrowser(browser)->GetWidget());
}
}
void TearDownOnMainThread() override {
private_test_impl().DoTestTearDown();
T::TearDownOnMainThread();
}
};
// Convenience test fixture for interactive browser tests. This is the preferred
// base class for Kombucha tests unless you specifically need something else.
//
// Note that this test fixture attempts to set the context widget from the
// created `browser()` during `SetUpOnMainThread()`. If your derived test
// fixture does not create a browser during set up, you will need to manually
// `SetContextWidget()` before calling `RunTestSequence()`, or use
// `RunTestTestSequenceInContext()` instead.
//
// See README.md for usage.
using InteractiveBrowserTest =
InteractiveBrowserTestMixin<InProcessBrowserTest>;
#endif // CHROME_TEST_INTERACTION_INTERACTIVE_BROWSER_TEST_H_
|