Refactor dialog testing framework to allow arbitrary UI testing.

This introduces a new base class, TestBrowserUI, and reorganizes the existing
test code into a series of virtual functions so tests can provide the necessary
implementation for non-dialog cases.

This also adds a single consumer of this new base class, InfoBarUITest, to
verify it works.

Bug: 686285
Change-Id: I2b5a7c86347f5042ac5218c9fa90e94f68adf577
Reviewed-on: https://chromium-review.googlesource.com/804953
Commit-Queue: Peter Kasting <[email protected]>
Reviewed-by: Scott Violet <[email protected]>
Reviewed-by: Trent Apted <[email protected]>
Cr-Commit-Position: refs/heads/master@{#524855}
diff --git a/docs/testing/test_browser_dialog.md b/docs/testing/test_browser_dialog.md
index 44cf92a..270fc51c 100644
--- a/docs/testing/test_browser_dialog.md
+++ b/docs/testing/test_browser_dialog.md
@@ -1,100 +1,109 @@
-# Testing Chrome browser dialogs with TestBrowserDialog
+# Testing Chrome browser UI with TestBrowserUi
 
-\#include "[chrome/browser/ui/test/test_browser_dialog.h]"
+\#include "[chrome/browser/ui/test/test_browser_ui.h]"
 
-`TestBrowserDialog` provides a way to register an `InProcessBrowserTest` testing
-harness with a framework that invokes Chrome browser dialogs in a consistent
-way. It optionally provides a way to invoke dialogs "interactively". This allows
-screenshots to be generated easily, with the same test data, to assist with UI
-review. It also provides a registry of dialogs so they can be systematically
-checked for subtle changes and regressions.
+`TestBrowserUi` (and convenience class `TestBrowserDialog`) provide ways to
+register an `InProcessBrowserTest` testing harness with a framework that invokes
+Chrome browser UI in a consistent way. They optionally provide a way to invoke
+UI "interactively". This allows screenshots to be generated easily, with the
+same test data, to assist with UI review. `TestBrowserUi` also provides a UI
+registry so pieces of UI can be systematically checked for subtle changes and
+regressions.
 
 [TOC]
 
-## How to register a dialog
+## How to register UI
 
-If registering an existing dialog, there's a chance it already has a test
-harness inheriting, using, or with `typedef InProcessBrowserTest` (or a
-descendant of it). If so, using `TestBrowserDialog` is straightforward. Assume
-the existing InProcessBrowserTest is in `foo_dialog_browsertest.cc`:
+If registering existing UI, there's a chance it already has a test harness
+inheriting, using, or with `typedef InProcessBrowserTest` (or a descendant of
+it). If so, using `TestBrowserDialog` (for a dialog) is straightforward, and
+`TestBrowserUi` (for other types of UI) relatively so. Assume the existing
+`InProcessBrowserTest` is in `foo_browsertest.cc`:
 
-    class FooDialogTest : public InProcessBrowserTest { ...
+    class FooUiTest : public InProcessBrowserTest { ...
 
-Change this to inherit from DialogBrowserTest, and override
-`ShowDialog(std::string)`. See [Advanced Usage](#Advanced-Usage) for details.
+Change this to inherit from `DialogBrowserTest` (for dialogs) or `UiBrowserTest`
+(for non-dialogs), and override `ShowUi(std::string)`. For non-dialogs, also
+override `VerifyUi()` and `WaitForUserDismissal()`. See
+[Advanced Usage](#Advanced-Usage) for details.
 
 ```cpp
-class FooDialogTest : public DialogBrowserTest {
+class FooUiTest : public UiBrowserTest {
  public:
   ..
-  // DialogBrowserTest:
-  void ShowDialog(const std::string& name) override {
-    /* Show dialog attached to browser() and leave it open. */
+  // UiBrowserTest:
+  void ShowUi(const std::string& name) override {
+    /* Show Ui attached to browser() and leave it open. */
+  }
+  // These next two are not necessary if subclassing DialogBrowserTest.
+  bool VerifyUi() override {
+    /* Return true if the UI was successfully shown. */
+  }
+  void WaitForUserDismissal() override {
+    /* Block until the UI has been dismissed. */
   }
   ..
 };
 ```
 
-Then add test invocations using the usual GTest macros, in
-`foo_dialog_browsertest.cc`:
+Finally, add test invocations using the usual GTest macros, in
+`foo_browsertest.cc`:
 
 ```cpp
-IN_PROC_BROWSER_TEST_F(FooDialogTest, InvokeDialog_default) {
-  RunDialog();
+IN_PROC_BROWSER_TEST_F(FooUiTest, InvokeUi_default) {
+  ShowAndVerifyUi();
 }
 ```
 
 Notes:
 
-*   The body of the test is always just "`RunDialog();`".
-*   "`default`" is the `std::string` passed to `ShowDialog()` and can be
+*   The body of the test is always just "`ShowAndVerifyUi();`".
+*   "`default`" is the `std::string` passed to `ShowUi()` and can be
     customized. See
-    [Testing additional dialog "styles"](#Testing-additional-dialog-styles).
-*   The text before `default` (in this case) must always be "`InvokeDialog_`".
+    [Testing additional UI "styles"](#Testing-additional-ui-styles).
+*   The text before `default` (in this case) must always be "`InvokeUi_`".
 
 ### Concrete examples
 
 *   [chrome/browser/ui/ask_google_for_suggestions_dialog_browsertest.cc]
-*   [chrome/browser/ui/autofill/card_unmask_prompt_view_browsertest.cc]
-*   [chrome/browser/ui/collected_cookies_browsertest.cc]
-*   [chrome/browser/ui/update_chrome_dialog_browsertest.cc]
+*   [chrome/browser/infobars/infobars_browsertest.cc]
 
 ##  Running the tests
 
-List the available dialogs with
+List the available pieces of UI with
 
-    $ ./browser_tests --gtest_filter=BrowserDialogTest.Invoke
+    $ ./browser_tests --gtest_filter=BrowserUiTest.Invoke
 
-E.g. `FooDialogTest.InvokeDialog_default` should be listed. To show the dialog
+E.g. `FooUiTest.InvokeUi_default` should be listed. To show the UI
 interactively, run
 
-    $ ./browser_tests --gtest_filter=BrowserDialogTest.Invoke --interactive \
-      --dialog=FooDialogTest.InvokeDialog_default
+    $ ./browser_tests --gtest_filter=BrowserUiTest.Invoke --interactive \
+      --ui=FooUiTest.InvokeUi_default
 
 ### Implementation
 
-`BrowserDialogTest.Invoke` searches for gtests that have "`InvokeDialog_`"  in
-their name, so they can be collected in a list. Providing a `--dialog` argument
-will invoke that test case in a subprocess. Including `--interactive` will set
-up an environment for that subprocess that allows interactivity, e.g., to take
-screenshots. The test ends once the dialog is dismissed.
+`BrowserUiTest.Invoke` searches for gtests that have "`InvokeUi_`"  in their
+names, so they can be collected in a list. Providing a `--ui` argument will
+invoke that test case in a subprocess. Including `--interactive` will set up an
+environment for that subprocess that allows interactivity, e.g., to take
+screenshots. The test ends once the UI is dismissed.
 
-The `FooDialogTest.InvokeDialog_default` test case **will still be run in the
-usual browser_tests test suite**. Ensure it passes, and isn’t flaky. This will
-give your dialog some regression test coverage. `RunDialog()` checks to ensure a
-dialog is actually created when it invokes `ShowDialog("default")`.
+The `FooUiTest.InvokeUi_default` test case **will still be run in the usual
+browser_tests test suite**. Ensure it passes, and isn’t flaky. This will
+give your UI some regression test coverage. `ShowAndVerifyUi()` checks to ensure
+UI is actually created when it invokes `ShowUi("default")`.
 
-### BrowserDialogTest.Invoke
+### BrowserUiTest.Invoke
 
 This is also run in browser_tests but, when run that way, the test case just
 lists the registered test harnesses (it does *not* iterate over them). A
-subprocess is never created unless --dialog is passed on the command line.
+subprocess is never created unless --ui is passed on the command line.
 
 ## Advanced Usage
 
 If your test harness inherits from a descendant of `InProcessBrowserTest` (one
-example: [ExtensionBrowserTest]) then the `SupportsTestDialog<>` template is
-provided. E.g.
+example: [ExtensionBrowserTest]) then the `SupportsTestUi<>` and
+`SupportsTestDialog` templates are provided. E.g.
 
 ```cpp
 class ExtensionInstallDialogViewTestBase : public ExtensionBrowserTest { ...
@@ -107,43 +116,47 @@
     public SupportsTestDialog<ExtensionBrowserTest> { ...
 ```
 
-### Testing additional dialog "styles"
+If you need to do any setup before `ShowUi()` is called, or any teardown in the
+non-interactive case, you can override the `PreShow()` and `DismissUi()
+methods.
 
-Add additional test cases, with a different string after "`InvokeDialog_`".
+### Testing additional UI "styles"
+
+Add additional test cases, with a different string after "`InvokeUi_`".
 Example:
 
 ```cpp
-IN_PROC_BROWSER_TEST_F(CardUnmaskViewBrowserTest, InvokeDialog_expired) {
-  RunDialog();
+IN_PROC_BROWSER_TEST_F(CardUnmaskViewBrowserTest, InvokeUi_expired) {
+  ShowAndVerifyUi();
 }
 
-IN_PROC_BROWSER_TEST_F(CardUnmaskViewBrowserTest, InvokeDialog_valid) {
-  RunDialog();
+IN_PROC_BROWSER_TEST_F(CardUnmaskViewBrowserTest, InvokeUi_valid) {
+  ShowAndVerifyUi();
 }
 ```
 
 The strings "`expired`" or “`valid`” will be given as arguments to
-`ShowDialog(std::string)`.
+`ShowUi(std::string)`.
 
 ## Rationale
 
 Bug reference: [Issue 654151](http://crbug.com/654151).
 
-Chrome has a lot of browser dialogs; often for obscure use-cases and often hard
-to invoke. It has traditionally been difficult to be systematic while checking
-dialogs for possible regressions. For example, to investigate changes to shared
-layout parameters which are testable only with visual inspection.
+Chrome has a lot of browser UI; often for obscure use-cases and often hard to
+invoke. It has traditionally been difficult to be systematic while checking UI
+for possible regressions. For example, to investigate changes to shared layout
+parameters which are testable only with visual inspection.
 
 For Chrome UI review, screenshots need to be taken. Iterating over all the
-"styles" that a dialog may appear with is fiddly. E.g. a login or particular web
+"styles" that UI may appear with is fiddly. E.g. a login or particular web
 server setup may be required. It’s important to provide a consistent “look” for
 UI review (e.g. same test data, same browser size, anchoring position, etc.).
 
-Some dialogs lack tests. Some dialogs have zero coverage on the bots. Dialogs
-can have tricky lifetimes and common mistakes are repeated. TestBrowserDialog
-runs simple "Show dialog" regression tests and can be extended to do more.
+Some UI lacks tests. Some UI has zero coverage on the bots. UI elements can have
+tricky lifetimes and common mistakes are repeated. TestBrowserUi runs simple
+"Show UI" regression tests and can be extended to do more.
 
-Even discovering the full set of dialogs present for each platform in Chrome is
+Even discovering the full set of UI present for each platform in Chrome is
 [difficult](http://crbug.com/686239).
 
 ### Why browser_tests?
@@ -152,12 +165,12 @@
     size that can be used as a dialog anchor and to take screenshots for UI
     review.
     *   UI review have requested that screenshots be provided with the entire
-        browser window so that the relative size of the dialog/change under
+        browser window so that the relative size of the UI element/change under
         review can be assessed.
 
-*   Some dialogs already have a test harness with appropriate setup (e.g. test
-    data) running in browser_tests.
-    *   Supporting `BrowserDialogTest` should require minimal setup and minimal
+*   Some UI already has a test harness with appropriate setup (e.g. test data)
+    running in browser_tests.
+    *   Supporting `BrowserUiTest` should require minimal setup and minimal
         ongoing maintenance.
 
 *   An alternative is to maintain a working end-to-end build target executable
@@ -167,19 +180,18 @@
          `MaterialDesignController::Initialize()`, etc.).
 
 *   Why not chrome.exe?
-    *   E.g. a scrappy chrome:// page with links to invoke dialogs would be
-        great!
+    *   E.g. a scrappy chrome:// page with links to invoke UI would be great!
     *   But...
-        *   A dialog may have test data (e.g. credit card info) which shouldn’t
-        be in the release build.
-        *   A dialog may use EmbeddedTestServer.
+        *   UI may have test data (e.g. credit card info) which shouldn’t be in
+        the release build.
+        *   UI may use EmbeddedTestServer.
         *   Higher maintenance cost - can’t leverage existing test harnesses.
 
 ## Future Work
 
-*   Opt in more dialogs!
-    *    Eventually, all of them.
-    *    A `BrowserDialogTest` for every descendant of `views::DialogDelegate`.
+*   Opt in more UI!
+    *    Eventually, all of it.
+    *    A `DialogBrowserTest` for every descendant of `views::DialogDelegate`.
 
 *   Automatically generate screenshots (for each platform, in various languages)
     *    Build upon [CL 2008283002](https://codereview.chromium.org/2008283002/)
@@ -188,8 +200,8 @@
     *    Probably requires altering the browser_test suite code directly rather
          than just adding a test case as in the current approach
 
-*   An automated test suite for dialogs
-    *    Test various ways to dismiss or hide a dialog
+*   An automated test suite for UI
+    *    Test various ways to dismiss or hide UI, especially dialogs
          *    e.g. native close (via taskbar?)
          *    close parent window (possibly via task bar)
          *    close parent tab
@@ -200,8 +212,8 @@
     *    Drag tab off browser into a new window
     *    Fullscreen that may create a new window/parent
 
-*   Find obscure workflows for invoking dialogs that have no test coverage and
-    cause crashes (e.g. [http://crrev.com/426302](http://crrev.com/426302))
+*   Find obscure workflows for invoking UI that has no test coverage and causes
+    crashes (e.g. [http://crrev.com/426302](http://crrev.com/426302))
     *   Supporting window-modal dialogs with a null parent window.
 
 *   Find memory leaks, e.g. [http://crrev.com/432320](http://crrev.com/432320)
@@ -209,71 +221,69 @@
 
 ## Appendix: Sample output
 
-**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserDialogTest.Invoke**
+**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserUiTest.Invoke**
 ```
-Note: Google Test filter = BrowserDialogTest.Invoke
+Note: Google Test filter = BrowserUiTest.Invoke
 [==========] Running 1 test from 1 test case.
 [----------] Global test environment set-up.
-[----------] 1 test from BrowserDialogTest
-[ RUN      ] BrowserDialogTest.Invoke
-[26879:775:0207/134949.118352:30434675...:INFO:browser_dialog_browsertest.cc(46)
-Pass one of the following after --dialog=
-  AskGoogleForSuggestionsDialogTest.InvokeDialog_default
-  CardUnmaskPromptViewBrowserTest.InvokeDialog_expired
-  CardUnmaskPromptViewBrowserTest.InvokeDialog_valid
-  CollectedCookiesTestMd.InvokeDialog_default
-  UpdateRecommendedDialogTest.InvokeDialog_default
-/* lots more will eventually be listed here */
-[       OK ] BrowserDialogTest.Invoke (0 ms)
-[----------] 1 test from BrowserDialogTest (0 ms total)
+[----------] 1 test from BrowserUiTest
+[ RUN      ] BrowserUiTest.Invoke
+[26879:775:0207/134949.118352:30434675...:INFO:browser_ui_browsertest.cc(46)
+Pass one of the following after --ui=
+        AppInfoDialogBrowserTest.InvokeUi_default
+        AskGoogleForSuggestionsDialogTest.DISABLED_InvokeUi_default
+        BluetoothChooserBrowserTest.InvokeUi_ConnectedBubble
+        BluetoothChooserBrowserTest.InvokeUi_ConnectedModal
+/* and many more */
+[       OK ] BrowserUiTest.Invoke (0 ms)
+[----------] 1 test from BrowserUiTest (0 ms total)
 [----------] Global test environment tear-down
 [==========] 1 test from 1 test case ran. (1 ms total)
 [  PASSED  ] 1 test.
-[1/1] BrowserDialogTest.Invoke (334 ms)
+[1/1] BrowserUiTest.Invoke (334 ms)
 SUCCESS: all tests passed.
 ```
 
-**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserDialogTest.Invoke
---dialog=CardUnmaskPromptViewBrowserTest.InvokeDialog_expired**
+**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserUiTest.Invoke
+--ui=CardUnmaskPromptViewBrowserTest.InvokeUi_expired**
 
 ```
-Note: Google Test filter = BrowserDialogTest.Invoke
+Note: Google Test filter = BrowserUiTest.Invoke
 [==========] Running 1 test from 1 test case.
 [----------] Global test environment set-up.
-[----------] 1 test from BrowserDialogTest
-[ RUN      ] BrowserDialogTest.Invoke
+[----------] 1 test from BrowserUiTest
+[ RUN      ] BrowserUiTest.Invoke
 Note: Google Test filter = CardUnmaskPromptViewBrowserTest.InvokeDefault
 [==========] Running 1 test from 1 test case.
 [----------] Global test environment set-up.
 [----------] 1 test from CardUnmaskPromptViewBrowserTest, where TypeParam =
-[ RUN      ] CardUnmaskPromptViewBrowserTest.InvokeDialog_expired
+[ RUN      ] CardUnmaskPromptViewBrowserTest.InvokeUi_expired
 /* 7 lines of uninteresting log spam */
-[       OK ] CardUnmaskPromptViewBrowserTest.InvokeDialog_expired (1324 ms)
+[       OK ] CardUnmaskPromptViewBrowserTest.InvokeUi_expired (1324 ms)
 [----------] 1 test from CardUnmaskPromptViewBrowserTest (1324 ms total)
 [----------] Global test environment tear-down
 [==========] 1 test from 1 test case ran. (1325 ms total)
 [  PASSED  ] 1 test.
-[       OK ] BrowserDialogTest.Invoke (1642 ms)
-[----------] 1 test from BrowserDialogTest (1642 ms total)
+[       OK ] BrowserUiTest.Invoke (1642 ms)
+[----------] 1 test from BrowserUiTest (1642 ms total)
 [----------] Global test environment tear-down
 [==========] 1 test from 1 test case ran. (1642 ms total)
 [  PASSED  ] 1 test.
-[1/1] BrowserDialogTest.Invoke (2111 ms)
+[1/1] BrowserUiTest.Invoke (2111 ms)
 SUCCESS: all tests passed.
 ```
 
-**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserDialogTest.Invoke
---dialog=CardUnmaskPromptViewBrowserTest.InvokeDialog_expired --interactive**
+**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserUiTest.Invoke
+--dialog=CardUnmaskPromptViewBrowserTest.InvokeUi_expired --interactive**
 ```
 /*
  * Output as above, except the test are not interleaved, and the browser window
- * should remain open until the dialog is dismissed
+ * should remain open until the UI is dismissed
  */
 ```
 
+[chrome/browser/ui/test/test_browser_ui.h]: https://cs.chromium.org/chromium/src/chrome/browser/ui/test/test_browser_ui.h
 [chrome/browser/ui/test/test_browser_dialog.h]: https://cs.chromium.org/chromium/src/chrome/browser/ui/test/test_browser_dialog.h
-[chrome/browser/ui/autofill/card_unmask_prompt_view_browsertest.cc]: https://cs.chromium.org/chromium/src/chrome/browser/ui/autofill/card_unmask_prompt_view_browsertest.cc?l=104&q=ShowDialog
-[chrome/browser/ui/collected_cookies_browsertest.cc]: https://cs.chromium.org/chromium/src/chrome/browser/ui/collected_cookies_browsertest.cc?l=26&q=ShowDialog
-[chrome/browser/ui/ask_google_for_suggestions_dialog_browsertest.cc]: https://cs.chromium.org/chromium/src/chrome/browser/ui/ask_google_for_suggestions_dialog_browsertest.cc?l=18&q=ShowDialog
-[chrome/browser/ui/update_chrome_dialog_browsertest.cc]: https://cs.chromium.org/chromium/src/chrome/browser/ui/update_chrome_dialog_browsertest.cc?l=15&q=ShowDialog
+[chrome/browser/ui/ask_google_for_suggestions_dialog_browsertest.cc]: https://cs.chromium.org/chromium/src/chrome/browser/ui/ask_google_for_suggestions_dialog_browsertest.cc?l=18&q=ShowUi
+[chrome/browser/infobars/infobars_browsertest.cc]: https://cs.chromium.org/chromium/src/chrome/browser/infobars/infobars_browsertest.cc?l=134&q=UiBrowserTest
 [ExtensionBrowserTest]: https://cs.chromium.org/chromium/src/chrome/browser/extensions/extension_browsertest.h?q=extensionbrowsertest&l=40