// 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_