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