1 // Copyright (c) 2010 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/command_line.h"
6 #include "base/file_util.h"
7 #include "chrome/app/chrome_command_ids.h"
8 #include "chrome/browser/ui/view_ids.h"
9 #include "chrome/common/chrome_paths.h"
10 #include "chrome/test/automation/tab_proxy.h"
11 #include "chrome/test/automation/browser_proxy.h"
12 #include "chrome/test/automation/window_proxy.h"
13 #include "chrome/test/ui/ui_test.h"
14 #include "googleurl/src/gurl.h"
15 #include "net/base/net_util.h"
16 #include "ui/gfx/rect.h"
17 #include "views/events/event.h"
18
19 #if defined(OS_LINUX)
20 // This test doesn't make sense on chromeos as chromeos doesn't allow dragging
21 // tabs out.
22 #define MAYBE_Tab2OutOfTabStrip DISABLED_Tab2OutOfTabStrip
23 #else
24 // Flaky, http://crbug.com/62311.
25 #define MAYBE_Tab2OutOfTabStrip FLAKY_Tab2OutOfTabStrip
26 #endif
27
28 #if defined(OS_LINUX)
29 // Disabled on Toolkit views bot. See http://crbug.com/42614
30 #define MAYBE_Tab1Tab3Escape DISABLED_Tab1Tab3Escape
31 #elif defined(OS_WIN)
32 // Disabled on Windows. See http://crbug.com/57687
33 #define MAYBE_Tab1Tab3Escape DISABLED_Tab1Tab3Escape
34 #else
35 #define MAYBE_Tab1Tab3Escape Tab1Tab3Escape
36 #endif
37
38 // These tests fail on Linux because we haven't implemented all of tab dragging
39 // (it's not needed on chromeos). See http://crbug.com/10941
40 #if defined(OS_LINUX)
41 #define MAYBE_Tab1Tab2 DISABLED_Tab1Tab2
42 #define MAYBE_Tab1Tab3 DISABLED_Tab1Tab3
43 #else
44 // Flaky, http://crbug.com/62311.
45 #define MAYBE_Tab1Tab2 FLAKY_Tab1Tab2
46 #define MAYBE_Tab1Tab3 FLAKY_Tab1Tab3
47 #endif
48
49 class TabDraggingTest : public UITest {
50 protected:
TabDraggingTest()51 TabDraggingTest() {
52 show_window_ = true;
53 }
54 };
55
56 // Automated UI test to open three tabs in a new window, and drag Tab_1 into
57 // the position of Tab_2.
TEST_F(TabDraggingTest,MAYBE_Tab1Tab2)58 TEST_F(TabDraggingTest, MAYBE_Tab1Tab2) {
59 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
60 ASSERT_TRUE(browser.get());
61 scoped_refptr<WindowProxy> window(browser->GetWindow());
62 ASSERT_TRUE(window.get());
63
64 // Get initial tab count.
65 int initial_tab_count = 0;
66 ASSERT_TRUE(browser->GetTabCount(&initial_tab_count));
67 ASSERT_TRUE(1 == initial_tab_count);
68
69 // Get Tab_1 which comes with the browser window.
70 scoped_refptr<TabProxy> tab1(browser->GetTab(0));
71 ASSERT_TRUE(tab1.get());
72 GURL tab1_url;
73 ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url));
74
75 // Add Tab_2.
76 GURL tab2_url("about:");
77 ASSERT_TRUE(browser->AppendTab(tab2_url));
78 scoped_refptr<TabProxy> tab2(browser->GetTab(1));
79 ASSERT_TRUE(tab2.get());
80
81 // Add Tab_3.
82 GURL tab3_url("about:plugins");
83 ASSERT_TRUE(browser->AppendTab(tab3_url));
84 scoped_refptr<TabProxy> tab3(browser->GetTab(2));
85 ASSERT_TRUE(tab3.get());
86
87 // Make sure 3 tabs are open.
88 ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2));
89
90 // Get bounds for the tabs.
91 gfx::Rect bounds1;
92 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false));
93 EXPECT_LT(0, bounds1.x());
94 EXPECT_LT(0, bounds1.width());
95 EXPECT_LT(0, bounds1.height());
96
97 gfx::Rect bounds2;
98 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false));
99 EXPECT_LT(0, bounds2.width());
100 EXPECT_LT(0, bounds2.height());
101 EXPECT_LT(bounds1.x(), bounds2.x());
102 EXPECT_EQ(bounds2.y(), bounds1.y());
103
104 gfx::Rect bounds3;
105 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false));
106 EXPECT_LT(0, bounds3.width());
107 EXPECT_LT(0, bounds3.height());
108 EXPECT_LT(bounds2.x(), bounds3.x());
109 EXPECT_EQ(bounds3.y(), bounds2.y());
110
111 // Get url Bar bounds.
112 gfx::Rect urlbar_bounds;
113 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds,
114 false));
115 EXPECT_LT(0, urlbar_bounds.x());
116 EXPECT_LT(0, urlbar_bounds.y());
117 EXPECT_LT(0, urlbar_bounds.width());
118 EXPECT_LT(0, urlbar_bounds.height());
119
120 /*
121 TEST: Move Tab_1 to the position of Tab_2
122 ____________ ____________ ____________
123 / \ / \ / \
124 | Tab_1 | Tab_2 | Tab_3 |
125 ---- ---- ---- ---- ---- ---- ---- ---- ----
126 x---- ---->
127 ____________
128 / X \
129 | Tab_1 |
130 ---- ---- ----
131 */
132
133 gfx::Point start(bounds1.x() + bounds1.width() / 2,
134 bounds1.y() + bounds1.height() / 2);
135 gfx::Point end(start.x() + 2 * bounds1.width() / 3, start.y());
136 ASSERT_TRUE(browser->SimulateDrag(start, end,
137 ui::EF_LEFT_BUTTON_DOWN,
138 false));
139
140 // Now check for expected results.
141 tab1 = browser->GetTab(0);
142 ASSERT_TRUE(tab1.get());
143 GURL tab1_new_url;
144 ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url));
145
146 tab2 = browser->GetTab(1);
147 ASSERT_TRUE(tab2.get());
148 GURL tab2_new_url;
149 ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url));
150
151 EXPECT_EQ(tab1_url.spec(), tab2_new_url.spec());
152 EXPECT_EQ(tab2_url.spec(), tab1_new_url.spec());
153 }
154
155 // Drag Tab_1 into the position of Tab_3.
TEST_F(TabDraggingTest,MAYBE_Tab1Tab3)156 TEST_F(TabDraggingTest, MAYBE_Tab1Tab3) {
157 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
158 ASSERT_TRUE(browser.get());
159 scoped_refptr<WindowProxy> window(browser->GetWindow());
160 ASSERT_TRUE(window.get());
161
162 // Get initial tab count.
163 int initial_tab_count = 0;
164 ASSERT_TRUE(browser->GetTabCount(&initial_tab_count));
165 ASSERT_TRUE(1 == initial_tab_count);
166
167 // Get Tab_1 which comes with the browser window.
168 scoped_refptr<TabProxy> tab1(browser->GetTab(0));
169 ASSERT_TRUE(tab1.get());
170 GURL tab1_url;
171 ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url));
172
173 // Add Tab_2.
174 GURL tab2_url("about:");
175 ASSERT_TRUE(browser->AppendTab(tab2_url));
176 scoped_refptr<TabProxy> tab2(browser->GetTab(1));
177 ASSERT_TRUE(tab2.get());
178
179 // Add Tab_3.
180 GURL tab3_url("about:plugins");
181 ASSERT_TRUE(browser->AppendTab(tab3_url));
182 scoped_refptr<TabProxy> tab3(browser->GetTab(2));
183 ASSERT_TRUE(tab3.get());
184
185 // Make sure 3 tabs are open.
186 ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2));
187
188 // Get bounds for the tabs.
189 gfx::Rect bounds1;
190 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false));
191 EXPECT_LT(0, bounds1.x());
192 EXPECT_LT(0, bounds1.width());
193 EXPECT_LT(0, bounds1.height());
194
195 gfx::Rect bounds2;
196 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false));
197 EXPECT_LT(0, bounds2.width());
198 EXPECT_LT(0, bounds2.height());
199 EXPECT_LT(bounds1.x(), bounds2.x());
200 EXPECT_EQ(bounds2.y(), bounds1.y());
201
202 gfx::Rect bounds3;
203 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false));
204 EXPECT_LT(0, bounds3.width());
205 EXPECT_LT(0, bounds3.height());
206 EXPECT_LT(bounds2.x(), bounds3.x());
207 EXPECT_EQ(bounds3.y(), bounds2.y());
208
209 // Get url Bar bounds.
210 gfx::Rect urlbar_bounds;
211 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds,
212 false));
213 EXPECT_LT(0, urlbar_bounds.x());
214 EXPECT_LT(0, urlbar_bounds.y());
215 EXPECT_LT(0, urlbar_bounds.width());
216 EXPECT_LT(0, urlbar_bounds.height());
217
218 /*
219 TEST: Move Tab_1 to the middle position of Tab_3
220 ____________ ____________ ____________
221 / \ / \ / \
222 | Tab_1 | Tab_2 | Tab_3 |
223 ---- ---- ---- ---- ---- ---- ---- ---- ----
224 x---- ---- ---- ---- ---- ---->
225 ____________
226 / X \
227 | Tab_1 |
228 ---- ---- ----
229 */
230
231 gfx::Point start(bounds1.x() + bounds1.width() / 2,
232 bounds1.y() + bounds1.height() / 2);
233 gfx::Point end(start.x() + bounds1.width() / 2 + bounds2.width() +
234 bounds3.width() / 2,
235 start.y());
236 ASSERT_TRUE(browser->SimulateDrag(start, end,
237 ui::EF_LEFT_BUTTON_DOWN,
238 false));
239
240 // Now check for expected results.
241 tab1 = browser->GetTab(0);
242 ASSERT_TRUE(tab1.get());
243 GURL tab1_new_url;
244 ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url));
245
246 tab2 = browser->GetTab(1);
247 ASSERT_TRUE(tab2.get());
248 GURL tab2_new_url;
249 ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url));
250
251 tab3 = browser->GetTab(2);
252 ASSERT_TRUE(tab3.get());
253 GURL tab3_new_url;
254 ASSERT_TRUE(tab3->GetCurrentURL(&tab3_new_url));
255
256 EXPECT_EQ(tab1_new_url.spec(), tab2_url.spec());
257 EXPECT_EQ(tab2_new_url.spec(), tab3_url.spec());
258 EXPECT_EQ(tab3_new_url.spec(), tab1_url.spec());
259 }
260
261 // Drag Tab_1 into the position of Tab_3, and press ESCAPE before releasing the
262 // left mouse button.
TEST_F(TabDraggingTest,MAYBE_Tab1Tab3Escape)263 TEST_F(TabDraggingTest, MAYBE_Tab1Tab3Escape) {
264 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
265 ASSERT_TRUE(browser.get());
266 scoped_refptr<WindowProxy> window(browser->GetWindow());
267 ASSERT_TRUE(window.get());
268
269 // Get initial tab count.
270 int initial_tab_count = 0;
271 ASSERT_TRUE(browser->GetTabCount(&initial_tab_count));
272 ASSERT_TRUE(1 == initial_tab_count);
273
274 // Get Tab_1 which comes with the browser window.
275 scoped_refptr<TabProxy> tab1(browser->GetTab(0));
276 ASSERT_TRUE(tab1.get());
277 GURL tab1_url;
278 ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url));
279
280 // Add Tab_2.
281 GURL tab2_url("about:blank");
282 ASSERT_TRUE(browser->AppendTab(tab2_url));
283 scoped_refptr<TabProxy> tab2(browser->GetTab(1));
284 ASSERT_TRUE(tab2.get());
285
286 // Add Tab_3.
287 GURL tab3_url("about:plugins");
288 ASSERT_TRUE(browser->AppendTab(tab3_url));
289 scoped_refptr<TabProxy> tab3(browser->GetTab(2));
290 ASSERT_TRUE(tab3.get());
291
292 // Make sure 3 tabs are open.
293 ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2));
294
295 // Get bounds for the tabs.
296 gfx::Rect bounds1;
297 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false));
298 EXPECT_LT(0, bounds1.x());
299 EXPECT_LT(0, bounds1.width());
300 EXPECT_LT(0, bounds1.height());
301
302 gfx::Rect bounds2;
303 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false));
304 EXPECT_LT(0, bounds2.width());
305 EXPECT_LT(0, bounds2.height());
306 EXPECT_LT(bounds1.x(), bounds2.x());
307 EXPECT_EQ(bounds2.y(), bounds1.y());
308
309 gfx::Rect bounds3;
310 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false));
311 EXPECT_LT(0, bounds3.width());
312 EXPECT_LT(0, bounds3.height());
313 EXPECT_LT(bounds2.x(), bounds3.x());
314 EXPECT_EQ(bounds3.y(), bounds2.y());
315
316 // Get url Bar bounds.
317 gfx::Rect urlbar_bounds;
318 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds,
319 false));
320 EXPECT_LT(0, urlbar_bounds.x());
321 EXPECT_LT(0, urlbar_bounds.y());
322 EXPECT_LT(0, urlbar_bounds.width());
323 EXPECT_LT(0, urlbar_bounds.height());
324
325 /*
326 TEST: Move Tab_1 to the middle position of Tab_3
327 ____________ ____________ ____________
328 / \ / \ / \
329 | Tab_1 | Tab_2 | Tab_3 |
330 ---- ---- ---- ---- ---- ---- ---- ---- ----
331 x---- ---- ---- ---- ---- ----> + ESCAPE
332 ____________
333 / X \
334 | Tab_1 |
335 ---- ---- ----
336 */
337
338 gfx::Point start(bounds1.x() + bounds1.width() / 2,
339 bounds1.y() + bounds1.height() / 2);
340 gfx::Point end(start.x() + bounds1.width() / 2 + bounds2.width() +
341 bounds3.width() / 2,
342 start.y());
343
344 // Simulate drag with 'true' as the last parameter. This will interrupt
345 // in-flight with Escape.
346 ASSERT_TRUE(browser->SimulateDrag(start, end,
347 ui::EF_LEFT_BUTTON_DOWN,
348 true));
349
350 // Now check for expected results.
351 tab1 = browser->GetTab(0);
352 ASSERT_TRUE(tab1.get());
353 GURL tab1_new_url;
354 ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url));
355
356 tab2 = browser->GetTab(1);
357 ASSERT_TRUE(tab2.get());
358 GURL tab2_new_url;
359 ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url));
360
361 tab3 = browser->GetTab(2);
362 ASSERT_TRUE(tab3.get());
363 GURL tab3_new_url;
364 ASSERT_TRUE(tab3->GetCurrentURL(&tab3_new_url));
365
366 // The tabs should be in their original positions.
367 EXPECT_EQ(tab1_new_url.spec(), tab1_url.spec());
368 EXPECT_EQ(tab2_new_url.spec(), tab2_url.spec());
369 EXPECT_EQ(tab3_new_url.spec(), tab3_url.spec());
370 }
371
372 // Drag Tab_2 out of the Tab strip. A new window should open with this tab.
TEST_F(TabDraggingTest,MAYBE_Tab2OutOfTabStrip)373 TEST_F(TabDraggingTest, MAYBE_Tab2OutOfTabStrip) {
374 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
375 ASSERT_TRUE(browser.get());
376 scoped_refptr<WindowProxy> window(browser->GetWindow());
377 ASSERT_TRUE(window.get());
378
379 // Get initial tab count.
380 int initial_tab_count = 0;
381 ASSERT_TRUE(browser->GetTabCount(&initial_tab_count));
382 ASSERT_TRUE(1 == initial_tab_count);
383
384 // Get Tab_1 which comes with the browser window.
385 scoped_refptr<TabProxy> tab1(browser->GetTab(0));
386 ASSERT_TRUE(tab1.get());
387 GURL tab1_url;
388 ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url));
389
390 // Add Tab_2.
391 GURL tab2_url("about:version");
392 ASSERT_TRUE(browser->AppendTab(tab2_url));
393 scoped_refptr<TabProxy> tab2(browser->GetTab(1));
394 ASSERT_TRUE(tab2.get());
395
396 // Add Tab_3.
397 GURL tab3_url("about:plugins");
398 ASSERT_TRUE(browser->AppendTab(tab3_url));
399 scoped_refptr<TabProxy> tab3(browser->GetTab(2));
400 ASSERT_TRUE(tab3.get());
401
402 // Make sure 3 tabs are opened.
403 ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2));
404
405 // Make sure all the tab URL specs are different.
406 ASSERT_TRUE(tab1_url != tab2_url);
407 ASSERT_TRUE(tab1_url != tab3_url);
408 ASSERT_TRUE(tab2_url != tab3_url);
409
410 // Get bounds for the tabs.
411 gfx::Rect bounds1;
412 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false));
413 EXPECT_LT(0, bounds1.x());
414 EXPECT_LT(0, bounds1.width());
415 EXPECT_LT(0, bounds1.height());
416
417 gfx::Rect bounds2;
418 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false));
419 EXPECT_LT(0, bounds2.width());
420 EXPECT_LT(0, bounds2.height());
421 EXPECT_LT(bounds1.x(), bounds2.x());
422 EXPECT_EQ(bounds2.y(), bounds1.y());
423
424 gfx::Rect bounds3;
425 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false));
426 EXPECT_LT(0, bounds3.width());
427 EXPECT_LT(0, bounds3.height());
428 EXPECT_LT(bounds2.x(), bounds3.x());
429 EXPECT_EQ(bounds3.y(), bounds2.y());
430
431 // Get url Bar bounds.
432 gfx::Rect urlbar_bounds;
433 ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds,
434 false));
435 EXPECT_LT(0, urlbar_bounds.x());
436 EXPECT_LT(0, urlbar_bounds.y());
437 EXPECT_LT(0, urlbar_bounds.width());
438 EXPECT_LT(0, urlbar_bounds.height());
439
440 /*
441 TEST: Move Tab_2 down, out of the tab strip.
442 This should result in the following:
443 1- Tab_3 shift left in place of Tab_2 in Window 1
444 2- Tab_1 to remain in its place
445 3- Tab_2 openes in a new window
446
447 ____________ ____________ ____________
448 / \ / \ / \
449 | Tab_1 | Tab_2 | Tab_3 |
450 ---- ---- ---- ---- ---- ---- ---- ---- ----
451 x
452 |
453 | (Drag this below, out of tab strip)
454 V
455 ____________
456 / X \
457 | Tab_2 | (New Window)
458 ---- ---- ---- ---- ---- ---- ----
459 */
460
461 gfx::Point start(bounds2.x() + bounds2.width() / 2,
462 bounds2.y() + bounds2.height() / 2);
463 gfx::Point end(start.x(),
464 start.y() + 3 * urlbar_bounds.height());
465
466 // Simulate tab drag.
467 ASSERT_TRUE(browser->SimulateDrag(start, end,
468 ui::EF_LEFT_BUTTON_DOWN,
469 false));
470
471 // Now, first make sure that the old window has only two tabs remaining.
472 int new_tab_count = 0;
473 ASSERT_TRUE(browser->GetTabCount(&new_tab_count));
474 ASSERT_EQ(2, new_tab_count);
475
476 // Get the two tabs - they are called Tab_1 and Tab_2 in the old window.
477 tab1 = browser->GetTab(0);
478 ASSERT_TRUE(tab1.get());
479 GURL tab1_new_url;
480 ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url));
481
482 tab2 = browser->GetTab(1);
483 ASSERT_TRUE(tab2.get());
484 GURL tab2_new_url;
485 ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url));
486
487 // Now check for proper shifting of tabs; i.e., Tab_3 in window 1 should
488 // shift left to the position of Tab_2; Tab_1 should stay where it was.
489 EXPECT_EQ(tab1_new_url.spec(), tab1_url.spec());
490 EXPECT_EQ(tab2_new_url.spec(), tab3_url.spec());
491
492 // Now check to make sure a new window has opened.
493 scoped_refptr<BrowserProxy> browser2(automation()->GetBrowserWindow(1));
494 ASSERT_TRUE(browser2.get());
495 scoped_refptr<WindowProxy> window2(browser2->GetWindow());
496 ASSERT_TRUE(window2.get());
497
498 // Make sure that the new window has only one tab.
499 int tab_count_window_2 = 0;
500 ASSERT_TRUE(browser2->GetTabCount(&tab_count_window_2));
501 ASSERT_EQ(1, tab_count_window_2);
502
503 // Get Tab_1_2 which should be Tab_1 in Window 2.
504 scoped_refptr<TabProxy> tab1_2(browser2->GetTab(0));
505 ASSERT_TRUE(tab1_2.get());
506 GURL tab1_2_url;
507 ASSERT_TRUE(tab1_2->GetCurrentURL(&tab1_2_url));
508
509 // Tab_1_2 of Window 2 should essentially be Tab_2 of Window 1.
510 EXPECT_EQ(tab1_2_url.spec(), tab2_url.spec());
511 EXPECT_NE(tab1_2_url.spec(), tab1_url.spec());
512 EXPECT_NE(tab1_2_url.spec(), tab3_url.spec());
513 }
514