bookmark_bar_view_test.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
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.
4
5#include "base/bind.h"
6#include "base/callback.h"
7#include "base/compiler_specific.h"
8#include "base/prefs/pref_service.h"
9#include "base/strings/string_number_conversions.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/app/chrome_command_ids.h"
12#include "chrome/browser/bookmarks/bookmark_model.h"
13#include "chrome/browser/bookmarks/bookmark_model_factory.h"
14#include "chrome/browser/chrome_notification_types.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
17#include "chrome/browser/ui/browser.h"
18#include "chrome/browser/ui/browser_tabstrip.h"
19#include "chrome/browser/ui/browser_window.h"
20#include "chrome/browser/ui/tabs/tab_strip_model.h"
21#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
22#include "chrome/browser/ui/views/chrome_views_delegate.h"
23#include "chrome/common/pref_names.h"
24#include "chrome/test/base/interactive_test_utils.h"
25#include "chrome/test/base/scoped_testing_local_state.h"
26#include "chrome/test/base/test_browser_window.h"
27#include "chrome/test/base/testing_browser_process.h"
28#include "chrome/test/base/testing_profile.h"
29#include "chrome/test/base/ui_test_utils.h"
30#include "chrome/test/base/view_event_test_base.h"
31#include "content/public/browser/notification_service.h"
32#include "content/public/browser/page_navigator.h"
33#include "content/public/test/test_browser_thread.h"
34#include "grit/generated_resources.h"
35#include "ui/base/accessibility/accessibility_types.h"
36#include "ui/base/clipboard/clipboard.h"
37#include "ui/base/keycodes/keyboard_codes.h"
38#include "ui/base/test/ui_controls.h"
39#include "ui/views/controls/button/menu_button.h"
40#include "ui/views/controls/button/text_button.h"
41#include "ui/views/controls/menu/menu_controller.h"
42#include "ui/views/controls/menu/menu_item_view.h"
43#include "ui/views/controls/menu/submenu_view.h"
44#include "ui/views/widget/widget.h"
45
46using content::BrowserThread;
47using content::OpenURLParams;
48using content::PageNavigator;
49using content::WebContents;
50
51namespace {
52
53void MoveMouseAndPress(const gfx::Point& screen_pos,
54                       ui_controls::MouseButton button,
55                       int state,
56                       const base::Closure& closure) {
57  ui_controls::SendMouseMove(screen_pos.x(), screen_pos.y());
58  ui_controls::SendMouseEventsNotifyWhenDone(button, state, closure);
59}
60
61// PageNavigator implementation that records the URL.
62class TestingPageNavigator : public PageNavigator {
63 public:
64  virtual WebContents* OpenURL(const OpenURLParams& params) OVERRIDE {
65    url_ = params.url;
66    return NULL;
67  }
68
69  GURL url_;
70};
71
72// TODO(jschuh): Fix bookmark DND tests on Win64. crbug.com/244605
73#if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
74#define MAYBE(x) DISABLED_##x
75#else
76#define MAYBE(x) x
77#endif
78
79}  // namespace
80
81// Base class for event generating bookmark view tests. These test are intended
82// to exercise View's menus, but that's easier done with BookmarkBarView rather
83// than View's menu itself.
84//
85// SetUp creates a bookmark model with the following structure.
86// All folders are in upper case, all URLs in lower case.
87// F1
88//   f1a
89//   F11
90//     f11a
91//   *
92// a
93// b
94// c
95// d
96// F2
97// e
98// OTHER
99//   oa
100//   OF
101//     ofa
102//     ofb
103//   OF2
104//     of2a
105//     of2b
106//
107// * if CreateBigMenu returns return true, 100 menu items are created here with
108//   the names f1-f100.
109//
110// Subclasses should be sure and invoke super's implementation of SetUp and
111// TearDown.
112class BookmarkBarViewEventTestBase : public ViewEventTestBase {
113 public:
114  BookmarkBarViewEventTestBase()
115      : ViewEventTestBase(),
116        model_(NULL) {}
117
118  virtual void SetUp() OVERRIDE {
119    views::MenuController::TurnOffMenuSelectionHoldForTest();
120    BookmarkBarView::DisableAnimationsForTesting(true);
121
122    profile_.reset(new TestingProfile());
123    profile_->CreateBookmarkModel(true);
124    model_ = BookmarkModelFactory::GetForProfile(profile_.get());
125    ui_test_utils::WaitForBookmarkModelToLoad(model_);
126    profile_->GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, true);
127
128    Browser::CreateParams native_params(profile_.get(),
129                                        chrome::GetActiveDesktop());
130    browser_.reset(
131        chrome::CreateBrowserWithTestWindowForParams(&native_params));
132
133    local_state_.reset(new ScopedTestingLocalState(
134        TestingBrowserProcess::GetGlobal()));
135    model_->ClearStore();
136
137    bb_view_.reset(new BookmarkBarView(browser_.get(), NULL));
138    bb_view_->set_owned_by_client();
139    bb_view_->SetPageNavigator(&navigator_);
140
141    AddTestData(CreateBigMenu());
142
143    // Calculate the preferred size so that one button doesn't fit, which
144    // triggers the overflow button to appear.
145    //
146    // BookmarkBarView::Layout does nothing if the parent is NULL and
147    // GetPreferredSize hard codes a width of 1. For that reason we add the
148    // BookmarkBarView to a dumby view as the parent.
149    //
150    // This code looks a bit hacky, but I've written it so that it shouldn't
151    // be dependant upon any of the layout code in BookmarkBarView. Instead
152    // we brute force search for a size that triggers the overflow button.
153    views::View tmp_parent;
154
155    tmp_parent.AddChildView(bb_view_.get());
156
157    bb_view_pref_ = bb_view_->GetPreferredSize();
158    bb_view_pref_.set_width(1000);
159    views::TextButton* button = GetBookmarkButton(6);
160    while (button->visible()) {
161      bb_view_pref_.set_width(bb_view_pref_.width() - 25);
162      bb_view_->SetBounds(0, 0, bb_view_pref_.width(), bb_view_pref_.height());
163      bb_view_->Layout();
164    }
165
166    tmp_parent.RemoveChildView(bb_view_.get());
167
168    views::ViewsDelegate::views_delegate = &views_delegate_;
169    ViewEventTestBase::SetUp();
170  }
171
172  virtual void TearDown() {
173    // Destroy everything, then run the message loop to ensure we delete all
174    // Tasks and fully shut down.
175    browser_->tab_strip_model()->CloseAllTabs();
176    bb_view_.reset();
177    browser_.reset();
178    profile_.reset();
179
180    // Run the message loop to ensure we delete allTasks and fully shut down.
181    base::MessageLoop::current()->PostTask(FROM_HERE,
182                                           base::MessageLoop::QuitClosure());
183    base::MessageLoop::current()->Run();
184
185    ViewEventTestBase::TearDown();
186    BookmarkBarView::DisableAnimationsForTesting(false);
187    views::ViewsDelegate::views_delegate = NULL;
188  }
189
190 protected:
191  virtual views::View* CreateContentsView() OVERRIDE {
192    return bb_view_.get();
193  }
194
195  virtual gfx::Size GetPreferredSize() OVERRIDE { return bb_view_pref_; }
196
197  views::TextButton* GetBookmarkButton(int view_index) {
198    return bb_view_->GetBookmarkButton(view_index);
199  }
200
201  // See comment above class description for what this does.
202  virtual bool CreateBigMenu() { return false; }
203
204  BookmarkModel* model_;
205  scoped_ptr<BookmarkBarView> bb_view_;
206  TestingPageNavigator navigator_;
207
208 private:
209  void AddTestData(bool big_menu) {
210    const BookmarkNode* bb_node = model_->bookmark_bar_node();
211    std::string test_base = "file:///c:/tmp/";
212    const BookmarkNode* f1 = model_->AddFolder(bb_node, 0, ASCIIToUTF16("F1"));
213    model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a"));
214    const BookmarkNode* f11 = model_->AddFolder(f1, 1, ASCIIToUTF16("F11"));
215    model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a"));
216    if (big_menu) {
217      for (int i = 1; i <= 100; ++i) {
218        model_->AddURL(f1, i + 1, ASCIIToUTF16("f") + base::IntToString16(i),
219                       GURL(test_base + "f" + base::IntToString(i)));
220      }
221    }
222    model_->AddURL(bb_node, 1, ASCIIToUTF16("a"), GURL(test_base + "a"));
223    model_->AddURL(bb_node, 2, ASCIIToUTF16("b"), GURL(test_base + "b"));
224    model_->AddURL(bb_node, 3, ASCIIToUTF16("c"), GURL(test_base + "c"));
225    model_->AddURL(bb_node, 4, ASCIIToUTF16("d"), GURL(test_base + "d"));
226    model_->AddFolder(bb_node, 5, ASCIIToUTF16("F2"));
227    model_->AddURL(bb_node, 6, ASCIIToUTF16("d"), GURL(test_base + "d"));
228
229    model_->AddURL(model_->other_node(), 0, ASCIIToUTF16("oa"),
230                   GURL(test_base + "oa"));
231    const BookmarkNode* of = model_->AddFolder(model_->other_node(), 1,
232                                               ASCIIToUTF16("OF"));
233    model_->AddURL(of, 0, ASCIIToUTF16("ofa"), GURL(test_base + "ofa"));
234    model_->AddURL(of, 1, ASCIIToUTF16("ofb"), GURL(test_base + "ofb"));
235    const BookmarkNode* of2 = model_->AddFolder(model_->other_node(), 2,
236                                                ASCIIToUTF16("OF2"));
237    model_->AddURL(of2, 0, ASCIIToUTF16("of2a"), GURL(test_base + "of2a"));
238    model_->AddURL(of2, 1, ASCIIToUTF16("of2b"), GURL(test_base + "of2b"));
239  }
240
241  gfx::Size bb_view_pref_;
242  scoped_ptr<TestingProfile> profile_;
243  scoped_ptr<Browser> browser_;
244  scoped_ptr<ScopedTestingLocalState> local_state_;
245  ChromeViewsDelegate views_delegate_;
246};
247
248// Clicks on first menu, makes sure button is depressed. Moves mouse to first
249// child, clicks it and makes sure a navigation occurs.
250class BookmarkBarViewTest1 : public BookmarkBarViewEventTestBase {
251 protected:
252  virtual void DoTestOnMessageLoop() OVERRIDE {
253    // Move the mouse to the first folder on the bookmark bar and press the
254    // mouse.
255    views::TextButton* button = GetBookmarkButton(0);
256    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
257        ui_controls::DOWN | ui_controls::UP,
258        CreateEventTask(this, &BookmarkBarViewTest1::Step2));
259  }
260
261 private:
262  void Step2() {
263    // Menu should be showing.
264    views::MenuItemView* menu = bb_view_->GetMenu();
265    ASSERT_TRUE(menu != NULL);
266    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
267
268    // Button should be depressed.
269    views::TextButton* button = GetBookmarkButton(0);
270    ASSERT_TRUE(button->state() == views::CustomButton::STATE_PRESSED);
271
272    // Click on the 2nd menu item (A URL).
273    ASSERT_TRUE(menu->GetSubmenu());
274
275    views::MenuItemView* menu_to_select =
276        menu->GetSubmenu()->GetMenuItemAt(0);
277    ui_test_utils::MoveMouseToCenterAndPress(menu_to_select, ui_controls::LEFT,
278        ui_controls::DOWN | ui_controls::UP,
279        CreateEventTask(this, &BookmarkBarViewTest1::Step3));
280  }
281
282  void Step3() {
283    // We should have navigated to URL f1a.
284    ASSERT_TRUE(navigator_.url_ ==
285                model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url());
286
287    // Make sure button is no longer pushed.
288    views::TextButton* button = GetBookmarkButton(0);
289    ASSERT_TRUE(button->state() == views::CustomButton::STATE_NORMAL);
290
291    views::MenuItemView* menu = bb_view_->GetMenu();
292    ASSERT_TRUE(menu == NULL || !menu->GetSubmenu()->IsShowing());
293
294    Done();
295  }
296};
297
298VIEW_TEST(BookmarkBarViewTest1, Basic)
299
300// Brings up menu, clicks on empty space and make sure menu hides.
301class BookmarkBarViewTest2 : public BookmarkBarViewEventTestBase {
302 protected:
303  virtual void DoTestOnMessageLoop() OVERRIDE {
304    // Move the mouse to the first folder on the bookmark bar and press the
305    // mouse.
306    views::TextButton* button = GetBookmarkButton(0);
307    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
308        ui_controls::DOWN | ui_controls::UP,
309        CreateEventTask(this, &BookmarkBarViewTest2::Step2));
310  }
311
312 private:
313  void Step2() {
314    // Menu should be showing.
315    views::MenuItemView* menu = bb_view_->GetMenu();
316    ASSERT_TRUE(menu != NULL && menu->GetSubmenu()->IsShowing());
317
318    // Click on 0x0, which should trigger closing menu.
319    // NOTE: this code assume there is a left margin, which is currently
320    // true. If that changes, this code will need to find another empty space
321    // to press the mouse on.
322    gfx::Point mouse_loc;
323    views::View::ConvertPointToScreen(bb_view_.get(), &mouse_loc);
324    ui_controls::SendMouseMoveNotifyWhenDone(0, 0,
325        CreateEventTask(this, &BookmarkBarViewTest2::Step3));
326  }
327
328  void Step3() {
329    // As the click is on the desktop the hook never sees the up, so we only
330    // wait on the down. We still send the up though else the system thinks
331    // the mouse is still down.
332    ui_controls::SendMouseEventsNotifyWhenDone(
333        ui_controls::LEFT, ui_controls::DOWN,
334        CreateEventTask(this, &BookmarkBarViewTest2::Step4));
335    ui_controls::SendMouseEvents(ui_controls::LEFT, ui_controls::UP);
336  }
337
338  void Step4() {
339    // The menu shouldn't be showing.
340    views::MenuItemView* menu = bb_view_->GetMenu();
341    ASSERT_TRUE(menu == NULL || !menu->GetSubmenu()->IsShowing());
342
343    // Make sure button is no longer pushed.
344    views::TextButton* button = GetBookmarkButton(0);
345    ASSERT_TRUE(button->state() == views::CustomButton::STATE_NORMAL);
346
347    Done();
348  }
349};
350
351VIEW_TEST(BookmarkBarViewTest2, HideOnDesktopClick)
352
353// Brings up menu. Moves over child to make sure submenu appears, moves over
354// another child and make sure next menu appears.
355class BookmarkBarViewTest3 : public BookmarkBarViewEventTestBase {
356 protected:
357  virtual void DoTestOnMessageLoop() OVERRIDE {
358    // Move the mouse to the first folder on the bookmark bar and press the
359    // mouse.
360    views::MenuButton* button = bb_view_->other_bookmarked_button();
361    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
362        ui_controls::DOWN | ui_controls::UP,
363        CreateEventTask(this, &BookmarkBarViewTest3::Step2));
364  }
365
366 private:
367  void Step2() {
368    // Menu should be showing.
369    views::MenuItemView* menu = bb_view_->GetMenu();
370    ASSERT_TRUE(menu != NULL);
371    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
372
373    views::MenuItemView* child_menu =
374        menu->GetSubmenu()->GetMenuItemAt(1);
375    ASSERT_TRUE(child_menu != NULL);
376
377    // Click on second child, which has a submenu.
378    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
379        ui_controls::DOWN | ui_controls::UP,
380        CreateEventTask(this, &BookmarkBarViewTest3::Step3));
381  }
382
383  void Step3() {
384    // Make sure sub menu is showing.
385    views::MenuItemView* menu = bb_view_->GetMenu();
386    ASSERT_TRUE(menu);
387    views::MenuItemView* child_menu =
388        menu->GetSubmenu()->GetMenuItemAt(1);
389    ASSERT_TRUE(child_menu->GetSubmenu() != NULL);
390    ASSERT_TRUE(child_menu->GetSubmenu()->IsShowing());
391
392    // Click on third child, which has a submenu too.
393    child_menu = menu->GetSubmenu()->GetMenuItemAt(2);
394    ASSERT_TRUE(child_menu != NULL);
395    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
396        ui_controls::DOWN | ui_controls::UP,
397        CreateEventTask(this, &BookmarkBarViewTest3::Step4));
398  }
399
400  void Step4() {
401    // Make sure sub menu we first clicked isn't showing.
402    views::MenuItemView* menu = bb_view_->GetMenu();
403    views::MenuItemView* child_menu =
404        menu->GetSubmenu()->GetMenuItemAt(1);
405    ASSERT_TRUE(child_menu->GetSubmenu() != NULL);
406    ASSERT_FALSE(child_menu->GetSubmenu()->IsShowing());
407
408    // And submenu we last clicked is showing.
409    child_menu = menu->GetSubmenu()->GetMenuItemAt(2);
410    ASSERT_TRUE(child_menu != NULL);
411    ASSERT_TRUE(child_menu->GetSubmenu()->IsShowing());
412
413    // Nothing should have been selected.
414    EXPECT_EQ(GURL(), navigator_.url_);
415
416    // Hide menu.
417    menu->GetMenuController()->CancelAll();
418
419    Done();
420  }
421};
422
423VIEW_TEST(BookmarkBarViewTest3, Submenus)
424
425// Observer that posts task upon the context menu creation.
426// This is necessary for Linux as the context menu has to check
427// the clipboard, which invokes the event loop.
428class ContextMenuNotificationObserver : public content::NotificationObserver {
429 public:
430  explicit ContextMenuNotificationObserver(const base::Closure& task)
431      : task_(task) {
432    registrar_.Add(this,
433                   chrome::NOTIFICATION_BOOKMARK_CONTEXT_MENU_SHOWN,
434                   content::NotificationService::AllSources());
435  }
436
437  virtual void Observe(int type,
438                       const content::NotificationSource& source,
439                       const content::NotificationDetails& details) OVERRIDE {
440    base::MessageLoop::current()->PostTask(FROM_HERE, task_);
441  }
442
443  // Sets the task that is posted when the context menu is shown.
444  void set_task(const base::Closure& task) { task_ = task; }
445
446 private:
447  content::NotificationRegistrar registrar_;
448  base::Closure task_;
449
450  DISALLOW_COPY_AND_ASSIGN(ContextMenuNotificationObserver);
451};
452
453// Tests context menus by way of opening a context menu for a bookmark,
454// then right clicking to get context menu and selecting the first menu item
455// (open).
456class BookmarkBarViewTest4 : public BookmarkBarViewEventTestBase {
457 public:
458  BookmarkBarViewTest4()
459      : observer_(CreateEventTask(this, &BookmarkBarViewTest4::Step3)) {
460  }
461
462 protected:
463  virtual void DoTestOnMessageLoop() OVERRIDE {
464    // Move the mouse to the first folder on the bookmark bar and press the
465    // mouse.
466    views::TextButton* button = bb_view_->other_bookmarked_button();
467    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
468        ui_controls::DOWN | ui_controls::UP,
469        CreateEventTask(this, &BookmarkBarViewTest4::Step2));
470  }
471
472 private:
473  void Step2() {
474    // Menu should be showing.
475    views::MenuItemView* menu = bb_view_->GetMenu();
476    ASSERT_TRUE(menu != NULL);
477    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
478
479    views::MenuItemView* child_menu =
480        menu->GetSubmenu()->GetMenuItemAt(0);
481    ASSERT_TRUE(child_menu != NULL);
482
483    // Right click on the first child to get its context menu.
484    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
485        ui_controls::DOWN | ui_controls::UP, base::Closure());
486    // Step3 will be invoked by ContextMenuNotificationObserver.
487  }
488
489  void Step3() {
490    // Make sure the context menu is showing.
491    views::MenuItemView* menu = bb_view_->GetContextMenu();
492    ASSERT_TRUE(menu != NULL);
493    ASSERT_TRUE(menu->GetSubmenu());
494    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
495
496    // Select the first menu item (open).
497    ui_test_utils::MoveMouseToCenterAndPress(
498        menu->GetSubmenu()->GetMenuItemAt(0),
499        ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
500        CreateEventTask(this, &BookmarkBarViewTest4::Step4));
501  }
502
503  void Step4() {
504    EXPECT_EQ(navigator_.url_, model_->other_node()->GetChild(0)->url());
505    Done();
506  }
507
508  ContextMenuNotificationObserver observer_;
509};
510
511VIEW_TEST(BookmarkBarViewTest4, ContextMenus)
512
513// Tests drag and drop within the same menu.
514class BookmarkBarViewTest5 : public BookmarkBarViewEventTestBase {
515 protected:
516  virtual void DoTestOnMessageLoop() OVERRIDE {
517    url_dragging_ =
518        model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url();
519
520    // Move the mouse to the first folder on the bookmark bar and press the
521    // mouse.
522    views::TextButton* button = GetBookmarkButton(0);
523    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
524        ui_controls::DOWN | ui_controls::UP,
525        CreateEventTask(this, &BookmarkBarViewTest5::Step2));
526  }
527
528 private:
529  void Step2() {
530    // Menu should be showing.
531    views::MenuItemView* menu = bb_view_->GetMenu();
532    ASSERT_TRUE(menu != NULL);
533    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
534
535    views::MenuItemView* child_menu =
536        menu->GetSubmenu()->GetMenuItemAt(0);
537    ASSERT_TRUE(child_menu != NULL);
538
539    // Move mouse to center of menu and press button.
540    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
541        ui_controls::DOWN,
542        CreateEventTask(this, &BookmarkBarViewTest5::Step3));
543  }
544
545  void Step3() {
546    views::MenuItemView* target_menu =
547        bb_view_->GetMenu()->GetSubmenu()->GetMenuItemAt(1);
548    gfx::Point loc(1, target_menu->height() - 1);
549    views::View::ConvertPointToScreen(target_menu, &loc);
550
551    // Start a drag.
552    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
553        CreateEventTask(this, &BookmarkBarViewTest5::Step4));
554
555    // See comment above this method as to why we do this.
556    ScheduleMouseMoveInBackground(loc.x(), loc.y());
557  }
558
559  void Step4() {
560    // Drop the item so that it's now the second item.
561    views::MenuItemView* target_menu =
562        bb_view_->GetMenu()->GetSubmenu()->GetMenuItemAt(1);
563    gfx::Point loc(1, target_menu->height() - 2);
564    views::View::ConvertPointToScreen(target_menu, &loc);
565    ui_controls::SendMouseMove(loc.x(), loc.y());
566
567    ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT,
568        ui_controls::UP,
569        CreateEventTask(this, &BookmarkBarViewTest5::Step5));
570  }
571
572  void Step5() {
573    GURL url = model_->bookmark_bar_node()->GetChild(0)->GetChild(1)->url();
574    EXPECT_EQ(url_dragging_, url);
575    Done();
576  }
577
578  GURL url_dragging_;
579};
580
581VIEW_TEST(BookmarkBarViewTest5, MAYBE(DND))
582
583// Tests holding mouse down on overflow button, dragging such that menu pops up
584// then selecting an item.
585class BookmarkBarViewTest6 : public BookmarkBarViewEventTestBase {
586 protected:
587  virtual void DoTestOnMessageLoop() OVERRIDE {
588    // Press the mouse button on the overflow button. Don't release it though.
589    views::TextButton* button = bb_view_->overflow_button();
590    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
591        ui_controls::DOWN, CreateEventTask(this, &BookmarkBarViewTest6::Step2));
592  }
593
594 private:
595  void Step2() {
596    // Menu should be showing.
597    views::MenuItemView* menu = bb_view_->GetMenu();
598    ASSERT_TRUE(menu != NULL);
599    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
600
601    views::MenuItemView* child_menu =
602        menu->GetSubmenu()->GetMenuItemAt(0);
603    ASSERT_TRUE(child_menu != NULL);
604
605    // Move mouse to center of menu and release mouse.
606    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
607        ui_controls::UP, CreateEventTask(this, &BookmarkBarViewTest6::Step3));
608  }
609
610  void Step3() {
611    ASSERT_TRUE(navigator_.url_ ==
612                model_->bookmark_bar_node()->GetChild(6)->url());
613    Done();
614  }
615
616  GURL url_dragging_;
617};
618
619VIEW_TEST(BookmarkBarViewTest6, OpenMenuOnClickAndHold)
620
621// Tests drag and drop to different menu.
622class BookmarkBarViewTest7 : public BookmarkBarViewEventTestBase {
623 protected:
624  virtual void DoTestOnMessageLoop() OVERRIDE {
625    url_dragging_ =
626        model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url();
627
628    // Move the mouse to the first folder on the bookmark bar and press the
629    // mouse.
630    views::TextButton* button = GetBookmarkButton(0);
631    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
632        ui_controls::DOWN | ui_controls::UP,
633        CreateEventTask(this, &BookmarkBarViewTest7::Step2));
634  }
635
636 private:
637  void Step2() {
638    // Menu should be showing.
639    views::MenuItemView* menu = bb_view_->GetMenu();
640    ASSERT_TRUE(menu != NULL);
641    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
642
643    views::MenuItemView* child_menu =
644        menu->GetSubmenu()->GetMenuItemAt(0);
645    ASSERT_TRUE(child_menu != NULL);
646
647    // Move mouse to center of menu and press button.
648    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
649        ui_controls::DOWN,
650        CreateEventTask(this, &BookmarkBarViewTest7::Step3));
651  }
652
653  void Step3() {
654    // Drag over other button.
655    views::TextButton* other_button =
656        bb_view_->other_bookmarked_button();
657    gfx::Point loc(other_button->width() / 2, other_button->height() / 2);
658    views::View::ConvertPointToScreen(other_button, &loc);
659
660#if defined(USE_AURA)
661    // TODO: fix this. Aura requires an additional mouse event to trigger drag
662    // and drop checking state.
663    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
664        base::Bind(&BookmarkBarViewTest7::Step3A, this));
665#else
666    // Start a drag.
667    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
668        base::Bind(&BookmarkBarViewTest7::Step4, this));
669
670    // See comment above this method as to why we do this.
671    ScheduleMouseMoveInBackground(loc.x(), loc.y());
672#endif
673  }
674
675  void Step3A() {
676    // Drag over other button.
677    views::TextButton* other_button =
678        bb_view_->other_bookmarked_button();
679    gfx::Point loc(other_button->width() / 2, other_button->height() / 2);
680    views::View::ConvertPointToScreen(other_button, &loc);
681
682    ui_controls::SendMouseMoveNotifyWhenDone(loc.x(), loc.y(),
683        base::Bind(&BookmarkBarViewTest7::Step4, this));
684  }
685
686  void Step4() {
687    views::MenuItemView* drop_menu = bb_view_->GetDropMenu();
688    ASSERT_TRUE(drop_menu != NULL);
689    ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing());
690
691    views::MenuItemView* target_menu =
692        drop_menu->GetSubmenu()->GetMenuItemAt(0);
693    gfx::Point loc(1, 1);
694    views::View::ConvertPointToScreen(target_menu, &loc);
695    ui_controls::SendMouseMoveNotifyWhenDone(loc.x(), loc.y(),
696        CreateEventTask(this, &BookmarkBarViewTest7::Step5));
697  }
698
699  void Step5() {
700    ui_controls::SendMouseEventsNotifyWhenDone(
701        ui_controls::LEFT, ui_controls::UP,
702        CreateEventTask(this, &BookmarkBarViewTest7::Step6));
703  }
704
705  void Step6() {
706    ASSERT_TRUE(model_->other_node()->GetChild(0)->url() == url_dragging_);
707    Done();
708  }
709
710  GURL url_dragging_;
711};
712
713#if !(defined(OS_WIN) && defined(USE_AURA))
714// This test passes locally (on aero and non-aero) but fails on the trybots and
715// buildbot.
716// http://crbug.com/154081
717VIEW_TEST(BookmarkBarViewTest7, MAYBE(DNDToDifferentMenu))
718#endif
719
720// Drags from one menu to next so that original menu closes, then back to
721// original menu.
722class BookmarkBarViewTest8 : public BookmarkBarViewEventTestBase {
723 protected:
724  virtual void DoTestOnMessageLoop() OVERRIDE {
725    url_dragging_ =
726        model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url();
727
728    // Move the mouse to the first folder on the bookmark bar and press the
729    // mouse.
730    views::TextButton* button = GetBookmarkButton(0);
731    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
732        ui_controls::DOWN | ui_controls::UP,
733        CreateEventTask(this, &BookmarkBarViewTest8::Step2));
734  }
735
736 private:
737  void Step2() {
738    // Menu should be showing.
739    views::MenuItemView* menu = bb_view_->GetMenu();
740    ASSERT_TRUE(menu != NULL);
741    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
742
743    views::MenuItemView* child_menu =
744        menu->GetSubmenu()->GetMenuItemAt(0);
745    ASSERT_TRUE(child_menu != NULL);
746
747    // Move mouse to center of menu and press button.
748    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
749        ui_controls::DOWN,
750        CreateEventTask(this, &BookmarkBarViewTest8::Step3));
751  }
752
753  void Step3() {
754    // Drag over other button.
755    views::TextButton* other_button =
756        bb_view_->other_bookmarked_button();
757    gfx::Point loc(other_button->width() / 2, other_button->height() / 2);
758    views::View::ConvertPointToScreen(other_button, &loc);
759
760    // Start a drag.
761#if defined(USE_AURA)
762    // TODO: fix this. Aura requires an additional mouse event to trigger drag
763    // and drop checking state.
764    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
765        base::Bind(&BookmarkBarViewTest8::Step3A, this));
766#else
767    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
768        base::Bind(&BookmarkBarViewTest8::Step4, this));
769    // See comment above this method as to why we do this.
770    ScheduleMouseMoveInBackground(loc.x(), loc.y());
771#endif
772  }
773
774  void Step3A() {
775    // Drag over other button.
776    views::TextButton* other_button =
777        bb_view_->other_bookmarked_button();
778    gfx::Point loc(other_button->width() / 2, other_button->height() / 2);
779    views::View::ConvertPointToScreen(other_button, &loc);
780
781    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
782        base::Bind(&BookmarkBarViewTest8::Step4, this));
783  }
784
785  void Step4() {
786    views::MenuItemView* drop_menu = bb_view_->GetDropMenu();
787    ASSERT_TRUE(drop_menu != NULL);
788    ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing());
789
790    // Now drag back over first menu.
791    views::TextButton* button = GetBookmarkButton(0);
792    gfx::Point loc(button->width() / 2, button->height() / 2);
793    views::View::ConvertPointToScreen(button, &loc);
794    ui_controls::SendMouseMoveNotifyWhenDone(loc.x(), loc.y(),
795        base::Bind(&BookmarkBarViewTest8::Step5, this));
796  }
797
798  void Step5() {
799    // Drop on folder F11.
800    views::MenuItemView* drop_menu = bb_view_->GetDropMenu();
801    ASSERT_TRUE(drop_menu != NULL);
802    ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing());
803
804    views::MenuItemView* target_menu =
805        drop_menu->GetSubmenu()->GetMenuItemAt(1);
806    ui_test_utils::MoveMouseToCenterAndPress(
807        target_menu, ui_controls::LEFT, ui_controls::UP,
808        CreateEventTask(this, &BookmarkBarViewTest8::Step6));
809  }
810
811  void Step6() {
812    // Make sure drop was processed.
813    GURL final_url = model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->
814        GetChild(1)->url();
815    ASSERT_TRUE(final_url == url_dragging_);
816    Done();
817  }
818
819  GURL url_dragging_;
820};
821
822#if !(defined(OS_WIN) && defined(USE_AURA))
823// This test passes locally (on aero and non-aero) but fails on the trybots and
824// buildbot.
825// http://crbug.com/154081
826VIEW_TEST(BookmarkBarViewTest8, MAYBE(DNDBackToOriginatingMenu))
827#endif
828
829// Moves the mouse over the scroll button and makes sure we get scrolling.
830class BookmarkBarViewTest9 : public BookmarkBarViewEventTestBase {
831 protected:
832  virtual bool CreateBigMenu() OVERRIDE { return true; }
833
834  virtual void DoTestOnMessageLoop() OVERRIDE {
835    // Move the mouse to the first folder on the bookmark bar and press the
836    // mouse.
837    views::TextButton* button = GetBookmarkButton(0);
838    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
839        ui_controls::DOWN | ui_controls::UP,
840        CreateEventTask(this, &BookmarkBarViewTest9::Step2));
841  }
842
843 private:
844  void Step2() {
845    // Menu should be showing.
846    views::MenuItemView* menu = bb_view_->GetMenu();
847    ASSERT_TRUE(menu != NULL);
848    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
849
850    first_menu_ = menu->GetSubmenu()->GetMenuItemAt(0);
851    gfx::Point menu_loc;
852    views::View::ConvertPointToScreen(first_menu_, &menu_loc);
853    start_y_ = menu_loc.y();
854
855    // Move the mouse over the scroll button.
856    views::View* scroll_container = menu->GetSubmenu()->parent();
857    ASSERT_TRUE(scroll_container != NULL);
858    scroll_container = scroll_container->parent();
859    ASSERT_TRUE(scroll_container != NULL);
860    views::View* scroll_down_button = scroll_container->child_at(1);
861    ASSERT_TRUE(scroll_down_button);
862    gfx::Point loc(scroll_down_button->width() / 2,
863                   scroll_down_button->height() / 2);
864    views::View::ConvertPointToScreen(scroll_down_button, &loc);
865
866    // On linux, the sending one location isn't enough.
867    ui_controls::SendMouseMove(loc.x() - 1 , loc.y() - 1);
868    ui_controls::SendMouseMoveNotifyWhenDone(
869        loc.x(), loc.y(), CreateEventTask(this, &BookmarkBarViewTest9::Step3));
870  }
871
872  void Step3() {
873    base::MessageLoop::current()->PostDelayedTask(
874        FROM_HERE,
875        base::Bind(&BookmarkBarViewTest9::Step4, this),
876        base::TimeDelta::FromMilliseconds(200));
877  }
878
879  void Step4() {
880    gfx::Point menu_loc;
881    views::View::ConvertPointToScreen(first_menu_, &menu_loc);
882    ASSERT_NE(start_y_, menu_loc.y());
883
884    // Hide menu.
885    bb_view_->GetMenu()->GetMenuController()->CancelAll();
886
887    // On linux, Cancelling menu will call Quit on the message loop,
888    // which can interfere with Done. We need to run Done in the
889    // next execution loop.
890    base::MessageLoop::current()->PostTask(
891        FROM_HERE, base::Bind(&ViewEventTestBase::Done, this));
892  }
893
894  int start_y_;
895  views::MenuItemView* first_menu_;
896};
897
898VIEW_TEST(BookmarkBarViewTest9, ScrollButtonScrolls)
899
900// Tests up/down/left/enter key messages.
901class BookmarkBarViewTest10 : public BookmarkBarViewEventTestBase {
902 protected:
903  virtual void DoTestOnMessageLoop() OVERRIDE {
904    // Move the mouse to the first folder on the bookmark bar and press the
905    // mouse.
906    views::TextButton* button = GetBookmarkButton(0);
907    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
908        ui_controls::DOWN | ui_controls::UP,
909        CreateEventTask(this, &BookmarkBarViewTest10::Step2));
910    base::MessageLoop::current()->RunUntilIdle();
911  }
912
913 private:
914  void Step2() {
915    // Menu should be showing.
916    views::MenuItemView* menu = bb_view_->GetMenu();
917    ASSERT_TRUE(menu != NULL);
918    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
919
920    // Send a down event, which should select the first item.
921    ui_controls::SendKeyPressNotifyWhenDone(
922        window_->GetNativeWindow(), ui::VKEY_DOWN, false, false, false, false,
923        CreateEventTask(this, &BookmarkBarViewTest10::Step3));
924  }
925
926  void Step3() {
927    // Make sure menu is showing and item is selected.
928    views::MenuItemView* menu = bb_view_->GetMenu();
929    ASSERT_TRUE(menu != NULL);
930    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
931    ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected());
932
933    // Send a key down event, which should select the next item.
934    ui_controls::SendKeyPressNotifyWhenDone(
935        window_->GetNativeWindow(), ui::VKEY_DOWN, false, false, false, false,
936        CreateEventTask(this, &BookmarkBarViewTest10::Step4));
937  }
938
939  void Step4() {
940    views::MenuItemView* menu = bb_view_->GetMenu();
941    ASSERT_TRUE(menu != NULL);
942    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
943    ASSERT_FALSE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected());
944    ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(1)->IsSelected());
945
946    // Send a right arrow to force the menu to open.
947    ui_controls::SendKeyPressNotifyWhenDone(
948        window_->GetNativeWindow(), ui::VKEY_RIGHT, false, false, false, false,
949        CreateEventTask(this, &BookmarkBarViewTest10::Step5));
950  }
951
952  void Step5() {
953    // Make sure the submenu is showing.
954    views::MenuItemView* menu = bb_view_->GetMenu();
955    ASSERT_TRUE(menu != NULL);
956    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
957    views::MenuItemView* submenu = menu->GetSubmenu()->GetMenuItemAt(1);
958    ASSERT_TRUE(submenu->IsSelected());
959    ASSERT_TRUE(submenu->GetSubmenu());
960    ASSERT_TRUE(submenu->GetSubmenu()->IsShowing());
961
962    // Send a left arrow to close the submenu.
963    ui_controls::SendKeyPressNotifyWhenDone(
964        window_->GetNativeWindow(), ui::VKEY_LEFT, false, false, false, false,
965        CreateEventTask(this, &BookmarkBarViewTest10::Step6));
966  }
967
968  void Step6() {
969    // Make sure the submenu is showing.
970    views::MenuItemView* menu = bb_view_->GetMenu();
971    ASSERT_TRUE(menu != NULL);
972    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
973    views::MenuItemView* submenu = menu->GetSubmenu()->GetMenuItemAt(1);
974    ASSERT_TRUE(submenu->IsSelected());
975    ASSERT_TRUE(!submenu->GetSubmenu() || !submenu->GetSubmenu()->IsShowing());
976
977    // Send a down arrow to wrap back to f1a
978    ui_controls::SendKeyPressNotifyWhenDone(
979        window_->GetNativeWindow(), ui::VKEY_DOWN, false, false, false, false,
980        CreateEventTask(this, &BookmarkBarViewTest10::Step7));
981  }
982
983  void Step7() {
984    // Make sure menu is showing and item is selected.
985    views::MenuItemView* menu = bb_view_->GetMenu();
986    ASSERT_TRUE(menu != NULL);
987    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
988    ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected());
989
990    // Send enter, which should select the item.
991    ui_controls::SendKeyPressNotifyWhenDone(
992        window_->GetNativeWindow(), ui::VKEY_RETURN, false, false, false, false,
993        CreateEventTask(this, &BookmarkBarViewTest10::Step8));
994  }
995
996  void Step8() {
997    ASSERT_TRUE(
998        model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url() ==
999        navigator_.url_);
1000    Done();
1001  }
1002};
1003
1004VIEW_TEST(BookmarkBarViewTest10, KeyEvents)
1005
1006// Make sure the menu closes with the following sequence: show menu, show
1007// context menu, close context menu (via escape), then click else where. This
1008// effectively verifies we maintain mouse capture after the context menu is
1009// hidden.
1010class BookmarkBarViewTest11 : public BookmarkBarViewEventTestBase {
1011 public:
1012  BookmarkBarViewTest11()
1013      : observer_(CreateEventTask(this, &BookmarkBarViewTest11::Step3)) {
1014  }
1015
1016 protected:
1017  virtual void DoTestOnMessageLoop() OVERRIDE {
1018    // Move the mouse to the first folder on the bookmark bar and press the
1019    // mouse.
1020    views::TextButton* button = bb_view_->other_bookmarked_button();
1021    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1022        ui_controls::DOWN | ui_controls::UP,
1023        CreateEventTask(this, &BookmarkBarViewTest11::Step2));
1024  }
1025
1026 private:
1027  void Step2() {
1028    // Menu should be showing.
1029    views::MenuItemView* menu = bb_view_->GetMenu();
1030    ASSERT_TRUE(menu != NULL);
1031    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1032
1033    views::MenuItemView* child_menu =
1034        menu->GetSubmenu()->GetMenuItemAt(0);
1035    ASSERT_TRUE(child_menu != NULL);
1036
1037    // Right click on the first child to get its context menu.
1038    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1039        ui_controls::DOWN | ui_controls::UP, base::Closure());
1040    // Step3 will be invoked by ContextMenuNotificationObserver.
1041  }
1042
1043  void Step3() {
1044    // Send escape so that the context menu hides.
1045    ui_controls::SendKeyPressNotifyWhenDone(
1046        window_->GetNativeWindow(), ui::VKEY_ESCAPE, false, false, false, false,
1047        CreateEventTask(this, &BookmarkBarViewTest11::Step4));
1048  }
1049
1050  void Step4() {
1051    // Make sure the context menu is no longer showing.
1052    views::MenuItemView* menu = bb_view_->GetContextMenu();
1053    ASSERT_TRUE(!menu || !menu->GetSubmenu() ||
1054                !menu->GetSubmenu()->IsShowing());
1055
1056    // But the menu should be showing.
1057    menu = bb_view_->GetMenu();
1058    ASSERT_TRUE(menu && menu->GetSubmenu() && menu->GetSubmenu()->IsShowing());
1059
1060    // Now click on empty space.
1061    gfx::Point mouse_loc;
1062    views::View::ConvertPointToScreen(bb_view_.get(), &mouse_loc);
1063    ui_controls::SendMouseMove(mouse_loc.x(), mouse_loc.y());
1064    ui_controls::SendMouseEventsNotifyWhenDone(
1065        ui_controls::LEFT, ui_controls::UP | ui_controls::DOWN,
1066        CreateEventTask(this, &BookmarkBarViewTest11::Step5));
1067  }
1068
1069  void Step5() {
1070    // Make sure the menu is not showing.
1071    views::MenuItemView* menu = bb_view_->GetMenu();
1072    ASSERT_TRUE(!menu || !menu->GetSubmenu() ||
1073                !menu->GetSubmenu()->IsShowing());
1074    Done();
1075  }
1076
1077  ContextMenuNotificationObserver observer_;
1078};
1079
1080VIEW_TEST(BookmarkBarViewTest11, CloseMenuAfterClosingContextMenu)
1081
1082// Tests showing a modal dialog from a context menu.
1083class BookmarkBarViewTest12 : public BookmarkBarViewEventTestBase {
1084 protected:
1085  virtual void DoTestOnMessageLoop() OVERRIDE {
1086    // Open up the other folder.
1087    views::TextButton* button = bb_view_->other_bookmarked_button();
1088    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1089        ui_controls::DOWN | ui_controls::UP,
1090        CreateEventTask(this, &BookmarkBarViewTest12::Step2));
1091    chrome::num_bookmark_urls_before_prompting = 1;
1092  }
1093
1094  virtual ~BookmarkBarViewTest12() {
1095    chrome::num_bookmark_urls_before_prompting = 15;
1096  }
1097
1098 private:
1099  void Step2() {
1100    // Menu should be showing.
1101    views::MenuItemView* menu = bb_view_->GetMenu();
1102    ASSERT_TRUE(menu != NULL);
1103    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1104
1105    views::MenuItemView* child_menu =
1106        menu->GetSubmenu()->GetMenuItemAt(1);
1107    ASSERT_TRUE(child_menu != NULL);
1108
1109    // Right click on the second child (a folder) to get its context menu.
1110    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1111        ui_controls::DOWN | ui_controls::UP,
1112        CreateEventTask(this, &BookmarkBarViewTest12::Step3));
1113  }
1114
1115  void Step3() {
1116    // Make sure the context menu is showing.
1117    views::MenuItemView* menu = bb_view_->GetContextMenu();
1118    ASSERT_TRUE(menu && menu->GetSubmenu() && menu->GetSubmenu()->IsShowing());
1119
1120    // Select the first item in the context menu (open all).
1121    views::MenuItemView* child_menu =
1122        menu->GetSubmenu()->GetMenuItemAt(0);
1123    ASSERT_TRUE(child_menu != NULL);
1124    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
1125        ui_controls::DOWN | ui_controls::UP, base::Closure());
1126
1127    // Delay until we send tab, otherwise the message box doesn't appear
1128    // correctly.
1129    base::MessageLoop::current()->PostDelayedTask(
1130        FROM_HERE,
1131        CreateEventTask(this, &BookmarkBarViewTest12::Step4),
1132        base::TimeDelta::FromSeconds(1));
1133  }
1134
1135  void Step4() {
1136    // Press tab to give focus to the cancel button.
1137    ui_controls::SendKeyPress(
1138        window_->GetNativeWindow(), ui::VKEY_TAB, false, false, false, false);
1139
1140    // For some reason return isn't processed correctly unless we delay.
1141    base::MessageLoop::current()->PostDelayedTask(
1142        FROM_HERE,
1143        CreateEventTask(this, &BookmarkBarViewTest12::Step5),
1144        base::TimeDelta::FromSeconds(1));
1145  }
1146
1147  void Step5() {
1148    // And press enter so that the cancel button is selected.
1149    ui_controls::SendKeyPressNotifyWhenDone(
1150        window_->GetNativeWindow(), ui::VKEY_RETURN, false, false, false, false,
1151        CreateEventTask(this, &BookmarkBarViewTest12::Step6));
1152  }
1153
1154  void Step6() {
1155    // Do a delayed task to give the dialog time to exit.
1156    base::MessageLoop::current()->PostTask(
1157        FROM_HERE, CreateEventTask(this, &BookmarkBarViewTest12::Step7));
1158  }
1159
1160  void Step7() {
1161    Done();
1162  }
1163};
1164
1165VIEW_TEST(BookmarkBarViewTest12, CloseWithModalDialog)
1166
1167// Tests clicking on the separator of a context menu (this is for coverage of
1168// bug 17862).
1169class BookmarkBarViewTest13 : public BookmarkBarViewEventTestBase {
1170 public:
1171  BookmarkBarViewTest13()
1172      : observer_(CreateEventTask(this, &BookmarkBarViewTest13::Step3)) {
1173  }
1174
1175 protected:
1176  virtual void DoTestOnMessageLoop() OVERRIDE {
1177    // Move the mouse to the first folder on the bookmark bar and press the
1178    // mouse.
1179    views::TextButton* button = bb_view_->other_bookmarked_button();
1180    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1181        ui_controls::DOWN | ui_controls::UP,
1182        CreateEventTask(this, &BookmarkBarViewTest13::Step2));
1183  }
1184
1185 private:
1186  void Step2() {
1187    // Menu should be showing.
1188    views::MenuItemView* menu = bb_view_->GetMenu();
1189    ASSERT_TRUE(menu != NULL);
1190    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1191
1192    views::MenuItemView* child_menu =
1193        menu->GetSubmenu()->GetMenuItemAt(0);
1194    ASSERT_TRUE(child_menu != NULL);
1195
1196    // Right click on the first child to get its context menu.
1197    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1198        ui_controls::DOWN | ui_controls::UP, base::Closure());
1199    // Step3 will be invoked by ContextMenuNotificationObserver.
1200  }
1201
1202  void Step3() {
1203    // Make sure the context menu is showing.
1204    views::MenuItemView* menu = bb_view_->GetContextMenu();
1205    ASSERT_TRUE(menu != NULL);
1206    ASSERT_TRUE(menu->GetSubmenu());
1207    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1208
1209    // Find the first separator.
1210    views::SubmenuView* submenu = menu->GetSubmenu();
1211    views::View* separator_view = NULL;
1212    for (int i = 0; i < submenu->child_count(); ++i) {
1213      if (submenu->child_at(i)->id() != views::MenuItemView::kMenuItemViewID) {
1214        separator_view = submenu->child_at(i);
1215        break;
1216      }
1217    }
1218    ASSERT_TRUE(separator_view);
1219
1220    // Click on the separator. Clicking on the separator shouldn't visually
1221    // change anything.
1222    ui_test_utils::MoveMouseToCenterAndPress(separator_view,
1223        ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1224        CreateEventTask(this, &BookmarkBarViewTest13::Step4));
1225  }
1226
1227  void Step4() {
1228    // The context menu should still be showing.
1229    views::MenuItemView* menu = bb_view_->GetContextMenu();
1230    ASSERT_TRUE(menu != NULL);
1231    ASSERT_TRUE(menu->GetSubmenu());
1232    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1233
1234    // Select the first context menu item.
1235    ui_test_utils::MoveMouseToCenterAndPress(
1236        menu->GetSubmenu()->GetMenuItemAt(0),
1237        ui_controls::LEFT,
1238        ui_controls::DOWN | ui_controls::UP,
1239        CreateEventTask(this, &BookmarkBarViewTest13::Step5));
1240  }
1241
1242  void Step5() {
1243    Done();
1244  }
1245
1246  ContextMenuNotificationObserver observer_;
1247};
1248
1249VIEW_TEST(BookmarkBarViewTest13, ClickOnContextMenuSeparator)
1250
1251// Makes sure right clicking on a folder on the bookmark bar doesn't result in
1252// both a context menu and showing the menu.
1253class BookmarkBarViewTest14 : public BookmarkBarViewEventTestBase {
1254 public:
1255  BookmarkBarViewTest14()
1256      : observer_(CreateEventTask(this, &BookmarkBarViewTest14::Step2)) {
1257  }
1258
1259 protected:
1260  virtual void DoTestOnMessageLoop() OVERRIDE {
1261    // Move the mouse to the first folder on the bookmark bar and press the
1262    // right mouse button.
1263    views::TextButton* button = GetBookmarkButton(0);
1264    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::RIGHT,
1265        ui_controls::DOWN | ui_controls::UP, base::Closure());
1266    // Step2 will be invoked by ContextMenuNotificationObserver.
1267  }
1268
1269 private:
1270
1271  void Step2() {
1272    // Menu should NOT be showing.
1273    views::MenuItemView* menu = bb_view_->GetMenu();
1274    ASSERT_TRUE(menu == NULL);
1275
1276    // Send escape so that the context menu hides.
1277    ui_controls::SendKeyPressNotifyWhenDone(
1278        window_->GetNativeWindow(), ui::VKEY_ESCAPE, false, false, false, false,
1279        CreateEventTask(this, &BookmarkBarViewTest14::Step3));
1280  }
1281
1282  void Step3() {
1283    Done();
1284  }
1285
1286  ContextMenuNotificationObserver observer_;
1287};
1288
1289VIEW_TEST(BookmarkBarViewTest14, ContextMenus2)
1290
1291// Makes sure deleting from the context menu keeps the bookmark menu showing.
1292class BookmarkBarViewTest15 : public BookmarkBarViewEventTestBase {
1293 public:
1294  BookmarkBarViewTest15()
1295      : deleted_menu_id_(0),
1296        observer_(CreateEventTask(this, &BookmarkBarViewTest15::Step3)) {
1297  }
1298
1299 protected:
1300  virtual void DoTestOnMessageLoop() OVERRIDE {
1301    // Show the other bookmarks.
1302    views::TextButton* button = bb_view_->other_bookmarked_button();
1303    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1304        ui_controls::DOWN | ui_controls::UP,
1305        CreateEventTask(this, &BookmarkBarViewTest15::Step2));
1306  }
1307
1308 private:
1309  void Step2() {
1310    // Menu should be showing.
1311    views::MenuItemView* menu = bb_view_->GetMenu();
1312    ASSERT_TRUE(menu != NULL);
1313    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1314
1315    views::MenuItemView* child_menu =
1316        menu->GetSubmenu()->GetMenuItemAt(1);
1317    ASSERT_TRUE(child_menu != NULL);
1318
1319    deleted_menu_id_ = child_menu->GetCommand();
1320
1321    // Right click on the second child to get its context menu.
1322    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1323        ui_controls::DOWN | ui_controls::UP, base::Closure());
1324    // Step3 will be invoked by ContextMenuNotificationObserver.
1325  }
1326
1327  void Step3() {
1328    // Make sure the context menu is showing.
1329    views::MenuItemView* menu = bb_view_->GetContextMenu();
1330    ASSERT_TRUE(menu != NULL);
1331    ASSERT_TRUE(menu->GetSubmenu());
1332    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1333
1334    views::MenuItemView* delete_menu =
1335        menu->GetMenuItemByID(IDC_BOOKMARK_BAR_REMOVE);
1336    ASSERT_TRUE(delete_menu);
1337
1338    // Click on the delete button.
1339    ui_test_utils::MoveMouseToCenterAndPress(delete_menu,
1340        ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1341        CreateEventTask(this, &BookmarkBarViewTest15::Step4));
1342  }
1343
1344  void Step4() {
1345    // The context menu should not be showing.
1346    views::MenuItemView* context_menu = bb_view_->GetContextMenu();
1347    ASSERT_TRUE(context_menu == NULL);
1348
1349    // But the menu should be showing.
1350    views::MenuItemView* menu = bb_view_->GetMenu();
1351    ASSERT_TRUE(menu != NULL);
1352    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1353
1354    // And the deleted_menu_id_ should have been removed.
1355    ASSERT_TRUE(menu->GetMenuItemByID(deleted_menu_id_) == NULL);
1356
1357    bb_view_->GetMenu()->GetMenuController()->CancelAll();
1358
1359    Done();
1360  }
1361
1362  int deleted_menu_id_;
1363  ContextMenuNotificationObserver observer_;
1364};
1365
1366VIEW_TEST(BookmarkBarViewTest15, MenuStaysVisibleAfterDelete)
1367
1368// Tests that we don't crash or get stuck if the parent of a menu is closed.
1369class BookmarkBarViewTest16 : public BookmarkBarViewEventTestBase {
1370 protected:
1371  virtual void DoTestOnMessageLoop() OVERRIDE {
1372    // Move the mouse to the first folder on the bookmark bar and press the
1373    // mouse.
1374    views::TextButton* button = GetBookmarkButton(0);
1375    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1376        ui_controls::DOWN | ui_controls::UP,
1377        CreateEventTask(this, &BookmarkBarViewTest16::Step2));
1378  }
1379
1380 private:
1381  void Step2() {
1382    // Menu should be showing.
1383    views::MenuItemView* menu = bb_view_->GetMenu();
1384    ASSERT_TRUE(menu != NULL);
1385    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1386
1387    // Button should be depressed.
1388    views::TextButton* button = GetBookmarkButton(0);
1389    ASSERT_TRUE(button->state() == views::CustomButton::STATE_PRESSED);
1390
1391    // Close the window.
1392    window_->Close();
1393    window_ = NULL;
1394
1395    base::MessageLoop::current()->PostTask(
1396        FROM_HERE, CreateEventTask(this, &BookmarkBarViewTest16::Done));
1397  }
1398};
1399
1400VIEW_TEST(BookmarkBarViewTest16, DeleteMenu)
1401
1402// Makes sure right clicking on an item while a context menu is already showing
1403// doesn't crash and works.
1404class BookmarkBarViewTest17 : public BookmarkBarViewEventTestBase {
1405 public:
1406  BookmarkBarViewTest17()
1407      : observer_(CreateEventTask(this, &BookmarkBarViewTest17::Step3)) {
1408  }
1409
1410 protected:
1411  virtual void DoTestOnMessageLoop() OVERRIDE {
1412    // Move the mouse to the other folder on the bookmark bar and press the
1413    // left mouse button.
1414    views::TextButton* button = bb_view_->other_bookmarked_button();
1415    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1416        ui_controls::DOWN | ui_controls::UP,
1417        CreateEventTask(this, &BookmarkBarViewTest17::Step2));
1418  }
1419
1420 private:
1421  void Step2() {
1422    // Menu should be showing.
1423    views::MenuItemView* menu = bb_view_->GetMenu();
1424    ASSERT_TRUE(menu != NULL);
1425    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1426
1427    // Right click on the second item to show its context menu.
1428    views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(2);
1429    ASSERT_TRUE(child_menu != NULL);
1430    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1431        ui_controls::DOWN | ui_controls::UP, base::Closure());
1432    // Step3 will be invoked by ContextMenuNotificationObserver.
1433  }
1434
1435  void Step3() {
1436    // Make sure the context menu is showing.
1437    views::MenuItemView* context_menu = bb_view_->GetContextMenu();
1438    ASSERT_TRUE(context_menu != NULL);
1439    ASSERT_TRUE(context_menu->GetSubmenu());
1440    ASSERT_TRUE(context_menu->GetSubmenu()->IsShowing());
1441
1442    // Right click on the first menu item to trigger its context menu.
1443    views::MenuItemView* menu = bb_view_->GetMenu();
1444    ASSERT_TRUE(menu != NULL);
1445    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1446    views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(1);
1447    ASSERT_TRUE(child_menu != NULL);
1448
1449    // The context menu and child_menu can be overlapped, calculate the
1450    // non-intersected Rect of the child menu and click on its center to make
1451    // sure the click is always on the child menu.
1452    gfx::Rect context_rect = context_menu->GetSubmenu()->GetBoundsInScreen();
1453    gfx::Rect child_menu_rect = child_menu->GetBoundsInScreen();
1454    gfx::Rect clickable_rect =
1455        gfx::SubtractRects(child_menu_rect, context_rect);
1456    ASSERT_FALSE(clickable_rect.IsEmpty());
1457    observer_.set_task(CreateEventTask(this, &BookmarkBarViewTest17::Step4));
1458    MoveMouseAndPress(clickable_rect.CenterPoint(), ui_controls::RIGHT,
1459        ui_controls::DOWN | ui_controls::UP, base::Closure());
1460    // Step4 will be invoked by ContextMenuNotificationObserver.
1461  }
1462
1463  void Step4() {
1464    // The context menu should still be showing.
1465    views::MenuItemView* context_menu = bb_view_->GetContextMenu();
1466    ASSERT_TRUE(context_menu != NULL);
1467
1468    // And the menu should be showing.
1469    views::MenuItemView* menu = bb_view_->GetMenu();
1470    ASSERT_TRUE(menu != NULL);
1471    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1472
1473    bb_view_->GetMenu()->GetMenuController()->CancelAll();
1474
1475    Done();
1476  }
1477
1478  ContextMenuNotificationObserver observer_;
1479};
1480
1481VIEW_TEST(BookmarkBarViewTest17, ContextMenus3)
1482
1483// Verifies sibling menus works. Clicks on the 'other bookmarks' folder, then
1484// moves the mouse over the first item on the bookmark bar and makes sure the
1485// menu appears.
1486class BookmarkBarViewTest18 : public BookmarkBarViewEventTestBase {
1487 protected:
1488  virtual void DoTestOnMessageLoop() OVERRIDE {
1489    // Move the mouse to the other folder on the bookmark bar and press the
1490    // left mouse button.
1491    views::TextButton* button = bb_view_->other_bookmarked_button();
1492    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1493        ui_controls::DOWN | ui_controls::UP,
1494        CreateEventTask(this, &BookmarkBarViewTest18::Step2));
1495  }
1496
1497 private:
1498  void Step2() {
1499    // Menu should be showing.
1500    views::MenuItemView* menu = bb_view_->GetMenu();
1501    ASSERT_TRUE(menu != NULL);
1502    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1503
1504    // Move the mouse to the first folder on the bookmark bar
1505    views::TextButton* button = GetBookmarkButton(0);
1506    gfx::Point button_center(button->width() / 2, button->height() / 2);
1507    views::View::ConvertPointToScreen(button, &button_center);
1508    ui_controls::SendMouseMoveNotifyWhenDone(
1509        button_center.x(), button_center.y(),
1510        CreateEventTask(this, &BookmarkBarViewTest18::Step3));
1511  }
1512
1513  void Step3() {
1514    // Make sure the menu is showing.
1515    views::MenuItemView* menu = bb_view_->GetMenu();
1516    ASSERT_TRUE(menu != NULL);
1517    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1518
1519    // The menu for the first folder should be in the pressed state (since the
1520    // menu is showing for it).
1521    EXPECT_EQ(views::CustomButton::STATE_PRESSED,
1522              GetBookmarkButton(0)->state());
1523
1524    menu->GetMenuController()->CancelAll();
1525
1526    Done();
1527  }
1528};
1529
1530VIEW_TEST(BookmarkBarViewTest18, BookmarkBarViewTest18_SiblingMenu)
1531
1532// Verifies mousing over an already open sibling menu doesn't prematurely cancel
1533// the menu.
1534class BookmarkBarViewTest19 : public BookmarkBarViewEventTestBase {
1535 protected:
1536  virtual void DoTestOnMessageLoop() OVERRIDE {
1537    // Move the mouse to the other folder on the bookmark bar and press the
1538    // left mouse button.
1539    views::TextButton* button = bb_view_->other_bookmarked_button();
1540    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1541        ui_controls::DOWN | ui_controls::UP,
1542        CreateEventTask(this, &BookmarkBarViewTest19::Step2));
1543  }
1544
1545 private:
1546  void Step2() {
1547    // Menu should be showing.
1548    views::MenuItemView* menu = bb_view_->GetMenu();
1549    ASSERT_TRUE(menu != NULL);
1550    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1551
1552    // Click on the first folder.
1553    views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(1);
1554    ASSERT_TRUE(child_menu != NULL);
1555    ui_test_utils::MoveMouseToCenterAndPress(
1556        child_menu, ui_controls::LEFT,
1557        ui_controls::DOWN | ui_controls::UP,
1558        CreateEventTask(this, &BookmarkBarViewTest19::Step3));
1559  }
1560
1561  void Step3() {
1562    // Make sure the menu is showing.
1563    views::MenuItemView* menu = bb_view_->GetMenu();
1564    ASSERT_TRUE(menu != NULL);
1565    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1566
1567    // Move the mouse back to the other bookmark button.
1568    views::TextButton* button = bb_view_->other_bookmarked_button();
1569    gfx::Point button_center(button->width() / 2, button->height() / 2);
1570    views::View::ConvertPointToScreen(button, &button_center);
1571    ui_controls::SendMouseMoveNotifyWhenDone(
1572        button_center.x() + 1, button_center.y() + 1,
1573        CreateEventTask(this, &BookmarkBarViewTest19::Step4));
1574  }
1575
1576  void Step4() {
1577    // Menu should be showing.
1578    views::MenuItemView* menu = bb_view_->GetMenu();
1579    ASSERT_TRUE(menu != NULL);
1580    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1581
1582    // Click on the first folder.
1583    views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(1);
1584    ASSERT_TRUE(child_menu != NULL);
1585    ui_test_utils::MoveMouseToCenterAndPress(
1586        child_menu,
1587        ui_controls::LEFT,
1588        ui_controls::DOWN | ui_controls::UP,
1589        CreateEventTask(this, &BookmarkBarViewTest19::Step5));
1590  }
1591
1592  void Step5() {
1593    // Make sure the menu is showing.
1594    views::MenuItemView* menu = bb_view_->GetMenu();
1595    ASSERT_TRUE(menu != NULL);
1596    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1597
1598    menu->GetMenuController()->CancelAll();
1599
1600    Done();
1601  }
1602};
1603
1604VIEW_TEST(BookmarkBarViewTest19, BookmarkBarViewTest19_SiblingMenu)
1605
1606#if !defined(OS_WIN)
1607// Not ready for Win Aura. (NOTREACHED in chrome_views_delegate.cc
1608// and desktop_root_window_host_win.cc.)
1609
1610// Verify that when clicking a mouse button outside a context menu,
1611// the context menu is dismissed *and* the underlying view receives
1612// the the mouse event (due to event reposting).
1613class BookmarkBarViewTest20 : public BookmarkBarViewEventTestBase {
1614 public:
1615  BookmarkBarViewTest20() : test_view_(new TestViewForMenuExit) {}
1616
1617 protected:
1618  virtual void DoTestOnMessageLoop() OVERRIDE {
1619    // Add |test_view_| next to |bb_view_|.
1620    views::View* parent = bb_view_->parent();
1621    views::View* container_view = new ContainerViewForMenuExit;
1622    container_view->AddChildView(bb_view_.get());
1623    container_view->AddChildView(test_view_);
1624    parent->AddChildView(container_view);
1625    parent->Layout();
1626
1627    ASSERT_EQ(test_view_->press_count(), 0);
1628
1629    // Move the mouse to the Test View and press the left mouse button.
1630    ui_test_utils::MoveMouseToCenterAndPress(
1631        test_view_, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1632        CreateEventTask(this, &BookmarkBarViewTest20::Step1));
1633  }
1634
1635 private:
1636  void Step1() {
1637    ASSERT_EQ(test_view_->press_count(), 1);
1638    ASSERT_TRUE(bb_view_->GetMenu() == NULL);
1639
1640    // Move the mouse to the first folder on the bookmark bar and press the
1641    // left mouse button.
1642    views::TextButton* button = GetBookmarkButton(0);
1643    ui_test_utils::MoveMouseToCenterAndPress(
1644        button, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1645        CreateEventTask(this, &BookmarkBarViewTest20::Step2));
1646  }
1647
1648  void Step2() {
1649    ASSERT_EQ(test_view_->press_count(), 1);
1650    views::MenuItemView* menu = bb_view_->GetMenu();
1651    ASSERT_TRUE(menu != NULL);
1652    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1653
1654    // Move the mouse to the Test View and press the left mouse button.
1655    // The context menu will consume the event and exit. Thereafter,
1656    // the event is reposted and delivered to the Test View which
1657    // increases its press-count.
1658    ui_test_utils::MoveMouseToCenterAndPress(
1659        test_view_, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1660        CreateEventTask(this, &BookmarkBarViewTest20::Step3));
1661  }
1662
1663  void Step3() {
1664    ASSERT_EQ(test_view_->press_count(), 2);
1665    ASSERT_TRUE(bb_view_->GetMenu() == NULL);
1666    Done();
1667  }
1668
1669  class ContainerViewForMenuExit : public views::View {
1670   public:
1671    ContainerViewForMenuExit() {
1672    }
1673
1674    virtual void Layout() OVERRIDE {
1675      DCHECK_EQ(2, child_count());
1676      views::View* bb_view = child_at(0);
1677      views::View* test_view = child_at(1);
1678      const int width = bb_view->width();
1679      const int height = bb_view->height();
1680      bb_view->SetBounds(0,0, width - 22, height);
1681      test_view->SetBounds(width - 20, 0, 20, height);
1682    }
1683
1684   private:
1685
1686    DISALLOW_COPY_AND_ASSIGN(ContainerViewForMenuExit);
1687  };
1688
1689  class TestViewForMenuExit : public views::View {
1690   public:
1691    TestViewForMenuExit() : press_count_(0) {
1692    }
1693    virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
1694      ++press_count_;
1695      return true;
1696    }
1697    int press_count() const { return press_count_; }
1698
1699   private:
1700    int press_count_;
1701
1702    DISALLOW_COPY_AND_ASSIGN(TestViewForMenuExit);
1703  };
1704
1705  TestViewForMenuExit* test_view_;
1706};
1707
1708VIEW_TEST(BookmarkBarViewTest20, ContextMenuExitTest)
1709
1710#endif // !defined(OS_WIN)
1711
1712// Tests context menu by way of opening a context menu for a empty folder menu.
1713// The opened context menu should behave as it is from the folder button.
1714class BookmarkBarViewTest21 : public BookmarkBarViewEventTestBase {
1715 public:
1716  BookmarkBarViewTest21()
1717      : observer_(CreateEventTask(this, &BookmarkBarViewTest21::Step3)) {
1718  }
1719
1720 protected:
1721  // Move the mouse to the empty folder on the bookmark bar and press the
1722  // left mouse button.
1723  virtual void DoTestOnMessageLoop() OVERRIDE {
1724    views::TextButton* button = GetBookmarkButton(5);
1725    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1726        ui_controls::DOWN | ui_controls::UP,
1727        CreateEventTask(this, &BookmarkBarViewTest21::Step2));
1728  }
1729
1730 private:
1731  // Confirm that a menu for empty folder shows and right click the menu.
1732  void Step2() {
1733    // Menu should be showing.
1734    views::MenuItemView* menu = bb_view_->GetMenu();
1735    ASSERT_TRUE(menu != NULL);
1736
1737    views::SubmenuView* submenu = menu->GetSubmenu();
1738    ASSERT_TRUE(submenu->IsShowing());
1739    ASSERT_EQ(1, submenu->child_count());
1740
1741    views::View* view = submenu->child_at(0);
1742    ASSERT_TRUE(view != NULL);
1743    EXPECT_EQ(views::MenuItemView::kEmptyMenuItemViewID, view->id());
1744
1745    // Right click on the first child to get its context menu.
1746    ui_test_utils::MoveMouseToCenterAndPress(view, ui_controls::RIGHT,
1747        ui_controls::DOWN | ui_controls::UP, base::Closure());
1748    // Step3 will be invoked by ContextMenuNotificationObserver.
1749  }
1750
1751  // Confirm that context menu shows and click REMOVE menu.
1752  void Step3() {
1753    // Make sure the context menu is showing.
1754    views::MenuItemView* menu = bb_view_->GetContextMenu();
1755    ASSERT_TRUE(menu != NULL);
1756    ASSERT_TRUE(menu->GetSubmenu());
1757    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1758
1759    views::MenuItemView* delete_menu =
1760        menu->GetMenuItemByID(IDC_BOOKMARK_BAR_REMOVE);
1761    ASSERT_TRUE(delete_menu);
1762
1763    // Click on the delete menu item.
1764    ui_test_utils::MoveMouseToCenterAndPress(delete_menu,
1765        ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1766        CreateEventTask(this, &BookmarkBarViewTest21::Step4));
1767  }
1768
1769  // Confirm that the empty folder gets removed and menu doesn't show.
1770  void Step4() {
1771    views::TextButton* button = GetBookmarkButton(5);
1772    ASSERT_TRUE(button);
1773    EXPECT_EQ(ASCIIToUTF16("d"), button->text());
1774    EXPECT_TRUE(bb_view_->GetContextMenu() == NULL);
1775    EXPECT_TRUE(bb_view_->GetMenu() == NULL);
1776
1777    Done();
1778  }
1779
1780  ContextMenuNotificationObserver observer_;
1781};
1782
1783VIEW_TEST(BookmarkBarViewTest21, ContextMenusForEmptyFolder)
1784