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/accessibility/accessibility_types.h"
36#include "ui/base/clipboard/clipboard.h"
37#include "ui/base/test/ui_controls.h"
38#include "ui/events/keycodes/keyboard_codes.h"
39#include "ui/views/controls/button/menu_button.h"
40#include "ui/views/controls/button/text_button.h"
41#include "ui/views/controls/menu/menu_controller.h"
42#include "ui/views/controls/menu/menu_item_view.h"
43#include "ui/views/controls/menu/submenu_view.h"
44#include "ui/views/widget/widget.h"
45
46using content::BrowserThread;
47using content::OpenURLParams;
48using content::PageNavigator;
49using content::WebContents;
50
51namespace {
52
53void MoveMouseAndPress(const gfx::Point& screen_pos,
54                       ui_controls::MouseButton button,
55                       int state,
56                       const base::Closure& closure) {
57  ui_controls::SendMouseMove(screen_pos.x(), screen_pos.y());
58  ui_controls::SendMouseEventsNotifyWhenDone(button, state, closure);
59}
60
61// PageNavigator implementation that records the URL.
62class TestingPageNavigator : public PageNavigator {
63 public:
64  virtual WebContents* OpenURL(const OpenURLParams& params) OVERRIDE {
65    url_ = params.url;
66    return NULL;
67  }
68
69  GURL url_;
70};
71
72// TODO(jschuh): Fix bookmark DND tests on Win64. crbug.com/244605
73// 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 ContextMenuNotificationObserver : public content::NotificationObserver {
435 public:
436  explicit ContextMenuNotificationObserver(const base::Closure& task)
437      : task_(task) {
438    registrar_.Add(this,
439                   chrome::NOTIFICATION_BOOKMARK_CONTEXT_MENU_SHOWN,
440                   content::NotificationService::AllSources());
441  }
442
443  virtual void Observe(int type,
444                       const content::NotificationSource& source,
445                       const content::NotificationDetails& details) OVERRIDE {
446    base::MessageLoop::current()->PostTask(FROM_HERE, task_);
447  }
448
449  // Sets the task that is posted when the context menu is shown.
450  void set_task(const base::Closure& task) { task_ = task; }
451
452 private:
453  content::NotificationRegistrar registrar_;
454  base::Closure task_;
455
456  DISALLOW_COPY_AND_ASSIGN(ContextMenuNotificationObserver);
457};
458
459// Tests context menus by way of opening a context menu for a bookmark,
460// then right clicking to get context menu and selecting the first menu item
461// (open).
462class BookmarkBarViewTest4 : public BookmarkBarViewEventTestBase {
463 public:
464  BookmarkBarViewTest4()
465      : observer_(CreateEventTask(this, &BookmarkBarViewTest4::Step3)) {
466  }
467
468 protected:
469  virtual void DoTestOnMessageLoop() OVERRIDE {
470    // Move the mouse to the first folder on the bookmark bar and press the
471    // mouse.
472    views::TextButton* button = bb_view_->other_bookmarked_button();
473    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
474        ui_controls::DOWN | ui_controls::UP,
475        CreateEventTask(this, &BookmarkBarViewTest4::Step2));
476  }
477
478 private:
479  void Step2() {
480    // Menu should be showing.
481    views::MenuItemView* menu = bb_view_->GetMenu();
482    ASSERT_TRUE(menu != NULL);
483    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
484
485    views::MenuItemView* child_menu =
486        menu->GetSubmenu()->GetMenuItemAt(0);
487    ASSERT_TRUE(child_menu != NULL);
488
489    // Right click on the first child to get its context menu.
490    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
491        ui_controls::DOWN | ui_controls::UP, base::Closure());
492    // Step3 will be invoked by ContextMenuNotificationObserver.
493  }
494
495  void Step3() {
496    // Make sure the context menu is showing.
497    views::MenuItemView* menu = bb_view_->GetContextMenu();
498    ASSERT_TRUE(menu != NULL);
499    ASSERT_TRUE(menu->GetSubmenu());
500    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
501
502    // Select the first menu item (open).
503    ui_test_utils::MoveMouseToCenterAndPress(
504        menu->GetSubmenu()->GetMenuItemAt(0),
505        ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
506        CreateEventTask(this, &BookmarkBarViewTest4::Step4));
507  }
508
509  void Step4() {
510    EXPECT_EQ(navigator_.url_, model_->other_node()->GetChild(0)->url());
511    Done();
512  }
513
514  ContextMenuNotificationObserver observer_;
515};
516
517VIEW_TEST(BookmarkBarViewTest4, ContextMenus)
518
519// Tests drag and drop within the same menu.
520class BookmarkBarViewTest5 : public BookmarkBarViewEventTestBase {
521 protected:
522  virtual void DoTestOnMessageLoop() OVERRIDE {
523    url_dragging_ =
524        model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url();
525
526    // Move the mouse to the first folder on the bookmark bar and press the
527    // mouse.
528    views::TextButton* button = GetBookmarkButton(0);
529    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
530        ui_controls::DOWN | ui_controls::UP,
531        CreateEventTask(this, &BookmarkBarViewTest5::Step2));
532  }
533
534 private:
535  void Step2() {
536    // Menu should be showing.
537    views::MenuItemView* menu = bb_view_->GetMenu();
538    ASSERT_TRUE(menu != NULL);
539    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
540
541    views::MenuItemView* child_menu =
542        menu->GetSubmenu()->GetMenuItemAt(0);
543    ASSERT_TRUE(child_menu != NULL);
544
545    // Move mouse to center of menu and press button.
546    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
547        ui_controls::DOWN,
548        CreateEventTask(this, &BookmarkBarViewTest5::Step3));
549  }
550
551  void Step3() {
552    views::MenuItemView* target_menu =
553        bb_view_->GetMenu()->GetSubmenu()->GetMenuItemAt(1);
554    gfx::Point loc(1, target_menu->height() - 1);
555    views::View::ConvertPointToScreen(target_menu, &loc);
556
557    // Start a drag.
558    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
559        CreateEventTask(this, &BookmarkBarViewTest5::Step4));
560
561    // See comment above this method as to why we do this.
562    ScheduleMouseMoveInBackground(loc.x(), loc.y());
563  }
564
565  void Step4() {
566    // Drop the item so that it's now the second item.
567    views::MenuItemView* target_menu =
568        bb_view_->GetMenu()->GetSubmenu()->GetMenuItemAt(1);
569    gfx::Point loc(1, target_menu->height() - 2);
570    views::View::ConvertPointToScreen(target_menu, &loc);
571    ui_controls::SendMouseMove(loc.x(), loc.y());
572
573    ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT,
574        ui_controls::UP,
575        CreateEventTask(this, &BookmarkBarViewTest5::Step5));
576  }
577
578  void Step5() {
579    GURL url = model_->bookmark_bar_node()->GetChild(0)->GetChild(1)->url();
580    EXPECT_EQ(url_dragging_, url);
581    Done();
582  }
583
584  GURL url_dragging_;
585};
586
587VIEW_TEST(BookmarkBarViewTest5, MAYBE(DND))
588
589// Tests holding mouse down on overflow button, dragging such that menu pops up
590// then selecting an item.
591class BookmarkBarViewTest6 : public BookmarkBarViewEventTestBase {
592 protected:
593  virtual void DoTestOnMessageLoop() OVERRIDE {
594    // Press the mouse button on the overflow button. Don't release it though.
595    views::TextButton* button = bb_view_->overflow_button();
596    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
597        ui_controls::DOWN, CreateEventTask(this, &BookmarkBarViewTest6::Step2));
598  }
599
600 private:
601  void Step2() {
602    // Menu should be showing.
603    views::MenuItemView* menu = bb_view_->GetMenu();
604    ASSERT_TRUE(menu != NULL);
605    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
606
607    views::MenuItemView* child_menu =
608        menu->GetSubmenu()->GetMenuItemAt(0);
609    ASSERT_TRUE(child_menu != NULL);
610
611    // Move mouse to center of menu and release mouse.
612    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
613        ui_controls::UP, CreateEventTask(this, &BookmarkBarViewTest6::Step3));
614  }
615
616  void Step3() {
617    ASSERT_TRUE(navigator_.url_ ==
618                model_->bookmark_bar_node()->GetChild(6)->url());
619    Done();
620  }
621
622  GURL url_dragging_;
623};
624
625VIEW_TEST(BookmarkBarViewTest6, OpenMenuOnClickAndHold)
626
627// Tests drag and drop to different menu.
628class BookmarkBarViewTest7 : public BookmarkBarViewEventTestBase {
629 protected:
630  virtual void DoTestOnMessageLoop() OVERRIDE {
631    url_dragging_ =
632        model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url();
633
634    // Move the mouse to the first folder on the bookmark bar and press the
635    // mouse.
636    views::TextButton* button = GetBookmarkButton(0);
637    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
638        ui_controls::DOWN | ui_controls::UP,
639        CreateEventTask(this, &BookmarkBarViewTest7::Step2));
640  }
641
642 private:
643  void Step2() {
644    // Menu should be showing.
645    views::MenuItemView* menu = bb_view_->GetMenu();
646    ASSERT_TRUE(menu != NULL);
647    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
648
649    views::MenuItemView* child_menu =
650        menu->GetSubmenu()->GetMenuItemAt(0);
651    ASSERT_TRUE(child_menu != NULL);
652
653    // Move mouse to center of menu and press button.
654    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
655        ui_controls::DOWN,
656        CreateEventTask(this, &BookmarkBarViewTest7::Step3));
657  }
658
659  void Step3() {
660    // Drag over other button.
661    views::TextButton* other_button =
662        bb_view_->other_bookmarked_button();
663    gfx::Point loc(other_button->width() / 2, other_button->height() / 2);
664    views::View::ConvertPointToScreen(other_button, &loc);
665
666#if defined(USE_AURA)
667    // TODO: fix this. Aura requires an additional mouse event to trigger drag
668    // and drop checking state.
669    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
670        base::Bind(&BookmarkBarViewTest7::Step3A, this));
671#else
672    // Start a drag.
673    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
674        base::Bind(&BookmarkBarViewTest7::Step4, this));
675
676    // See comment above this method as to why we do this.
677    ScheduleMouseMoveInBackground(loc.x(), loc.y());
678#endif
679  }
680
681  void Step3A() {
682    // Drag over other button.
683    views::TextButton* other_button =
684        bb_view_->other_bookmarked_button();
685    gfx::Point loc(other_button->width() / 2, other_button->height() / 2);
686    views::View::ConvertPointToScreen(other_button, &loc);
687
688    ui_controls::SendMouseMoveNotifyWhenDone(loc.x(), loc.y(),
689        base::Bind(&BookmarkBarViewTest7::Step4, this));
690  }
691
692  void Step4() {
693    views::MenuItemView* drop_menu = bb_view_->GetDropMenu();
694    ASSERT_TRUE(drop_menu != NULL);
695    ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing());
696
697    views::MenuItemView* target_menu =
698        drop_menu->GetSubmenu()->GetMenuItemAt(0);
699    gfx::Point loc(1, 1);
700    views::View::ConvertPointToScreen(target_menu, &loc);
701    ui_controls::SendMouseMoveNotifyWhenDone(loc.x(), loc.y(),
702        CreateEventTask(this, &BookmarkBarViewTest7::Step5));
703  }
704
705  void Step5() {
706    ui_controls::SendMouseEventsNotifyWhenDone(
707        ui_controls::LEFT, ui_controls::UP,
708        CreateEventTask(this, &BookmarkBarViewTest7::Step6));
709  }
710
711  void Step6() {
712    ASSERT_TRUE(model_->other_node()->GetChild(0)->url() == url_dragging_);
713    Done();
714  }
715
716  GURL url_dragging_;
717};
718
719#if !(defined(OS_WIN) && defined(USE_AURA))
720// This test passes locally (on aero and non-aero) but fails on the trybots and
721// buildbot.
722// http://crbug.com/154081
723VIEW_TEST(BookmarkBarViewTest7, MAYBE(DNDToDifferentMenu))
724#endif
725
726// Drags from one menu to next so that original menu closes, then back to
727// original menu.
728class BookmarkBarViewTest8 : public BookmarkBarViewEventTestBase {
729 protected:
730  virtual void DoTestOnMessageLoop() OVERRIDE {
731    url_dragging_ =
732        model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url();
733
734    // Move the mouse to the first folder on the bookmark bar and press the
735    // mouse.
736    views::TextButton* button = GetBookmarkButton(0);
737    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
738        ui_controls::DOWN | ui_controls::UP,
739        CreateEventTask(this, &BookmarkBarViewTest8::Step2));
740  }
741
742 private:
743  void Step2() {
744    // Menu should be showing.
745    views::MenuItemView* menu = bb_view_->GetMenu();
746    ASSERT_TRUE(menu != NULL);
747    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
748
749    views::MenuItemView* child_menu =
750        menu->GetSubmenu()->GetMenuItemAt(0);
751    ASSERT_TRUE(child_menu != NULL);
752
753    // Move mouse to center of menu and press button.
754    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
755        ui_controls::DOWN,
756        CreateEventTask(this, &BookmarkBarViewTest8::Step3));
757  }
758
759  void Step3() {
760    // Drag over other button.
761    views::TextButton* other_button =
762        bb_view_->other_bookmarked_button();
763    gfx::Point loc(other_button->width() / 2, other_button->height() / 2);
764    views::View::ConvertPointToScreen(other_button, &loc);
765
766    // Start a drag.
767#if defined(USE_AURA)
768    // TODO: fix this. Aura requires an additional mouse event to trigger drag
769    // and drop checking state.
770    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
771        base::Bind(&BookmarkBarViewTest8::Step3A, this));
772#else
773    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
774        base::Bind(&BookmarkBarViewTest8::Step4, this));
775    // See comment above this method as to why we do this.
776    ScheduleMouseMoveInBackground(loc.x(), loc.y());
777#endif
778  }
779
780  void Step3A() {
781    // Drag over other button.
782    views::TextButton* other_button =
783        bb_view_->other_bookmarked_button();
784    gfx::Point loc(other_button->width() / 2, other_button->height() / 2);
785    views::View::ConvertPointToScreen(other_button, &loc);
786
787    ui_controls::SendMouseMoveNotifyWhenDone(loc.x() + 10, loc.y(),
788        base::Bind(&BookmarkBarViewTest8::Step4, this));
789  }
790
791  void Step4() {
792    views::MenuItemView* drop_menu = bb_view_->GetDropMenu();
793    ASSERT_TRUE(drop_menu != NULL);
794    ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing());
795
796    // Now drag back over first menu.
797    views::TextButton* button = GetBookmarkButton(0);
798    gfx::Point loc(button->width() / 2, button->height() / 2);
799    views::View::ConvertPointToScreen(button, &loc);
800    ui_controls::SendMouseMoveNotifyWhenDone(loc.x(), loc.y(),
801        base::Bind(&BookmarkBarViewTest8::Step5, this));
802  }
803
804  void Step5() {
805    // Drop on folder F11.
806    views::MenuItemView* drop_menu = bb_view_->GetDropMenu();
807    ASSERT_TRUE(drop_menu != NULL);
808    ASSERT_TRUE(drop_menu->GetSubmenu()->IsShowing());
809
810    views::MenuItemView* target_menu =
811        drop_menu->GetSubmenu()->GetMenuItemAt(1);
812    ui_test_utils::MoveMouseToCenterAndPress(
813        target_menu, ui_controls::LEFT, ui_controls::UP,
814        CreateEventTask(this, &BookmarkBarViewTest8::Step6));
815  }
816
817  void Step6() {
818    // Make sure drop was processed.
819    GURL final_url = model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->
820        GetChild(1)->url();
821    ASSERT_TRUE(final_url == url_dragging_);
822    Done();
823  }
824
825  GURL url_dragging_;
826};
827
828#if !(defined(OS_WIN) && defined(USE_AURA))
829// This test passes locally (on aero and non-aero) but fails on the trybots and
830// buildbot.
831// http://crbug.com/154081
832VIEW_TEST(BookmarkBarViewTest8, MAYBE(DNDBackToOriginatingMenu))
833#endif
834
835// Moves the mouse over the scroll button and makes sure we get scrolling.
836class BookmarkBarViewTest9 : public BookmarkBarViewEventTestBase {
837 protected:
838  virtual bool CreateBigMenu() OVERRIDE { return true; }
839
840  virtual void DoTestOnMessageLoop() OVERRIDE {
841    // Move the mouse to the first folder on the bookmark bar and press the
842    // mouse.
843    views::TextButton* button = GetBookmarkButton(0);
844    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
845        ui_controls::DOWN | ui_controls::UP,
846        CreateEventTask(this, &BookmarkBarViewTest9::Step2));
847  }
848
849 private:
850  void Step2() {
851    // Menu should be showing.
852    views::MenuItemView* menu = bb_view_->GetMenu();
853    ASSERT_TRUE(menu != NULL);
854    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
855
856    first_menu_ = menu->GetSubmenu()->GetMenuItemAt(0);
857    gfx::Point menu_loc;
858    views::View::ConvertPointToScreen(first_menu_, &menu_loc);
859    start_y_ = menu_loc.y();
860
861    // Move the mouse over the scroll button.
862    views::View* scroll_container = menu->GetSubmenu()->parent();
863    ASSERT_TRUE(scroll_container != NULL);
864    scroll_container = scroll_container->parent();
865    ASSERT_TRUE(scroll_container != NULL);
866    views::View* scroll_down_button = scroll_container->child_at(1);
867    ASSERT_TRUE(scroll_down_button);
868    gfx::Point loc(scroll_down_button->width() / 2,
869                   scroll_down_button->height() / 2);
870    views::View::ConvertPointToScreen(scroll_down_button, &loc);
871
872    // On linux, the sending one location isn't enough.
873    ui_controls::SendMouseMove(loc.x() - 1 , loc.y() - 1);
874    ui_controls::SendMouseMoveNotifyWhenDone(
875        loc.x(), loc.y(), CreateEventTask(this, &BookmarkBarViewTest9::Step3));
876  }
877
878  void Step3() {
879    base::MessageLoop::current()->PostDelayedTask(
880        FROM_HERE,
881        base::Bind(&BookmarkBarViewTest9::Step4, this),
882        base::TimeDelta::FromMilliseconds(200));
883  }
884
885  void Step4() {
886    gfx::Point menu_loc;
887    views::View::ConvertPointToScreen(first_menu_, &menu_loc);
888    ASSERT_NE(start_y_, menu_loc.y());
889
890    // Hide menu.
891    bb_view_->GetMenu()->GetMenuController()->CancelAll();
892
893    // On linux, Cancelling menu will call Quit on the message loop,
894    // which can interfere with Done. We need to run Done in the
895    // next execution loop.
896    base::MessageLoop::current()->PostTask(
897        FROM_HERE, base::Bind(&ViewEventTestBase::Done, this));
898  }
899
900  int start_y_;
901  views::MenuItemView* first_menu_;
902};
903
904VIEW_TEST(BookmarkBarViewTest9, ScrollButtonScrolls)
905
906// Tests up/down/left/enter key messages.
907class BookmarkBarViewTest10 : public BookmarkBarViewEventTestBase {
908 protected:
909  virtual void DoTestOnMessageLoop() OVERRIDE {
910    // Move the mouse to the first folder on the bookmark bar and press the
911    // mouse.
912    views::TextButton* button = GetBookmarkButton(0);
913    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
914        ui_controls::DOWN | ui_controls::UP,
915        CreateEventTask(this, &BookmarkBarViewTest10::Step2));
916    base::MessageLoop::current()->RunUntilIdle();
917  }
918
919 private:
920  void Step2() {
921    // Menu should be showing.
922    views::MenuItemView* menu = bb_view_->GetMenu();
923    ASSERT_TRUE(menu != NULL);
924    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
925
926    // Send a down event, which should select the first item.
927    ui_controls::SendKeyPressNotifyWhenDone(
928        window_->GetNativeWindow(), ui::VKEY_DOWN, false, false, false, false,
929        CreateEventTask(this, &BookmarkBarViewTest10::Step3));
930  }
931
932  void Step3() {
933    // Make sure menu is showing and item is selected.
934    views::MenuItemView* menu = bb_view_->GetMenu();
935    ASSERT_TRUE(menu != NULL);
936    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
937    ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected());
938
939    // Send a key down event, which should select the next item.
940    ui_controls::SendKeyPressNotifyWhenDone(
941        window_->GetNativeWindow(), ui::VKEY_DOWN, false, false, false, false,
942        CreateEventTask(this, &BookmarkBarViewTest10::Step4));
943  }
944
945  void Step4() {
946    views::MenuItemView* menu = bb_view_->GetMenu();
947    ASSERT_TRUE(menu != NULL);
948    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
949    ASSERT_FALSE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected());
950    ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(1)->IsSelected());
951
952    // Send a right arrow to force the menu to open.
953    ui_controls::SendKeyPressNotifyWhenDone(
954        window_->GetNativeWindow(), ui::VKEY_RIGHT, false, false, false, false,
955        CreateEventTask(this, &BookmarkBarViewTest10::Step5));
956  }
957
958  void Step5() {
959    // Make sure the submenu is showing.
960    views::MenuItemView* menu = bb_view_->GetMenu();
961    ASSERT_TRUE(menu != NULL);
962    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
963    views::MenuItemView* submenu = menu->GetSubmenu()->GetMenuItemAt(1);
964    ASSERT_TRUE(submenu->IsSelected());
965    ASSERT_TRUE(submenu->GetSubmenu());
966    ASSERT_TRUE(submenu->GetSubmenu()->IsShowing());
967
968    // Send a left arrow to close the submenu.
969    ui_controls::SendKeyPressNotifyWhenDone(
970        window_->GetNativeWindow(), ui::VKEY_LEFT, false, false, false, false,
971        CreateEventTask(this, &BookmarkBarViewTest10::Step6));
972  }
973
974  void Step6() {
975    // Make sure the submenu is showing.
976    views::MenuItemView* menu = bb_view_->GetMenu();
977    ASSERT_TRUE(menu != NULL);
978    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
979    views::MenuItemView* submenu = menu->GetSubmenu()->GetMenuItemAt(1);
980    ASSERT_TRUE(submenu->IsSelected());
981    ASSERT_TRUE(!submenu->GetSubmenu() || !submenu->GetSubmenu()->IsShowing());
982
983    // Send a down arrow to wrap back to f1a
984    ui_controls::SendKeyPressNotifyWhenDone(
985        window_->GetNativeWindow(), ui::VKEY_DOWN, false, false, false, false,
986        CreateEventTask(this, &BookmarkBarViewTest10::Step7));
987  }
988
989  void Step7() {
990    // Make sure menu is showing and item is selected.
991    views::MenuItemView* menu = bb_view_->GetMenu();
992    ASSERT_TRUE(menu != NULL);
993    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
994    ASSERT_TRUE(menu->GetSubmenu()->GetMenuItemAt(0)->IsSelected());
995
996    // Send enter, which should select the item.
997    ui_controls::SendKeyPressNotifyWhenDone(
998        window_->GetNativeWindow(), ui::VKEY_RETURN, false, false, false, false,
999        CreateEventTask(this, &BookmarkBarViewTest10::Step8));
1000  }
1001
1002  void Step8() {
1003    ASSERT_TRUE(
1004        model_->bookmark_bar_node()->GetChild(0)->GetChild(0)->url() ==
1005        navigator_.url_);
1006    Done();
1007  }
1008};
1009
1010VIEW_TEST(BookmarkBarViewTest10, KeyEvents)
1011
1012// Make sure the menu closes with the following sequence: show menu, show
1013// context menu, close context menu (via escape), then click else where. This
1014// effectively verifies we maintain mouse capture after the context menu is
1015// hidden.
1016class BookmarkBarViewTest11 : public BookmarkBarViewEventTestBase {
1017 public:
1018  BookmarkBarViewTest11()
1019      : observer_(CreateEventTask(this, &BookmarkBarViewTest11::Step3)) {
1020  }
1021
1022 protected:
1023  virtual void DoTestOnMessageLoop() OVERRIDE {
1024    // Move the mouse to the first folder on the bookmark bar and press the
1025    // mouse.
1026    views::TextButton* button = bb_view_->other_bookmarked_button();
1027    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1028        ui_controls::DOWN | ui_controls::UP,
1029        CreateEventTask(this, &BookmarkBarViewTest11::Step2));
1030  }
1031
1032 private:
1033  void Step2() {
1034    // Menu should be showing.
1035    views::MenuItemView* menu = bb_view_->GetMenu();
1036    ASSERT_TRUE(menu != NULL);
1037    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1038
1039    views::MenuItemView* child_menu =
1040        menu->GetSubmenu()->GetMenuItemAt(0);
1041    ASSERT_TRUE(child_menu != NULL);
1042
1043    // Right click on the first child to get its context menu.
1044    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1045        ui_controls::DOWN | ui_controls::UP, base::Closure());
1046    // Step3 will be invoked by ContextMenuNotificationObserver.
1047  }
1048
1049  void Step3() {
1050    // Send escape so that the context menu hides.
1051    ui_controls::SendKeyPressNotifyWhenDone(
1052        window_->GetNativeWindow(), ui::VKEY_ESCAPE, false, false, false, false,
1053        CreateEventTask(this, &BookmarkBarViewTest11::Step4));
1054  }
1055
1056  void Step4() {
1057    // Make sure the context menu is no longer showing.
1058    views::MenuItemView* menu = bb_view_->GetContextMenu();
1059    ASSERT_TRUE(!menu || !menu->GetSubmenu() ||
1060                !menu->GetSubmenu()->IsShowing());
1061
1062    // But the menu should be showing.
1063    menu = bb_view_->GetMenu();
1064    ASSERT_TRUE(menu && menu->GetSubmenu() && menu->GetSubmenu()->IsShowing());
1065
1066    // Now click on empty space.
1067    gfx::Point mouse_loc;
1068    views::View::ConvertPointToScreen(bb_view_.get(), &mouse_loc);
1069    ui_controls::SendMouseMove(mouse_loc.x(), mouse_loc.y());
1070    ui_controls::SendMouseEventsNotifyWhenDone(
1071        ui_controls::LEFT, ui_controls::UP | ui_controls::DOWN,
1072        CreateEventTask(this, &BookmarkBarViewTest11::Step5));
1073  }
1074
1075  void Step5() {
1076    // Make sure the menu is not showing.
1077    views::MenuItemView* menu = bb_view_->GetMenu();
1078    ASSERT_TRUE(!menu || !menu->GetSubmenu() ||
1079                !menu->GetSubmenu()->IsShowing());
1080    Done();
1081  }
1082
1083  ContextMenuNotificationObserver observer_;
1084};
1085
1086#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
1087// TODO(erg): linux_aura bringup: http://crbug.com/163931
1088#define MAYBE_CloseMenuAfterClosingContextMenu \
1089  DISABLED_CloseMenuAfterClosingContextMenu
1090#else
1091#define MAYBE_CloseMenuAfterClosingContextMenu CloseMenuAfterClosingContextMenu
1092#endif
1093
1094VIEW_TEST(BookmarkBarViewTest11, MAYBE_CloseMenuAfterClosingContextMenu)
1095
1096// Tests showing a modal dialog from a context menu.
1097class BookmarkBarViewTest12 : public BookmarkBarViewEventTestBase {
1098 protected:
1099  virtual void DoTestOnMessageLoop() OVERRIDE {
1100    // Open up the other folder.
1101    views::TextButton* button = bb_view_->other_bookmarked_button();
1102    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1103        ui_controls::DOWN | ui_controls::UP,
1104        CreateEventTask(this, &BookmarkBarViewTest12::Step2));
1105    chrome::num_bookmark_urls_before_prompting = 1;
1106  }
1107
1108  virtual ~BookmarkBarViewTest12() {
1109    chrome::num_bookmark_urls_before_prompting = 15;
1110  }
1111
1112 private:
1113  void Step2() {
1114    // Menu should be showing.
1115    views::MenuItemView* menu = bb_view_->GetMenu();
1116    ASSERT_TRUE(menu != NULL);
1117    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1118
1119    views::MenuItemView* child_menu =
1120        menu->GetSubmenu()->GetMenuItemAt(1);
1121    ASSERT_TRUE(child_menu != NULL);
1122
1123    // Right click on the second child (a folder) to get its context menu.
1124    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1125        ui_controls::DOWN | ui_controls::UP,
1126        CreateEventTask(this, &BookmarkBarViewTest12::Step3));
1127  }
1128
1129  void Step3() {
1130    // Make sure the context menu is showing.
1131    views::MenuItemView* menu = bb_view_->GetContextMenu();
1132    ASSERT_TRUE(menu && menu->GetSubmenu() && menu->GetSubmenu()->IsShowing());
1133
1134    // Select the first item in the context menu (open all).
1135    views::MenuItemView* child_menu =
1136        menu->GetSubmenu()->GetMenuItemAt(0);
1137    ASSERT_TRUE(child_menu != NULL);
1138    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::LEFT,
1139        ui_controls::DOWN | ui_controls::UP, base::Closure());
1140
1141    // Delay until we send tab, otherwise the message box doesn't appear
1142    // correctly.
1143    base::MessageLoop::current()->PostDelayedTask(
1144        FROM_HERE,
1145        CreateEventTask(this, &BookmarkBarViewTest12::Step4),
1146        base::TimeDelta::FromSeconds(1));
1147  }
1148
1149  void Step4() {
1150    // Press tab to give focus to the cancel button.
1151    ui_controls::SendKeyPress(
1152        window_->GetNativeWindow(), ui::VKEY_TAB, false, false, false, false);
1153
1154    // For some reason return isn't processed correctly unless we delay.
1155    base::MessageLoop::current()->PostDelayedTask(
1156        FROM_HERE,
1157        CreateEventTask(this, &BookmarkBarViewTest12::Step5),
1158        base::TimeDelta::FromSeconds(1));
1159  }
1160
1161  void Step5() {
1162    // And press enter so that the cancel button is selected.
1163    ui_controls::SendKeyPressNotifyWhenDone(
1164        window_->GetNativeWindow(), ui::VKEY_RETURN, false, false, false, false,
1165        CreateEventTask(this, &BookmarkBarViewTest12::Step6));
1166  }
1167
1168  void Step6() {
1169    // Do a delayed task to give the dialog time to exit.
1170    base::MessageLoop::current()->PostTask(
1171        FROM_HERE, CreateEventTask(this, &BookmarkBarViewTest12::Step7));
1172  }
1173
1174  void Step7() {
1175    Done();
1176  }
1177};
1178
1179#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
1180// TODO(erg): linux_aura bringup: http://crbug.com/163931
1181#define MAYBE_CloseWithModalDialog DISABLED_CloseWithModalDialog
1182#else
1183#define MAYBE_CloseWithModalDialog CloseWithModalDialog
1184#endif
1185
1186VIEW_TEST(BookmarkBarViewTest12, MAYBE_CloseWithModalDialog)
1187
1188// Tests clicking on the separator of a context menu (this is for coverage of
1189// bug 17862).
1190class BookmarkBarViewTest13 : public BookmarkBarViewEventTestBase {
1191 public:
1192  BookmarkBarViewTest13()
1193      : observer_(CreateEventTask(this, &BookmarkBarViewTest13::Step3)) {
1194  }
1195
1196 protected:
1197  virtual void DoTestOnMessageLoop() OVERRIDE {
1198    // Move the mouse to the first folder on the bookmark bar and press the
1199    // mouse.
1200    views::TextButton* button = bb_view_->other_bookmarked_button();
1201    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1202        ui_controls::DOWN | ui_controls::UP,
1203        CreateEventTask(this, &BookmarkBarViewTest13::Step2));
1204  }
1205
1206 private:
1207  void Step2() {
1208    // Menu should be showing.
1209    views::MenuItemView* menu = bb_view_->GetMenu();
1210    ASSERT_TRUE(menu != NULL);
1211    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1212
1213    views::MenuItemView* child_menu =
1214        menu->GetSubmenu()->GetMenuItemAt(0);
1215    ASSERT_TRUE(child_menu != NULL);
1216
1217    // Right click on the first child to get its context menu.
1218    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1219        ui_controls::DOWN | ui_controls::UP, base::Closure());
1220    // Step3 will be invoked by ContextMenuNotificationObserver.
1221  }
1222
1223  void Step3() {
1224    // Make sure the context menu is showing.
1225    views::MenuItemView* menu = bb_view_->GetContextMenu();
1226    ASSERT_TRUE(menu != NULL);
1227    ASSERT_TRUE(menu->GetSubmenu());
1228    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1229
1230    // Find the first separator.
1231    views::SubmenuView* submenu = menu->GetSubmenu();
1232    views::View* separator_view = NULL;
1233    for (int i = 0; i < submenu->child_count(); ++i) {
1234      if (submenu->child_at(i)->id() != views::MenuItemView::kMenuItemViewID) {
1235        separator_view = submenu->child_at(i);
1236        break;
1237      }
1238    }
1239    ASSERT_TRUE(separator_view);
1240
1241    // Click on the separator. Clicking on the separator shouldn't visually
1242    // change anything.
1243    ui_test_utils::MoveMouseToCenterAndPress(separator_view,
1244        ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1245        CreateEventTask(this, &BookmarkBarViewTest13::Step4));
1246  }
1247
1248  void Step4() {
1249    // The context menu should still be showing.
1250    views::MenuItemView* menu = bb_view_->GetContextMenu();
1251    ASSERT_TRUE(menu != NULL);
1252    ASSERT_TRUE(menu->GetSubmenu());
1253    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1254
1255    // Select the first context menu item.
1256    ui_test_utils::MoveMouseToCenterAndPress(
1257        menu->GetSubmenu()->GetMenuItemAt(0),
1258        ui_controls::LEFT,
1259        ui_controls::DOWN | ui_controls::UP,
1260        CreateEventTask(this, &BookmarkBarViewTest13::Step5));
1261  }
1262
1263  void Step5() {
1264    Done();
1265  }
1266
1267  ContextMenuNotificationObserver observer_;
1268};
1269
1270VIEW_TEST(BookmarkBarViewTest13, ClickOnContextMenuSeparator)
1271
1272// Makes sure right clicking on a folder on the bookmark bar doesn't result in
1273// both a context menu and showing the menu.
1274class BookmarkBarViewTest14 : public BookmarkBarViewEventTestBase {
1275 public:
1276  BookmarkBarViewTest14()
1277      : observer_(CreateEventTask(this, &BookmarkBarViewTest14::Step2)) {
1278  }
1279
1280 protected:
1281  virtual void DoTestOnMessageLoop() OVERRIDE {
1282    // Move the mouse to the first folder on the bookmark bar and press the
1283    // right mouse button.
1284    views::TextButton* button = GetBookmarkButton(0);
1285    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::RIGHT,
1286        ui_controls::DOWN | ui_controls::UP, base::Closure());
1287    // Step2 will be invoked by ContextMenuNotificationObserver.
1288  }
1289
1290 private:
1291
1292  void Step2() {
1293    // Menu should NOT be showing.
1294    views::MenuItemView* menu = bb_view_->GetMenu();
1295    ASSERT_TRUE(menu == NULL);
1296
1297    // Send escape so that the context menu hides.
1298    ui_controls::SendKeyPressNotifyWhenDone(
1299        window_->GetNativeWindow(), ui::VKEY_ESCAPE, false, false, false, false,
1300        CreateEventTask(this, &BookmarkBarViewTest14::Step3));
1301  }
1302
1303  void Step3() {
1304    Done();
1305  }
1306
1307  ContextMenuNotificationObserver observer_;
1308};
1309
1310VIEW_TEST(BookmarkBarViewTest14, ContextMenus2)
1311
1312// Makes sure deleting from the context menu keeps the bookmark menu showing.
1313class BookmarkBarViewTest15 : public BookmarkBarViewEventTestBase {
1314 public:
1315  BookmarkBarViewTest15()
1316      : deleted_menu_id_(0),
1317        observer_(CreateEventTask(this, &BookmarkBarViewTest15::Step3)) {
1318  }
1319
1320 protected:
1321  virtual void DoTestOnMessageLoop() OVERRIDE {
1322    // Show the other bookmarks.
1323    views::TextButton* button = bb_view_->other_bookmarked_button();
1324    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1325        ui_controls::DOWN | ui_controls::UP,
1326        CreateEventTask(this, &BookmarkBarViewTest15::Step2));
1327  }
1328
1329 private:
1330  void Step2() {
1331    // Menu should be showing.
1332    views::MenuItemView* menu = bb_view_->GetMenu();
1333    ASSERT_TRUE(menu != NULL);
1334    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1335
1336    views::MenuItemView* child_menu =
1337        menu->GetSubmenu()->GetMenuItemAt(1);
1338    ASSERT_TRUE(child_menu != NULL);
1339
1340    deleted_menu_id_ = child_menu->GetCommand();
1341
1342    // Right click on the second child to get its context menu.
1343    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1344        ui_controls::DOWN | ui_controls::UP, base::Closure());
1345    // Step3 will be invoked by ContextMenuNotificationObserver.
1346  }
1347
1348  void Step3() {
1349    // Make sure the context menu is showing.
1350    views::MenuItemView* menu = bb_view_->GetContextMenu();
1351    ASSERT_TRUE(menu != NULL);
1352    ASSERT_TRUE(menu->GetSubmenu());
1353    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1354
1355    views::MenuItemView* delete_menu =
1356        menu->GetMenuItemByID(IDC_BOOKMARK_BAR_REMOVE);
1357    ASSERT_TRUE(delete_menu);
1358
1359    // Click on the delete button.
1360    ui_test_utils::MoveMouseToCenterAndPress(delete_menu,
1361        ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1362        CreateEventTask(this, &BookmarkBarViewTest15::Step4));
1363  }
1364
1365  void Step4() {
1366    // The context menu should not be showing.
1367    views::MenuItemView* context_menu = bb_view_->GetContextMenu();
1368    ASSERT_TRUE(context_menu == NULL);
1369
1370    // But the menu should be showing.
1371    views::MenuItemView* menu = bb_view_->GetMenu();
1372    ASSERT_TRUE(menu != NULL);
1373    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1374
1375    // And the deleted_menu_id_ should have been removed.
1376    ASSERT_TRUE(menu->GetMenuItemByID(deleted_menu_id_) == NULL);
1377
1378    bb_view_->GetMenu()->GetMenuController()->CancelAll();
1379
1380    Done();
1381  }
1382
1383  int deleted_menu_id_;
1384  ContextMenuNotificationObserver observer_;
1385};
1386
1387VIEW_TEST(BookmarkBarViewTest15, MenuStaysVisibleAfterDelete)
1388
1389// Tests that we don't crash or get stuck if the parent of a menu is closed.
1390class BookmarkBarViewTest16 : public BookmarkBarViewEventTestBase {
1391 protected:
1392  virtual void DoTestOnMessageLoop() OVERRIDE {
1393    // Move the mouse to the first folder on the bookmark bar and press the
1394    // mouse.
1395    views::TextButton* button = GetBookmarkButton(0);
1396    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1397        ui_controls::DOWN | ui_controls::UP,
1398        CreateEventTask(this, &BookmarkBarViewTest16::Step2));
1399  }
1400
1401 private:
1402  void Step2() {
1403    // Menu should be showing.
1404    views::MenuItemView* menu = bb_view_->GetMenu();
1405    ASSERT_TRUE(menu != NULL);
1406    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1407
1408    // Button should be depressed.
1409    views::TextButton* button = GetBookmarkButton(0);
1410    ASSERT_TRUE(button->state() == views::CustomButton::STATE_PRESSED);
1411
1412    // Close the window.
1413    window_->Close();
1414    window_ = NULL;
1415
1416    base::MessageLoop::current()->PostTask(
1417        FROM_HERE, CreateEventTask(this, &BookmarkBarViewTest16::Done));
1418  }
1419};
1420
1421#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1422// TODO(erg): linux_aura bringup: http://crbug.com/163931
1423#define MAYBE_DeleteMenu DISABLED_DeleteMenu
1424#else
1425#define MAYBE_DeleteMenu DeleteMenu
1426#endif
1427
1428VIEW_TEST(BookmarkBarViewTest16, MAYBE_DeleteMenu)
1429
1430// Makes sure right clicking on an item while a context menu is already showing
1431// doesn't crash and works.
1432class BookmarkBarViewTest17 : public BookmarkBarViewEventTestBase {
1433 public:
1434  BookmarkBarViewTest17()
1435      : observer_(CreateEventTask(this, &BookmarkBarViewTest17::Step3)) {
1436  }
1437
1438 protected:
1439  virtual void DoTestOnMessageLoop() OVERRIDE {
1440    // Move the mouse to the other folder on the bookmark bar and press the
1441    // left mouse button.
1442    views::TextButton* button = bb_view_->other_bookmarked_button();
1443    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1444        ui_controls::DOWN | ui_controls::UP,
1445        CreateEventTask(this, &BookmarkBarViewTest17::Step2));
1446  }
1447
1448 private:
1449  void Step2() {
1450    // Menu should be showing.
1451    views::MenuItemView* menu = bb_view_->GetMenu();
1452    ASSERT_TRUE(menu != NULL);
1453    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1454
1455    // Right click on the second item to show its context menu.
1456    views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(2);
1457    ASSERT_TRUE(child_menu != NULL);
1458    ui_test_utils::MoveMouseToCenterAndPress(child_menu, ui_controls::RIGHT,
1459        ui_controls::DOWN | ui_controls::UP, base::Closure());
1460    // Step3 will be invoked by ContextMenuNotificationObserver.
1461  }
1462
1463  void Step3() {
1464    // Make sure the context menu is showing.
1465    views::MenuItemView* context_menu = bb_view_->GetContextMenu();
1466    ASSERT_TRUE(context_menu != NULL);
1467    ASSERT_TRUE(context_menu->GetSubmenu());
1468    ASSERT_TRUE(context_menu->GetSubmenu()->IsShowing());
1469
1470    // Right click on the first menu item to trigger its context menu.
1471    views::MenuItemView* menu = bb_view_->GetMenu();
1472    ASSERT_TRUE(menu != NULL);
1473    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1474    views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(1);
1475    ASSERT_TRUE(child_menu != NULL);
1476
1477    // The context menu and child_menu can be overlapped, calculate the
1478    // non-intersected Rect of the child menu and click on its center to make
1479    // sure the click is always on the child menu.
1480    gfx::Rect context_rect = context_menu->GetSubmenu()->GetBoundsInScreen();
1481    gfx::Rect child_menu_rect = child_menu->GetBoundsInScreen();
1482    gfx::Rect clickable_rect =
1483        gfx::SubtractRects(child_menu_rect, context_rect);
1484    ASSERT_FALSE(clickable_rect.IsEmpty());
1485    observer_.set_task(CreateEventTask(this, &BookmarkBarViewTest17::Step4));
1486    MoveMouseAndPress(clickable_rect.CenterPoint(), ui_controls::RIGHT,
1487        ui_controls::DOWN | ui_controls::UP, base::Closure());
1488    // Step4 will be invoked by ContextMenuNotificationObserver.
1489  }
1490
1491  void Step4() {
1492    // The context menu should still be showing.
1493    views::MenuItemView* context_menu = bb_view_->GetContextMenu();
1494    ASSERT_TRUE(context_menu != NULL);
1495
1496    // And the menu should be showing.
1497    views::MenuItemView* menu = bb_view_->GetMenu();
1498    ASSERT_TRUE(menu != NULL);
1499    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1500
1501    bb_view_->GetMenu()->GetMenuController()->CancelAll();
1502
1503    Done();
1504  }
1505
1506  ContextMenuNotificationObserver observer_;
1507};
1508
1509#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
1510// TODO(erg): linux_aura bringup: http://crbug.com/163931
1511#define MAYBE_ContextMenus3 DISABLED_ContextMenus3
1512#else
1513#define MAYBE_ContextMenus3 ContextMenus3
1514#endif
1515
1516VIEW_TEST(BookmarkBarViewTest17, MAYBE_ContextMenus3)
1517
1518// Verifies sibling menus works. Clicks on the 'other bookmarks' folder, then
1519// moves the mouse over the first item on the bookmark bar and makes sure the
1520// menu appears.
1521class BookmarkBarViewTest18 : public BookmarkBarViewEventTestBase {
1522 protected:
1523  virtual void DoTestOnMessageLoop() OVERRIDE {
1524    // Move the mouse to the other folder on the bookmark bar and press the
1525    // left mouse button.
1526    views::TextButton* button = bb_view_->other_bookmarked_button();
1527    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1528        ui_controls::DOWN | ui_controls::UP,
1529        CreateEventTask(this, &BookmarkBarViewTest18::Step2));
1530  }
1531
1532 private:
1533  void Step2() {
1534    // Menu should be showing.
1535    views::MenuItemView* menu = bb_view_->GetMenu();
1536    ASSERT_TRUE(menu != NULL);
1537    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1538
1539    // Move the mouse to the first folder on the bookmark bar
1540    views::TextButton* button = GetBookmarkButton(0);
1541    gfx::Point button_center(button->width() / 2, button->height() / 2);
1542    views::View::ConvertPointToScreen(button, &button_center);
1543    ui_controls::SendMouseMoveNotifyWhenDone(
1544        button_center.x(), button_center.y(),
1545        CreateEventTask(this, &BookmarkBarViewTest18::Step3));
1546  }
1547
1548  void Step3() {
1549    // Make sure the menu is showing.
1550    views::MenuItemView* menu = bb_view_->GetMenu();
1551    ASSERT_TRUE(menu != NULL);
1552    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1553
1554    // The menu for the first folder should be in the pressed state (since the
1555    // menu is showing for it).
1556    EXPECT_EQ(views::CustomButton::STATE_PRESSED,
1557              GetBookmarkButton(0)->state());
1558
1559    menu->GetMenuController()->CancelAll();
1560
1561    Done();
1562  }
1563};
1564
1565#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1566// TODO(erg): linux_aura bringup: http://crbug.com/163931
1567#define MAYBE_BookmarkBarViewTest18_SiblingMenu \
1568  DISABLED_BookmarkBarViewTest18_SiblingMenu
1569#else
1570#define MAYBE_BookmarkBarViewTest18_SiblingMenu \
1571  BookmarkBarViewTest18_SiblingMenu
1572#endif
1573
1574VIEW_TEST(BookmarkBarViewTest18, MAYBE_BookmarkBarViewTest18_SiblingMenu)
1575
1576// Verifies mousing over an already open sibling menu doesn't prematurely cancel
1577// the menu.
1578class BookmarkBarViewTest19 : public BookmarkBarViewEventTestBase {
1579 protected:
1580  virtual void DoTestOnMessageLoop() OVERRIDE {
1581    // Move the mouse to the other folder on the bookmark bar and press the
1582    // left mouse button.
1583    views::TextButton* button = bb_view_->other_bookmarked_button();
1584    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1585        ui_controls::DOWN | ui_controls::UP,
1586        CreateEventTask(this, &BookmarkBarViewTest19::Step2));
1587  }
1588
1589 private:
1590  void Step2() {
1591    // Menu should be showing.
1592    views::MenuItemView* menu = bb_view_->GetMenu();
1593    ASSERT_TRUE(menu != NULL);
1594    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1595
1596    // Click on the first folder.
1597    views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(1);
1598    ASSERT_TRUE(child_menu != NULL);
1599    ui_test_utils::MoveMouseToCenterAndPress(
1600        child_menu, ui_controls::LEFT,
1601        ui_controls::DOWN | ui_controls::UP,
1602        CreateEventTask(this, &BookmarkBarViewTest19::Step3));
1603  }
1604
1605  void Step3() {
1606    // Make sure the menu is showing.
1607    views::MenuItemView* menu = bb_view_->GetMenu();
1608    ASSERT_TRUE(menu != NULL);
1609    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1610
1611    // Move the mouse back to the other bookmark button.
1612    views::TextButton* button = bb_view_->other_bookmarked_button();
1613    gfx::Point button_center(button->width() / 2, button->height() / 2);
1614    views::View::ConvertPointToScreen(button, &button_center);
1615    ui_controls::SendMouseMoveNotifyWhenDone(
1616        button_center.x() + 1, button_center.y() + 1,
1617        CreateEventTask(this, &BookmarkBarViewTest19::Step4));
1618  }
1619
1620  void Step4() {
1621    // Menu should be showing.
1622    views::MenuItemView* menu = bb_view_->GetMenu();
1623    ASSERT_TRUE(menu != NULL);
1624    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1625
1626    // Click on the first folder.
1627    views::MenuItemView* child_menu = menu->GetSubmenu()->GetMenuItemAt(1);
1628    ASSERT_TRUE(child_menu != NULL);
1629    ui_test_utils::MoveMouseToCenterAndPress(
1630        child_menu,
1631        ui_controls::LEFT,
1632        ui_controls::DOWN | ui_controls::UP,
1633        CreateEventTask(this, &BookmarkBarViewTest19::Step5));
1634  }
1635
1636  void Step5() {
1637    // Make sure the menu is showing.
1638    views::MenuItemView* menu = bb_view_->GetMenu();
1639    ASSERT_TRUE(menu != NULL);
1640    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1641
1642    menu->GetMenuController()->CancelAll();
1643
1644    Done();
1645  }
1646};
1647
1648VIEW_TEST(BookmarkBarViewTest19, BookmarkBarViewTest19_SiblingMenu)
1649
1650// Verify that when clicking a mouse button outside a context menu,
1651// the context menu is dismissed *and* the underlying view receives
1652// the the mouse event (due to event reposting).
1653class BookmarkBarViewTest20 : public BookmarkBarViewEventTestBase {
1654 public:
1655  BookmarkBarViewTest20() : test_view_(new TestViewForMenuExit) {}
1656
1657 protected:
1658  virtual void DoTestOnMessageLoop() OVERRIDE {
1659    // Add |test_view_| next to |bb_view_|.
1660    views::View* parent = bb_view_->parent();
1661    views::View* container_view = new ContainerViewForMenuExit;
1662    container_view->AddChildView(bb_view_.get());
1663    container_view->AddChildView(test_view_);
1664    parent->AddChildView(container_view);
1665    parent->Layout();
1666
1667    ASSERT_EQ(test_view_->press_count(), 0);
1668
1669    // Move the mouse to the Test View and press the left mouse button.
1670    ui_test_utils::MoveMouseToCenterAndPress(
1671        test_view_, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1672        CreateEventTask(this, &BookmarkBarViewTest20::Step1));
1673  }
1674
1675 private:
1676  void Step1() {
1677    ASSERT_EQ(test_view_->press_count(), 1);
1678    ASSERT_TRUE(bb_view_->GetMenu() == NULL);
1679
1680    // Move the mouse to the first folder on the bookmark bar and press the
1681    // left mouse button.
1682    views::TextButton* button = GetBookmarkButton(0);
1683    ui_test_utils::MoveMouseToCenterAndPress(
1684        button, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1685        CreateEventTask(this, &BookmarkBarViewTest20::Step2));
1686  }
1687
1688  void Step2() {
1689    ASSERT_EQ(test_view_->press_count(), 1);
1690    views::MenuItemView* menu = bb_view_->GetMenu();
1691    ASSERT_TRUE(menu != NULL);
1692    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1693
1694    // Move the mouse to the Test View and press the left mouse button.
1695    // The context menu will consume the event and exit. Thereafter,
1696    // the event is reposted and delivered to the Test View which
1697    // increases its press-count.
1698    ui_test_utils::MoveMouseToCenterAndPress(
1699        test_view_, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1700        CreateEventTask(this, &BookmarkBarViewTest20::Step3));
1701  }
1702
1703  void Step3() {
1704    ASSERT_EQ(test_view_->press_count(), 2);
1705    ASSERT_TRUE(bb_view_->GetMenu() == NULL);
1706    Done();
1707  }
1708
1709  class ContainerViewForMenuExit : public views::View {
1710   public:
1711    ContainerViewForMenuExit() {
1712    }
1713
1714    virtual void Layout() OVERRIDE {
1715      DCHECK_EQ(2, child_count());
1716      views::View* bb_view = child_at(0);
1717      views::View* test_view = child_at(1);
1718      const int width = bb_view->width();
1719      const int height = bb_view->height();
1720      bb_view->SetBounds(0,0, width - 22, height);
1721      test_view->SetBounds(width - 20, 0, 20, height);
1722    }
1723
1724   private:
1725
1726    DISALLOW_COPY_AND_ASSIGN(ContainerViewForMenuExit);
1727  };
1728
1729  class TestViewForMenuExit : public views::View {
1730   public:
1731    TestViewForMenuExit() : press_count_(0) {
1732    }
1733    virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
1734      ++press_count_;
1735      return true;
1736    }
1737    int press_count() const { return press_count_; }
1738
1739   private:
1740    int press_count_;
1741
1742    DISALLOW_COPY_AND_ASSIGN(TestViewForMenuExit);
1743  };
1744
1745  TestViewForMenuExit* test_view_;
1746};
1747
1748#if defined(OS_WIN) && !defined(USE_AURA)
1749#define MAYBE_ContextMenuExitTest DISABLED_ContextMenuExitTest
1750#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
1751// TODO(erg): linux_aura bringup: http://crbug.com/163931
1752#define MAYBE_ContextMenuExitTest DISABLED_ContextMenuExitTest
1753#else
1754#define MAYBE_ContextMenuExitTest ContextMenuExitTest
1755#endif
1756
1757VIEW_TEST(BookmarkBarViewTest20, MAYBE_ContextMenuExitTest)
1758
1759// Tests context menu by way of opening a context menu for a empty folder menu.
1760// The opened context menu should behave as it is from the folder button.
1761class BookmarkBarViewTest21 : public BookmarkBarViewEventTestBase {
1762 public:
1763  BookmarkBarViewTest21()
1764      : observer_(CreateEventTask(this, &BookmarkBarViewTest21::Step3)) {
1765  }
1766
1767 protected:
1768  // Move the mouse to the empty folder on the bookmark bar and press the
1769  // left mouse button.
1770  virtual void DoTestOnMessageLoop() OVERRIDE {
1771    views::TextButton* button = GetBookmarkButton(5);
1772    ui_test_utils::MoveMouseToCenterAndPress(button, ui_controls::LEFT,
1773        ui_controls::DOWN | ui_controls::UP,
1774        CreateEventTask(this, &BookmarkBarViewTest21::Step2));
1775  }
1776
1777 private:
1778  // Confirm that a menu for empty folder shows and right click the menu.
1779  void Step2() {
1780    // Menu should be showing.
1781    views::MenuItemView* menu = bb_view_->GetMenu();
1782    ASSERT_TRUE(menu != NULL);
1783
1784    views::SubmenuView* submenu = menu->GetSubmenu();
1785    ASSERT_TRUE(submenu->IsShowing());
1786    ASSERT_EQ(1, submenu->child_count());
1787
1788    views::View* view = submenu->child_at(0);
1789    ASSERT_TRUE(view != NULL);
1790    EXPECT_EQ(views::MenuItemView::kEmptyMenuItemViewID, view->id());
1791
1792    // Right click on the first child to get its context menu.
1793    ui_test_utils::MoveMouseToCenterAndPress(view, ui_controls::RIGHT,
1794        ui_controls::DOWN | ui_controls::UP, base::Closure());
1795    // Step3 will be invoked by ContextMenuNotificationObserver.
1796  }
1797
1798  // Confirm that context menu shows and click REMOVE menu.
1799  void Step3() {
1800    // Make sure the context menu is showing.
1801    views::MenuItemView* menu = bb_view_->GetContextMenu();
1802    ASSERT_TRUE(menu != NULL);
1803    ASSERT_TRUE(menu->GetSubmenu());
1804    ASSERT_TRUE(menu->GetSubmenu()->IsShowing());
1805
1806    views::MenuItemView* delete_menu =
1807        menu->GetMenuItemByID(IDC_BOOKMARK_BAR_REMOVE);
1808    ASSERT_TRUE(delete_menu);
1809
1810    // Click on the delete menu item.
1811    ui_test_utils::MoveMouseToCenterAndPress(delete_menu,
1812        ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
1813        CreateEventTask(this, &BookmarkBarViewTest21::Step4));
1814  }
1815
1816  // Confirm that the empty folder gets removed and menu doesn't show.
1817  void Step4() {
1818    views::TextButton* button = GetBookmarkButton(5);
1819    ASSERT_TRUE(button);
1820    EXPECT_EQ(ASCIIToUTF16("d"), button->text());
1821    EXPECT_TRUE(bb_view_->GetContextMenu() == NULL);
1822    EXPECT_TRUE(bb_view_->GetMenu() == NULL);
1823
1824    Done();
1825  }
1826
1827  ContextMenuNotificationObserver observer_;
1828};
1829
1830VIEW_TEST(BookmarkBarViewTest21, ContextMenusForEmptyFolder)
1831