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