chromium/components/autofill/core/browser/test_autofill_manager_waiter.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 COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_MANAGER_WAITER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_MANAGER_WAITER_H_

#include <map>
#include <memory>

#include "base/containers/span.h"
#include "base/location.h"
#include "base/run_loop.h"
#include "base/scoped_observation.h"
#include "base/synchronization/lock.h"
#include "base/test/scoped_run_loop_timeout.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/core/common/dense_set.h"
#include "components/autofill/core/common/unique_ids.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace autofill {

// One constant `kFoo` for each event
// `AutofillManager::Observer::On{Before,After}Foo()`.
enum class AutofillManagerEvent {};

// Records AutofillManager::Observer::OnBeforeFoo() events and blocks until the
// corresponding OnAfterFoo() events have happened.
//
// This mechanism relies on AutofillManager::Observer's guarantee that
// OnBeforeFoo() is followed by OnAfterFoo() in normal circumstances.
//
// If an OnBeforeFoo() event happens multiple times, the waiter expects multiple
// OnAfterFoo() events. Which events Wait() should be waiting for can be limited
// by providing a list of `relevant_events` to the constructor.
//
// `Wait(k)` blocks until
// - at least `k` relevant OnBeforeFoo() events have been seen and
// - for every observed (relevant or non-relevant) OnBeforeFoo() event the
//   associated OnAfterFoo() event has happened.
//
// The waiter resets itself on OnAutofillManagerStateChanged() events for
// kPendingReset. This makes it suitable for use with
// TestAutofillManagerInjector.
//
// Typical usage in unit tests is as follows:
//
//   TestAutofillManagerWaiter waiter(manager,
//                                    {AutofillManagerEvent::kFoo,
//                                     AutofillManagerEvent::kBar,
//                                     ...});
//   ... trigger events ...
//   ASSERT_TRUE(waiter.Wait());  // Blocks.
//
// In browser tests, it is important to create the waiter soon enough and not
// create it between two On{Before,After}Foo() events:
//
//   class TestAutofillManager : public BrowserAutofillManager {
//    public:
//     ...
//     TestAutofillManagerWaiter waiter(manager,
//                                      {AutofillManagerEvent::kFoo,
//                                       AutofillManagerEvent::kBar,
//                                       ...});
//   };
//   TestAutofillManagerInjector<TestAutofillManager> injector;
//   ... trigger events ...
//   ASSERT_TRUE(injector[main_rfh()].waiter.Wait());  // Blocks.
//
// In case of failure, the error message of Wait() informs about the pending
// OnAfterFoo() calls.
class TestAutofillManagerWaiter : public AutofillManager::Observer {};

// Returns a FormStructure that satisfies `pred` if such a form exists at call
// time or appears within a RunLoop's timeout. Returns nullptr otherwise.
const FormStructure* WaitForMatchingForm(
    AutofillManager* manager,
    base::RepeatingCallback<bool(const FormStructure&)> pred,
    base::TimeDelta timeout = base::Seconds(30),
    const base::Location& location = FROM_HERE);

// Returns a waiter for a single for a given `event` whose arguments match
// given `matchers`.
//
// Unlike TestAutofillManagerWaiter, this waiter does not block on pending
// OnAfterFoo() events. To wait for On{Before,After}Foo() events, strongly
// consider using TestAutofillManagerWaiter instead.
//
// The `event` must be a pointer to an AutofillManager::Observer member
// function. When adding a new event to AutofillManager::Observer, a
// corresponding override must be added to the nested Impl class.
//
// Typical usage is as follows:
//
//   TestAutofillManagerSingleEventWaiter waiter(
//      *autofill_manager,
//      &AutofillManager::Observer::OnFillOrPreviewDataModelForm,
//      _, mojom::ActionPersistence::kPreview, _, _);
//   ...
//   EXPECT_TRUE(std::move(waiter).Wait());
class TestAutofillManagerSingleEventWaiter {};

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_MANAGER_WAITER_H_