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 |