Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1707)

Unified Diff: docs/testing/test_browser_dialog.md

Issue 2684513002: Markdown docs for TestBrowserDialog (Closed)
Patch Set: respond to comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: docs/testing/test_browser_dialog.md
diff --git a/docs/testing/test_browser_dialog.md b/docs/testing/test_browser_dialog.md
new file mode 100644
index 0000000000000000000000000000000000000000..c96045556aeaa25c9fae213fcf3526461c6eaad3
--- /dev/null
+++ b/docs/testing/test_browser_dialog.md
@@ -0,0 +1,279 @@
+# Testing Chrome browser dialogs with TestBrowserDialog
+
+\#include "[chrome/browser/ui/test/test_browser_dialog.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.
+
+[TOC]
+
+## How to register a dialog
+
+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`:
+
+ class FooDialogTest : public InProcessBrowserTest { ...
+
+Change this to inherit from DialogBrowserTest, and override
+`ShowDialog(std::string)`. See [Advanced Usage](#Advanced-Usage) for details.
+
+```cpp
+class FooDialogTest : public DialogBrowserTest {
+ public:
+ ..
+ // DialogBrowserTest:
+ void ShowDialog(const std::string& name) override {
+ /* Show dialog attached to browser() and leave it open. */
+ }
+ ..
+};
+```
+
+Then add test invocations using the usual GTest macros, in
+`foo_dialog_browsertest.cc`:
+
+```cpp
+IN_PROC_BROWSER_TEST_F(FooDialogTest, InvokeDialog_default) {
+ RunDialog();
+}
+```
+
+Notes:
+
+* The body of the test is always just "`RunDialog();`".
+* "`default`" is the `std::string` passed to `ShowDialog()` and can be
+ customized. See
+ [Testing additional dialog "styles"](#Testing-additional-dialog-styles_).
+* The text before `default` (in this case) must always be "`InvokeDialog_`".
+
+### 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]
+
+## Running the tests
+
+List the available dialogs with
+
+ $ ./browser_tests --gtest_filter=BrowserDialogTest.Invoke
+
+E.g. `FooDialogTest.InvokeDialog_default` should be listed. To show the dialog
+interactively, run
+
+ $ ./browser_tests --gtest_filter=BrowserDialogTest.Invoke --interactive \
+ --dialog=FooDialogTest.InvokeDialog_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.
+
+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")`.
+
+### BrowserDialogTest.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.
+
+## Advanced Usage
+
+If your test harness inherits from a descendant of `InProcessBrowserTest` (one
+example: [ExtensionBrowserTest]) then the `SupportsTestDialog<>` template is
+provided. E.g.
+
+```cpp
+class ExtensionInstallDialogViewTestBase : public ExtensionBrowserTest { ...
+```
+
+becomes
+
+```cpp
+class ExtensionInstallDialogViewTestBase :
+ public SupportsTestDialog<ExtensionBrowserTest> { ...
+```
+
+### Testing additional dialog "styles"
+
+Add additional test cases, with a different string after "`InvokeDialog_`".
+Example:
+
+```cpp
+IN_PROC_BROWSER_TEST_F(CardUnmaskViewBrowserTest, InvokeDialog_expired) {
+ RunDialog();
+}
+
+IN_PROC_BROWSER_TEST_F(CardUnmaskViewBrowserTest, InvokeDialog_valid) {
+ RunDialog();
+}
+```
+
+The strings "`expired`" or “`valid`” will be given as arguments to
+`ShowDialog(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.
+
+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
+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.
+
+Even discovering the full set of dialogs present for each platform in Chrome is
+[difficult](http://crbug.com/686239).
+
+### Why browser_tests?
+
+* `browser_tests` already provides a `browser()->window()` of a consistent
+ 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
+ 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
+ ongoing maintenance.
+
+* An alternative is to maintain a working end-to-end build target executable
+ to do this, but this has additional costs (and is hard).
+ * E.g. setup/teardown of low-level functions (
+ `InitializeGLOneOffPlatform()`,
+ `MaterialDesignController::Initialize()`, etc.).
+
+* Why not chrome.exe?
+ * E.g. a scrappy chrome:// page with links to invoke dialogs 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.
+ * 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`.
+
+* Automatically generate screenshots (for each platform, in various languages)
+ * Build upon [CL 2008283002](https://codereview.chromium.org/2008283002/)
+
+* (maybe) Try removing the subprocess
+ * 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
+ * e.g. native close (via taskbar?)
+ * close parent window (possibly via task bar)
+ * close parent tab
+ * switch tabs
+ * close via `DialogClientView::AcceptWindow` (and `CancelWindow`)
+ * close via `Widget::Close`
+ * close via `Widget::CloseNow`
+ * 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))
+ * Supporting window-modal dialogs with a null parent window.
+
+* Find memory leaks, e.g. [http://crrev.com/432320](http://crrev.com/432320)
+ * "Fix memory leak for extension uninstall dialog".
+
+## Appendix: Sample output
+
+**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserDialogTest.Invoke**
+```
+Note: Google Test filter = BrowserDialogTest.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)
+[----------] Global test environment tear-down
+[==========] 1 test from 1 test case ran. (1 ms total)
+[ PASSED ] 1 test.
+[1/1] BrowserDialogTest.Invoke (334 ms)
+SUCCESS: all tests passed.
+```
+
+**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserDialogTest.Invoke
+--dialog=CardUnmaskPromptViewBrowserTest.InvokeDialog_expired**
+
+```
+Note: Google Test filter = BrowserDialogTest.Invoke
+[==========] Running 1 test from 1 test case.
+[----------] Global test environment set-up.
+[----------] 1 test from BrowserDialogTest
+[ RUN ] BrowserDialogTest.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
+/* 7 lines of uninteresting log spam */
+[ OK ] CardUnmaskPromptViewBrowserTest.InvokeDialog_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)
+[----------] Global test environment tear-down
+[==========] 1 test from 1 test case ran. (1642 ms total)
+[ PASSED ] 1 test.
+[1/1] BrowserDialogTest.Invoke (2111 ms)
+SUCCESS: all tests passed.
+```
+
+**$ ./out/gn_Debug/browser_tests --gtest_filter=BrowserDialogTest.Invoke
+--dialog=CardUnmaskPromptViewBrowserTest.InvokeDialog_expired --interactive**
+```
+/*
+ * Output as above, except the test are not interleaved, and the browser window
+ * should remain open until the dialog is dismissed
+ */
+```
+
+[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
+[ExtensionBrowserTest]: https://cs.chromium.org/chromium/src/chrome/browser/extensions/extension_browsertest.h?q=extensionbrowsertest&l=40
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698