Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: chrome/browser/ui/views/ash/tab_scrubber_browsertest.cc

Issue 11881042: highlight intermediate tabs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Disable tests for win7_aura Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/views/ash/tab_scrubber.cc ('k') | chrome/browser/ui/views/tabs/tab.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "chrome/browser/ui/views/ash/tab_scrubber.h"
6
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.h"
12 #include "base/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 "chrome/test/base/ui_test_utils.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/common/url_constants.h"
25 #include "content/public/test/test_utils.h"
26 #include "ui/aura/test/event_generator.h"
27 #include "ui/aura/window.h"
28 #include "ui/base/events/event_utils.h"
29
30 namespace {
31
32 class TabScrubberTest : public InProcessBrowserTest,
33 public TabStripModelObserver {
34 public:
35 TabScrubberTest()
36 : target_index_(-1) {
37 }
38
39 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
40 #if defined(OS_CHROMEOS)
41 command_line->AppendSwitch(switches::kNaturalScrollDefault);
42 #endif
43 command_line->AppendSwitch(switches::kAshEnableTabScrubbing);
44 command_line->AppendSwitch(switches::kOpenAsh);
45 }
46
47 virtual void SetUpOnMainThread() OVERRIDE {
48 TabScrubber::GetInstance()->set_activation_delay(
49 base::TimeDelta::FromMilliseconds(0));
50
51 // Disable external monitor scaling of coordinates.
52 ash::Shell* shell = ash::Shell::GetInstance();
53 shell->event_transformation_handler()->set_transformation_mode(
54 ash::internal::EventTransformationHandler::TRANSFORM_NONE);
55 }
56
57 virtual void CleanUpOnMainThread() {
58 browser()->tab_strip_model()->RemoveObserver(this);
59 }
60
61 TabStrip* GetTabStrip(Browser* browser) {
62 aura::Window* window = browser->window()->GetNativeWindow();
63 return BrowserView::GetBrowserViewForNativeWindow(window)->tabstrip();
64 }
65
66 int GetStartX(Browser* browser,
67 int index,
68 TabScrubber::Direction direction) {
69 return TabScrubber::GetStartPoint(
70 GetTabStrip(browser), index, direction).x();
71 }
72
73 int GetTabCenter(Browser* browser, int index) {
74 return GetTabStrip(browser)->tab_at(index)->bounds().CenterPoint().x();
75 }
76
77 // Sends one scroll event synchronously without initial or final
78 // fling events.
79 void SendScrubEvent(Browser* browser, int index) {
80 aura::Window* window = browser->window()->GetNativeWindow();
81 aura::RootWindow* root = window->GetRootWindow();
82 aura::test::EventGenerator event_generator(root, window);
83 int active_index = browser->tab_strip_model()->active_index();
84 TabScrubber::Direction direction = index < active_index ?
85 TabScrubber::LEFT : TabScrubber::RIGHT;
86 int offset = GetTabCenter(browser, index) -
87 GetStartX(browser, active_index, direction);
88 ui::ScrollEvent scroll_event(ui::ET_SCROLL,
89 gfx::Point(0, 0),
90 ui::EventTimeForNow(),
91 0,
92 offset,
93 0,
94 3);
95 event_generator.Dispatch(&scroll_event);
96 }
97
98 enum ScrubType {
99 EACH_TAB,
100 SKIP_TABS,
101 REPEAT_TABS,
102 };
103
104 // Sends asynchronous events and waits for tab at |index| to become
105 // active.
106 void Scrub(Browser* browser, int index, ScrubType scrub_type) {
107 aura::Window* window = browser->window()->GetNativeWindow();
108 aura::RootWindow* root = window->GetRootWindow();
109 aura::test::EventGenerator event_generator(root, window);
110 event_generator.set_async(true);
111 activation_order_.clear();
112 int active_index = browser->tab_strip_model()->active_index();
113 ASSERT_NE(index, active_index);
114 ASSERT_TRUE(scrub_type != SKIP_TABS || ((index - active_index) % 2) == 0);
115 TabScrubber::Direction direction;
116 int increment;
117 if (index < active_index) {
118 direction = TabScrubber::LEFT;
119 increment = -1;
120 } else {
121 direction = TabScrubber::RIGHT;
122 increment = 1;
123 }
124 if (scrub_type == SKIP_TABS)
125 increment *= 2;
126 int last = GetStartX(browser, active_index, direction);
127 std::vector<gfx::Point> offsets;
128 for (int i = active_index + increment; i != (index + increment);
129 i += increment) {
130 int tab_center = GetTabCenter(browser, i);
131 offsets.push_back(gfx::Point(tab_center - last, 0));
132 last = GetStartX(browser, i, direction);
133 if (scrub_type == REPEAT_TABS) {
134 offsets.push_back(gfx::Point(increment, 0));
135 last += increment;
136 }
137 }
138 event_generator.ScrollSequence(gfx::Point(0, 0),
139 base::TimeDelta::FromMilliseconds(100),
140 offsets,
141 3);
142 RunUntilTabActive(browser, index);
143 }
144
145 // Sends events and waits for tab at |index| to become active
146 // if it's different from the currently active tab.
147 // If the active tab is expected to stay the same, send events
148 // synchronously (as we don't have anything to wait for).
149 void SendScrubSequence(Browser* browser, int x_offset, int index) {
150 aura::Window* window = browser->window()->GetNativeWindow();
151 aura::RootWindow* root = window->GetRootWindow();
152 aura::test::EventGenerator event_generator(root, window);
153 bool wait_for_active = false;
154 if (index != browser->tab_strip_model()->active_index()) {
155 wait_for_active = true;
156 event_generator.set_async(true);
157 }
158 event_generator.ScrollSequence(gfx::Point(0, 0),
159 ui::EventTimeForNow(),
160 x_offset,
161 0,
162 1,
163 3);
164 if (wait_for_active)
165 RunUntilTabActive(browser, index);
166 }
167
168 void AddTabs(Browser* browser, int num_tabs) {
169 TabStrip* tab_strip = GetTabStrip(browser);
170 for (int i = 0; i < num_tabs; ++i)
171 AddBlankTabAndShow(browser);
172 ASSERT_EQ(num_tabs + 1, browser->tab_strip_model()->count());
173 ASSERT_EQ(num_tabs, browser->tab_strip_model()->active_index());
174 tab_strip->StopAnimating(true);
175 ASSERT_FALSE(tab_strip->IsAnimating());
176 }
177
178 // TabStripModelObserver overrides.
179 virtual void TabInsertedAt(content::WebContents* contents,
180 int index,
181 bool foreground) {}
182 virtual void TabClosingAt(TabStripModel* tab_strip_model,
183 content::WebContents* contents,
184 int index) {}
185 virtual void TabDetachedAt(content::WebContents* contents, int index) {}
186 virtual void TabDeactivated(content::WebContents* contents) {}
187 virtual void ActiveTabChanged(content::WebContents* old_contents,
188 content::WebContents* new_contents,
189 int index,
190 bool user_gesture) {
191 activation_order_.push_back(index);
192 if (index == target_index_)
193 quit_closure_.Run();
194 }
195
196 virtual void TabSelectionChanged(TabStripModel* tab_strip_model,
197 const ui::ListSelectionModel& old_model) {}
198 virtual void TabMoved(content::WebContents* contents,
199 int from_index,
200 int to_index) {}
201 virtual void TabChangedAt(content::WebContents* contents,
202 int index,
203 TabChangeType change_type) {}
204 virtual void TabReplacedAt(TabStripModel* tab_strip_model,
205 content::WebContents* old_contents,
206 content::WebContents* new_contents,
207 int index) {}
208 virtual void TabPinnedStateChanged(content::WebContents* contents,
209 int index) {}
210 virtual void TabMiniStateChanged(content::WebContents* contents, int index) {}
211 virtual void TabBlockedStateChanged(content::WebContents* contents,
212 int index) {}
213 virtual void TabStripEmpty() {}
214 virtual void TabStripModelDeleted() {}
215
216 // History of tab activation. Scrub() resets it.
217 std::vector<int> activation_order_;
218
219 private:
220 void RunUntilTabActive(Browser* browser, int target) {
221 base::RunLoop run_loop;
222 quit_closure_ = content::GetQuitTaskForRunLoop(&run_loop);
223 browser->tab_strip_model()->AddObserver(this);
224 target_index_ = target;
225 content::RunThisRunLoop(&run_loop);
226 browser->tab_strip_model()->RemoveObserver(this);
227 target_index_ = -1;
228 }
229
230 base::Closure quit_closure_;
231 int target_index_;
232
233 DISALLOW_COPY_AND_ASSIGN(TabScrubberTest);
234 };
235
236 } // namespace
237
238 #if defined(OS_CHROMEOS)
239 // Swipe a single tab in each direction.
240 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Single) {
241 AddTabs(browser(), 1);
242
243 Scrub(browser(), 0, EACH_TAB);
244 EXPECT_EQ(1U, activation_order_.size());
245 EXPECT_EQ(0, activation_order_[0]);
246 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
247
248 Scrub(browser(), 1, EACH_TAB);
249 EXPECT_EQ(1U, activation_order_.size());
250 EXPECT_EQ(1, activation_order_[0]);
251 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
252 }
253
254 // Swipe 4 tabs in each direction. Each of the tabs should become active.
255 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Multi) {
256 AddTabs(browser(), 4);
257
258 Scrub(browser(), 0, EACH_TAB);
259 ASSERT_EQ(4U, activation_order_.size());
260 EXPECT_EQ(3, activation_order_[0]);
261 EXPECT_EQ(2, activation_order_[1]);
262 EXPECT_EQ(1, activation_order_[2]);
263 EXPECT_EQ(0, activation_order_[3]);
264 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
265
266 Scrub(browser(), 4, EACH_TAB);
267 ASSERT_EQ(4U, activation_order_.size());
268 EXPECT_EQ(1, activation_order_[0]);
269 EXPECT_EQ(2, activation_order_[1]);
270 EXPECT_EQ(3, activation_order_[2]);
271 EXPECT_EQ(4, activation_order_[3]);
272 EXPECT_EQ(4, browser()->tab_strip_model()->active_index());
273 }
274
275 IN_PROC_BROWSER_TEST_F(TabScrubberTest, MultiBrowser) {
276 AddTabs(browser(), 1);
277 Scrub(browser(), 0, EACH_TAB);
278 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
279
280 Browser* browser2 = CreateBrowser(browser()->profile());
281 browser2->window()->Activate();
282 ASSERT_TRUE(browser2->window()->IsActive());
283 ASSERT_FALSE(browser()->window()->IsActive());
284 AddTabs(browser2, 1);
285
286 Scrub(browser2, 0, EACH_TAB);
287 EXPECT_EQ(0, browser2->tab_strip_model()->active_index());
288 }
289
290 // Swipe 4 tabs in each direction with an extra swipe within each. The same
291 // 4 tabs should become active.
292 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Repeated) {
293 AddTabs(browser(), 4);
294
295 Scrub(browser(), 0, REPEAT_TABS);
296 ASSERT_EQ(4U, activation_order_.size());
297 EXPECT_EQ(3, activation_order_[0]);
298 EXPECT_EQ(2, activation_order_[1]);
299 EXPECT_EQ(1, activation_order_[2]);
300 EXPECT_EQ(0, activation_order_[3]);
301 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
302
303 Scrub(browser(), 4, REPEAT_TABS);
304 ASSERT_EQ(4U, activation_order_.size());
305 EXPECT_EQ(1, activation_order_[0]);
306 EXPECT_EQ(2, activation_order_[1]);
307 EXPECT_EQ(3, activation_order_[2]);
308 EXPECT_EQ(4, activation_order_[3]);
309 EXPECT_EQ(4, browser()->tab_strip_model()->active_index());
310 }
311
312 // Confirm that we get the last tab made active when we skip tabs.
313 // These tests have 5 total tabs. We will only received scroll events
314 // on tabs 0, 2 and 4.
315 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Skipped) {
316 AddTabs(browser(), 4);
317
318 Scrub(browser(), 0, SKIP_TABS);
319 EXPECT_EQ(2U, activation_order_.size());
320 EXPECT_EQ(2, activation_order_[0]);
321 EXPECT_EQ(0, activation_order_[1]);
322 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
323
324 Scrub(browser(), 4, SKIP_TABS);
325 EXPECT_EQ(2U, activation_order_.size());
326 EXPECT_EQ(2, activation_order_[0]);
327 EXPECT_EQ(4, activation_order_[1]);
328 EXPECT_EQ(4, browser()->tab_strip_model()->active_index());
329 }
330
331 // Confirm that nothing happens when the swipe is small.
332 IN_PROC_BROWSER_TEST_F(TabScrubberTest, NoChange) {
333 AddTabs(browser(), 1);
334
335 SendScrubSequence(browser(), -1, 1);
336 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
337
338 SendScrubSequence(browser(), 1, 1);
339 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
340 }
341
342 // Confirm that very large swipes go to the beginning and and of the tabstrip.
343 IN_PROC_BROWSER_TEST_F(TabScrubberTest, Bounds) {
344 AddTabs(browser(), 1);
345
346 SendScrubSequence(browser(), -10000, 0);
347 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
348
349 SendScrubSequence(browser(), 10000, 1);
350 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
351 }
352
353 IN_PROC_BROWSER_TEST_F(TabScrubberTest, DeleteHighlighted) {
354 AddTabs(browser(), 1);
355
356 SendScrubEvent(browser(), 0);
357 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
358 browser()->tab_strip_model()->CloseWebContentsAt(0,
359 TabStripModel::CLOSE_NONE);
360 EXPECT_FALSE(TabScrubber::GetInstance()->IsActivationPending());
361 }
362
363 // Delete the currently highlighted tab. Make sure the TabScrubber is aware.
364 IN_PROC_BROWSER_TEST_F(TabScrubberTest, DeleteBeforeHighlighted) {
365 AddTabs(browser(), 2);
366
367 SendScrubEvent(browser(), 1);
368 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
369 browser()->tab_strip_model()->CloseWebContentsAt(0,
370 TabStripModel::CLOSE_NONE);
371 EXPECT_EQ(0, TabScrubber::GetInstance()->highlighted_tab());
372 }
373
374 // Move the currently highlighted tab and confirm it gets tracked.
375 IN_PROC_BROWSER_TEST_F(TabScrubberTest, MoveHighlighted) {
376 AddTabs(browser(), 1);
377
378 SendScrubEvent(browser(), 0);
379 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
380 browser()->tab_strip_model()->ToggleSelectionAt(0);
381 browser()->tab_strip_model()->ToggleSelectionAt(1);
382 browser()->tab_strip_model()->MoveSelectedTabsTo(1);
383 EXPECT_EQ(1, TabScrubber::GetInstance()->highlighted_tab());
384 }
385
386 // Move a tab to before the highlighted one.
387 IN_PROC_BROWSER_TEST_F(TabScrubberTest, MoveBefore) {
388 AddTabs(browser(), 2);
389
390 SendScrubEvent(browser(), 1);
391 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
392 browser()->tab_strip_model()->ToggleSelectionAt(0);
393 browser()->tab_strip_model()->ToggleSelectionAt(2);
394 browser()->tab_strip_model()->MoveSelectedTabsTo(2);
395 EXPECT_EQ(0, TabScrubber::GetInstance()->highlighted_tab());
396 }
397
398 // Move a tab to after the highlighted one.
399 IN_PROC_BROWSER_TEST_F(TabScrubberTest, MoveAfter) {
400 AddTabs(browser(), 2);
401
402 SendScrubEvent(browser(), 1);
403 EXPECT_TRUE(TabScrubber::GetInstance()->IsActivationPending());
404 browser()->tab_strip_model()->MoveSelectedTabsTo(0);
405 EXPECT_EQ(2, TabScrubber::GetInstance()->highlighted_tab());
406 }
407
408 #endif // OS_CHROMEOS
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/ash/tab_scrubber.cc ('k') | chrome/browser/ui/views/tabs/tab.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698