| // Copyright 2017 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_BROWSER_UI_TEST_TEST_BROWSER_UI_H_ | 
 | #define CHROME_BROWSER_UI_TEST_TEST_BROWSER_UI_H_ | 
 |  | 
 | #include <memory> | 
 | #include <optional> | 
 | #include <string> | 
 |  | 
 | #include "build/build_config.h" | 
 | #include "chrome/test/base/in_process_browser_test.h" | 
 | #include "ui/base/interaction/interaction_test_util.h" | 
 | #include "ui/base/test/skia_gold_matching_algorithm.h" | 
 | #include "ui/gfx/geometry/rect.h" | 
 |  | 
 | namespace views { | 
 | class Widget; | 
 | class View; | 
 | }  // namespace views | 
 |  | 
 | // How to handle focus on the view when taking the screenshot. | 
 | enum class ScreenshotFocusMode { | 
 |   // Clear focus before taking the screenshot to reduce flakiness. This is the | 
 |   // default to reduce flakiness. See VerifyPixelUi() implementation for more | 
 |   // details. | 
 |   kClearFocus, | 
 |   // Leave focus where it is. | 
 |   kLeaveFocusWhereItIs, | 
 | }; | 
 |  | 
 | // Options for taking a screenshot. | 
 | struct ScreenshotOptions { | 
 |   // The region of the view to take a screenshot of. If std::nullopt, the entire | 
 |   // view is captured. | 
 |   std::optional<gfx::Rect> region; | 
 |   // How to handle focus on the view when taking the screenshot. Defaults to | 
 |   // kClearFocus which will clear focus before taking the screenshot to reduce | 
 |   // flakiness. See VerifyPixelUi() implementation for more details. | 
 |   ScreenshotFocusMode focus = ScreenshotFocusMode::kClearFocus; | 
 | }; | 
 |  | 
 | // TestBrowserUi provides a way to register an InProcessBrowserTest testing | 
 | // harness with a framework that invokes Chrome browser UI in a consistent way. | 
 | // It optionally provides a way to invoke UI "interactively". This allows | 
 | // screenshots to be generated easily, with the same test data, to assist with | 
 | // UI review. It also provides a UI registry so pieces of UI can be | 
 | // systematically checked for subtle changes and regressions. | 
 | // | 
 | // To use TestBrowserUi, a test harness should inherit from UiBrowserTest rather | 
 | // than InProcessBrowserTest, then provide some overrides: | 
 | // | 
 | // class FooUiTest : public UiBrowserTest { | 
 | //  public: | 
 | //   .. | 
 | //   // UiBrowserTest: | 
 | //   void ShowUi(const std::string& name) override { | 
 | //     /* Show Ui attached to browser() and leave it open. */ | 
 | //   } | 
 | // | 
 | //   bool VerifyUi() override { | 
 | //     /* Return true if the UI was successfully shown. */ | 
 | //   } | 
 | // | 
 | //   void WaitForUserDismissal() override { | 
 | //     /* Block until the user closes the UI. */ | 
 | //   } | 
 | //   .. | 
 | // }; | 
 | // | 
 | // Further overrides are available for tests which need to do work before | 
 | // showing any UI or when closing in non-interactive mode.  For tests whose UI | 
 | // is a dialog, there's also the TestBrowserDialog class, which provides all but | 
 | // ShowUi() already; see test_browser_dialog.h. | 
 | // | 
 | // The test may then define any number of cases for individual pieces of UI: | 
 | // | 
 | // IN_PROC_BROWSER_TEST_F(FooUiTest, InvokeUi_name) { | 
 | //   // Perform optional setup here; then: | 
 | //   ShowAndVerifyUi(); | 
 | // } | 
 | // | 
 | // The string after "InvokeUi_" (here, "name") is the argument given to | 
 | // ShowUi(). In a regular test suite run, ShowAndVerifyUi() shows the UI and | 
 | // immediately closes it (after ensuring it was actually created). | 
 | // | 
 | // To get a list of all available UI, run the "BrowserUiTest.Invoke" test case | 
 | // without other arguments, i.e.: | 
 | // | 
 | //   browser_tests --gtest_filter=BrowserUiTest.Invoke | 
 | // | 
 | // UI listed can be shown interactively using the --ui argument. E.g. | 
 | // | 
 | //   browser_tests --gtest_filter=BrowserUiTest.Invoke | 
 | //       --test-launcher-interactive --ui=FooUiTest.InvokeUi_name | 
 | class TestBrowserUi { | 
 |  public: | 
 |   TestBrowserUi(const TestBrowserUi&) = delete; | 
 |   TestBrowserUi& operator=(const TestBrowserUi&) = delete; | 
 |  | 
 |  protected: | 
 |   TestBrowserUi(); | 
 |   virtual ~TestBrowserUi(); | 
 |  | 
 |   // Called by ShowAndVerifyUi() before ShowUi(), to provide a place to do any | 
 |   // setup needed in order to successfully verify the UI post-show. | 
 |   virtual void PreShow() {} | 
 |  | 
 |   // Should be implemented in individual tests to show UI with the given |name| | 
 |   // (which will be supplied by the test case). | 
 |   virtual void ShowUi(const std::string& name) = 0; | 
 |  | 
 |   // Called by ShowAndVerifyUi() after ShowUi().  Returns whether the UI was | 
 |   // successfully shown. | 
 |   virtual bool VerifyUi() = 0; | 
 |  | 
 |   // Returns ActionResult::Succeeded if the screenshot matches the golden image. | 
 |   // Returns ActionResult::kFailed if the matching fails. | 
 |   // Returns ActionResult::kKnownIncompatible if pixel tests are unsupported. | 
 |   ui::test::ActionResult VerifyPixelUi(views::Widget* widget, | 
 |                                        const std::string& screenshot_prefix, | 
 |                                        const std::string& screenshot_name); | 
 |  | 
 |   // Can be called by VerifyUi() to ensure pixel correctness. | 
 |   ui::test::ActionResult VerifyPixelUi(views::View* view, | 
 |                                        const std::string& screenshot_prefix, | 
 |                                        const std::string& screenshot_name); | 
 |  | 
 |   // Verifies a region within a View. For example, verify an element within | 
 |   // web content. | 
 |   ui::test::ActionResult VerifyPixelUi(views::View* view, | 
 |                                        const ScreenshotOptions& options, | 
 |                                        const std::string& screenshot_prefix, | 
 |                                        const std::string& screenshot_name); | 
 |  | 
 |   // Own |algorithm|. | 
 |   void SetPixelMatchAlgorithm( | 
 |       std::unique_ptr<ui::test::SkiaGoldMatchingAlgorithm> algorithm); | 
 |   ui::test::SkiaGoldMatchingAlgorithm* GetPixelMatchAlgorithm() { | 
 |     return algorithm_.get(); | 
 |   } | 
 |  | 
 |   // Called by ShowAndVerifyUi() after VerifyUi(), in the case where the test is | 
 |   // interactive.  This should block until the UI has been dismissed. | 
 |   virtual void WaitForUserDismissal() = 0; | 
 |  | 
 |   // Called by ShowAndVerifyUi() after VerifyUi(), in the case where the test is | 
 |   // non-interactive.  This should do anything necessary to close the UI before | 
 |   // browser shutdown. | 
 |   virtual void DismissUi() {} | 
 |  | 
 |   // Shows the UI whose name corresponds to the current test case, and verifies | 
 |   // it was successfully shown.  Most test cases can simply invoke this directly | 
 |   // with no other code. | 
 |   void ShowAndVerifyUi(); | 
 |  | 
 |   // Returns whether or not the test was invoked with the interactive ui flag. | 
 |   // This is useful for some SetUp() calls that may be interested in that state. | 
 |   bool IsInteractiveUi() const; | 
 |  | 
 |  private: | 
 |   std::unique_ptr<ui::test::SkiaGoldMatchingAlgorithm> algorithm_; | 
 | }; | 
 |  | 
 | // Helper to mix in a TestBrowserUi to an existing test harness. |Base| must be | 
 | // a descendant of InProcessBrowserTest. | 
 | template <class Base, class TestUi> | 
 | class SupportsTestUi : public Base, public TestUi { | 
 |  public: | 
 |   SupportsTestUi(const SupportsTestUi&) = delete; | 
 |   SupportsTestUi& operator=(const SupportsTestUi&) = delete; | 
 |  | 
 |  protected: | 
 |   template <class... Args> | 
 |   explicit SupportsTestUi(Args&&... args) : Base(std::forward<Args>(args)...) {} | 
 | }; | 
 |  | 
 | using UiBrowserTest = SupportsTestUi<InProcessBrowserTest, TestBrowserUi>; | 
 |  | 
 | #endif  // CHROME_BROWSER_UI_TEST_TEST_BROWSER_UI_H_ |