Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / views / ash / tab_scrubber_browsertest.cc
blob2290bd8445b7ab2208640a6acf0b10f75d20d52a
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.
5 #include "chrome/browser/ui/views/ash/tab_scrubber.h"
7 #include "ash/display/event_transformation_handler.h"
8 #include "ash/shell.h"
9 #include "base/command_line.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "chrome/browser/ui/browser_tabstrip.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
16 #include "chrome/browser/ui/views/frame/browser_view.h"
17 #include "chrome/browser/ui/views/tabs/tab.h"
18 #include "chrome/browser/ui/views/tabs/tab_strip.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "content/public/browser/notification_service.h"
22 #include "content/public/common/url_constants.h"
23 #include "content/public/test/test_utils.h"
24 #include "ui/aura/window.h"
25 #include "ui/events/event_utils.h"
26 #include "ui/events/test/event_generator.h"
28 #if defined(OS_CHROMEOS)
29 #include "chromeos/chromeos_switches.h"
30 #endif
32 namespace {
34 class TabScrubberTest : public InProcessBrowserTest,
35 public TabStripModelObserver {
36 public:
37 TabScrubberTest()
38 : target_index_(-1) {
41 void SetUpCommandLine(base::CommandLine* command_line) override {
42 #if defined(OS_CHROMEOS)
43 command_line->AppendSwitch(chromeos::switches::kNaturalScrollDefault);
44 #endif
45 command_line->AppendSwitch(switches::kOpenAsh);
48 void SetUpOnMainThread() override {
49 TabScrubber::GetInstance()->set_activation_delay(0);
51 // Disable external monitor scaling of coordinates.
52 ash::Shell* shell = ash::Shell::GetInstance();
53 shell->event_transformation_handler()->set_transformation_mode(
54 ash::EventTransformationHandler::TRANSFORM_NONE);
57 void TearDownOnMainThread() override {
58 browser()->tab_strip_model()->RemoveObserver(this);
61 TabStrip* GetTabStrip(Browser* browser) {
62 aura::Window* window = browser->window()->GetNativeWindow();
63 return BrowserView::GetBrowserViewForNativeWindow(window)->tabstrip();
66 float GetStartX(Browser* browser,
67 int index,
68 TabScrubber::Direction direction) {
69 return static_cast<float>(TabScrubber::GetStartPoint(
70 GetTabStrip(browser), index, direction).x());
73 float GetTabCenter(Browser* browser, int index) {
74 return static_cast<float>(
75 GetTabStrip(browser)->tab_at(index)->bounds().CenterPoint().x());
78 // Sends one scroll event synchronously without initial or final
79 // fling events.
80 void SendScrubEvent(Browser* browser, int index) {
81 aura::Window* window = browser->window()->GetNativeWindow();
82 aura::Window* root = window->GetRootWindow();
83 ui::test::EventGenerator event_generator(root, window);
84 int active_index = browser->tab_strip_model()->active_index();
85 TabScrubber::Direction direction = index < active_index ?
86 TabScrubber::LEFT : TabScrubber::RIGHT;
87 float offset = GetTabCenter(browser, index) -
88 GetStartX(browser, active_index, direction);
89 ui::ScrollEvent scroll_event(ui::ET_SCROLL,
90 gfx::PointF(0, 0),
91 ui::EventTimeForNow(),
93 offset, 0,
94 offset, 0,
95 3);
96 event_generator.Dispatch(&scroll_event);
99 enum ScrubType {
100 EACH_TAB,
101 SKIP_TABS,
102 REPEAT_TABS,
105 // Sends asynchronous events and waits for tab at |index| to become
106 // active.
107 void Scrub(Browser* browser, int index, ScrubType scrub_type) {
108 aura::Window* window = browser->window()->GetNativeWindow();
109 aura::Window* root = window->GetRootWindow();
110 ui::test::EventGenerator event_generator(root, window);
111 event_generator.set_async(true);
112 activation_order_.clear();
113 int active_index = browser->tab_strip_model()->active_index();
114 ASSERT_NE(index, active_index);
115 ASSERT_TRUE(scrub_type != SKIP_TABS || ((index - active_index) % 2) == 0);
116 TabScrubber::Direction direction;
117 int increment;
118 if (index < active_index) {
119 direction = TabScrubber::LEFT;
120 increment = -1;
121 } else {
122 direction = TabScrubber::RIGHT;
123 increment = 1;
125 if (scrub_type == SKIP_TABS)
126 increment *= 2;
127 float last = GetStartX(browser, active_index, direction);
128 std::vector<gfx::PointF> offsets;
129 for (int i = active_index + increment; i != (index + increment);
130 i += increment) {
131 float tab_center = GetTabCenter(browser, i);
132 offsets.push_back(gfx::PointF(tab_center - last, 0));
133 last = GetStartX(browser, i, direction);
134 if (scrub_type == REPEAT_TABS) {
135 offsets.push_back(gfx::PointF(static_cast<float>(increment), 0));
136 last += increment;
139 event_generator.ScrollSequence(gfx::Point(0, 0),
140 base::TimeDelta::FromMilliseconds(100),
141 offsets,
143 RunUntilTabActive(browser, index);
146 // Sends events and waits for tab at |index| to become active
147 // if it's different from the currently active tab.
148 // If the active tab is expected to stay the same, send events
149 // synchronously (as we don't have anything to wait for).
150 void SendScrubSequence(Browser* browser, float x_offset, int index) {
151 aura::Window* window = browser->window()->GetNativeWindow();
152 aura::Window* root = window->GetRootWindow();
153 ui::test::EventGenerator event_generator(root, window);
154 bool wait_for_active = false;
155 if (index != browser->tab_strip_model()->active_index()) {
156 wait_for_active = true;
157 event_generator.set_async(true);
159 event_generator.ScrollSequence(gfx::Point(0, 0),
160 ui::EventTimeForNow(),
161 x_offset,
165 if (wait_for_active)
166 RunUntilTabActive(browser, index);
169 void AddTabs(Browser* browser, int num_tabs) {
170 TabStrip* tab_strip = GetTabStrip(browser);
171 for (int i = 0; i < num_tabs; ++i)
172 AddBlankTabAndShow(browser);
173 ASSERT_EQ(num_tabs + 1, browser->tab_strip_model()->count());
174 ASSERT_EQ(num_tabs, browser->tab_strip_model()->active_index());
175 tab_strip->StopAnimating(true);
176 ASSERT_FALSE(tab_strip->IsAnimating());
179 // TabStripModelObserver overrides.
180 void TabInsertedAt(content::WebContents* contents,
181 int index,
182 bool foreground) override {}
183 void TabClosingAt(TabStripModel* tab_strip_model,
184 content::WebContents* contents,
185 int index) override {}
186 void TabDetachedAt(content::WebContents* contents, int index) override {}
187 void TabDeactivated(content::WebContents* contents) override {}
188 void ActiveTabChanged(content::WebContents* old_contents,
189 content::WebContents* new_contents,
190 int index,
191 int reason) override {
192 activation_order_.push_back(index);
193 if (index == target_index_)
194 quit_closure_.Run();
197 void TabSelectionChanged(TabStripModel* tab_strip_model,
198 const ui::ListSelectionModel& old_model) override {}
199 void TabMoved(content::WebContents* contents,
200 int from_index,
201 int to_index) override {}
202 void TabChangedAt(content::WebContents* contents,
203 int index,
204 TabChangeType change_type) override {}
205 void TabReplacedAt(TabStripModel* tab_strip_model,
206 content::WebContents* old_contents,
207 content::WebContents* new_contents,
208 int index) override {}
209 void TabPinnedStateChanged(content::WebContents* contents,
210 int index) override {}
211 void TabMiniStateChanged(content::WebContents* contents, int index) override {
213 void TabBlockedStateChanged(content::WebContents* contents,
214 int index) override {}
215 void TabStripEmpty() override {}
216 void TabStripModelDeleted() override {}
218 // History of tab activation. Scrub() resets it.
219 std::vector<int> activation_order_;
221 private:
222 void RunUntilTabActive(Browser* browser, int target) {
223 base::RunLoop run_loop;
224 quit_closure_ = content::GetQuitTaskForRunLoop(&run_loop);
225 browser->tab_strip_model()->AddObserver(this);
226 target_index_ = target;
227 content::RunThisRunLoop(&run_loop);
228 browser->tab_strip_model()->RemoveObserver(this);
229 target_index_ = -1;
232 base::Closure quit_closure_;
233 int target_index_;
235 DISALLOW_COPY_AND_ASSIGN(TabScrubberTest);
238 } // namespace
240 #if defined(OS_CHROMEOS)
241 // Swipe a single tab in each direction.
242 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Single) {
243 AddTabs(browser(), 1);
245 Scrub(browser(), 0, EACH_TAB);
246 EXPECT_EQ(1U, activation_order_.size());
247 EXPECT_EQ(0, activation_order_[0]);
248 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
250 Scrub(browser(), 1, EACH_TAB);
251 EXPECT_EQ(1U, activation_order_.size());
252 EXPECT_EQ(1, activation_order_[0]);
253 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
256 // Swipe 4 tabs in each direction. Each of the tabs should become active.
257 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Multi) {
258 AddTabs(browser(), 4);
260 Scrub(browser(), 0, EACH_TAB);
261 ASSERT_EQ(4U, activation_order_.size());
262 EXPECT_EQ(3, activation_order_[0]);
263 EXPECT_EQ(2, activation_order_[1]);
264 EXPECT_EQ(1, activation_order_[2]);
265 EXPECT_EQ(0, activation_order_[3]);
266 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
268 Scrub(browser(), 4, EACH_TAB);
269 ASSERT_EQ(4U, activation_order_.size());
270 EXPECT_EQ(1, activation_order_[0]);
271 EXPECT_EQ(2, activation_order_[1]);
272 EXPECT_EQ(3, activation_order_[2]);
273 EXPECT_EQ(4, activation_order_[3]);
274 EXPECT_EQ(4, browser()->tab_strip_model()->active_index());
277 IN_PROC_BROWSER_TEST_F(TabScrubberTest, MultiBrowser) {
278 AddTabs(browser(), 1);
279 Scrub(browser(), 0, EACH_TAB);
280 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
282 Browser* browser2 = CreateBrowser(browser()->profile());
283 browser2->window()->Activate();
284 ASSERT_TRUE(browser2->window()->IsActive());
285 ASSERT_FALSE(browser()->window()->IsActive());
286 AddTabs(browser2, 1);
288 Scrub(browser2, 0, EACH_TAB);
289 EXPECT_EQ(0, browser2->tab_strip_model()->active_index());
292 // Swipe 4 tabs in each direction with an extra swipe within each. The same
293 // 4 tabs should become active.
294 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Repeated) {
295 AddTabs(browser(), 4);
297 Scrub(browser(), 0, REPEAT_TABS);
298 ASSERT_EQ(4U, activation_order_.size());
299 EXPECT_EQ(3, activation_order_[0]);
300 EXPECT_EQ(2, activation_order_[1]);
301 EXPECT_EQ(1, activation_order_[2]);
302 EXPECT_EQ(0, activation_order_[3]);
303 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
305 Scrub(browser(), 4, REPEAT_TABS);
306 ASSERT_EQ(4U, activation_order_.size());
307 EXPECT_EQ(1, activation_order_[0]);
308 EXPECT_EQ(2, activation_order_[1]);
309 EXPECT_EQ(3, activation_order_[2]);
310 EXPECT_EQ(4, activation_order_[3]);
311 EXPECT_EQ(4, browser()->tab_strip_model()->active_index());
314 // Confirm that we get the last tab made active when we skip tabs.
315 // These tests have 5 total tabs. We will only received scroll events
316 // on tabs 0, 2 and 4.
317 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Skipped) {
318 AddTabs(browser(), 4);
320 Scrub(browser(), 0, SKIP_TABS);
321 EXPECT_EQ(2U, activation_order_.size());
322 EXPECT_EQ(2, activation_order_[0]);
323 EXPECT_EQ(0, activation_order_[1]);
324 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
326 Scrub(browser(), 4, SKIP_TABS);
327 EXPECT_EQ(2U, activation_order_.size());
328 EXPECT_EQ(2, activation_order_[0]);
329 EXPECT_EQ(4, activation_order_[1]);
330 EXPECT_EQ(4, browser()->tab_strip_model()->active_index());
333 // Confirm that nothing happens when the swipe is small.
334 IN_PROC_BROWSER_TEST_F(TabScrubberTest, NoChange) {
335 AddTabs(browser(), 1);
337 SendScrubSequence(browser(), -1, 1);
338 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
340 SendScrubSequence(browser(), 1, 1);
341 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
344 // Confirm that very large swipes go to the beginning and and of the tabstrip.
345 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Bounds) {
346 AddTabs(browser(), 1);
348 SendScrubSequence(browser(), -10000, 0);
349 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
351 SendScrubSequence(browser(), 10000, 1);
352 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
355 IN_PROC_BROWSER_TEST_F(TabScrubberTest, DeleteHighlighted) {
356 AddTabs(browser(), 1);
358 SendScrubEvent(browser(), 0);
359 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
360 browser()->tab_strip_model()->CloseWebContentsAt(0,
361 TabStripModel::CLOSE_NONE);
362 EXPECT_FALSE(TabScrubber::GetInstance()->IsActivationPending());
365 // Delete the currently highlighted tab. Make sure the TabScrubber is aware.
366 IN_PROC_BROWSER_TEST_F(TabScrubberTest, DeleteBeforeHighlighted) {
367 AddTabs(browser(), 2);
369 SendScrubEvent(browser(), 1);
370 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
371 browser()->tab_strip_model()->CloseWebContentsAt(0,
372 TabStripModel::CLOSE_NONE);
373 EXPECT_EQ(0, TabScrubber::GetInstance()->highlighted_tab());
376 // Move the currently highlighted tab and confirm it gets tracked.
377 IN_PROC_BROWSER_TEST_F(TabScrubberTest, MoveHighlighted) {
378 AddTabs(browser(), 1);
380 SendScrubEvent(browser(), 0);
381 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
382 browser()->tab_strip_model()->ToggleSelectionAt(0);
383 browser()->tab_strip_model()->ToggleSelectionAt(1);
384 browser()->tab_strip_model()->MoveSelectedTabsTo(1);
385 EXPECT_EQ(1, TabScrubber::GetInstance()->highlighted_tab());
388 // Move a tab to before the highlighted one.
389 IN_PROC_BROWSER_TEST_F(TabScrubberTest, MoveBefore) {
390 AddTabs(browser(), 2);
392 SendScrubEvent(browser(), 1);
393 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
394 browser()->tab_strip_model()->ToggleSelectionAt(0);
395 browser()->tab_strip_model()->ToggleSelectionAt(2);
396 browser()->tab_strip_model()->MoveSelectedTabsTo(2);
397 EXPECT_EQ(0, TabScrubber::GetInstance()->highlighted_tab());
400 // Move a tab to after the highlighted one.
401 IN_PROC_BROWSER_TEST_F(TabScrubberTest, MoveAfter) {
402 AddTabs(browser(), 2);
404 SendScrubEvent(browser(), 1);
405 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
406 browser()->tab_strip_model()->MoveSelectedTabsTo(0);
407 EXPECT_EQ(2, TabScrubber::GetInstance()->highlighted_tab());
410 // Close the browser while an activation is pending.
411 IN_PROC_BROWSER_TEST_F(TabScrubberTest, CloseBrowser) {
412 AddTabs(browser(), 1);
414 SendScrubEvent(browser(), 0);
415 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
416 browser()->window()->Close();
417 EXPECT_FALSE(TabScrubber::GetInstance()->IsActivationPending());
420 #endif // defined(OS_CHROMEOS)