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

Side by Side Diff: chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm

Issue 2579613002: [Media Router Action] Hide action back in the overflow menu after popping it out (Closed)
Patch Set: Modify a comment Created 3 years, 11 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 unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/ui/toolbar/media_router_action.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #import "chrome/browser/ui/cocoa/extensions/browser_action_button.h" 5 #import "chrome/browser/ui/cocoa/extensions/browser_action_button.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 11 matching lines...) Expand all
22 #include "chrome/browser/ui/browser_window.h" 22 #include "chrome/browser/ui/browser_window.h"
23 #import "chrome/browser/ui/cocoa/app_menu/app_menu_controller.h" 23 #import "chrome/browser/ui/cocoa/app_menu/app_menu_controller.h"
24 #import "chrome/browser/ui/cocoa/browser_window_controller.h" 24 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
25 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h" 25 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h"
26 #import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h" 26 #import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
27 #import "chrome/browser/ui/cocoa/test/run_loop_testing.h" 27 #import "chrome/browser/ui/cocoa/test/run_loop_testing.h"
28 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" 28 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
29 #include "chrome/browser/ui/global_error/global_error.h" 29 #include "chrome/browser/ui/global_error/global_error.h"
30 #include "chrome/browser/ui/global_error/global_error_service.h" 30 #include "chrome/browser/ui/global_error/global_error_service.h"
31 #include "chrome/browser/ui/global_error/global_error_service_factory.h" 31 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
32 #include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
33 #include "chrome/browser/ui/toolbar/media_router_action.h"
32 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" 34 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
33 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" 35 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
34 #include "chrome/test/base/interactive_test_utils.h" 36 #include "chrome/test/base/interactive_test_utils.h"
35 #include "extensions/common/feature_switch.h" 37 #include "extensions/common/feature_switch.h"
36 #include "ui/base/cocoa/cocoa_base_utils.h" 38 #include "ui/base/cocoa/cocoa_base_utils.h"
37 #import "ui/events/test/cocoa_test_event_utils.h" 39 #import "ui/events/test/cocoa_test_event_utils.h"
38 40
39 namespace { 41 namespace {
40 42
41 const int kMenuPadding = 26; 43 const int kMenuPadding = 26;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 87
86 // Moves the mouse (synchronously) to the center of the given |view|. 88 // Moves the mouse (synchronously) to the center of the given |view|.
87 void MoveMouseToCenter(NSView* view) { 89 void MoveMouseToCenter(NSView* view) {
88 NSPoint centerPoint = GetCenterPoint(view); 90 NSPoint centerPoint = GetCenterPoint(view);
89 base::RunLoop runLoop; 91 base::RunLoop runLoop;
90 ui_controls::SendMouseMoveNotifyWhenDone( 92 ui_controls::SendMouseMoveNotifyWhenDone(
91 centerPoint.x, centerPoint.y, runLoop.QuitClosure()); 93 centerPoint.x, centerPoint.y, runLoop.QuitClosure());
92 runLoop.Run(); 94 runLoop.Run();
93 } 95 }
94 96
97 // Simulates a click on the action button in the overflow menu, and runs
98 // |closure| upon completion.
99 void ClickOnOverflowedAction(ToolbarController* toolbarController,
100 const base::Closure& closure) {
101 AppMenuController* appMenuController = [toolbarController appMenuController];
102 // The app menu should start as open (since that's where the overflowed
103 // actions are).
104 EXPECT_TRUE([appMenuController isMenuOpen]);
105 BrowserActionsController* overflowController =
106 [appMenuController browserActionsController];
107
108 ASSERT_TRUE(overflowController);
109 BrowserActionButton* actionButton = [overflowController buttonWithIndex:0];
110 // The action should be attached to a superview.
111 EXPECT_TRUE([actionButton superview]);
112
113 // ui_controls:: methods don't play nice when there is an open menu (like the
114 // app menu). Instead, simulate a right click by feeding the event directly to
115 // the button.
116 NSPoint centerPoint = GetCenterPoint(actionButton);
117 NSEvent* mouseEvent = cocoa_test_event_utils::RightMouseDownAtPointInWindow(
118 centerPoint, [actionButton window]);
119 [actionButton rightMouseDown:mouseEvent];
120
121 // This should close the app menu.
122 EXPECT_FALSE([appMenuController isMenuOpen]);
123 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure);
124 }
125
95 } // namespace 126 } // namespace
96 127
97 // A simple helper menu delegate that will keep track of if a menu is opened, 128 // A simple helper menu delegate that will keep track of if a menu is opened,
98 // and closes them immediately (which is useful because message loops with 129 // and closes them immediately (which is useful because message loops with
99 // menus open in Cocoa don't play nicely with testing). 130 // menus open in Cocoa don't play nicely with testing).
100 @interface MenuHelper : NSObject<NSMenuDelegate> { 131 @interface MenuHelper : NSObject<NSMenuDelegate> {
101 // Whether or not a menu has been opened. This can be reset so the helper can 132 // Whether or not a menu has been opened. This can be reset so the helper can
102 // be used multiple times. 133 // be used multiple times.
103 BOOL menuOpened_; 134 BOOL menuOpened_;
104 135
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 extensions::FeatureSwitch::extension_action_redesign(), true)); 253 extensions::FeatureSwitch::extension_action_redesign(), true));
223 ToolbarActionsBar::disable_animations_for_testing_ = true; 254 ToolbarActionsBar::disable_animations_for_testing_ = true;
224 } 255 }
225 256
226 void TearDownOnMainThread() override { 257 void TearDownOnMainThread() override {
227 enable_redesign_.reset(); 258 enable_redesign_.reset();
228 ToolbarActionsBar::disable_animations_for_testing_ = false; 259 ToolbarActionsBar::disable_animations_for_testing_ = false;
229 ExtensionBrowserTest::TearDownOnMainThread(); 260 ExtensionBrowserTest::TearDownOnMainThread();
230 } 261 }
231 262
263 // Opens the app menu and the context menu of the overflowed action, and
264 // checks that the menus get opened/closed properly. |menuHelper| must be set
265 // as the delegate for the context menu.
266 void OpenAppMenuAndActionContextMenu(MenuHelper* menuHelper) {
267 // Move the mouse over the app menu button.
268 MoveMouseToCenter(appMenuButton());
269
270 // No menu yet (on the browser action).
271 EXPECT_FALSE([menuHelper menuOpened]);
272 base::RunLoop runLoop;
273 // Click on the app menu, and pass in a callback to continue the test in
274 // ClickOnOverflowedAction. Due to the blocking nature of Cocoa menus, we
275 // can't test the menu synchronously here by quitting the run loop when it
276 // opens, and instead need to test through a callback.
277 base::scoped_nsobject<MenuWatcher> menuWatcher(
278 [[MenuWatcher alloc] initWithController:appMenuController()]);
279 [menuWatcher
280 setOpenClosure:base::Bind(&ClickOnOverflowedAction,
281 base::Unretained(toolbarController()),
282 runLoop.QuitClosure())];
283 ui_controls::SendMouseEvents(ui_controls::LEFT,
284 ui_controls::DOWN | ui_controls::UP);
285 runLoop.Run();
286
287 // The menu opened on the main bar's action button rather than the
288 // overflow's since Cocoa does not support running a menu within a menu.
289 EXPECT_TRUE([menuHelper menuOpened]);
290 }
291
232 ToolbarController* toolbarController() { return toolbarController_; } 292 ToolbarController* toolbarController() { return toolbarController_; }
233 AppMenuController* appMenuController() { return appMenuController_; } 293 AppMenuController* appMenuController() { return appMenuController_; }
234 ToolbarActionsModel* model() { return model_; } 294 ToolbarActionsModel* model() { return model_; }
235 NSView* appMenuButton() { return [toolbarController_ appMenuButton]; } 295 NSView* appMenuButton() { return [toolbarController_ appMenuButton]; }
236 296
237 private: 297 private:
238 std::unique_ptr<extensions::FeatureSwitch::ScopedOverride> enable_redesign_; 298 std::unique_ptr<extensions::FeatureSwitch::ScopedOverride> enable_redesign_;
239 299
240 ToolbarController* toolbarController_ = nil; 300 ToolbarController* toolbarController_ = nil;
241 AppMenuController* appMenuController_ = nil; 301 AppMenuController* appMenuController_ = nil;
242 ToolbarActionsModel* model_ = nullptr; 302 ToolbarActionsModel* model_ = nullptr;
243 303
244 DISALLOW_COPY_AND_ASSIGN(BrowserActionButtonUiTest); 304 DISALLOW_COPY_AND_ASSIGN(BrowserActionButtonUiTest);
245 }; 305 };
246 306
247 // Simulates a clicks on the action button in the overflow menu, and runs
248 // |closure| upon completion.
249 void ClickOnOverflowedAction(ToolbarController* toolbarController,
250 const base::Closure& closure) {
251 AppMenuController* appMenuController =
252 [toolbarController appMenuController];
253 // The app menu should start as open (since that's where the overflowed
254 // actions are).
255 EXPECT_TRUE([appMenuController isMenuOpen]);
256 BrowserActionsController* overflowController =
257 [appMenuController browserActionsController];
258
259 ASSERT_TRUE(overflowController);
260 BrowserActionButton* actionButton =
261 [overflowController buttonWithIndex:0];
262 // The action should be attached to a superview.
263 EXPECT_TRUE([actionButton superview]);
264
265 // ui_controls:: methods don't play nice when there is an open menu (like the
266 // app menu). Instead, simulate a right click by feeding the event directly to
267 // the button.
268 NSPoint centerPoint = GetCenterPoint(actionButton);
269 NSEvent* mouseEvent = cocoa_test_event_utils::RightMouseDownAtPointInWindow(
270 centerPoint, [actionButton window]);
271 [actionButton rightMouseDown:mouseEvent];
272
273 // This should close the app menu.
274 EXPECT_FALSE([appMenuController isMenuOpen]);
275 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure);
276 }
277
278 // Verifies that the action is "popped out" of overflow; that is, it is visible 307 // Verifies that the action is "popped out" of overflow; that is, it is visible
279 // on the main bar, and is set as the popped out action on the controlling 308 // on the main bar, and is set as the popped out action on the controlling
280 // ToolbarActionsBar. 309 // ToolbarActionsBar.
281 void CheckActionIsPoppedOut(BrowserActionsController* actionsController, 310 void CheckActionIsPoppedOut(BrowserActionsController* actionsController,
282 BrowserActionButton* actionButton) { 311 BrowserActionButton* actionButton) {
283 EXPECT_EQ([actionsController containerView], [actionButton superview]); 312 EXPECT_EQ([actionsController containerView], [actionButton superview]);
284 EXPECT_EQ([actionButton viewController], 313 EXPECT_EQ([actionButton viewController],
285 [actionsController toolbarActionsBar]->popped_out_action()); 314 [actionsController toolbarActionsBar]->popped_out_action());
286 // Since the button is popped out for a popup or context menu, it should be 315 // Since the button is popped out for a popup or context menu, it should be
287 // highlighted. 316 // highlighted.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 364
336 // Reset the menu helper so we can use it again. 365 // Reset the menu helper so we can use it again.
337 [menuHelper setMenuOpened:NO]; 366 [menuHelper setMenuOpened:NO];
338 [menuHelper setVerify:base::Bind( 367 [menuHelper setVerify:base::Bind(
339 CheckActionIsPoppedOut, actionsController, actionButton)]; 368 CheckActionIsPoppedOut, actionsController, actionButton)];
340 369
341 // Shrink the visible count to be 0. This should hide the action button. 370 // Shrink the visible count to be 0. This should hide the action button.
342 model()->SetVisibleIconCount(0); 371 model()->SetVisibleIconCount(0);
343 EXPECT_EQ(nil, [actionButton superview]); 372 EXPECT_EQ(nil, [actionButton superview]);
344 373
345 // Move the mouse over the app menu button. 374 OpenAppMenuAndActionContextMenu(menuHelper.get());
346 MoveMouseToCenter(appMenuButton()); 375 }
347 376
348 { 377 IN_PROC_BROWSER_TEST_F(BrowserActionButtonUiTest,
349 // No menu yet (on the browser action). 378 MediaRouterActionContextMenuInOverflow) {
350 EXPECT_FALSE([menuHelper menuOpened]); 379 model()->AddComponentAction(
351 base::RunLoop runLoop; 380 ComponentToolbarActionsFactory::kMediaRouterActionId);
352 // Click on the app menu, and pass in a callback to continue the test in 381 ASSERT_EQ(1u, model()->toolbar_items().size());
353 // ClickOnOverflowedAction (Due to the blocking nature of Cocoa menus,
354 // passing in runLoop.QuitClosure() is not sufficient here.)
355 base::scoped_nsobject<MenuWatcher> menuWatcher(
356 [[MenuWatcher alloc] initWithController:appMenuController()]);
357 [menuWatcher setOpenClosure:
358 base::Bind(&ClickOnOverflowedAction,
359 base::Unretained(toolbarController()),
360 runLoop.QuitClosure())];
361 ui_controls::SendMouseEvents(ui_controls::LEFT,
362 ui_controls::DOWN | ui_controls::UP);
363 runLoop.Run();
364 382
365 // The menu should have opened. Note that the menu opened on the main bar's 383 BrowserActionButton* actionButton =
366 // action button, not the overflow's. Since Cocoa doesn't support running 384 [[toolbarController() browserActionsController] buttonWithIndex:0];
367 // a menu-within-a-menu, this is what has to happen. 385 ASSERT_TRUE(actionButton);
368 EXPECT_TRUE([menuHelper menuOpened]); 386
369 EXPECT_FALSE([actionButton isHighlighted]); 387 // Stub out the action button's normal context menu with a fake one so we
370 } 388 // can track when it opens.
389 base::scoped_nsobject<NSMenu> testContextMenu(
390 [[NSMenu alloc] initWithTitle:@""]);
391 base::scoped_nsobject<MenuHelper> menuHelper([[MenuHelper alloc] init]);
392 [testContextMenu setDelegate:menuHelper.get()];
393 [actionButton setTestContextMenu:testContextMenu.get()];
394
395 model()->SetActionVisibility(
396 ComponentToolbarActionsFactory::kMediaRouterActionId, false);
397
398 OpenAppMenuAndActionContextMenu(menuHelper.get());
399
400 ToolbarActionsBar* actions_bar =
Robert Sesek 2017/01/03 21:42:22 nit: while under_scores are correct for this funct
takumif 2017/01/03 22:09:37 Done.
401 [[toolbarController() browserActionsController] toolbarActionsBar];
402 // The action should be back in the overflow.
403 EXPECT_FALSE(
404 actions_bar->IsActionVisibleOnMainBar(actions_bar->GetActions()[0]));
371 } 405 }
372 406
373 // Checks the layout of the overflow bar in the app menu. 407 // Checks the layout of the overflow bar in the app menu.
374 void CheckAppMenuLayout(ToolbarController* toolbarController, 408 void CheckAppMenuLayout(ToolbarController* toolbarController,
375 int overflowStartIndex, 409 int overflowStartIndex,
376 const std::string& error_message, 410 const std::string& error_message,
377 const base::Closure& closure) { 411 const base::Closure& closure) {
378 AppMenuController* appMenuController = 412 AppMenuController* appMenuController =
379 [toolbarController appMenuController]; 413 [toolbarController appMenuController];
380 // The app menu should start as open (since that's where the overflowed 414 // The app menu should start as open (since that's where the overflowed
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 openAndCloseAppMenu(appMenuController()); 677 openAndCloseAppMenu(appMenuController());
644 678
645 // Move the extension back to the main bar, so an overflow bar is no longer 679 // Move the extension back to the main bar, so an overflow bar is no longer
646 // needed. Then open and close the app menu a couple times. 680 // needed. Then open and close the app menu a couple times.
647 // This tests that the menu properly cleans up after itself when an overflow 681 // This tests that the menu properly cleans up after itself when an overflow
648 // was present, and is no longer (fix for crbug.com/603241). 682 // was present, and is no longer (fix for crbug.com/603241).
649 model()->SetVisibleIconCount(1); 683 model()->SetVisibleIconCount(1);
650 openAndCloseAppMenu(appMenuController()); 684 openAndCloseAppMenu(appMenuController());
651 openAndCloseAppMenu(appMenuController()); 685 openAndCloseAppMenu(appMenuController());
652 } 686 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/toolbar/media_router_action.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698