Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/test/test_browser_dialog.h" | |
| 6 | |
| 7 #include "base/command_line.h" | |
| 8 #include "base/message_loop/message_loop.h" | |
| 9 #include "chrome/browser/platform_util.h" | |
| 10 #include "ui/base/material_design/material_design_controller.h" | |
| 11 #include "ui/base/test/material_design_controller_test_api.h" | |
| 12 #include "ui/base/test/user_interactive_test_case.h" | |
| 13 #include "ui/base/ui_base_switches.h" | |
| 14 #include "ui/views/widget/widget.h" | |
| 15 #include "ui/views/widget/widget_observer.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 // An automatic action for WidgetCloser to post to the RunLoop. | |
| 20 // TODO(tapted): Explore asynchronous Widget::Close() and DialogClientView:: | |
| 21 // {Accept,Cancel}Window() approaches to test other dialog lifetimes. | |
| 22 enum class DialogAction { | |
| 23 INTERACTIVE, // Run interactively. | |
| 24 CLOSE_NOW, // Call Widget::CloseNow(). | |
| 25 }; | |
| 26 | |
| 27 // Helper to break out of the nested run loop that runs a test dialog. | |
| 28 class WidgetCloser : public views::WidgetObserver { | |
| 29 public: | |
| 30 WidgetCloser(views::Widget* widget, DialogAction action) | |
| 31 : widget_(widget), weak_ptr_factory_(this) { | |
| 32 widget->AddObserver(this); | |
| 33 if (action == DialogAction::INTERACTIVE) | |
| 34 return; | |
| 35 | |
| 36 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 37 FROM_HERE, | |
| 38 base::Bind(&WidgetCloser::CloseNow, weak_ptr_factory_.GetWeakPtr())); | |
| 39 } | |
| 40 | |
| 41 // WidgetObserver: | |
| 42 void OnWidgetDestroyed(views::Widget* widget) override { | |
| 43 widget_->RemoveObserver(this); | |
| 44 widget_ = nullptr; | |
| 45 base::MessageLoop::current()->QuitNow(); | |
| 46 } | |
| 47 | |
| 48 private: | |
| 49 void CloseNow() { | |
| 50 if (widget_) | |
| 51 widget_->CloseNow(); | |
| 52 } | |
| 53 | |
| 54 views::Widget* widget_; | |
| 55 | |
| 56 base::WeakPtrFactory<WidgetCloser> weak_ptr_factory_; | |
| 57 | |
| 58 DISALLOW_COPY_AND_ASSIGN(WidgetCloser); | |
| 59 }; | |
| 60 | |
| 61 // Extracts the |name| argument for ShowDialog() from the current test case. | |
| 62 std::string NameFromTestCase() { | |
|
Paweł Hajdan Jr.
2016/12/20 16:27:15
Is this the same as TestNameWithoutDisabledPrefix
tapted
2016/12/20 23:34:47
Thanks for the pointer - there's some interesting
| |
| 63 const std::string disabled_prefix = "DISABLED_"; | |
| 64 std::string name = | |
| 65 testing::UnitTest::GetInstance()->current_test_info()->name(); | |
| 66 if (name.find(disabled_prefix) == 0) | |
| 67 name = name.substr(disabled_prefix.size()); | |
| 68 | |
| 69 std::string::size_type underscore = name.find('_'); | |
| 70 return underscore == std::string::npos ? std::string() | |
| 71 : name.substr(underscore + 1); | |
| 72 } | |
| 73 | |
| 74 } // namespace | |
| 75 | |
| 76 TestBrowserDialog::TestBrowserDialog() {} | |
| 77 | |
| 78 void TestBrowserDialog::RunDialog() { | |
| 79 #if defined(OS_MACOSX) | |
| 80 // The rest of this method assumes the child dialog is toolkit-views. So, for | |
| 81 // Mac, it will only work if --secondary-ui-md is passed. Without this, a | |
| 82 // Cocoa dialog will be created, which TestBrowserDialog doesn't support. | |
| 83 // Force SecondaryUiMaterial() on Mac to get coverage on the bots. Leave it | |
| 84 // optional elsewhere so that the non-MD dialog can be invoked to compare. | |
| 85 ui::test::MaterialDesignControllerTestAPI md_test_api( | |
| 86 ui::MaterialDesignController::GetMode()); | |
| 87 md_test_api.SetSecondaryUiMaterial(true); | |
| 88 #endif | |
| 89 | |
| 90 gfx::NativeView parent = platform_util::GetViewForWindow(DialogParent()); | |
| 91 views::Widget::Widgets widgets_before; | |
| 92 views::Widget::GetAllChildWidgets(parent, &widgets_before); | |
| 93 | |
| 94 ShowDialog(NameFromTestCase()); | |
| 95 views::Widget::Widgets widgets_after; | |
| 96 views::Widget::GetAllChildWidgets(parent, &widgets_after); | |
| 97 | |
| 98 auto added = base::STLSetDifference<std::vector<views::Widget*>>( | |
| 99 widgets_after, widgets_before); | |
| 100 | |
| 101 // This can fail if no dialog was shown, if the dialog shown wasn't a toolkit- | |
| 102 // views dialog, or if more than one child dialog was shown. | |
| 103 ASSERT_EQ(1u, added.size()); | |
| 104 | |
| 105 const DialogAction action = base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 106 internal::kInteractiveSwitch) | |
| 107 ? DialogAction::INTERACTIVE | |
| 108 : DialogAction::CLOSE_NOW; | |
| 109 | |
| 110 WidgetCloser closer(added[0], action); | |
| 111 ::test::RunTestInteractively(); | |
| 112 } | |
| OLD | NEW |