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 49class TabDraggingTest : public UITest { 50 protected: 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. 58TEST_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. 156TEST_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. 263TEST_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. 373TEST_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