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