File: test_autofill_driver.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; 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 (227 lines) | stat: -rw-r--r-- 8,619 bytes parent folder | download | duplicates (5)
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_FOUNDATIONS_TEST_AUTOFILL_DRIVER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_FOUNDATIONS_TEST_AUTOFILL_DRIVER_H_

#include <concepts>
#include <map>
#include <string>
#include <variant>
#include <vector>

#include "base/compiler_specific.h"
#include "base/containers/flat_map.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/foundations/autofill_driver.h"
#include "components/autofill/core/browser/foundations/autofill_manager.h"
#include "components/autofill/core/browser/foundations/test_autofill_client.h"
#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
#include "ui/accessibility/ax_tree_id.h"
#include "url/origin.h"

#if !BUILDFLAG(IS_IOS)
#include "components/webauthn/core/browser/internal_authenticator.h"
#endif

namespace autofill {

// This class is only for easier writing of tests. There are two instances of
// the template:
//
// - TestAutofillDriver is a simple AutofillDriver;
// - TestContentAutofillDriver is a ContentAutofillDriver, i.e., is associated
//   to a content::WebContents and has a ContentAutofillDriverFactory
//
// As a rule of thumb, TestContentAutofillDriver is preferable in tests that
// have a content::WebContents.
template <std::derived_from<AutofillDriver> T>
class TestAutofillDriverTemplate : public T {
 public:
  using T::T;
  TestAutofillDriverTemplate(const TestAutofillDriverTemplate&) = delete;
  TestAutofillDriverTemplate& operator=(const TestAutofillDriverTemplate&) =
      delete;
  ~TestAutofillDriverTemplate() override = default;

  // AutofillDriver:
  LocalFrameToken GetFrameToken() const override { return frame_token_; }
  TestAutofillDriverTemplate* GetParent() override { return parent_; }
  std::optional<LocalFrameToken> Resolve(FrameToken query) override {
    if (auto* local_frame_token = std::get_if<LocalFrameToken>(&query)) {
      return *local_frame_token;
    }
    auto it = remote_frame_tokens_.find(std::get<RemoteFrameToken>(query));
    if (it != remote_frame_tokens_.end()) {
      return it->second;
    }
    return std::nullopt;
  }
  bool IsActive() const override { return is_active_; }
  bool HasSharedAutofillPermission() const override { return shared_autofill_; }
  bool CanShowAutofillUi() const override { return true; }
  void ApplyFieldAction(mojom::FieldActionType action_type,
                        mojom::ActionPersistence action_persistence,
                        const FieldGlobalId& field,
                        const std::u16string& value) override {}
  void SendTypePredictionsToRenderer(const FormStructure& form) override {}
  void ExposeDomNodeIDs() override {}
  void RendererShouldAcceptDataListSuggestion(
      const FieldGlobalId& field,
      const std::u16string& value) override {}
  void RendererShouldClearPreviewedForm() override {}
  void RendererShouldTriggerSuggestions(
      const FieldGlobalId& field_id,
      AutofillSuggestionTriggerSource trigger_source) override {}
  void RendererShouldSetSuggestionAvailability(
      const FieldGlobalId& field,
      mojom::AutofillSuggestionAvailability suggestion_availability) override {}
  std::optional<net::IsolationInfo> GetIsolationInfo() override {
    // In AutofillDriverIOS, we always return std::nullopt here. That behavior
    // should be reflected in iOS tests.
#if BUILDFLAG(IS_IOS)
    return std::nullopt;
#else
    return isolation_info_;
#endif
  }
  void TriggerFormExtractionInDriverFrame(
      AutofillDriver::AutofillDriverRouterAndFormForestPassKey pass_key)
      override {}
  void TriggerFormExtractionInAllFrames(
      base::OnceCallback<void(bool)> form_extraction_finished_callback)
      override {}
  void ExtractForm(
      FormGlobalId form,
      AutofillDriver::BrowserFormHandler response_handler) override {}
  void GetFourDigitCombinationsFromDom(
      base::OnceCallback<void(const std::vector<std::string>&)>
          potential_matches) override {}
  void ExtractLabeledTextNodeValue(
      const std::u16string& value_regex,
      const std::u16string& label_regex,
      uint32_t number_of_ancestor_levels_to_search,
      base::OnceCallback<void(const std::string& amount)> response_callback)
      override {}

  // The return value contains the FieldGlobalIds of all elements (field_id,
  // type) of `field_type_map` for which
  // `field_type_map_filter_.Run(triggered_origin, field, type)` is true and for
  // which there's a corresponding field in `fields`.
  base::flat_set<FieldGlobalId> ApplyFormAction(
      mojom::FormActionType action_type,
      mojom::ActionPersistence action_persistence,
      base::span<const FormFieldData> fields,
      const url::Origin& triggered_origin,
      const base::flat_map<FieldGlobalId, FieldType>& field_type_map) override {
    if (action_type == mojom::FormActionType::kUndo) {
      return {};
    }
    std::vector<FieldGlobalId> result;
    for (const auto& [id, type] : field_type_map) {
      if ((!field_type_map_filter_ ||
           field_type_map_filter_.Run(triggered_origin, id, type)) &&
          base::Contains(fields, id, &FormFieldData::global_id)) {
        result.push_back(id);
      }
    }
    return result;
  }

  // Methods unique to TestAutofillDriver that tests can use to specialize
  // functionality.

  void SetLocalFrameToken(LocalFrameToken frame_token) {
    frame_token_ = frame_token;
  }

  void SetRemoteFrameToken(RemoteFrameToken remote_frame_token,
                           LocalFrameToken local_frame_token) {
    remote_frame_tokens_[remote_frame_token] = local_frame_token;
  }

  void SetParent(TestAutofillDriverTemplate* parent) { parent_ = parent; }

  void SetIsActive(bool is_active) { is_active_ = is_active; }

  void SetSharedAutofill(bool shared_autofill) {
    shared_autofill_ = shared_autofill;
  }

  void SetIsolationInfo(const net::IsolationInfo& isolation_info) {
    isolation_info_ = isolation_info;
  }

  // The filter that determines the return value of FillOrPreviewForm().
  void SetFieldTypeMapFilter(
      base::RepeatingCallback<
          bool(const url::Origin&, FieldGlobalId, FieldType)> callback) {
    field_type_map_filter_ = callback;
  }

  void SetSharedURLLoaderFactory(
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);

#if !BUILDFLAG(IS_IOS)
  void SetAuthenticator(webauthn::InternalAuthenticator* authenticator_) {
    test_authenticator_.reset(authenticator_);
  }
#endif

 private:
  LocalFrameToken frame_token_;
  std::map<RemoteFrameToken, LocalFrameToken> remote_frame_tokens_;
  raw_ptr<TestAutofillDriverTemplate> parent_ = nullptr;
  bool is_active_ = true;
  bool shared_autofill_ = false;
  net::IsolationInfo isolation_info_;
  base::RepeatingCallback<bool(const url::Origin&, FieldGlobalId, FieldType)>
      field_type_map_filter_;

#if !BUILDFLAG(IS_IOS)
  std::unique_ptr<webauthn::InternalAuthenticator> test_authenticator_;
#endif
};

// A simple `AutofillDriver` for tests. Consider `TestContentAutofillDriver` as
// an alternative for tests where the content layer is visible.
//
// Consider using TestAutofillDriverInjector in browser tests.
class TestAutofillDriver : public TestAutofillDriverTemplate<AutofillDriver> {
 public:
  explicit TestAutofillDriver(TestAutofillClient* client);
  ~TestAutofillDriver() override;

  // AutofillDriver
  TestAutofillClient& GetAutofillClient() override;
  AutofillManager& GetAutofillManager() override;
  ukm::SourceId GetPageUkmSourceId() const override;
  ukm::SourceId GetPageUkmSourceId();

  void set_autofill_manager(std::unique_ptr<AutofillManager> autofill_manager) {
    autofill_manager_ = std::move(autofill_manager);
  }

  // Initializes UKM source from `url()`. This needs to be called in unittests
  // after calling Purge for ukm recorder to re-initialize sources.
  void InitializeUKMSources();

  // The faked URL of the driver's frame.
  const GURL& url() { return url_; }
  void set_url(GURL url) { url_ = std::move(url); }

 private:
  raw_ref<TestAutofillClient> autofill_client_;
  ukm::SourceId ukm_source_id_ = ukm::kInvalidSourceId;
  GURL url_{"https://example.test"};
  std::unique_ptr<AutofillManager> autofill_manager_ = nullptr;
};

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_FOUNDATIONS_TEST_AUTOFILL_DRIVER_H_