Home | History | Annotate | Download | only in bookmarks
      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 
     48 using base::ASCIIToUTF16;
     49 using content::BrowserThread;
     50 using content::OpenURLParams;
     51 using content::PageNavigator;
     52 using content::WebContents;
     53 
     54 namespace {
     55 
     56 // Waits for a views::Widget dialog to show up.
     57 class 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.
    113 class 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.
    150 class 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 
    190 void 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.
    199 class 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.
    249 class 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(bookmarks::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.
    397 class 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 
    445 VIEW_TEST(BookmarkBarViewTest1, Basic)
    446 
    447 // Brings up menu, clicks on empty space and make sure menu hides.
    448 class 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 
    505 VIEW_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.
    509 class 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 
    577 VIEW_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.
    582 class 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).
    611 class 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 
    666 VIEW_TEST(BookmarkBarViewTest4, ContextMenus)
    667 
    668 // Tests drag and drop within the same menu.
    669 class 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
    737 VIEW_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.
    742 class 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 
    776 VIEW_TEST(BookmarkBarViewTest6, OpenMenuOnClickAndHold)
    777 
    778 // Tests drag and drop to different menu.
    779 class 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
    874 VIEW_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.
    879 class 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
    983 VIEW_TEST(BookmarkBarViewTest8, MAYBE(DNDBackToOriginatingMenu))
    984 #endif
    985 
    986 // Moves the mouse over the scroll button and makes sure we get scrolling.
    987 class 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 
   1055 VIEW_TEST(BookmarkBarViewTest9, ScrollButtonScrolls)
   1056 
   1057 // Tests up/down/left/enter key messages.
   1058 class 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 
   1168 VIEW_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.
   1174 class 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 
   1256 VIEW_TEST(BookmarkBarViewTest11, MAYBE_CloseMenuAfterClosingContextMenu)
   1257 
   1258 // Tests showing a modal dialog from a context menu.
   1259 class 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 
   1352 VIEW_TEST(BookmarkBarViewTest12, MAYBE_CloseWithModalDialog)
   1353 
   1354 // Tests clicking on the separator of a context menu (this is for coverage of
   1355 // bug 17862).
   1356 class 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 
   1436 VIEW_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.
   1440 class 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 
   1483 VIEW_TEST(BookmarkBarViewTest14, MAYBE_ContextMenus2)
   1484 
   1485 // Makes sure deleting from the context menu keeps the bookmark menu showing.
   1486 class 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 
   1560 VIEW_TEST(BookmarkBarViewTest15, MenuStaysVisibleAfterDelete)
   1561 
   1562 // Tests that we don't crash or get stuck if the parent of a menu is closed.
   1563 class 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 
   1601 VIEW_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.
   1605 class 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 
   1694 VIEW_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.
   1699 class 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 
   1752 VIEW_TEST(BookmarkBarViewTest18, MAYBE_BookmarkBarViewTest18_SiblingMenu)
   1753 
   1754 // Verifies mousing over an already open sibling menu doesn't prematurely cancel
   1755 // the menu.
   1756 class 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 
   1826 VIEW_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).
   1831 class 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 
   1933 VIEW_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.
   1937 class 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 
   2006 VIEW_TEST(BookmarkBarViewTest21, ContextMenusForEmptyFolder)
   2007