blob: 0447f5b35b54129242a6a74490c6e139de78f2e6 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_INTERACTION_POLLING_VIEW_OBSERVER_H_
#define UI_VIEWS_INTERACTION_POLLING_VIEW_OBSERVER_H_
#include <optional>
#include <type_traits>
#include <utility>
#include "base/time/time.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/polling_state_observer.h"
#include "ui/views/interaction/element_tracker_views.h"
#include "ui/views/interaction/interactive_views_test_internal.h"
#include "ui/views/view.h"
#include "ui/views/view_utils.h"
namespace views::test {
// Polling static observer that repeatedly calls `poll_view_callback` on a View
// of type `V` with `view_id` in `context` (or any context if not specified) to
// determine the value of the state, which is of `type std::optional<T>`.
// The state value `std::nullopt` corresponds to no matching view present.
//
// Designed for use with the `InteractiveViewsTestApi::PollView()` testing verb.
//
// See `PollingElementStateObserver<T>` for more information on usage.
template <typename T, typename V>
requires(std::is_base_of_v<View, V>)
class PollingViewObserver : public ui::test::PollingElementStateObserver<T> {
public:
using PollViewCallback = base::RepeatingCallback<T(const V*)>;
template <typename C>
PollingViewObserver(
ui::ElementIdentifier view_id,
std::optional<ui::ElementContext> context,
C&& poll_view_callback,
base::TimeDelta polling_interval = ui::test::PollingStateObserver<
std::optional<T>>::kDefaultPollingInterval)
: ui::test::PollingElementStateObserver<T>(
view_id,
context,
base::BindRepeating(
[](PollViewCallback callback, const ui::TrackedElement* el) {
const auto* const view_el = el->AsA<TrackedElementViews>();
CHECK(view_el);
const auto* const view =
views::AsViewClass<V>(view_el->view());
CHECK(view);
return callback.Run(view);
},
ui::test::internal::MaybeBindRepeating(
std::forward<C>(poll_view_callback))),
polling_interval) {}
~PollingViewObserver() = default;
};
// Polling static observer that repeatedly calls `property` on a View of type
// of type `V` with `view_id` in `context` (or any context if not specified) to
// determine the value of the state, which is of `type std::optional<T>`.
// The state value `std::nullopt` corresponds to no matching view present.
//
// Designed for use with the `InteractiveViewsTestApi::PollViewProperty()`
// testing verb.
//
// See `PollingElementStateObserver<T>` for more information on usage.
template <typename T, typename V>
requires(std::is_base_of_v<View, V>)
class PollingViewPropertyObserver : public PollingViewObserver<T, V> {
public:
template <typename R>
PollingViewPropertyObserver(
ui::ElementIdentifier view_id,
std::optional<ui::ElementContext> context,
R (V::*property)() const,
base::TimeDelta polling_interval = ui::test::PollingStateObserver<
std::optional<T>>::kDefaultPollingInterval)
: PollingViewObserver<T, V>(
view_id,
context,
base::BindRepeating(
[](R (V::*property)() const, const V* view) {
return T((view->*property)());
},
property),
polling_interval) {}
~PollingViewPropertyObserver() override = default;
};
} // namespace views::test
#endif // UI_VIEWS_INTERACTION_POLLING_VIEW_OBSERVER_H_