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