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