chromium/ui/views/interaction/interactive_views_test.h

// 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 UI_VIEWS_INTERACTION_INTERACTIVE_VIEWS_TEST_H_
#define UI_VIEWS_INTERACTION_INTERACTIVE_VIEWS_TEST_H_

#include <functional>
#include <memory>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <variant>

#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/element_tracker.h"
#include "ui/base/interaction/interactive_test.h"
#include "ui/base/interaction/interactive_test_internal.h"
#include "ui/base/metadata/metadata_types.h"
#include "ui/views/interaction/element_tracker_views.h"
#include "ui/views/interaction/interaction_test_util_mouse.h"
#include "ui/views/interaction/interactive_views_test_internal.h"
#include "ui/views/interaction/polling_view_observer.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/view.h"
#include "ui/views/view_utils.h"

namespace views::test {

// Provides interactive test functionality for Views.
//
// Interactive tests use InteractionSequence, ElementTracker, and
// InteractionTestUtil to provide a common library of concise test methods. This
// convenience API is nicknamed "Kombucha" (see
// //chrome/test/interaction/README.md for more information).
//
// This class is not a test fixture; it is a mixin that can be added to existing
// test classes using `InteractiveViewsTestT<T>` - or just use
// `InteractiveViewsTest`, which *is* a test fixture (preferred; see below).
//
// To use Kombucha for in-process browser tests, instead see:
// //chrome/test/interaction/interactive_browser_test.h
class InteractiveViewsTestApi : public ui::test::InteractiveTestApi {};

// Template that adds InteractiveViewsTestApi to any test fixture. Prefer to use
// InteractiveViewsTest unless you specifically need to inherit from another
// test class.
//
// You must call SetContextWidget() before using RunTestSequence() or any of the
// mouse actions.
//
// See //chrome/test/interaction/README.md for usage.
template <typename T>
class InteractiveViewsTestT : public T, public InteractiveViewsTestApi {};

// Convenience test fixture for Views tests that supports
// InteractiveViewsTestApi.
//
// You must call SetContextWidget() before using RunTestSequence() or any of the
// mouse actions.
//
// See //chrome/test/interaction/README.md for usage.
InteractiveViewsTest;

// Template definitions:

// static
template <class T>
T* InteractiveViewsTestApi::AsView(ui::TrackedElement* el) {}

// static
template <class T>
const T* InteractiveViewsTestApi::AsView(const ui::TrackedElement* el) {}

template <typename... Args>
bool InteractiveViewsTestApi::RunTestSequence(Args&&... steps) {}

// static
template <typename C, typename V, typename R>
  requires ui::test::internal::HasSignature<C, R*(V*)>
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::NameViewRelative(
    ElementSpecifier relative_to,
    std::string_view name,
    C&& find_callback) {}

// static
template <typename F, typename V>
  requires ui::test::internal::HasSignature<F, void(V*)>
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::WithView(
    ElementSpecifier view,
    F&& function) {}

// static
template <typename C, typename T, typename U, typename V>
  requires ui::test::internal::HasSignature<
      C,
      bool(const V*)>  // NOLINT(readability/casting)
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::IfView(
    ElementSpecifier element,
    C&& condition,
    T&& then_steps,
    U&& else_steps) {}

// static
template <typename F,
          typename M,
          typename T,
          typename U,
          typename R,
          typename V>
  requires ui::test::internal::HasSignature<F, R(const V*)>
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::IfViewMatches(
    ElementSpecifier element,
    F&& function,
    M&& matcher,
    T&& then_steps,
    U&& else_steps) {}

// static
template <typename R, typename M, typename V, typename T, typename U>
  requires internal::IsView<V>
ui::InteractionSequence::StepBuilder
InteractiveViewsTestApi::IfViewPropertyMatches(ElementSpecifier element,
                                               R (V::*property)() const,
                                               M&& matcher,
                                               T&& then_steps,
                                               U&& else_steps) {}

// static
template <typename V>
  requires internal::IsView<V>
ui::InteractionSequence::StepBuilder
InteractiveViewsTestApi::NameChildViewByType(ElementSpecifier parent,
                                             std::string_view name,
                                             size_t index) {}

// static
template <typename V>
  requires internal::IsView<V>
ui::InteractionSequence::StepBuilder
InteractiveViewsTestApi::NameDescendantViewByType(ElementSpecifier ancestor,
                                                  std::string_view name,
                                                  size_t index) {}

// static
template <typename F, typename V>
// NOLINTNEXTLINE(readability/casting)
  requires ui::test::internal::HasSignature<F, bool(V*)>
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::CheckView(
    ElementSpecifier view,
    F&& check) {}

// static
template <typename F, typename M, typename R, typename V>
  requires ui::test::internal::HasSignature<F, R(V*)>
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::CheckView(
    ElementSpecifier view,
    F&& function,
    M&& matcher) {}

// static
template <typename V, typename R, typename M>
  requires internal::IsView<V>
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::CheckViewProperty(
    ElementSpecifier view,
    R (V::*property)() const,
    M&& matcher) {}

// static
template <typename V, typename R, typename M>
  requires internal::IsView<V>
ui::test::InteractiveTestApi::MultiStep
InteractiveViewsTestApi::WaitForViewPropertyCallback(
    ElementSpecifier view,
    R (V::*property)() const,
    base::CallbackListSubscription (V::*add_listener)(
        ui::metadata::PropertyChangedCallback),
    M&& matcher,
    ui::CustomElementEventType event_type) {}

// Waits for a property named `Property` to have a value that matches `matcher`
// on View `view` of View class `Class`. Convenience method for
// `InteractiveViewsTestApi::WaitForClassPropertyCallback`.
//
// Do not use with the "Visible" property; use `WaitForShow()` or
// `WaitForHide()` instead.
#define WaitForViewProperty(view, Class, Property, matcher)

template <typename T, typename V, typename C>
  requires internal::IsView<V> &&
           ui::test::internal::HasSignature<C, T(const V*)>
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::PollView(
    ui::test::StateIdentifier<PollingViewObserver<T, V>> id,
    ui::ElementIdentifier view_id,
    C&& callback,
    base::TimeDelta polling_interval) {}

template <typename R, typename V, typename T>
  requires internal::IsView<V>
ui::InteractionSequence::StepBuilder InteractiveViewsTestApi::PollViewProperty(
    ui::test::StateIdentifier<PollingViewPropertyObserver<T, V>> id,
    ui::ElementIdentifier view_id,
    R (V::*property)() const,
    base::TimeDelta polling_interval) {}

}  // namespace views::test

#endif  // UI_VIEWS_INTERACTION_INTERACTIVE_VIEWS_TEST_H_