File: interactive_browser_test_internal.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (181 lines) | stat: -rw-r--r-- 6,860 bytes parent folder | download | duplicates (3)
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
// 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_INTERNAL_H_
#define CHROME_TEST_INTERACTION_INTERACTIVE_BROWSER_TEST_INTERNAL_H_

#include <compare>
#include <memory>
#include <utility>
#include <vector>

#include "base/values.h"
#include "chrome/test/interaction/interaction_test_util_browser.h"
#include "chrome/test/interaction/tracked_element_webcontents.h"
#include "chrome/test/interaction/webcontents_interaction_test_util.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/interaction_sequence.h"
#include "ui/base/interaction/interactive_test_definitions.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/interaction/interactive_views_test_internal.h"

class DevToolsAgentCoverageObserver;
class InteractiveBrowserTestApi;

namespace internal {

// Class that provides functionality needed by InteractiveBrowserTestApi but
// which should not be directly visible to tests inheriting from the API class.
class InteractiveBrowserTestPrivate
    : public views::test::internal::InteractiveViewsTestPrivate {
 public:
  explicit InteractiveBrowserTestPrivate(
      std::unique_ptr<InteractionTestUtilBrowser> test_util);
  ~InteractiveBrowserTestPrivate() override;

  // views::test::internal::InteractiveViewsTestPrivate:
  void DoTestSetUp() override;
  void DoTestTearDown() override;

  // Starts code coverage if the proper configuration is present.
  void MaybeStartWebUICodeCoverage();

  void AddInstrumentedWebContents(
      std::unique_ptr<WebContentsInteractionTestUtil>
          instrumented_web_contents);

  bool IsInstrumentedWebContents(ui::ElementIdentifier element_id) const;

  // Removes WebContents instrumentation; can allow for re-instrumentation using
  // the same ID later. Returns whether `to_remove` was found and removed.
  bool UninstrumentWebContents(ui::ElementIdentifier to_remove);

  static std::string DeepQueryToString(
      const WebContentsInteractionTestUtil::DeepQuery& deep_query);

 protected:
  // views::test::InteractiveViewsTestPrivate:
  gfx::NativeWindow GetNativeWindowFromElement(
      ui::TrackedElement* el) const override;
  gfx::NativeWindow GetNativeWindowFromContext(
      ui::ElementContext context) const override;
  std::string DebugDescribeContext(ui::ElementContext context) const override;
  DebugTreeNode DebugDumpElement(const ui::TrackedElement* el) const override;

 private:
  friend InteractiveBrowserTestApi;

  // Optional WebUI code coverage tool.
  std::unique_ptr<DevToolsAgentCoverageObserver> coverage_observer_;

  // Stores instrumented WebContents and WebUI.
  std::vector<std::unique_ptr<WebContentsInteractionTestUtil>>
      instrumented_web_contents_;
};

// This class wraps a `base::Value` in a wrapper that allows copying when
// necessary via the `Clone()` method. This is so that Value objects can be
// used with gtest and gmock matchers, much of the logic of which requires copy
// operations in order to work.
class MatchableValue {
 public:
  MatchableValue() noexcept;
  MatchableValue(const base::Value& value) noexcept;  // NOLINT
  MatchableValue(base::Value&& value) noexcept;       // NOLINT
  MatchableValue(const MatchableValue& value) noexcept;
  MatchableValue(MatchableValue&&) noexcept;
  MatchableValue& operator=(const base::Value& value) noexcept;
  MatchableValue& operator=(base::Value&& value) noexcept;
  MatchableValue& operator=(const MatchableValue& value) noexcept;
  MatchableValue& operator=(MatchableValue&&) noexcept;
  ~MatchableValue();

  template <typename T>
  MatchableValue(T value) noexcept  // NOLINT
      : MatchableValue(base::Value(value)) {}

  // These enable implicit comparison between MatchableValue objects and types
  // that a base::Value can be constructed from. This is also required for a lot
  // of gtest and gmock logic to work properly.
  bool operator==(const MatchableValue& other) const;
  bool operator<(const MatchableValue& other) const;
  bool operator>(const MatchableValue& other) const;
  bool operator<=(const MatchableValue& other) const;
  bool operator>=(const MatchableValue& other) const;

  operator std::string() const;  // NOLINT

  const base::Value& value() const { return value_; }

 private:
  base::Value value_;
};

// Matcher that determines whether a particular value is truthy.
//
// Uses an `internal::MatchableValue` because much of the gtest infrastructure
// expects a value that can be copied, and `base::Value` cannot.
class IsTruthyMatcher
    : public testing::MatcherInterface<const internal::MatchableValue&> {
 public:
  IsTruthyMatcher() = default;
  IsTruthyMatcher(const IsTruthyMatcher&) = default;
  IsTruthyMatcher& operator=(const IsTruthyMatcher&) = default;
  ~IsTruthyMatcher() override = default;

  using is_gtest_matcher = void;

  bool MatchAndExplain(const internal::MatchableValue& x,
                       testing::MatchResultListener* listener) const override;
  void DescribeTo(std::ostream* os) const override;
  void DescribeNegationTo(std::ostream* os) const override;
};

extern std::ostream& operator<<(std::ostream& out, const MatchableValue& value);

// Helper class that converts am input into a matcher that can match a
// `base::Value`.
//
// The default implementation wraps a literal value or something that unwraps to
// a literal value to be matched.
template <typename M>
struct MakeValueMatcherHelper {
  static auto MakeValueMatcher(M m) {
    return testing::Matcher<base::Value>(testing::Eq(m));
  }
};

// This specialization handles things that can be directly cast/moved into a
// `testing::Matcher`, which is required since "matcher" is very duck-typed.
template <typename M>
  requires requires(M&& m) {
    testing::Matcher<MatchableValue>(std::forward<M>(m));
  }
struct MakeValueMatcherHelper<M> {
  static auto MakeValueMatcher(M&& m) {
    return testing::Matcher<MatchableValue>(std::forward<M>(m));
  }
};

// Wraps `m` in a `testing::Matcher` that will match a `base::Value`.
// Does not work for all possible inputs, but will work for most.
template <typename M>
auto MakeValueMatcher(M&& m) {
  return MakeValueMatcherHelper<M>::MakeValueMatcher(
      ui::test::internal::UnwrapArgument(std::forward<M>(m)));
}

// Wraps `m` in a `testing::Matcher` that will match a `base::Value`.
// Does not work for all possible inputs, but will work for most.
template <typename M>
auto MakeConstValueMatcher(const M& m) {
  return MakeValueMatcherHelper<M>::MakeValueMatcher(
      ui::test::internal::UnwrapArgument(m));
}

}  // namespace internal

#endif  // CHROME_TEST_INTERACTION_INTERACTIVE_BROWSER_TEST_INTERNAL_H_