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
3 // found in the LICENSE file.
5 #include "ash/shelf/shelf_view.h"
10 #include "ash/ash_switches.h"
11 #include "ash/root_window_controller.h"
12 #include "ash/shelf/overflow_bubble.h"
13 #include "ash/shelf/overflow_bubble_view.h"
14 #include "ash/shelf/shelf.h"
15 #include "ash/shelf/shelf_button.h"
16 #include "ash/shelf/shelf_constants.h"
17 #include "ash/shelf/shelf_icon_observer.h"
18 #include "ash/shelf/shelf_item_delegate_manager.h"
19 #include "ash/shelf/shelf_layout_manager.h"
20 #include "ash/shelf/shelf_model.h"
21 #include "ash/shelf/shelf_tooltip_manager.h"
22 #include "ash/shelf/shelf_widget.h"
23 #include "ash/shell.h"
24 #include "ash/shell_window_ids.h"
25 #include "ash/test/ash_test_base.h"
26 #include "ash/test/overflow_bubble_view_test_api.h"
27 #include "ash/test/shelf_test_api.h"
28 #include "ash/test/shelf_view_test_api.h"
29 #include "ash/test/shell_test_api.h"
30 #include "ash/test/test_shelf_delegate.h"
31 #include "ash/test/test_shelf_item_delegate.h"
32 #include "ash/wm/coordinate_conversion.h"
33 #include "base/basictypes.h"
34 #include "base/command_line.h"
35 #include "base/compiler_specific.h"
36 #include "base/memory/scoped_ptr.h"
37 #include "base/strings/string_number_conversions.h"
38 #include "grit/ash_resources.h"
39 #include "ui/aura/test/aura_test_base.h"
40 #include "ui/aura/test/event_generator.h"
41 #include "ui/aura/window.h"
42 #include "ui/aura/window_event_dispatcher.h"
43 #include "ui/base/l10n/l10n_util.h"
44 #include "ui/compositor/layer.h"
45 #include "ui/events/event.h"
46 #include "ui/events/event_constants.h"
47 #include "ui/views/view_model.h"
48 #include "ui/views/widget/widget.h"
49 #include "ui/views/widget/widget_delegate.h"
54 ////////////////////////////////////////////////////////////////////////////////
55 // ShelfIconObserver tests.
57 class TestShelfIconObserver
: public ShelfIconObserver
{
59 explicit TestShelfIconObserver(Shelf
* shelf
)
61 change_notified_(false) {
63 shelf_
->AddIconObserver(this);
66 virtual ~TestShelfIconObserver() {
68 shelf_
->RemoveIconObserver(this);
71 // ShelfIconObserver implementation.
72 virtual void OnShelfIconPositionsChanged() OVERRIDE
{
73 change_notified_
= true;
76 int change_notified() const { return change_notified_
; }
77 void Reset() { change_notified_
= false; }
81 bool change_notified_
;
83 DISALLOW_COPY_AND_ASSIGN(TestShelfIconObserver
);
86 class ShelfViewIconObserverTest
: public AshTestBase
{
88 ShelfViewIconObserverTest() {}
89 virtual ~ShelfViewIconObserverTest() {}
91 virtual void SetUp() OVERRIDE
{
93 Shelf
* shelf
= Shelf::ForPrimaryDisplay();
94 observer_
.reset(new TestShelfIconObserver(shelf
));
96 shelf_view_test_
.reset(
97 new ShelfViewTestAPI(ShelfTestAPI(shelf
).shelf_view()));
98 shelf_view_test_
->SetAnimationDuration(1);
101 virtual void TearDown() OVERRIDE
{
103 AshTestBase::TearDown();
106 TestShelfIconObserver
* observer() { return observer_
.get(); }
108 ShelfViewTestAPI
* shelf_view_test() {
109 return shelf_view_test_
.get();
112 Shelf
* ShelfForSecondaryDisplay() {
113 return Shelf::ForWindow(Shell::GetAllRootWindows()[1]);
117 scoped_ptr
<TestShelfIconObserver
> observer_
;
118 scoped_ptr
<ShelfViewTestAPI
> shelf_view_test_
;
120 DISALLOW_COPY_AND_ASSIGN(ShelfViewIconObserverTest
);
123 // TestShelfItemDelegate which tracks whether it gets selected.
124 class ShelfItemSelectionTracker
: public TestShelfItemDelegate
{
126 ShelfItemSelectionTracker() : TestShelfItemDelegate(NULL
), selected_(false) {
129 virtual ~ShelfItemSelectionTracker() {
132 // Returns true if the delegate was selected.
137 // TestShelfItemDelegate:
138 virtual bool ItemSelected(const ui::Event
& event
) OVERRIDE
{
146 DISALLOW_COPY_AND_ASSIGN(ShelfItemSelectionTracker
);
149 TEST_F(ShelfViewIconObserverTest
, AddRemove
) {
150 TestShelfDelegate
* shelf_delegate
= TestShelfDelegate::instance();
151 ASSERT_TRUE(shelf_delegate
);
153 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
154 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
155 params
.bounds
= gfx::Rect(0, 0, 200, 200);
156 params
.context
= CurrentContext();
158 scoped_ptr
<views::Widget
> widget(new views::Widget());
159 widget
->Init(params
);
160 shelf_delegate
->AddShelfItem(widget
->GetNativeWindow());
161 shelf_view_test()->RunMessageLoopUntilAnimationsDone();
162 EXPECT_TRUE(observer()->change_notified());
166 widget
->GetNativeWindow()->parent()->RemoveChild(widget
->GetNativeWindow());
167 shelf_view_test()->RunMessageLoopUntilAnimationsDone();
168 EXPECT_TRUE(observer()->change_notified());
172 // Sometimes fails on trybots on win7_aura. http://crbug.com/177135
174 #define MAYBE_AddRemoveWithMultipleDisplays \
175 DISABLED_AddRemoveWithMultipleDisplays
177 #define MAYBE_AddRemoveWithMultipleDisplays \
178 AddRemoveWithMultipleDisplays
180 // Make sure creating/deleting an window on one displays notifies a
181 // shelf on external display as well as one on primary.
182 TEST_F(ShelfViewIconObserverTest
, MAYBE_AddRemoveWithMultipleDisplays
) {
183 UpdateDisplay("400x400,400x400");
184 TestShelfIconObserver
second_observer(ShelfForSecondaryDisplay());
186 TestShelfDelegate
* shelf_delegate
= TestShelfDelegate::instance();
187 ASSERT_TRUE(shelf_delegate
);
189 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
190 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
191 params
.bounds
= gfx::Rect(0, 0, 200, 200);
192 params
.context
= CurrentContext();
194 scoped_ptr
<views::Widget
> widget(new views::Widget());
195 widget
->Init(params
);
196 shelf_delegate
->AddShelfItem(widget
->GetNativeWindow());
197 shelf_view_test()->RunMessageLoopUntilAnimationsDone();
198 EXPECT_TRUE(observer()->change_notified());
199 EXPECT_TRUE(second_observer
.change_notified());
201 second_observer
.Reset();
203 widget
->GetNativeWindow()->parent()->RemoveChild(widget
->GetNativeWindow());
204 shelf_view_test()->RunMessageLoopUntilAnimationsDone();
205 EXPECT_TRUE(observer()->change_notified());
206 EXPECT_TRUE(second_observer
.change_notified());
209 second_observer
.Reset();
212 TEST_F(ShelfViewIconObserverTest
, BoundsChanged
) {
213 ShelfWidget
* widget
= Shell::GetPrimaryRootWindowController()->shelf();
214 Shelf
* shelf
= Shelf::ForPrimaryDisplay();
215 gfx::Size shelf_size
= widget
->GetWindowBoundsInScreen().size();
216 shelf_size
.set_width(shelf_size
.width() / 2);
217 ASSERT_GT(shelf_size
.width(), 0);
218 shelf
->SetShelfViewBounds(gfx::Rect(shelf_size
));
219 // No animation happens for ShelfView bounds change.
220 EXPECT_TRUE(observer()->change_notified());
224 ////////////////////////////////////////////////////////////////////////////////
227 // Simple ShelfDelegate implmentation for ShelfViewTest.OverflowBubbleSize
228 // and CheckDragAndDropFromOverflowBubbleToShelf
229 class TestShelfDelegateForShelfView
: public ShelfDelegate
{
231 explicit TestShelfDelegateForShelfView(ShelfModel
* model
)
233 virtual ~TestShelfDelegateForShelfView() {}
235 // ShelfDelegate overrides:
236 virtual void OnShelfCreated(Shelf
* shelf
) OVERRIDE
{}
238 virtual void OnShelfDestroyed(Shelf
* shelf
) OVERRIDE
{}
240 virtual ShelfID
GetShelfIDForAppID(const std::string
& app_id
) OVERRIDE
{
242 EXPECT_TRUE(base::StringToInt(app_id
, &id
));
246 virtual const std::string
& GetAppIDForShelfID(ShelfID id
) OVERRIDE
{
247 // Use |app_id_| member variable because returning a reference to local
248 // variable is not allowed.
249 app_id_
= base::IntToString(id
);
253 virtual void PinAppWithID(const std::string
& app_id
) OVERRIDE
{
256 virtual bool IsAppPinned(const std::string
& app_id
) OVERRIDE
{
257 // Returns true for ShelfViewTest.OverflowBubbleSize. To test ripping off in
258 // that test, an item is already pinned state.
262 virtual bool CanPin() const OVERRIDE
{
266 virtual void UnpinAppWithID(const std::string
& app_id
) OVERRIDE
{
268 EXPECT_TRUE(base::StringToInt(app_id
, &id
));
270 int index
= model_
->ItemIndexByID(id
);
273 model_
->RemoveItemAt(index
);
279 // Temp member variable for returning a value. See the comment in the
280 // GetAppIDForShelfID().
283 DISALLOW_COPY_AND_ASSIGN(TestShelfDelegateForShelfView
);
286 class ShelfViewTest
: public AshTestBase
{
288 ShelfViewTest() : model_(NULL
), shelf_view_(NULL
), browser_index_(1) {}
289 virtual ~ShelfViewTest() {}
291 virtual void SetUp() OVERRIDE
{
292 AshTestBase::SetUp();
293 test::ShellTestApi
test_api(Shell::GetInstance());
294 model_
= test_api
.shelf_model();
295 Shelf
* shelf
= Shelf::ForPrimaryDisplay();
296 shelf_view_
= ShelfTestAPI(shelf
).shelf_view();
298 // The bounds should be big enough for 4 buttons + overflow chevron.
299 shelf_view_
->SetBounds(0, 0, 500, kShelfSize
);
301 test_api_
.reset(new ShelfViewTestAPI(shelf_view_
));
302 test_api_
->SetAnimationDuration(1); // Speeds up animation for test.
304 item_manager_
= Shell::GetInstance()->shelf_item_delegate_manager();
305 DCHECK(item_manager_
);
307 // Add browser shortcut shelf item at index 0 for test.
308 AddBrowserShortcut();
311 virtual void TearDown() OVERRIDE
{
313 AshTestBase::TearDown();
317 void CreateAndSetShelfItemDelegateForID(ShelfID id
) {
318 scoped_ptr
<ShelfItemDelegate
> delegate(new TestShelfItemDelegate(NULL
));
319 item_manager_
->SetShelfItemDelegate(id
, delegate
.Pass());
322 ShelfID
AddBrowserShortcut() {
323 ShelfItem browser_shortcut
;
324 browser_shortcut
.type
= TYPE_BROWSER_SHORTCUT
;
326 ShelfID id
= model_
->next_id();
327 model_
->AddAt(browser_index_
, browser_shortcut
);
328 CreateAndSetShelfItemDelegateForID(id
);
329 test_api_
->RunMessageLoopUntilAnimationsDone();
333 ShelfID
AddAppShortcut() {
335 item
.type
= TYPE_APP_SHORTCUT
;
336 item
.status
= STATUS_CLOSED
;
338 ShelfID id
= model_
->next_id();
340 CreateAndSetShelfItemDelegateForID(id
);
341 test_api_
->RunMessageLoopUntilAnimationsDone();
346 ShelfID id
= AddPanelNoWait();
347 test_api_
->RunMessageLoopUntilAnimationsDone();
351 ShelfID
AddPlatformAppNoWait() {
353 item
.type
= TYPE_PLATFORM_APP
;
354 item
.status
= STATUS_RUNNING
;
356 ShelfID id
= model_
->next_id();
358 CreateAndSetShelfItemDelegateForID(id
);
362 ShelfID
AddPanelNoWait() {
364 item
.type
= TYPE_APP_PANEL
;
365 item
.status
= STATUS_RUNNING
;
367 ShelfID id
= model_
->next_id();
369 CreateAndSetShelfItemDelegateForID(id
);
373 ShelfID
AddPlatformApp() {
374 ShelfID id
= AddPlatformAppNoWait();
375 test_api_
->RunMessageLoopUntilAnimationsDone();
379 void RemoveByID(ShelfID id
) {
380 model_
->RemoveItemAt(model_
->ItemIndexByID(id
));
381 test_api_
->RunMessageLoopUntilAnimationsDone();
384 ShelfButton
* GetButtonByID(ShelfID id
) {
385 int index
= model_
->ItemIndexByID(id
);
386 return test_api_
->GetButton(index
);
389 ShelfItem
GetItemByID(ShelfID id
) {
390 ShelfItems::const_iterator items
= model_
->ItemByID(id
);
395 const std::vector
<std::pair
<ShelfID
, views::View
*> >& id_map
) {
396 size_t map_index
= 0;
397 for (size_t model_index
= 0;
398 model_index
< model_
->items().size();
400 ShelfItem item
= model_
->items()[model_index
];
401 ShelfID id
= item
.id
;
402 EXPECT_EQ(id_map
[map_index
].first
, id
);
403 EXPECT_EQ(id_map
[map_index
].second
, GetButtonByID(id
));
406 ASSERT_EQ(map_index
, id_map
.size());
409 void VerifyShelfItemBoundsAreValid() {
410 for (int i
=0;i
<= test_api_
->GetLastVisibleIndex(); ++i
) {
411 if (test_api_
->GetButton(i
)) {
412 gfx::Rect shelf_view_bounds
= shelf_view_
->GetLocalBounds();
413 gfx::Rect item_bounds
= test_api_
->GetBoundsByIndex(i
);
414 EXPECT_GE(item_bounds
.x(), 0);
415 EXPECT_GE(item_bounds
.y(), 0);
416 EXPECT_LE(item_bounds
.right(), shelf_view_bounds
.width());
417 EXPECT_LE(item_bounds
.bottom(), shelf_view_bounds
.height());
422 views::View
* SimulateButtonPressed(ShelfButtonHost::Pointer pointer
,
424 ShelfButtonHost
* button_host
= shelf_view_
;
425 views::View
* button
= test_api_
->GetButton(button_index
);
426 ui::MouseEvent
click_event(ui::ET_MOUSE_PRESSED
,
428 button
->GetBoundsInScreen().origin(), 0, 0);
429 button_host
->PointerPressedOnButton(button
, pointer
, click_event
);
433 views::View
* SimulateClick(ShelfButtonHost::Pointer pointer
,
435 ShelfButtonHost
* button_host
= shelf_view_
;
436 views::View
* button
= SimulateButtonPressed(pointer
, button_index
);
437 button_host
->PointerReleasedOnButton(button
, ShelfButtonHost::MOUSE
, false);
441 views::View
* SimulateDrag(ShelfButtonHost::Pointer pointer
,
443 int destination_index
) {
444 ShelfButtonHost
* button_host
= shelf_view_
;
445 views::View
* button
= SimulateButtonPressed(pointer
, button_index
);
448 views::View
* destination
= test_api_
->GetButton(destination_index
);
449 ui::MouseEvent
drag_event(ui::ET_MOUSE_DRAGGED
,
450 gfx::Point(destination
->x() - button
->x(),
451 destination
->y() - button
->y()),
452 destination
->GetBoundsInScreen().origin(), 0, 0);
453 button_host
->PointerDraggedOnButton(button
, pointer
, drag_event
);
457 void SetupForDragTest(
458 std::vector
<std::pair
<ShelfID
, views::View
*> >* id_map
) {
459 // Initialize |id_map| with the automatically-created shelf buttons.
460 for (size_t i
= 0; i
< model_
->items().size(); ++i
) {
461 ShelfButton
* button
= test_api_
->GetButton(i
);
462 id_map
->push_back(std::make_pair(model_
->items()[i
].id
, button
));
464 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(*id_map
));
466 // Add 5 app shelf buttons for testing.
467 for (int i
= 0; i
< 5; ++i
) {
468 ShelfID id
= AddAppShortcut();
469 // App Icon is located at index 0, and browser shortcut is located at
470 // index 1. So we should start to add app shortcut at index 2.
471 id_map
->insert(id_map
->begin() + (i
+ browser_index_
+ 1),
472 std::make_pair(id
, GetButtonByID(id
)));
474 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(*id_map
));
477 views::View
* GetTooltipAnchorView() {
478 return shelf_view_
->tooltip_manager()->anchor_
;
481 void AddButtonsUntilOverflow() {
483 while (!test_api_
->IsOverflowButtonVisible()) {
486 ASSERT_LT(items_added
, 10000);
491 shelf_view_
->tooltip_manager()->ShowInternal();
494 void TestDraggingAnItemFromOverflowToShelf(bool cancel
) {
495 test_api_
->ShowOverflowBubble();
496 ASSERT_TRUE(test_api_
->overflow_bubble() &&
497 test_api_
->overflow_bubble()->IsShowing());
499 ash::test::ShelfViewTestAPI
test_api_for_overflow(
500 test_api_
->overflow_bubble()->shelf_view());
502 int total_item_count
= model_
->item_count();
504 int last_visible_item_id_in_shelf
=
505 GetItemId(test_api_
->GetLastVisibleIndex());
506 int second_last_visible_item_id_in_shelf
=
507 GetItemId(test_api_
->GetLastVisibleIndex() - 1);
508 int first_visible_item_id_in_overflow
=
509 GetItemId(test_api_for_overflow
.GetFirstVisibleIndex());
510 int second_last_visible_item_id_in_overflow
=
511 GetItemId(test_api_for_overflow
.GetLastVisibleIndex() - 1);
513 int drag_item_index
=
514 test_api_for_overflow
.GetLastVisibleIndex();
515 ShelfID drag_item_id
= GetItemId(drag_item_index
);
516 ShelfButton
* drag_button
= test_api_for_overflow
.GetButton(drag_item_index
);
517 gfx::Point center_point_of_drag_item
=
518 drag_button
->GetBoundsInScreen().CenterPoint();
520 aura::test::EventGenerator
generator(ash::Shell::GetPrimaryRootWindow(),
521 center_point_of_drag_item
);
522 // Rip an item off to OverflowBubble.
523 generator
.PressLeftButton();
524 gfx::Point
rip_off_point(center_point_of_drag_item
.x(), 0);
525 generator
.MoveMouseTo(rip_off_point
);
526 test_api_for_overflow
.RunMessageLoopUntilAnimationsDone();
527 ASSERT_TRUE(test_api_for_overflow
.IsRippedOffFromShelf());
528 ASSERT_FALSE(test_api_for_overflow
.DraggedItemFromOverflowToShelf());
530 // Move a dragged item into Shelf at |drop_index|.
532 gfx::Point drop_point
=
533 test_api_
->GetButton(drop_index
)->GetBoundsInScreen().CenterPoint();
534 int item_width
= test_api_for_overflow
.GetButtonSize();
535 // To insert at |drop_index|, more smaller x-axis value of |drop_point|
537 gfx::Point
modified_drop_point(drop_point
.x() - item_width
/ 4,
539 generator
.MoveMouseTo(modified_drop_point
);
540 test_api_for_overflow
.RunMessageLoopUntilAnimationsDone();
541 test_api_
->RunMessageLoopUntilAnimationsDone();
542 ASSERT_TRUE(test_api_for_overflow
.IsRippedOffFromShelf());
543 ASSERT_TRUE(test_api_for_overflow
.DraggedItemFromOverflowToShelf());
546 drag_button
->OnMouseCaptureLost();
548 generator
.ReleaseLeftButton();
550 test_api_for_overflow
.RunMessageLoopUntilAnimationsDone();
551 test_api_
->RunMessageLoopUntilAnimationsDone();
552 ASSERT_FALSE(test_api_for_overflow
.IsRippedOffFromShelf());
553 ASSERT_FALSE(test_api_for_overflow
.DraggedItemFromOverflowToShelf());
555 // Compare pre-stored items' id with newly positioned items' after dragging
556 // is canceled or finished.
558 EXPECT_EQ(last_visible_item_id_in_shelf
,
559 GetItemId(test_api_
->GetLastVisibleIndex()));
560 EXPECT_EQ(second_last_visible_item_id_in_shelf
,
561 GetItemId(test_api_
->GetLastVisibleIndex() - 1));
562 EXPECT_EQ(first_visible_item_id_in_overflow
,
563 GetItemId(test_api_for_overflow
.GetFirstVisibleIndex()));
564 EXPECT_EQ(second_last_visible_item_id_in_overflow
,
565 GetItemId(test_api_for_overflow
.GetLastVisibleIndex() - 1));
567 EXPECT_EQ(drag_item_id
, GetItemId(drop_index
));
568 EXPECT_EQ(total_item_count
, model_
->item_count());
569 EXPECT_EQ(last_visible_item_id_in_shelf
,
570 GetItemId(test_api_for_overflow
.GetFirstVisibleIndex()));
571 EXPECT_EQ(second_last_visible_item_id_in_shelf
,
572 GetItemId(test_api_
->GetLastVisibleIndex()));
573 EXPECT_EQ(first_visible_item_id_in_overflow
,
574 GetItemId(test_api_for_overflow
.GetFirstVisibleIndex() + 1));
575 EXPECT_EQ(second_last_visible_item_id_in_overflow
,
576 GetItemId(test_api_for_overflow
.GetLastVisibleIndex()));
580 // Returns the item's ShelfID at |index|.
581 ShelfID
GetItemId(int index
) {
583 return model_
->items()[index
].id
;
586 void ReplaceShelfDelegateForRipOffTest() {
587 // Replace ShelfDelegate.
588 test::ShellTestApi
test_api(Shell::GetInstance());
589 test_api
.SetShelfDelegate(NULL
);
590 ShelfDelegate
* delegate
= new TestShelfDelegateForShelfView(model_
);
591 test_api
.SetShelfDelegate(delegate
);
592 test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).SetShelfDelegate(delegate
);
593 test_api_
->SetShelfDelegate(delegate
);
597 ShelfView
* shelf_view_
;
599 ShelfItemDelegateManager
* item_manager_
;
601 scoped_ptr
<ShelfViewTestAPI
> test_api_
;
604 DISALLOW_COPY_AND_ASSIGN(ShelfViewTest
);
607 class ScopedTextDirectionChange
{
609 ScopedTextDirectionChange(bool is_rtl
)
611 original_locale_
= l10n_util::GetApplicationLocale(std::string());
613 base::i18n::SetICUDefaultLocale("he");
614 CheckTextDirectionIsCorrect();
617 ~ScopedTextDirectionChange() {
619 base::i18n::SetICUDefaultLocale(original_locale_
);
623 void CheckTextDirectionIsCorrect() {
624 ASSERT_EQ(is_rtl_
, base::i18n::IsRTL());
628 std::string original_locale_
;
631 class ShelfViewTextDirectionTest
632 : public ShelfViewTest
,
633 public testing::WithParamInterface
<bool> {
635 ShelfViewTextDirectionTest() : text_direction_change_(GetParam()) {}
636 virtual ~ShelfViewTextDirectionTest() {}
638 virtual void SetUp() OVERRIDE
{
639 ShelfViewTest::SetUp();
642 virtual void TearDown() OVERRIDE
{
643 ShelfViewTest::TearDown();
647 ScopedTextDirectionChange text_direction_change_
;
649 DISALLOW_COPY_AND_ASSIGN(ShelfViewTextDirectionTest
);
652 // Checks that the ideal item icon bounds match the view's bounds in the screen
653 // in both LTR and RTL.
654 TEST_P(ShelfViewTextDirectionTest
, IdealBoundsOfItemIcon
) {
655 ShelfID id
= AddPlatformApp();
656 ShelfButton
* button
= GetButtonByID(id
);
657 gfx::Rect item_bounds
= button
->GetBoundsInScreen();
658 gfx::Point icon_offset
= button
->GetIconBounds().origin();
659 item_bounds
.Offset(icon_offset
.OffsetFromOrigin());
660 gfx::Rect ideal_bounds
= shelf_view_
->GetIdealBoundsOfItemIcon(id
);
661 gfx::Point screen_origin
;
662 views::View::ConvertPointToScreen(shelf_view_
, &screen_origin
);
663 ideal_bounds
.Offset(screen_origin
.x(), screen_origin
.y());
664 EXPECT_EQ(item_bounds
.x(), ideal_bounds
.x());
665 EXPECT_EQ(item_bounds
.y(), ideal_bounds
.y());
668 // Check that items in the overflow area are returning the overflow button as
670 TEST_F(ShelfViewTest
, OverflowButtonBounds
) {
671 ShelfID first_id
= AddPlatformApp();
672 ShelfID overflow_id
= AddPlatformApp();
674 while (!test_api_
->IsOverflowButtonVisible()) {
675 // Added button is visible after animation while in this loop.
676 EXPECT_TRUE(GetButtonByID(overflow_id
)->visible());
677 overflow_id
= AddPlatformApp();
679 ASSERT_LT(items_added
, 10000);
681 ShelfID last_id
= AddPlatformApp();
683 gfx::Rect first_bounds
= shelf_view_
->GetIdealBoundsOfItemIcon(first_id
);
684 gfx::Rect overflow_bounds
=
685 shelf_view_
->GetIdealBoundsOfItemIcon(overflow_id
);
686 gfx::Rect last_bounds
= shelf_view_
->GetIdealBoundsOfItemIcon(last_id
);
688 // Check that all items have the same size and that the overflow items are
689 // identical whereas the first one does not match either of them.
690 EXPECT_EQ(first_bounds
.size().ToString(), last_bounds
.size().ToString());
691 EXPECT_NE(first_bounds
.ToString(), last_bounds
.ToString());
692 EXPECT_EQ(overflow_bounds
.ToString(), last_bounds
.ToString());
695 // Checks that shelf view contents are considered in the correct drag group.
696 TEST_F(ShelfViewTest
, EnforceDragType
) {
697 EXPECT_TRUE(test_api_
->SameDragType(TYPE_PLATFORM_APP
, TYPE_PLATFORM_APP
));
698 EXPECT_FALSE(test_api_
->SameDragType(TYPE_PLATFORM_APP
, TYPE_APP_SHORTCUT
));
699 EXPECT_FALSE(test_api_
->SameDragType(TYPE_PLATFORM_APP
,
700 TYPE_BROWSER_SHORTCUT
));
701 EXPECT_FALSE(test_api_
->SameDragType(TYPE_PLATFORM_APP
, TYPE_WINDOWED_APP
));
702 EXPECT_FALSE(test_api_
->SameDragType(TYPE_PLATFORM_APP
, TYPE_APP_LIST
));
703 EXPECT_FALSE(test_api_
->SameDragType(TYPE_PLATFORM_APP
, TYPE_APP_PANEL
));
705 EXPECT_TRUE(test_api_
->SameDragType(TYPE_APP_SHORTCUT
, TYPE_APP_SHORTCUT
));
706 EXPECT_TRUE(test_api_
->SameDragType(TYPE_APP_SHORTCUT
,
707 TYPE_BROWSER_SHORTCUT
));
708 EXPECT_FALSE(test_api_
->SameDragType(TYPE_APP_SHORTCUT
,
710 EXPECT_FALSE(test_api_
->SameDragType(TYPE_APP_SHORTCUT
, TYPE_APP_LIST
));
711 EXPECT_FALSE(test_api_
->SameDragType(TYPE_APP_SHORTCUT
, TYPE_APP_PANEL
));
713 EXPECT_TRUE(test_api_
->SameDragType(TYPE_BROWSER_SHORTCUT
,
714 TYPE_BROWSER_SHORTCUT
));
715 EXPECT_FALSE(test_api_
->SameDragType(TYPE_BROWSER_SHORTCUT
,
717 EXPECT_FALSE(test_api_
->SameDragType(TYPE_BROWSER_SHORTCUT
, TYPE_APP_LIST
));
718 EXPECT_FALSE(test_api_
->SameDragType(TYPE_BROWSER_SHORTCUT
, TYPE_APP_PANEL
));
720 EXPECT_TRUE(test_api_
->SameDragType(TYPE_WINDOWED_APP
, TYPE_WINDOWED_APP
));
721 EXPECT_FALSE(test_api_
->SameDragType(TYPE_WINDOWED_APP
, TYPE_APP_LIST
));
722 EXPECT_FALSE(test_api_
->SameDragType(TYPE_WINDOWED_APP
, TYPE_APP_PANEL
));
724 EXPECT_TRUE(test_api_
->SameDragType(TYPE_APP_LIST
, TYPE_APP_LIST
));
725 EXPECT_FALSE(test_api_
->SameDragType(TYPE_APP_LIST
, TYPE_APP_PANEL
));
727 EXPECT_TRUE(test_api_
->SameDragType(TYPE_APP_PANEL
, TYPE_APP_PANEL
));
730 // Adds platform app button until overflow and verifies that the last added
731 // platform app button is hidden.
732 TEST_F(ShelfViewTest
, AddBrowserUntilOverflow
) {
733 // All buttons should be visible.
734 ASSERT_EQ(test_api_
->GetButtonCount(),
735 test_api_
->GetLastVisibleIndex() + 1);
737 // Add platform app button until overflow.
739 ShelfID last_added
= AddPlatformApp();
740 while (!test_api_
->IsOverflowButtonVisible()) {
741 // Added button is visible after animation while in this loop.
742 EXPECT_TRUE(GetButtonByID(last_added
)->visible());
744 last_added
= AddPlatformApp();
746 ASSERT_LT(items_added
, 10000);
749 // The last added button should be invisible.
750 EXPECT_FALSE(GetButtonByID(last_added
)->visible());
753 // Adds one platform app button then adds app shortcut until overflow. Verifies
754 // that the browser button gets hidden on overflow and last added app shortcut
756 TEST_F(ShelfViewTest
, AddAppShortcutWithBrowserButtonUntilOverflow
) {
757 // All buttons should be visible.
758 ASSERT_EQ(test_api_
->GetButtonCount(),
759 test_api_
->GetLastVisibleIndex() + 1);
761 ShelfID browser_button_id
= AddPlatformApp();
763 // Add app shortcut until overflow.
765 ShelfID last_added
= AddAppShortcut();
766 while (!test_api_
->IsOverflowButtonVisible()) {
767 // Added button is visible after animation while in this loop.
768 EXPECT_TRUE(GetButtonByID(last_added
)->visible());
770 last_added
= AddAppShortcut();
772 ASSERT_LT(items_added
, 10000);
775 // And the platform app button is invisible.
776 EXPECT_FALSE(GetButtonByID(browser_button_id
)->visible());
779 TEST_F(ShelfViewTest
, AddPanelHidesPlatformAppButton
) {
780 // All buttons should be visible.
781 ASSERT_EQ(test_api_
->GetButtonCount(),
782 test_api_
->GetLastVisibleIndex() + 1);
784 // Add platform app button until overflow, remember last visible platform app
787 ShelfID first_added
= AddPlatformApp();
788 EXPECT_TRUE(GetButtonByID(first_added
)->visible());
790 ShelfID added
= AddPlatformApp();
791 if (test_api_
->IsOverflowButtonVisible()) {
792 EXPECT_FALSE(GetButtonByID(added
)->visible());
797 ASSERT_LT(items_added
, 10000);
800 ShelfID panel
= AddPanel();
801 EXPECT_TRUE(test_api_
->IsOverflowButtonVisible());
804 EXPECT_FALSE(test_api_
->IsOverflowButtonVisible());
807 // When there are more panels then platform app buttons we should hide panels
808 // rather than platform apps.
809 TEST_F(ShelfViewTest
, PlatformAppHidesExcessPanels
) {
810 // All buttons should be visible.
811 ASSERT_EQ(test_api_
->GetButtonCount(),
812 test_api_
->GetLastVisibleIndex() + 1);
814 // Add platform app button.
815 ShelfID platform_app
= AddPlatformApp();
816 ShelfID first_panel
= AddPanel();
818 EXPECT_TRUE(GetButtonByID(platform_app
)->visible());
819 EXPECT_TRUE(GetButtonByID(first_panel
)->visible());
821 // Add panels until there is an overflow.
822 ShelfID last_panel
= first_panel
;
824 while (!test_api_
->IsOverflowButtonVisible()) {
825 last_panel
= AddPanel();
827 ASSERT_LT(items_added
, 10000);
830 // The first panel should now be hidden by the new platform apps needing
832 EXPECT_FALSE(GetButtonByID(first_panel
)->visible());
833 EXPECT_TRUE(GetButtonByID(last_panel
)->visible());
834 EXPECT_TRUE(GetButtonByID(platform_app
)->visible());
836 // Adding platform apps should eventually begin to hide platform apps. We will
837 // add platform apps until either the last panel or platform app is hidden.
839 while (GetButtonByID(platform_app
)->visible() &&
840 GetButtonByID(last_panel
)->visible()) {
841 platform_app
= AddPlatformApp();
843 ASSERT_LT(items_added
, 10000);
845 EXPECT_TRUE(GetButtonByID(last_panel
)->visible());
846 EXPECT_FALSE(GetButtonByID(platform_app
)->visible());
849 // Adds button until overflow then removes first added one. Verifies that
850 // the last added one changes from invisible to visible and overflow
852 TEST_F(ShelfViewTest
, RemoveButtonRevealsOverflowed
) {
853 // All buttons should be visible.
854 ASSERT_EQ(test_api_
->GetButtonCount(),
855 test_api_
->GetLastVisibleIndex() + 1);
857 // Add platform app buttons until overflow.
859 ShelfID first_added
= AddPlatformApp();
860 ShelfID last_added
= first_added
;
861 while (!test_api_
->IsOverflowButtonVisible()) {
862 last_added
= AddPlatformApp();
864 ASSERT_LT(items_added
, 10000);
867 // Expect add more than 1 button. First added is visible and last is not.
868 EXPECT_NE(first_added
, last_added
);
869 EXPECT_TRUE(GetButtonByID(first_added
)->visible());
870 EXPECT_FALSE(GetButtonByID(last_added
)->visible());
872 // Remove first added.
873 RemoveByID(first_added
);
875 // Last added button becomes visible and overflow chevron is gone.
876 EXPECT_TRUE(GetButtonByID(last_added
)->visible());
877 EXPECT_EQ(1.0f
, GetButtonByID(last_added
)->layer()->opacity());
878 EXPECT_FALSE(test_api_
->IsOverflowButtonVisible());
881 // Verifies that remove last overflowed button should hide overflow chevron.
882 TEST_F(ShelfViewTest
, RemoveLastOverflowed
) {
883 // All buttons should be visible.
884 ASSERT_EQ(test_api_
->GetButtonCount(),
885 test_api_
->GetLastVisibleIndex() + 1);
887 // Add platform app button until overflow.
889 ShelfID last_added
= AddPlatformApp();
890 while (!test_api_
->IsOverflowButtonVisible()) {
891 last_added
= AddPlatformApp();
893 ASSERT_LT(items_added
, 10000);
896 RemoveByID(last_added
);
897 EXPECT_FALSE(test_api_
->IsOverflowButtonVisible());
900 // Adds platform app button without waiting for animation to finish and verifies
901 // that all added buttons are visible.
902 TEST_F(ShelfViewTest
, AddButtonQuickly
) {
903 // All buttons should be visible.
904 ASSERT_EQ(test_api_
->GetButtonCount(),
905 test_api_
->GetLastVisibleIndex() + 1);
907 // Add a few platform buttons quickly without wait for animation.
909 while (!test_api_
->IsOverflowButtonVisible()) {
910 AddPlatformAppNoWait();
912 ASSERT_LT(added_count
, 10000);
915 // ShelfView should be big enough to hold at least 3 new buttons.
916 ASSERT_GE(added_count
, 3);
918 // Wait for the last animation to finish.
919 test_api_
->RunMessageLoopUntilAnimationsDone();
921 // Verifies non-overflow buttons are visible.
922 for (int i
= 0; i
<= test_api_
->GetLastVisibleIndex(); ++i
) {
923 ShelfButton
* button
= test_api_
->GetButton(i
);
925 EXPECT_TRUE(button
->visible()) << "button index=" << i
;
926 EXPECT_EQ(1.0f
, button
->layer()->opacity()) << "button index=" << i
;
931 // Check that model changes are handled correctly while a shelf icon is being
933 TEST_F(ShelfViewTest
, ModelChangesWhileDragging
) {
934 ShelfButtonHost
* button_host
= shelf_view_
;
936 std::vector
<std::pair
<ShelfID
, views::View
*> > id_map
;
937 SetupForDragTest(&id_map
);
939 // Dragging browser shortcut at index 1.
940 EXPECT_TRUE(model_
->items()[1].type
== TYPE_BROWSER_SHORTCUT
);
941 views::View
* dragged_button
= SimulateDrag(ShelfButtonHost::MOUSE
, 1, 3);
942 std::rotate(id_map
.begin() + 1,
945 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
946 button_host
->PointerReleasedOnButton(
947 dragged_button
, ShelfButtonHost::MOUSE
, false);
948 EXPECT_TRUE(model_
->items()[3].type
== TYPE_BROWSER_SHORTCUT
);
950 // Dragging changes model order.
951 dragged_button
= SimulateDrag(ShelfButtonHost::MOUSE
, 1, 3);
952 std::rotate(id_map
.begin() + 1,
955 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
957 // Cancelling the drag operation restores previous order.
958 button_host
->PointerReleasedOnButton(
959 dragged_button
, ShelfButtonHost::MOUSE
, true);
960 std::rotate(id_map
.begin() + 1,
963 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
965 // Deleting an item keeps the remaining intact.
966 dragged_button
= SimulateDrag(ShelfButtonHost::MOUSE
, 1, 3);
967 model_
->RemoveItemAt(1);
968 id_map
.erase(id_map
.begin() + 1);
969 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
970 button_host
->PointerReleasedOnButton(
971 dragged_button
, ShelfButtonHost::MOUSE
, false);
973 // Adding a shelf item cancels the drag and respects the order.
974 dragged_button
= SimulateDrag(ShelfButtonHost::MOUSE
, 1, 3);
975 ShelfID new_id
= AddAppShortcut();
976 id_map
.insert(id_map
.begin() + 6,
977 std::make_pair(new_id
, GetButtonByID(new_id
)));
978 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
979 button_host
->PointerReleasedOnButton(
980 dragged_button
, ShelfButtonHost::MOUSE
, false);
982 // Adding a shelf item at the end (i.e. a panel) canels drag and respects
984 dragged_button
= SimulateDrag(ShelfButtonHost::MOUSE
, 1, 3);
986 id_map
.insert(id_map
.begin() + 7,
987 std::make_pair(new_id
, GetButtonByID(new_id
)));
988 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
989 button_host
->PointerReleasedOnButton(
990 dragged_button
, ShelfButtonHost::MOUSE
, false);
993 // Check that 2nd drag from the other pointer would be ignored.
994 TEST_F(ShelfViewTest
, SimultaneousDrag
) {
995 ShelfButtonHost
* button_host
= shelf_view_
;
997 std::vector
<std::pair
<ShelfID
, views::View
*> > id_map
;
998 SetupForDragTest(&id_map
);
1000 // Start a mouse drag.
1001 views::View
* dragged_button_mouse
=
1002 SimulateDrag(ShelfButtonHost::MOUSE
, 1, 3);
1003 std::rotate(id_map
.begin() + 1,
1005 id_map
.begin() + 4);
1006 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
1007 // Attempt a touch drag before the mouse drag finishes.
1008 views::View
* dragged_button_touch
=
1009 SimulateDrag(ShelfButtonHost::TOUCH
, 4, 2);
1011 // Nothing changes since 2nd drag is ignored.
1012 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
1014 // Finish the mouse drag.
1015 button_host
->PointerReleasedOnButton(
1016 dragged_button_mouse
, ShelfButtonHost::MOUSE
, false);
1017 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
1019 // Now start a touch drag.
1020 dragged_button_touch
= SimulateDrag(ShelfButtonHost::TOUCH
, 4, 2);
1021 std::rotate(id_map
.begin() + 3,
1023 id_map
.begin() + 5);
1024 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
1026 // And attempt a mouse drag before the touch drag finishes.
1027 dragged_button_mouse
= SimulateDrag(ShelfButtonHost::MOUSE
, 1, 2);
1029 // Nothing changes since 2nd drag is ignored.
1030 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
1032 button_host
->PointerReleasedOnButton(
1033 dragged_button_touch
, ShelfButtonHost::TOUCH
, false);
1034 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
1037 // Check that clicking first on one item and then dragging another works as
1039 TEST_F(ShelfViewTest
, ClickOneDragAnother
) {
1040 ShelfButtonHost
* button_host
= shelf_view_
;
1042 std::vector
<std::pair
<ShelfID
, views::View
*> > id_map
;
1043 SetupForDragTest(&id_map
);
1045 // A click on item 1 is simulated.
1046 SimulateClick(ShelfButtonHost::MOUSE
, 1);
1048 // Dragging browser index at 0 should change the model order correctly.
1049 EXPECT_TRUE(model_
->items()[1].type
== TYPE_BROWSER_SHORTCUT
);
1050 views::View
* dragged_button
= SimulateDrag(ShelfButtonHost::MOUSE
, 1, 3);
1051 std::rotate(id_map
.begin() + 1,
1053 id_map
.begin() + 4);
1054 ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map
));
1055 button_host
->PointerReleasedOnButton(
1056 dragged_button
, ShelfButtonHost::MOUSE
, false);
1057 EXPECT_TRUE(model_
->items()[3].type
== TYPE_BROWSER_SHORTCUT
);
1060 // Check that clicking an item and jittering the mouse a bit still selects the
1062 TEST_F(ShelfViewTest
, ClickAndMoveSlightly
) {
1063 std::vector
<std::pair
<ShelfID
, views::View
*> > id_map
;
1064 SetupForDragTest(&id_map
);
1066 ShelfID shelf_id
= (id_map
.begin() + 1)->first
;
1067 views::View
* button
= (id_map
.begin() + 1)->second
;
1069 // Replace the ShelfItemDelegate for |shelf_id| with one which tracks whether
1070 // the shelf item gets selected.
1071 ShelfItemSelectionTracker
* selection_tracker
= new ShelfItemSelectionTracker
;
1072 item_manager_
->SetShelfItemDelegate(
1074 scoped_ptr
<ShelfItemDelegate
>(selection_tracker
).Pass());
1076 gfx::Vector2d
press_offset(5, 30);
1077 gfx::Point press_location
= gfx::Point() + press_offset
;
1078 gfx::Point press_location_in_screen
=
1079 button
->GetBoundsInScreen().origin() + press_offset
;
1081 ui::MouseEvent
click_event(ui::ET_MOUSE_PRESSED
,
1083 press_location_in_screen
,
1084 ui::EF_LEFT_MOUSE_BUTTON
, 0);
1085 button
->OnMousePressed(click_event
);
1087 ui::MouseEvent
drag_event1(ui::ET_MOUSE_DRAGGED
,
1088 press_location
+ gfx::Vector2d(0, 1),
1089 press_location_in_screen
+ gfx::Vector2d(0, 1),
1090 ui::EF_LEFT_MOUSE_BUTTON
, 0);
1091 button
->OnMouseDragged(drag_event1
);
1093 ui::MouseEvent
drag_event2(ui::ET_MOUSE_DRAGGED
,
1094 press_location
+ gfx::Vector2d(-1, 0),
1095 press_location_in_screen
+ gfx::Vector2d(-1, 0),
1096 ui::EF_LEFT_MOUSE_BUTTON
, 0);
1097 button
->OnMouseDragged(drag_event2
);
1099 ui::MouseEvent
release_event(ui::ET_MOUSE_RELEASED
,
1100 press_location
+ gfx::Vector2d(-1, 0),
1101 press_location_in_screen
+ gfx::Vector2d(-1, 0),
1102 ui::EF_LEFT_MOUSE_BUTTON
, 0);
1103 button
->OnMouseReleased(release_event
);
1105 EXPECT_TRUE(selection_tracker
->WasSelected());
1108 // Confirm that item status changes are reflected in the buttons.
1109 TEST_F(ShelfViewTest
, ShelfItemStatus
) {
1110 // All buttons should be visible.
1111 ASSERT_EQ(test_api_
->GetButtonCount(),
1112 test_api_
->GetLastVisibleIndex() + 1);
1114 // Add platform app button.
1115 ShelfID last_added
= AddPlatformApp();
1116 ShelfItem item
= GetItemByID(last_added
);
1117 int index
= model_
->ItemIndexByID(last_added
);
1118 ShelfButton
* button
= GetButtonByID(last_added
);
1119 ASSERT_EQ(ShelfButton::STATE_RUNNING
, button
->state());
1120 item
.status
= STATUS_ACTIVE
;
1121 model_
->Set(index
, item
);
1122 ASSERT_EQ(ShelfButton::STATE_ACTIVE
, button
->state());
1123 item
.status
= STATUS_ATTENTION
;
1124 model_
->Set(index
, item
);
1125 ASSERT_EQ(ShelfButton::STATE_ATTENTION
, button
->state());
1128 // Confirm that item status changes are reflected in the buttons
1129 // for platform apps.
1130 TEST_F(ShelfViewTest
, ShelfItemStatusPlatformApp
) {
1131 // All buttons should be visible.
1132 ASSERT_EQ(test_api_
->GetButtonCount(),
1133 test_api_
->GetLastVisibleIndex() + 1);
1135 // Add platform app button.
1136 ShelfID last_added
= AddPlatformApp();
1137 ShelfItem item
= GetItemByID(last_added
);
1138 int index
= model_
->ItemIndexByID(last_added
);
1139 ShelfButton
* button
= GetButtonByID(last_added
);
1140 ASSERT_EQ(ShelfButton::STATE_RUNNING
, button
->state());
1141 item
.status
= STATUS_ACTIVE
;
1142 model_
->Set(index
, item
);
1143 ASSERT_EQ(ShelfButton::STATE_ACTIVE
, button
->state());
1144 item
.status
= STATUS_ATTENTION
;
1145 model_
->Set(index
, item
);
1146 ASSERT_EQ(ShelfButton::STATE_ATTENTION
, button
->state());
1149 // Confirm that shelf item bounds are correctly updated on shelf changes.
1150 TEST_F(ShelfViewTest
, ShelfItemBoundsCheck
) {
1151 VerifyShelfItemBoundsAreValid();
1152 shelf_view_
->shelf_layout_manager()->SetAutoHideBehavior(
1153 SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
1154 test_api_
->RunMessageLoopUntilAnimationsDone();
1155 VerifyShelfItemBoundsAreValid();
1156 shelf_view_
->shelf_layout_manager()->SetAutoHideBehavior(
1157 SHELF_AUTO_HIDE_BEHAVIOR_NEVER
);
1158 test_api_
->RunMessageLoopUntilAnimationsDone();
1159 VerifyShelfItemBoundsAreValid();
1162 TEST_F(ShelfViewTest
, ShelfTooltipTest
) {
1163 ASSERT_EQ(test_api_
->GetLastVisibleIndex() + 1,
1164 test_api_
->GetButtonCount());
1166 // Prepare some items to the shelf.
1167 ShelfID app_button_id
= AddAppShortcut();
1168 ShelfID platform_button_id
= AddPlatformApp();
1170 ShelfButton
* app_button
= GetButtonByID(app_button_id
);
1171 ShelfButton
* platform_button
= GetButtonByID(platform_button_id
);
1173 ShelfButtonHost
* button_host
= shelf_view_
;
1174 ShelfTooltipManager
* tooltip_manager
= shelf_view_
->tooltip_manager();
1176 button_host
->MouseEnteredButton(app_button
);
1177 // There's a delay to show the tooltip, so it's not visible yet.
1178 EXPECT_FALSE(tooltip_manager
->IsVisible());
1179 EXPECT_EQ(app_button
, GetTooltipAnchorView());
1182 EXPECT_TRUE(tooltip_manager
->IsVisible());
1184 // Once it's visible, it keeps visibility and is pointing to the same
1186 button_host
->MouseExitedButton(app_button
);
1187 EXPECT_TRUE(tooltip_manager
->IsVisible());
1188 EXPECT_EQ(app_button
, GetTooltipAnchorView());
1190 // When entered to another item, it switches to the new item. There is no
1191 // delay for the visibility.
1192 button_host
->MouseEnteredButton(platform_button
);
1193 EXPECT_TRUE(tooltip_manager
->IsVisible());
1194 EXPECT_EQ(platform_button
, GetTooltipAnchorView());
1196 button_host
->MouseExitedButton(platform_button
);
1197 tooltip_manager
->Close();
1199 // Next time: enter app_button -> move immediately to tab_button.
1200 button_host
->MouseEnteredButton(app_button
);
1201 button_host
->MouseExitedButton(app_button
);
1202 button_host
->MouseEnteredButton(platform_button
);
1203 EXPECT_FALSE(tooltip_manager
->IsVisible());
1204 EXPECT_EQ(platform_button
, GetTooltipAnchorView());
1207 // Verify a fix for crash caused by a tooltip update for a deletedshelf
1208 // button, see crbug.com/288838.
1209 TEST_F(ShelfViewTest
, RemovingItemClosesTooltip
) {
1210 ShelfButtonHost
* button_host
= shelf_view_
;
1211 ShelfTooltipManager
* tooltip_manager
= shelf_view_
->tooltip_manager();
1213 // Add an item to the shelf.
1214 ShelfID app_button_id
= AddAppShortcut();
1215 ShelfButton
* app_button
= GetButtonByID(app_button_id
);
1217 // Spawn a tooltip on that item.
1218 button_host
->MouseEnteredButton(app_button
);
1220 EXPECT_TRUE(tooltip_manager
->IsVisible());
1222 // Remove the app shortcut while the tooltip is open. The tooltip should be
1224 RemoveByID(app_button_id
);
1225 EXPECT_FALSE(tooltip_manager
->IsVisible());
1227 // Change the shelf layout. This should not crash.
1228 Shell::GetInstance()->SetShelfAlignment(SHELF_ALIGNMENT_LEFT
,
1229 Shell::GetPrimaryRootWindow());
1232 // Changing the shelf alignment closes any open tooltip.
1233 TEST_F(ShelfViewTest
, ShelfAlignmentClosesTooltip
) {
1234 ShelfButtonHost
* button_host
= shelf_view_
;
1235 ShelfTooltipManager
* tooltip_manager
= shelf_view_
->tooltip_manager();
1237 // Add an item to the shelf.
1238 ShelfID app_button_id
= AddAppShortcut();
1239 ShelfButton
* app_button
= GetButtonByID(app_button_id
);
1241 // Spawn a tooltip on the item.
1242 button_host
->MouseEnteredButton(app_button
);
1244 EXPECT_TRUE(tooltip_manager
->IsVisible());
1246 // Changing shelf alignment hides the tooltip.
1247 Shell::GetInstance()->SetShelfAlignment(SHELF_ALIGNMENT_LEFT
,
1248 Shell::GetPrimaryRootWindow());
1249 EXPECT_FALSE(tooltip_manager
->IsVisible());
1252 TEST_F(ShelfViewTest
, ShouldHideTooltipTest
) {
1253 ShelfID app_button_id
= AddAppShortcut();
1254 ShelfID platform_button_id
= AddPlatformApp();
1256 // The tooltip shouldn't hide if the mouse is on normal buttons.
1257 for (int i
= 0; i
< test_api_
->GetButtonCount(); i
++) {
1258 ShelfButton
* button
= test_api_
->GetButton(i
);
1262 EXPECT_FALSE(shelf_view_
->ShouldHideTooltip(
1263 button
->GetMirroredBounds().CenterPoint()))
1264 << "ShelfView tries to hide on button " << i
;
1267 // The tooltip should not hide on the app-list button.
1268 views::View
* app_list_button
= shelf_view_
->GetAppListButtonView();
1269 EXPECT_FALSE(shelf_view_
->ShouldHideTooltip(
1270 app_list_button
->GetMirroredBounds().CenterPoint()));
1272 // The tooltip shouldn't hide if the mouse is in the gap between two buttons.
1273 gfx::Rect app_button_rect
= GetButtonByID(app_button_id
)->GetMirroredBounds();
1274 gfx::Rect platform_button_rect
=
1275 GetButtonByID(platform_button_id
)->GetMirroredBounds();
1276 ASSERT_FALSE(app_button_rect
.Intersects(platform_button_rect
));
1277 EXPECT_FALSE(shelf_view_
->ShouldHideTooltip(
1278 gfx::UnionRects(app_button_rect
, platform_button_rect
).CenterPoint()));
1280 // The tooltip should hide if it's outside of all buttons.
1282 for (int i
= 0; i
< test_api_
->GetButtonCount(); i
++) {
1283 ShelfButton
* button
= test_api_
->GetButton(i
);
1287 all_area
.Union(button
->GetMirroredBounds());
1289 all_area
.Union(shelf_view_
->GetAppListButtonView()->GetMirroredBounds());
1290 EXPECT_FALSE(shelf_view_
->ShouldHideTooltip(all_area
.origin()));
1291 EXPECT_FALSE(shelf_view_
->ShouldHideTooltip(
1292 gfx::Point(all_area
.right() - 1, all_area
.bottom() - 1)));
1293 EXPECT_TRUE(shelf_view_
->ShouldHideTooltip(
1294 gfx::Point(all_area
.right(), all_area
.y())));
1295 EXPECT_TRUE(shelf_view_
->ShouldHideTooltip(
1296 gfx::Point(all_area
.x() - 1, all_area
.y())));
1297 EXPECT_TRUE(shelf_view_
->ShouldHideTooltip(
1298 gfx::Point(all_area
.x(), all_area
.y() - 1)));
1299 EXPECT_TRUE(shelf_view_
->ShouldHideTooltip(
1300 gfx::Point(all_area
.x(), all_area
.bottom())));
1303 TEST_F(ShelfViewTest
, ShouldHideTooltipWithAppListWindowTest
) {
1304 Shell::GetInstance()->ToggleAppList(NULL
);
1305 ASSERT_TRUE(Shell::GetInstance()->GetAppListWindow());
1307 // The tooltip shouldn't hide if the mouse is on normal buttons.
1308 for (int i
= 1; i
< test_api_
->GetButtonCount(); i
++) {
1309 ShelfButton
* button
= test_api_
->GetButton(i
);
1313 EXPECT_FALSE(shelf_view_
->ShouldHideTooltip(
1314 button
->GetMirroredBounds().CenterPoint()))
1315 << "ShelfView tries to hide on button " << i
;
1318 // The tooltip should hide on the app-list button.
1319 views::View
* app_list_button
= shelf_view_
->GetAppListButtonView();
1320 EXPECT_TRUE(shelf_view_
->ShouldHideTooltip(
1321 app_list_button
->GetMirroredBounds().CenterPoint()));
1324 // Test that by moving the mouse cursor off the button onto the bubble it closes
1326 TEST_F(ShelfViewTest
, ShouldHideTooltipWhenHoveringOnTooltip
) {
1327 ShelfTooltipManager
* tooltip_manager
= shelf_view_
->tooltip_manager();
1328 tooltip_manager
->CreateZeroDelayTimerForTest();
1329 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow());
1331 // Move the mouse off any item and check that no tooltip is shown.
1332 generator
.MoveMouseTo(gfx::Point(0, 0));
1333 EXPECT_FALSE(tooltip_manager
->IsVisible());
1335 // Move the mouse over the button and check that it is visible.
1336 views::View
* app_list_button
= shelf_view_
->GetAppListButtonView();
1337 gfx::Rect bounds
= app_list_button
->GetBoundsInScreen();
1338 generator
.MoveMouseTo(bounds
.CenterPoint());
1339 // Wait for the timer to go off.
1340 RunAllPendingInMessageLoop();
1341 EXPECT_TRUE(tooltip_manager
->IsVisible());
1343 // Move the mouse cursor slightly to the right of the item. The tooltip should
1345 generator
.MoveMouseBy(bounds
.width() / 2 + 5, 0);
1346 // Make sure there is no delayed close.
1347 RunAllPendingInMessageLoop();
1348 EXPECT_TRUE(tooltip_manager
->IsVisible());
1350 // Move back - it should still stay open.
1351 generator
.MoveMouseBy(-(bounds
.width() / 2 + 5), 0);
1352 // Make sure there is no delayed close.
1353 RunAllPendingInMessageLoop();
1354 EXPECT_TRUE(tooltip_manager
->IsVisible());
1356 // Now move the mouse cursor slightly above the item - so that it is over the
1357 // tooltip bubble. Now it should disappear.
1358 generator
.MoveMouseBy(0, -(bounds
.height() / 2 + 5));
1359 // Wait until the delayed close kicked in.
1360 RunAllPendingInMessageLoop();
1361 EXPECT_FALSE(tooltip_manager
->IsVisible());
1364 // Resizing shelf view while an add animation without fade-in is running,
1365 // which happens when overflow happens. App list button should end up in its
1366 // new ideal bounds.
1367 TEST_F(ShelfViewTest
, ResizeDuringOverflowAddAnimation
) {
1368 // All buttons should be visible.
1369 ASSERT_EQ(test_api_
->GetButtonCount(),
1370 test_api_
->GetLastVisibleIndex() + 1);
1372 // Add buttons until overflow. Let the non-overflow add animations finish but
1373 // leave the last running.
1374 int items_added
= 0;
1375 AddPlatformAppNoWait();
1376 while (!test_api_
->IsOverflowButtonVisible()) {
1377 test_api_
->RunMessageLoopUntilAnimationsDone();
1378 AddPlatformAppNoWait();
1380 ASSERT_LT(items_added
, 10000);
1383 // Resize shelf view with that animation running and stay overflown.
1384 gfx::Rect bounds
= shelf_view_
->bounds();
1385 bounds
.set_width(bounds
.width() - kShelfSize
);
1386 shelf_view_
->SetBoundsRect(bounds
);
1387 ASSERT_TRUE(test_api_
->IsOverflowButtonVisible());
1389 // Finish the animation.
1390 test_api_
->RunMessageLoopUntilAnimationsDone();
1392 // App list button should ends up in its new ideal bounds.
1393 const int app_list_button_index
= test_api_
->GetButtonCount() - 1;
1394 const gfx::Rect
& app_list_ideal_bounds
=
1395 test_api_
->GetIdealBoundsByIndex(app_list_button_index
);
1396 const gfx::Rect
& app_list_bounds
=
1397 test_api_
->GetBoundsByIndex(app_list_button_index
);
1398 EXPECT_EQ(app_list_ideal_bounds
, app_list_bounds
);
1401 // Checks the overflow bubble size when an item is ripped off and re-inserted.
1402 TEST_F(ShelfViewTest
, OverflowBubbleSize
) {
1403 // Replace current ShelfDelegate with TestShelfDelegateForShelfView.
1404 ReplaceShelfDelegateForRipOffTest();
1406 AddButtonsUntilOverflow();
1408 // Show overflow bubble.
1409 test_api_
->ShowOverflowBubble();
1410 ASSERT_TRUE(test_api_
->overflow_bubble() &&
1411 test_api_
->overflow_bubble()->IsShowing());
1413 ShelfViewTestAPI
test_for_overflow_view(
1414 test_api_
->overflow_bubble()->shelf_view());
1416 int ripped_index
= test_for_overflow_view
.GetLastVisibleIndex();
1417 gfx::Size bubble_size
= test_for_overflow_view
.GetPreferredSize();
1418 int item_width
= test_for_overflow_view
.GetButtonSize() +
1419 test_for_overflow_view
.GetButtonSpacing();
1421 aura::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
1423 ShelfButton
* button
= test_for_overflow_view
.GetButton(ripped_index
);
1424 // Rip off the last visible item.
1425 gfx::Point start_point
= button
->GetBoundsInScreen().CenterPoint();
1426 gfx::Point
rip_off_point(start_point
.x(), 0);
1427 generator
.MoveMouseTo(start_point
.x(), start_point
.y());
1428 base::MessageLoop::current()->RunUntilIdle();
1429 generator
.PressLeftButton();
1430 base::MessageLoop::current()->RunUntilIdle();
1431 generator
.MoveMouseTo(rip_off_point
.x(), rip_off_point
.y());
1432 base::MessageLoop::current()->RunUntilIdle();
1433 test_for_overflow_view
.RunMessageLoopUntilAnimationsDone();
1435 // Check the overflow bubble size when an item is ripped off.
1436 EXPECT_EQ(bubble_size
.width() - item_width
,
1437 test_for_overflow_view
.GetPreferredSize().width());
1438 ASSERT_TRUE(test_api_
->overflow_bubble() &&
1439 test_api_
->overflow_bubble()->IsShowing());
1441 // Re-insert an item into the overflow bubble.
1442 int first_index
= test_for_overflow_view
.GetFirstVisibleIndex();
1443 button
= test_for_overflow_view
.GetButton(first_index
);
1445 // Check the bubble size after an item is re-inserted.
1446 generator
.MoveMouseTo(button
->GetBoundsInScreen().CenterPoint());
1447 test_for_overflow_view
.RunMessageLoopUntilAnimationsDone();
1448 EXPECT_EQ(bubble_size
.width(),
1449 test_for_overflow_view
.GetPreferredSize().width());
1451 generator
.ReleaseLeftButton();
1452 test_for_overflow_view
.RunMessageLoopUntilAnimationsDone();
1453 EXPECT_EQ(bubble_size
.width(),
1454 test_for_overflow_view
.GetPreferredSize().width());
1457 // Check the drag insertion bounds of scrolled overflow bubble.
1458 TEST_F(ShelfViewTest
, CheckDragInsertBoundsOfScrolledOverflowBubble
) {
1459 UpdateDisplay("400x300");
1461 EXPECT_EQ(2, model_
->item_count());
1463 AddButtonsUntilOverflow();
1465 // Show overflow bubble.
1466 test_api_
->ShowOverflowBubble();
1467 ASSERT_TRUE(test_api_
->overflow_bubble() &&
1468 test_api_
->overflow_bubble()->IsShowing());
1470 int item_width
= test_api_
->GetButtonSize() +
1471 test_api_
->GetButtonSpacing();
1472 OverflowBubbleView
* bubble_view
= test_api_
->overflow_bubble()->bubble_view();
1473 test::OverflowBubbleViewTestAPI
bubble_view_api(bubble_view
);
1475 // Add more buttons until OverflowBubble is scrollable and it has 3 invisible
1477 while (bubble_view_api
.GetContentsSize().width() <
1478 (bubble_view
->GetContentsBounds().width() + 3 * item_width
))
1481 ASSERT_TRUE(test_api_
->overflow_bubble() &&
1482 test_api_
->overflow_bubble()->IsShowing());
1484 ShelfViewTestAPI
test_for_overflow_view(
1485 test_api_
->overflow_bubble()->shelf_view());
1486 int first_index
= test_for_overflow_view
.GetFirstVisibleIndex();
1487 int last_index
= test_for_overflow_view
.GetLastVisibleIndex();
1489 ShelfButton
* first_button
= test_for_overflow_view
.GetButton(first_index
);
1490 ShelfButton
* last_button
= test_for_overflow_view
.GetButton(last_index
);
1491 gfx::Point first_point
= first_button
->GetBoundsInScreen().CenterPoint();
1492 gfx::Point last_point
= last_button
->GetBoundsInScreen().CenterPoint();
1493 gfx::Rect drag_reinsert_bounds
=
1494 test_for_overflow_view
.GetBoundsForDragInsertInScreen();
1495 EXPECT_TRUE(drag_reinsert_bounds
.Contains(first_point
));
1496 EXPECT_FALSE(drag_reinsert_bounds
.Contains(last_point
));
1498 // Scrolls sufficiently to show last item.
1499 bubble_view_api
.ScrollByXOffset(3 * item_width
);
1500 drag_reinsert_bounds
=
1501 test_for_overflow_view
.GetBoundsForDragInsertInScreen();
1502 first_point
= first_button
->GetBoundsInScreen().CenterPoint();
1503 last_point
= last_button
->GetBoundsInScreen().CenterPoint();
1504 EXPECT_FALSE(drag_reinsert_bounds
.Contains(first_point
));
1505 EXPECT_TRUE(drag_reinsert_bounds
.Contains(last_point
));
1508 // Check the drag insertion bounds of shelf view in multi monitor environment.
1509 TEST_F(ShelfViewTest
, CheckDragInsertBoundsWithMultiMonitor
) {
1510 // win8-aura doesn't support multiple display.
1511 if (!SupportsMultipleDisplays())
1514 UpdateDisplay("800x600,800x600");
1515 Shelf
* secondary_shelf
= Shelf::ForWindow(Shell::GetAllRootWindows()[1]);
1516 ShelfView
* shelf_view_for_secondary
=
1517 ShelfTestAPI(secondary_shelf
).shelf_view();
1519 // The bounds should be big enough for 4 buttons + overflow chevron.
1520 shelf_view_for_secondary
->SetBounds(0, 0, 500, kShelfSize
);
1522 ShelfViewTestAPI
test_api_for_secondary(shelf_view_for_secondary
);
1523 // Speeds up animation for test.
1524 test_api_for_secondary
.SetAnimationDuration(1);
1526 AddButtonsUntilOverflow();
1528 // Test #1: Test drag insertion bounds of primary shelf.
1529 // Show overflow bubble.
1530 test_api_
->ShowOverflowBubble();
1531 ASSERT_TRUE(test_api_
->overflow_bubble() &&
1532 test_api_
->overflow_bubble()->IsShowing());
1534 ShelfViewTestAPI
test_api_for_overflow_view(
1535 test_api_
->overflow_bubble()->shelf_view());
1537 ShelfButton
* button
= test_api_for_overflow_view
.GetButton(
1538 test_api_for_overflow_view
.GetLastVisibleIndex());
1540 // Checks that a point in shelf is contained in drag insert bounds.
1541 gfx::Point point_in_shelf_view
= button
->GetBoundsInScreen().CenterPoint();
1542 gfx::Rect drag_reinsert_bounds
=
1543 test_api_for_overflow_view
.GetBoundsForDragInsertInScreen();
1544 EXPECT_TRUE(drag_reinsert_bounds
.Contains(point_in_shelf_view
));
1545 // Checks that a point out of shelf is not contained in drag insert bounds.
1546 EXPECT_FALSE(drag_reinsert_bounds
.Contains(
1547 gfx::Point(point_in_shelf_view
.x(), 0)));
1549 // Test #2: Test drag insertion bounds of secondary shelf.
1550 // Show overflow bubble.
1551 test_api_for_secondary
.ShowOverflowBubble();
1552 ASSERT_TRUE(test_api_for_secondary
.overflow_bubble() &&
1553 test_api_for_secondary
.overflow_bubble()->IsShowing());
1555 ShelfViewTestAPI
test_api_for_overflow_view_of_secondary(
1556 test_api_for_secondary
.overflow_bubble()->shelf_view());
1558 ShelfButton
* button_in_secondary
=
1559 test_api_for_overflow_view_of_secondary
.GetButton(
1560 test_api_for_overflow_view_of_secondary
.GetLastVisibleIndex());
1562 // Checks that a point in shelf is contained in drag insert bounds.
1563 gfx::Point point_in_secondary_shelf_view
=
1564 button_in_secondary
->GetBoundsInScreen().CenterPoint();
1565 gfx::Rect drag_reinsert_bounds_in_secondary
=
1566 test_api_for_overflow_view_of_secondary
.GetBoundsForDragInsertInScreen();
1567 EXPECT_TRUE(drag_reinsert_bounds_in_secondary
.Contains(
1568 point_in_secondary_shelf_view
));
1569 // Checks that a point out of shelf is not contained in drag insert bounds.
1570 EXPECT_FALSE(drag_reinsert_bounds_in_secondary
.Contains(
1571 gfx::Point(point_in_secondary_shelf_view
.x(), 0)));
1572 // Checks that a point of overflow bubble in primary shelf should not be
1573 // contained by insert bounds of secondary shelf.
1574 EXPECT_FALSE(drag_reinsert_bounds_in_secondary
.Contains(point_in_shelf_view
));
1577 // Checks the rip an item off from left aligned shelf in secondary monitor.
1578 TEST_F(ShelfViewTest
, CheckRipOffFromLeftShelfAlignmentWithMultiMonitor
) {
1579 // win8-aura doesn't support multiple display.
1580 if (!SupportsMultipleDisplays())
1583 UpdateDisplay("800x600,800x600");
1584 ASSERT_EQ(2U, Shell::GetAllRootWindows().size());
1586 aura::Window
* second_root
= Shell::GetAllRootWindows()[1];
1588 Shell::GetInstance()->SetShelfAlignment(SHELF_ALIGNMENT_LEFT
, second_root
);
1589 ASSERT_EQ(SHELF_ALIGNMENT_LEFT
,
1590 Shell::GetInstance()->GetShelfAlignment(second_root
));
1592 // Initially, app list and browser shortcut are added.
1593 EXPECT_EQ(2, model_
->item_count());
1594 int browser_index
= model_
->GetItemIndexForType(TYPE_BROWSER_SHORTCUT
);
1595 EXPECT_GT(browser_index
, 0);
1597 Shelf
* secondary_shelf
= Shelf::ForWindow(second_root
);
1598 ShelfView
* shelf_view_for_secondary
=
1599 ShelfTestAPI(secondary_shelf
).shelf_view();
1601 ShelfViewTestAPI
test_api_for_secondary_shelf_view(shelf_view_for_secondary
);
1602 ShelfButton
* button
=
1603 test_api_for_secondary_shelf_view
.GetButton(browser_index
);
1605 // Fetch the start point of dragging.
1606 gfx::Point start_point
= button
->GetBoundsInScreen().CenterPoint();
1607 wm::ConvertPointFromScreen(second_root
, &start_point
);
1609 aura::test::EventGenerator
generator(second_root
, start_point
);
1611 // Rip off the browser item.
1612 generator
.PressLeftButton();
1613 generator
.MoveMouseTo(start_point
.x() + 400, start_point
.y());
1614 test_api_for_secondary_shelf_view
.RunMessageLoopUntilAnimationsDone();
1615 EXPECT_TRUE(test_api_for_secondary_shelf_view
.IsRippedOffFromShelf());
1618 // Checks various drag and drop operations from OverflowBubble to Shelf.
1619 TEST_F(ShelfViewTest
, CheckDragAndDropFromOverflowBubbleToShelf
) {
1620 // Replace current ShelfDelegate with TestShelfDelegateForShelfView.
1621 ReplaceShelfDelegateForRipOffTest();
1623 AddButtonsUntilOverflow();
1625 TestDraggingAnItemFromOverflowToShelf(false);
1626 TestDraggingAnItemFromOverflowToShelf(true);
1629 class ShelfViewVisibleBoundsTest
: public ShelfViewTest
,
1630 public testing::WithParamInterface
<bool> {
1632 ShelfViewVisibleBoundsTest() : text_direction_change_(GetParam()) {}
1634 void CheckAllItemsAreInBounds() {
1635 gfx::Rect visible_bounds
= shelf_view_
->GetVisibleItemsBoundsInScreen();
1636 gfx::Rect shelf_bounds
= shelf_view_
->GetBoundsInScreen();
1637 EXPECT_TRUE(shelf_bounds
.Contains(visible_bounds
));
1638 for (int i
= 0; i
< test_api_
->GetButtonCount(); ++i
)
1639 if (ShelfButton
* button
= test_api_
->GetButton(i
))
1640 EXPECT_TRUE(visible_bounds
.Contains(button
->GetBoundsInScreen()));
1641 CheckAppListButtonIsInBounds();
1644 void CheckAppListButtonIsInBounds() {
1645 gfx::Rect visible_bounds
= shelf_view_
->GetVisibleItemsBoundsInScreen();
1646 gfx::Rect app_list_button_bounds
= shelf_view_
->GetAppListButtonView()->
1647 GetBoundsInScreen();
1648 EXPECT_TRUE(visible_bounds
.Contains(app_list_button_bounds
));
1652 ScopedTextDirectionChange text_direction_change_
;
1654 DISALLOW_COPY_AND_ASSIGN(ShelfViewVisibleBoundsTest
);
1657 TEST_P(ShelfViewVisibleBoundsTest
, ItemsAreInBounds
) {
1658 // Adding elements leaving some empty space.
1659 for (int i
= 0; i
< 3; i
++) {
1662 test_api_
->RunMessageLoopUntilAnimationsDone();
1663 EXPECT_FALSE(test_api_
->IsOverflowButtonVisible());
1664 CheckAllItemsAreInBounds();
1665 // Same for overflow case.
1666 while (!test_api_
->IsOverflowButtonVisible()) {
1669 test_api_
->RunMessageLoopUntilAnimationsDone();
1670 CheckAllItemsAreInBounds();
1673 INSTANTIATE_TEST_CASE_P(LtrRtl
, ShelfViewTextDirectionTest
, testing::Bool());
1674 INSTANTIATE_TEST_CASE_P(VisibleBounds
, ShelfViewVisibleBoundsTest
,