toolbar_view_interactive_uitest.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright 2014 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/run_loop.h"
6#include "chrome/browser/extensions/extension_browsertest.h"
7#include "chrome/browser/ui/views/frame/browser_view.h"
8#include "chrome/browser/ui/views/frame/test_with_browser_view.h"
9#include "chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h"
10#include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
11#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
12#include "chrome/browser/ui/views/toolbar/wrench_toolbar_button.h"
13#include "chrome/test/base/interactive_test_utils.h"
14#include "extensions/common/feature_switch.h"
15
16// Borrowed from chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc,
17// since these are also disabled on Linux for drag and drop.
18// TODO(erg): Fix DND tests on linux_aura. crbug.com/163931
19#if defined(OS_LINUX) && defined(USE_AURA)
20#define MAYBE(x) DISABLED_##x
21#else
22#define MAYBE(x) x
23#endif
24
25class ToolbarViewInteractiveUITest : public ExtensionBrowserTest {
26 public:
27  ToolbarViewInteractiveUITest();
28  virtual ~ToolbarViewInteractiveUITest();
29
30 protected:
31  ToolbarView* toolbar_view() { return toolbar_view_; }
32  BrowserActionsContainer* browser_actions() { return browser_actions_; }
33
34  // Performs a drag-and-drop operation by moving the mouse to |start|, clicking
35  // the left button, moving the mouse to |end|, and releasing the left button.
36  // TestWhileInDragOperation() is called after the mouse has moved to |end|,
37  // but before the click is released.
38  void DoDragAndDrop(const gfx::Point& start, const gfx::Point& end);
39
40  // A function to perform testing actions while in the drag operation from
41  // DoDragAndDrop.
42  void TestWhileInDragOperation();
43
44 private:
45  // Finishes the drag-and-drop operation started in DoDragAndDrop().
46  void FinishDragAndDrop(const base::Closure& quit_closure);
47
48  // InProcessBrowserTest:
49  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE;
50  virtual void SetUpOnMainThread() OVERRIDE;
51  virtual void TearDownOnMainThread() OVERRIDE;
52
53  ToolbarView* toolbar_view_;
54
55  BrowserActionsContainer* browser_actions_;
56
57  // The drag-and-drop background thread.
58  scoped_ptr<base::Thread> dnd_thread_;
59
60  // Override the extensions-action-redesign switch.
61  scoped_ptr<extensions::FeatureSwitch::ScopedOverride> feature_override_;
62};
63
64ToolbarViewInteractiveUITest::ToolbarViewInteractiveUITest()
65    : toolbar_view_(NULL),
66      browser_actions_(NULL) {
67}
68
69ToolbarViewInteractiveUITest::~ToolbarViewInteractiveUITest() {
70}
71
72void ToolbarViewInteractiveUITest::DoDragAndDrop(const gfx::Point& start,
73                                                 const gfx::Point& end) {
74  // Much of this function is modeled after methods in ViewEventTestBase (in
75  // particular, the |dnd_thread_|, but it's easier to move that here than try
76  // to make ViewEventTestBase play nice with a BrowserView (for the toolbar).
77  // TODO(devlin): In a perfect world, this would be factored better.
78
79  // Send the mouse to |start|, and click.
80  ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(start));
81  ASSERT_TRUE(ui_test_utils::SendMouseEventsSync(
82                  ui_controls::LEFT, ui_controls::DOWN));
83
84  scoped_refptr<content::MessageLoopRunner> runner =
85      new content::MessageLoopRunner();
86
87  ui_controls::SendMouseMoveNotifyWhenDone(
88      end.x() + 10,
89      end.y(),
90      base::Bind(&ToolbarViewInteractiveUITest::FinishDragAndDrop,
91                 base::Unretained(this),
92                 runner->QuitClosure()));
93
94  // Also post a move task to the drag and drop thread.
95  if (!dnd_thread_.get()) {
96    dnd_thread_.reset(new base::Thread("mouse_move_thread"));
97    dnd_thread_->Start();
98  }
99
100  dnd_thread_->message_loop()->PostDelayedTask(
101      FROM_HERE,
102      base::Bind(base::IgnoreResult(&ui_controls::SendMouseMove),
103                 end.x(),
104                 end.y()),
105      base::TimeDelta::FromMilliseconds(200));
106  runner->Run();
107}
108
109void ToolbarViewInteractiveUITest::TestWhileInDragOperation() {
110  EXPECT_TRUE(toolbar_view()->IsWrenchMenuShowing());
111}
112
113void ToolbarViewInteractiveUITest::FinishDragAndDrop(
114    const base::Closure& quit_closure) {
115  dnd_thread_.reset();
116  TestWhileInDragOperation();
117  ui_controls::SendMouseEvents(ui_controls::LEFT, ui_controls::UP);
118  ui_controls::RunClosureAfterAllPendingUIEvents(
119      quit_closure);
120}
121
122void ToolbarViewInteractiveUITest::SetUpCommandLine(
123    base::CommandLine* command_line) {
124  ExtensionBrowserTest::SetUpCommandLine(command_line);
125  // We do this before the rest of the setup because it can affect how the views
126  // are constructed.
127  feature_override_.reset(new extensions::FeatureSwitch::ScopedOverride(
128      extensions::FeatureSwitch::extension_action_redesign(), true));
129  BrowserActionsContainer::disable_animations_during_testing_ = true;
130  WrenchToolbarButton::g_open_wrench_immediately_for_testing = true;
131}
132
133void ToolbarViewInteractiveUITest::SetUpOnMainThread() {
134  ExtensionBrowserTest::SetUpOnMainThread();
135
136  toolbar_view_ = BrowserView::GetBrowserViewForBrowser(browser())->toolbar();
137  browser_actions_ = toolbar_view_->browser_actions();
138}
139
140void ToolbarViewInteractiveUITest::TearDownOnMainThread() {
141  BrowserActionsContainer::disable_animations_during_testing_ = false;
142  WrenchToolbarButton::g_open_wrench_immediately_for_testing = false;
143}
144
145IN_PROC_BROWSER_TEST_F(ToolbarViewInteractiveUITest,
146                       MAYBE(TestWrenchMenuOpensOnDrag)) {
147  // Load an extension that has a browser action.
148  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
149                                          .AppendASCII("browser_action")
150                                          .AppendASCII("basics")));
151  base::RunLoop().RunUntilIdle();  // Ensure the extension is fully loaded.
152
153  ASSERT_EQ(1u, browser_actions()->VisibleBrowserActions());
154
155  BrowserActionView* view = browser_actions()->GetBrowserActionViewAt(0);
156  ASSERT_TRUE(view);
157
158  gfx::Point browser_action_view_loc = test::GetCenterInScreenCoordinates(view);
159  gfx::Point wrench_button_loc =
160      test::GetCenterInScreenCoordinates(toolbar_view()->app_menu());
161
162  // Perform a drag and drop from the browser action view to the wrench button,
163  // which should open the wrench menu.
164  DoDragAndDrop(browser_action_view_loc, wrench_button_loc);
165}
166