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