OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/callback.h" | 6 #include "base/callback.h" |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "chrome/test/base/testing_browser_process.h" | 27 #include "chrome/test/base/testing_browser_process.h" |
28 #include "chrome/test/base/testing_profile.h" | 28 #include "chrome/test/base/testing_profile.h" |
29 #include "chrome/test/base/ui_test_utils.h" | 29 #include "chrome/test/base/ui_test_utils.h" |
30 #include "chrome/test/base/view_event_test_base.h" | 30 #include "chrome/test/base/view_event_test_base.h" |
31 #include "components/bookmarks/browser/bookmark_model.h" | 31 #include "components/bookmarks/browser/bookmark_model.h" |
32 #include "components/bookmarks/test/bookmark_test_helpers.h" | 32 #include "components/bookmarks/test/bookmark_test_helpers.h" |
33 #include "content/public/browser/notification_service.h" | 33 #include "content/public/browser/notification_service.h" |
34 #include "content/public/browser/page_navigator.h" | 34 #include "content/public/browser/page_navigator.h" |
35 #include "content/public/test/test_browser_thread.h" | 35 #include "content/public/test/test_browser_thread.h" |
36 #include "grit/generated_resources.h" | 36 #include "grit/generated_resources.h" |
| 37 #include "ui/aura/env.h" |
| 38 #include "ui/aura/env_observer.h" |
| 39 #include "ui/aura/window.h" |
37 #include "ui/base/clipboard/clipboard.h" | 40 #include "ui/base/clipboard/clipboard.h" |
38 #include "ui/base/test/ui_controls.h" | 41 #include "ui/base/test/ui_controls.h" |
39 #include "ui/events/keycodes/keyboard_codes.h" | 42 #include "ui/events/keycodes/keyboard_codes.h" |
40 #include "ui/views/controls/button/menu_button.h" | 43 #include "ui/views/controls/button/menu_button.h" |
41 #include "ui/views/controls/button/text_button.h" | 44 #include "ui/views/controls/button/text_button.h" |
42 #include "ui/views/controls/menu/menu_controller.h" | 45 #include "ui/views/controls/menu/menu_controller.h" |
43 #include "ui/views/controls/menu/menu_item_view.h" | 46 #include "ui/views/controls/menu/menu_item_view.h" |
44 #include "ui/views/controls/menu/submenu_view.h" | 47 #include "ui/views/controls/menu/submenu_view.h" |
45 #include "ui/views/widget/widget.h" | 48 #include "ui/views/widget/widget.h" |
46 | 49 |
47 using base::ASCIIToUTF16; | 50 using base::ASCIIToUTF16; |
48 using content::BrowserThread; | 51 using content::BrowserThread; |
49 using content::OpenURLParams; | 52 using content::OpenURLParams; |
50 using content::PageNavigator; | 53 using content::PageNavigator; |
51 using content::WebContents; | 54 using content::WebContents; |
52 | 55 |
53 namespace { | 56 namespace { |
54 | 57 |
| 58 // Waits for a views::Widget dialog to show up. |
| 59 class DialogWaiter : public aura::EnvObserver, |
| 60 public views::WidgetObserver { |
| 61 public: |
| 62 DialogWaiter() |
| 63 : dialog_created_(false), |
| 64 dialog_(NULL) { |
| 65 aura::Env::GetInstance()->AddObserver(this); |
| 66 } |
| 67 |
| 68 virtual ~DialogWaiter() { |
| 69 aura::Env::GetInstance()->RemoveObserver(this); |
| 70 } |
| 71 |
| 72 views::Widget* WaitForDialog() { |
| 73 if (dialog_created_) |
| 74 return dialog_; |
| 75 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
| 76 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); |
| 77 base::RunLoop run_loop; |
| 78 quit_closure_ = run_loop.QuitClosure(); |
| 79 run_loop.Run(); |
| 80 return dialog_; |
| 81 } |
| 82 |
| 83 private: |
| 84 // aura::EnvObserver: |
| 85 virtual void OnWindowInitialized(aura::Window* window) OVERRIDE { |
| 86 if (dialog_) |
| 87 return; |
| 88 views::Widget* widget = views::Widget::GetWidgetForNativeView(window); |
| 89 if (!widget || !widget->IsDialogBox()) |
| 90 return; |
| 91 dialog_ = widget; |
| 92 dialog_->AddObserver(this); |
| 93 } |
| 94 |
| 95 // views::WidgetObserver: |
| 96 virtual void OnWidgetVisibilityChanged(views::Widget* widget, |
| 97 bool visible) OVERRIDE { |
| 98 CHECK_EQ(dialog_, widget); |
| 99 if (visible) { |
| 100 dialog_created_ = true; |
| 101 dialog_->RemoveObserver(this); |
| 102 if (!quit_closure_.is_null()) |
| 103 quit_closure_.Run(); |
| 104 } |
| 105 } |
| 106 |
| 107 bool dialog_created_; |
| 108 views::Widget* dialog_; |
| 109 base::Closure quit_closure_; |
| 110 |
| 111 DISALLOW_COPY_AND_ASSIGN(DialogWaiter); |
| 112 }; |
| 113 |
| 114 // Waits for a dialog to terminate. |
| 115 class DialogCloseWaiter : public views::WidgetObserver { |
| 116 public: |
| 117 explicit DialogCloseWaiter(views::Widget* dialog) |
| 118 : dialog_closed_(false) { |
| 119 dialog->AddObserver(this); |
| 120 } |
| 121 |
| 122 virtual ~DialogCloseWaiter() { |
| 123 // It is not necessary to remove |this| from the dialog's observer, since |
| 124 // the dialog is destroyed before this waiter. |
| 125 } |
| 126 |
| 127 void WaitForDialogClose() { |
| 128 if (dialog_closed_) |
| 129 return; |
| 130 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
| 131 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); |
| 132 base::RunLoop run_loop; |
| 133 quit_closure_ = run_loop.QuitClosure(); |
| 134 run_loop.Run(); |
| 135 } |
| 136 |
| 137 private: |
| 138 // views::WidgetObserver: |
| 139 virtual void OnWidgetDestroyed(views::Widget* widget) OVERRIDE { |
| 140 dialog_closed_ = true; |
| 141 if (!quit_closure_.is_null()) |
| 142 quit_closure_.Run(); |
| 143 } |
| 144 |
| 145 bool dialog_closed_; |
| 146 base::Closure quit_closure_; |
| 147 |
| 148 DISALLOW_COPY_AND_ASSIGN(DialogCloseWaiter); |
| 149 }; |
| 150 |
| 151 // Waits for a views::Widget to receive a Tab key. |
| 152 class TabKeyWaiter : public ui::EventHandler { |
| 153 public: |
| 154 explicit TabKeyWaiter(views::Widget* widget) |
| 155 : widget_(widget), |
| 156 received_tab_(false) { |
| 157 widget_->GetNativeView()->AddPreTargetHandler(this); |
| 158 } |
| 159 |
| 160 virtual ~TabKeyWaiter() { |
| 161 widget_->GetNativeView()->RemovePreTargetHandler(this); |
| 162 } |
| 163 |
| 164 void WaitForTab() { |
| 165 if (received_tab_) |
| 166 return; |
| 167 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
| 168 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); |
| 169 base::RunLoop run_loop; |
| 170 quit_closure_ = run_loop.QuitClosure(); |
| 171 run_loop.Run(); |
| 172 } |
| 173 |
| 174 private: |
| 175 // ui::EventHandler: |
| 176 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { |
| 177 if (event->type() == ui::ET_KEY_RELEASED && |
| 178 event->key_code() == ui::VKEY_TAB) { |
| 179 received_tab_ = true; |
| 180 if (!quit_closure_.is_null()) |
| 181 quit_closure_.Run(); |
| 182 } |
| 183 } |
| 184 |
| 185 views::Widget* widget_; |
| 186 bool received_tab_; |
| 187 base::Closure quit_closure_; |
| 188 |
| 189 DISALLOW_COPY_AND_ASSIGN(TabKeyWaiter); |
| 190 }; |
| 191 |
55 void MoveMouseAndPress(const gfx::Point& screen_pos, | 192 void MoveMouseAndPress(const gfx::Point& screen_pos, |
56 ui_controls::MouseButton button, | 193 ui_controls::MouseButton button, |
57 int state, | 194 int state, |
58 const base::Closure& closure) { | 195 const base::Closure& closure) { |
59 ui_controls::SendMouseMove(screen_pos.x(), screen_pos.y()); | 196 ui_controls::SendMouseMove(screen_pos.x(), screen_pos.y()); |
60 ui_controls::SendMouseEventsNotifyWhenDone(button, state, closure); | 197 ui_controls::SendMouseEventsNotifyWhenDone(button, state, closure); |
61 } | 198 } |
62 | 199 |
63 // PageNavigator implementation that records the URL. | 200 // PageNavigator implementation that records the URL. |
64 class TestingPageNavigator : public PageNavigator { | 201 class TestingPageNavigator : public PageNavigator { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 | 314 |
178 virtual void TearDown() { | 315 virtual void TearDown() { |
179 // Destroy everything, then run the message loop to ensure we delete all | 316 // Destroy everything, then run the message loop to ensure we delete all |
180 // Tasks and fully shut down. | 317 // Tasks and fully shut down. |
181 browser_->tab_strip_model()->CloseAllTabs(); | 318 browser_->tab_strip_model()->CloseAllTabs(); |
182 bb_view_.reset(); | 319 bb_view_.reset(); |
183 browser_.reset(); | 320 browser_.reset(); |
184 profile_.reset(); | 321 profile_.reset(); |
185 | 322 |
186 // Run the message loop to ensure we delete allTasks and fully shut down. | 323 // Run the message loop to ensure we delete allTasks and fully shut down. |
187 base::MessageLoop::current()->PostTask(FROM_HERE, | 324 base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); |
188 base::MessageLoop::QuitClosure()); | 325 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); |
189 base::MessageLoop::current()->Run(); | 326 base::RunLoop run_loop; |
| 327 loop->PostTask(FROM_HERE, run_loop.QuitClosure()); |
| 328 run_loop.Run(); |
190 | 329 |
191 ViewEventTestBase::TearDown(); | 330 ViewEventTestBase::TearDown(); |
192 BookmarkBarView::DisableAnimationsForTesting(false); | 331 BookmarkBarView::DisableAnimationsForTesting(false); |
193 | 332 |
194 browser_content_client_.reset(); | 333 browser_content_client_.reset(); |
195 content_client_.reset(); | 334 content_client_.reset(); |
196 content::SetContentClient(NULL); | 335 content::SetContentClient(NULL); |
197 } | 336 } |
198 | 337 |
199 protected: | 338 protected: |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 | 1279 |
1141 void Step3() { | 1280 void Step3() { |
1142 // Make sure the context menu is showing. | 1281 // Make sure the context menu is showing. |
1143 views::MenuItemView* menu = bb_view_->GetContextMenu(); | 1282 views::MenuItemView* menu = bb_view_->GetContextMenu(); |
1144 ASSERT_TRUE(menu && menu->GetSubmenu() && menu->GetSubmenu()->IsShowing()); | 1283 ASSERT_TRUE(menu && menu->GetSubmenu() && menu->GetSubmenu()->IsShowing()); |
1145 | 1284 |
1146 // Select the first item in the context menu (open all). | 1285 // Select the first item in the context menu (open all). |
1147 views::MenuItemView* child_menu = | 1286 views::MenuItemView* child_menu = |
1148 menu->GetSubmenu()->GetMenuItemAt(0); | 1287 menu->GetSubmenu()->GetMenuItemAt(0); |
1149 ASSERT_TRUE(child_menu != NULL); | 1288 ASSERT_TRUE(child_menu != NULL); |
1150 ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT, | |
1151 ui_controls::DOWN | ui_controls::UP, base::Closure()); | |
1152 | 1289 |
1153 // Delay until we send tab, otherwise the message box doesn't appear | 1290 // Click and wait until the dialog box appears. |
1154 // correctly. | 1291 scoped_ptr<DialogWaiter> dialog_waiter(new DialogWaiter()); |
1155 base::MessageLoop::current()->PostDelayedTask( | 1292 ui_test_utils::MoveMouseToCenterAndPress( |
1156 FROM_HERE, | 1293 child_menu, |
1157 CreateEventTask(this, &BookmarkBarViewTest12::Step4), | 1294 ui_controls::LEFT, |
1158 base::TimeDelta::FromSeconds(1)); | 1295 ui_controls::DOWN | ui_controls::UP, |
| 1296 base::Bind( |
| 1297 &BookmarkBarViewTest12::Step4, this, base::Passed(&dialog_waiter))); |
1159 } | 1298 } |
1160 | 1299 |
1161 void Step4() { | 1300 void Step4(scoped_ptr<DialogWaiter> waiter) { |
1162 // Press tab to give focus to the cancel button. | 1301 views::Widget* dialog = waiter->WaitForDialog(); |
| 1302 waiter.reset(); |
| 1303 |
| 1304 // Press tab to give focus to the cancel button. Wait until the widget |
| 1305 // receives the tab key. |
| 1306 TabKeyWaiter tab_waiter(dialog); |
1163 ui_controls::SendKeyPress( | 1307 ui_controls::SendKeyPress( |
1164 window_->GetNativeWindow(), ui::VKEY_TAB, false, false, false, false); | 1308 window_->GetNativeWindow(), ui::VKEY_TAB, false, false, false, false); |
| 1309 tab_waiter.WaitForTab(); |
1165 | 1310 |
1166 // For some reason return isn't processed correctly unless we delay. | 1311 // For some reason return isn't processed correctly unless we delay. |
1167 base::MessageLoop::current()->PostDelayedTask( | 1312 base::MessageLoop::current()->PostDelayedTask( |
1168 FROM_HERE, | 1313 FROM_HERE, |
1169 CreateEventTask(this, &BookmarkBarViewTest12::Step5), | 1314 base::Bind( |
| 1315 &BookmarkBarViewTest12::Step5, this, base::Unretained(dialog)), |
1170 base::TimeDelta::FromSeconds(1)); | 1316 base::TimeDelta::FromSeconds(1)); |
1171 } | 1317 } |
1172 | 1318 |
1173 void Step5() { | 1319 void Step5(views::Widget* dialog) { |
| 1320 DialogCloseWaiter waiter(dialog); |
1174 // And press enter so that the cancel button is selected. | 1321 // And press enter so that the cancel button is selected. |
1175 ui_controls::SendKeyPressNotifyWhenDone( | 1322 ui_controls::SendKeyPressNotifyWhenDone(window_->GetNativeWindow(), |
1176 window_->GetNativeWindow(), ui::VKEY_RETURN, false, false, false, false, | 1323 ui::VKEY_RETURN, |
1177 CreateEventTask(this, &BookmarkBarViewTest12::Step6)); | 1324 false, |
1178 } | 1325 false, |
1179 | 1326 false, |
1180 void Step6() { | 1327 false, |
1181 // Do a delayed task to give the dialog time to exit. | 1328 base::Closure()); |
1182 base::MessageLoop::current()->PostTask( | 1329 waiter.WaitForDialogClose(); |
1183 FROM_HERE, CreateEventTask(this, &BookmarkBarViewTest12::Step7)); | |
1184 } | |
1185 | |
1186 void Step7() { | |
1187 Done(); | 1330 Done(); |
1188 } | 1331 } |
1189 }; | 1332 }; |
1190 | 1333 |
1191 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) | 1334 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) |
1192 // TODO(erg): linux_aura bringup: http://crbug.com/163931 | 1335 // TODO(erg): linux_aura bringup: http://crbug.com/163931 |
1193 #define MAYBE_CloseWithModalDialog DISABLED_CloseWithModalDialog | 1336 #define MAYBE_CloseWithModalDialog DISABLED_CloseWithModalDialog |
1194 #else | 1337 #else |
1195 #define MAYBE_CloseWithModalDialog CloseWithModalDialog | 1338 #define MAYBE_CloseWithModalDialog CloseWithModalDialog |
1196 #endif | 1339 #endif |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1831 EXPECT_TRUE(bb_view_->GetContextMenu() == NULL); | 1974 EXPECT_TRUE(bb_view_->GetContextMenu() == NULL); |
1832 EXPECT_TRUE(bb_view_->GetMenu() == NULL); | 1975 EXPECT_TRUE(bb_view_->GetMenu() == NULL); |
1833 | 1976 |
1834 Done(); | 1977 Done(); |
1835 } | 1978 } |
1836 | 1979 |
1837 BookmarkContextMenuNotificationObserver observer_; | 1980 BookmarkContextMenuNotificationObserver observer_; |
1838 }; | 1981 }; |
1839 | 1982 |
1840 VIEW_TEST(BookmarkBarViewTest21, ContextMenusForEmptyFolder) | 1983 VIEW_TEST(BookmarkBarViewTest21, ContextMenusForEmptyFolder) |
OLD | NEW |