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 <string> 6 7 #include "base/bind.h" 8 #include "base/command_line.h" 9 #include "base/compiler_specific.h" 10 #include "base/files/file_path.h" 11 #include "base/prefs/pref_service.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "base/sys_info.h" 14 #include "chrome/app/chrome_command_ids.h" 15 #include "chrome/browser/chrome_content_browser_client.h" 16 #include "chrome/browser/chrome_notification_types.h" 17 #include "chrome/browser/command_updater.h" 18 #include "chrome/browser/content_settings/host_content_settings_map.h" 19 #include "chrome/browser/defaults.h" 20 #include "chrome/browser/extensions/extension_browsertest.h" 21 #include "chrome/browser/extensions/extension_service.h" 22 #include "chrome/browser/extensions/extension_system.h" 23 #include "chrome/browser/extensions/tab_helper.h" 24 #include "chrome/browser/first_run/first_run.h" 25 #include "chrome/browser/lifetime/application_lifetime.h" 26 #include "chrome/browser/prefs/incognito_mode_prefs.h" 27 #include "chrome/browser/profiles/profile.h" 28 #include "chrome/browser/profiles/profile_manager.h" 29 #include "chrome/browser/sessions/session_backend.h" 30 #include "chrome/browser/sessions/session_service_factory.h" 31 #include "chrome/browser/translate/translate_tab_helper.h" 32 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" 33 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" 34 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h" 35 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" 36 #include "chrome/browser/ui/browser.h" 37 #include "chrome/browser/ui/browser_command_controller.h" 38 #include "chrome/browser/ui/browser_commands.h" 39 #include "chrome/browser/ui/browser_finder.h" 40 #include "chrome/browser/ui/browser_iterator.h" 41 #include "chrome/browser/ui/browser_navigator.h" 42 #include "chrome/browser/ui/browser_tabstrip.h" 43 #include "chrome/browser/ui/browser_ui_prefs.h" 44 #include "chrome/browser/ui/browser_window.h" 45 #include "chrome/browser/ui/extensions/application_launch.h" 46 #include "chrome/browser/ui/host_desktop.h" 47 #include "chrome/browser/ui/startup/startup_browser_creator.h" 48 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h" 49 #include "chrome/browser/ui/tabs/pinned_tab_codec.h" 50 #include "chrome/browser/ui/tabs/tab_strip_model.h" 51 #include "chrome/common/chrome_switches.h" 52 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 53 #include "chrome/common/translate/language_detection_details.h" 54 #include "chrome/common/url_constants.h" 55 #include "chrome/test/base/in_process_browser_test.h" 56 #include "chrome/test/base/test_switches.h" 57 #include "chrome/test/base/ui_test_utils.h" 58 #include "content/public/browser/favicon_status.h" 59 #include "content/public/browser/host_zoom_map.h" 60 #include "content/public/browser/interstitial_page.h" 61 #include "content/public/browser/interstitial_page_delegate.h" 62 #include "content/public/browser/navigation_entry.h" 63 #include "content/public/browser/notification_service.h" 64 #include "content/public/browser/render_process_host.h" 65 #include "content/public/browser/render_view_host.h" 66 #include "content/public/browser/render_widget_host_view.h" 67 #include "content/public/browser/resource_context.h" 68 #include "content/public/browser/web_contents.h" 69 #include "content/public/browser/web_contents_observer.h" 70 #include "content/public/browser/web_contents_view.h" 71 #include "content/public/common/frame_navigate_params.h" 72 #include "content/public/common/page_transition_types.h" 73 #include "content/public/common/renderer_preferences.h" 74 #include "content/public/common/url_constants.h" 75 #include "content/public/test/browser_test_utils.h" 76 #include "content/public/test/test_navigation_observer.h" 77 #include "extensions/common/extension.h" 78 #include "grit/chromium_strings.h" 79 #include "grit/generated_resources.h" 80 #include "net/dns/mock_host_resolver.h" 81 #include "net/test/spawned_test_server/spawned_test_server.h" 82 #include "ui/base/l10n/l10n_util.h" 83 84 #if defined(OS_MACOSX) 85 #include "base/mac/mac_util.h" 86 #include "base/mac/scoped_nsautorelease_pool.h" 87 #include "chrome/browser/ui/cocoa/run_loop_testing.h" 88 #endif 89 90 #if defined(OS_WIN) 91 #include "base/i18n/rtl.h" 92 #include "chrome/browser/browser_process.h" 93 #endif 94 95 using content::InterstitialPage; 96 using content::HostZoomMap; 97 using content::NavigationController; 98 using content::NavigationEntry; 99 using content::OpenURLParams; 100 using content::Referrer; 101 using content::WebContents; 102 using content::WebContentsObserver; 103 using extensions::Extension; 104 105 namespace { 106 107 const char* kBeforeUnloadHTML = 108 "<html><head><title>beforeunload</title></head><body>" 109 "<script>window.onbeforeunload=function(e){return 'foo'}</script>" 110 "</body></html>"; 111 112 const char* kOpenNewBeforeUnloadPage = 113 "w=window.open(); w.onbeforeunload=function(e){return 'foo'};"; 114 115 const base::FilePath::CharType* kBeforeUnloadFile = 116 FILE_PATH_LITERAL("beforeunload.html"); 117 118 const base::FilePath::CharType* kTitle1File = FILE_PATH_LITERAL("title1.html"); 119 const base::FilePath::CharType* kTitle2File = FILE_PATH_LITERAL("title2.html"); 120 121 const base::FilePath::CharType kDocRoot[] = 122 FILE_PATH_LITERAL("chrome/test/data"); 123 124 // Given a page title, returns the expected window caption string. 125 base::string16 WindowCaptionFromPageTitle(const base::string16& page_title) { 126 #if defined(OS_MACOSX) || defined(OS_CHROMEOS) 127 // On Mac or ChromeOS, we don't want to suffix the page title with 128 // the application name. 129 if (page_title.empty()) 130 return l10n_util::GetStringUTF16(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); 131 return page_title; 132 #else 133 if (page_title.empty()) 134 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 135 136 return l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT, 137 page_title); 138 #endif 139 } 140 141 // Returns the number of active RenderProcessHosts. 142 int CountRenderProcessHosts() { 143 int result = 0; 144 for (content::RenderProcessHost::iterator i( 145 content::RenderProcessHost::AllHostsIterator()); 146 !i.IsAtEnd(); i.Advance()) 147 ++result; 148 return result; 149 } 150 151 class MockTabStripModelObserver : public TabStripModelObserver { 152 public: 153 MockTabStripModelObserver() : closing_count_(0) {} 154 155 virtual void TabClosingAt(TabStripModel* tab_strip_model, 156 WebContents* contents, 157 int index) OVERRIDE { 158 ++closing_count_; 159 } 160 161 int closing_count() const { return closing_count_; } 162 163 private: 164 int closing_count_; 165 166 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver); 167 }; 168 169 class InterstitialObserver : public content::WebContentsObserver { 170 public: 171 InterstitialObserver(content::WebContents* web_contents, 172 const base::Closure& attach_callback, 173 const base::Closure& detach_callback) 174 : WebContentsObserver(web_contents), 175 attach_callback_(attach_callback), 176 detach_callback_(detach_callback) { 177 } 178 179 virtual void DidAttachInterstitialPage() OVERRIDE { 180 attach_callback_.Run(); 181 } 182 183 virtual void DidDetachInterstitialPage() OVERRIDE { 184 detach_callback_.Run(); 185 } 186 187 private: 188 base::Closure attach_callback_; 189 base::Closure detach_callback_; 190 191 DISALLOW_COPY_AND_ASSIGN(InterstitialObserver); 192 }; 193 194 // Causes the browser to swap processes on a redirect to an HTTPS URL. 195 class TransferHttpsRedirectsContentBrowserClient 196 : public chrome::ChromeContentBrowserClient { 197 public: 198 virtual bool ShouldSwapProcessesForRedirect( 199 content::ResourceContext* resource_context, 200 const GURL& current_url, 201 const GURL& new_url) OVERRIDE { 202 return new_url.SchemeIs(content::kHttpsScheme); 203 } 204 }; 205 206 // Used by CloseWithAppMenuOpen. Invokes CloseWindow on the supplied browser. 207 void CloseWindowCallback(Browser* browser) { 208 chrome::CloseWindow(browser); 209 } 210 211 // Used by CloseWithAppMenuOpen. Posts a CloseWindowCallback and shows the app 212 // menu. 213 void RunCloseWithAppMenuCallback(Browser* browser) { 214 // ShowAppMenu is modal under views. Schedule a task that closes the window. 215 base::MessageLoop::current()->PostTask( 216 FROM_HERE, base::Bind(&CloseWindowCallback, browser)); 217 chrome::ShowAppMenu(browser); 218 } 219 220 // Displays "INTERSTITIAL" while the interstitial is attached. 221 // (InterstitialPage can be used in a test directly, but there would be no way 222 // to visually tell if it is showing or not.) 223 class TestInterstitialPage : public content::InterstitialPageDelegate { 224 public: 225 TestInterstitialPage(WebContents* tab, bool new_navigation, const GURL& url) { 226 interstitial_page_ = InterstitialPage::Create( 227 tab, new_navigation, url , this); 228 interstitial_page_->Show(); 229 } 230 virtual ~TestInterstitialPage() { } 231 void Proceed() { 232 interstitial_page_->Proceed(); 233 } 234 void DontProceed() { 235 interstitial_page_->DontProceed(); 236 } 237 238 virtual std::string GetHTMLContents() OVERRIDE { 239 return "<h1>INTERSTITIAL</h1>"; 240 } 241 242 private: 243 InterstitialPage* interstitial_page_; // Owns us. 244 }; 245 246 class RenderViewSizeObserver : public content::WebContentsObserver { 247 public: 248 RenderViewSizeObserver(content::WebContents* web_contents, 249 BrowserWindow* browser_window) 250 : WebContentsObserver(web_contents), 251 browser_window_(browser_window) { 252 } 253 254 void GetSizeForRenderViewHost( 255 content::RenderViewHost* render_view_host, 256 gfx::Size* rwhv_create_size, 257 gfx::Size* rwhv_commit_size, 258 gfx::Size* wcv_commit_size) { 259 RenderViewSizes::const_iterator result = render_view_sizes_.end(); 260 result = render_view_sizes_.find(render_view_host); 261 if (result != render_view_sizes_.end()) { 262 *rwhv_create_size = result->second.rwhv_create_size; 263 *rwhv_commit_size = result->second.rwhv_commit_size; 264 *wcv_commit_size = result->second.wcv_commit_size; 265 } 266 } 267 268 void set_wcv_resize_insets(const gfx::Size& wcv_resize_insets) { 269 wcv_resize_insets_ = wcv_resize_insets; 270 } 271 272 // Cache the size when RenderViewHost is first created. 273 virtual void RenderViewCreated( 274 content::RenderViewHost* render_view_host) OVERRIDE { 275 render_view_sizes_[render_view_host].rwhv_create_size = 276 render_view_host->GetView()->GetViewBounds().size(); 277 } 278 279 // Enlarge WebContentsView by |wcv_resize_insets_| while the navigation entry 280 // is pending. 281 virtual void DidStartNavigationToPendingEntry( 282 const GURL& url, 283 NavigationController::ReloadType reload_type) OVERRIDE { 284 if (wcv_resize_insets_.IsEmpty()) 285 return; 286 // Resizing the main browser window by |wcv_resize_insets_| will 287 // automatically resize the WebContentsView by the same amount. 288 // Just resizing WebContentsView directly doesn't work on Linux, because the 289 // next automatic layout of the browser window will resize WebContentsView 290 // back to the previous size. To make it consistent, resize main browser 291 // window on all platforms. 292 gfx::Rect bounds(browser_window_->GetBounds()); 293 gfx::Size size(bounds.size()); 294 size.Enlarge(wcv_resize_insets_.width(), wcv_resize_insets_.height()); 295 bounds.set_size(size); 296 browser_window_->SetBounds(bounds); 297 // Let the message loop run so that resize actually takes effect. 298 content::RunAllPendingInMessageLoop(); 299 } 300 301 // Cache the sizes of RenderWidgetHostView and WebContentsView when the 302 // navigation entry is committed, which is before 303 // WebContentsDelegate::DidNavigateMainFramePostCommit is called. 304 virtual void NavigationEntryCommitted( 305 const content::LoadCommittedDetails& details) OVERRIDE { 306 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); 307 render_view_sizes_[rvh].rwhv_commit_size = 308 web_contents()->GetRenderWidgetHostView()->GetViewBounds().size(); 309 render_view_sizes_[rvh].wcv_commit_size = 310 web_contents()->GetView()->GetContainerSize(); 311 } 312 313 private: 314 struct Sizes { 315 gfx::Size rwhv_create_size; // Size of RenderWidgetHostView when created. 316 gfx::Size rwhv_commit_size; // Size of RenderWidgetHostView when committed. 317 gfx::Size wcv_commit_size; // Size of WebContentsView when committed. 318 }; 319 320 typedef std::map<content::RenderViewHost*, Sizes> RenderViewSizes; 321 RenderViewSizes render_view_sizes_; 322 // Enlarge WebContentsView by this size insets in 323 // DidStartNavigationToPendingEntry. 324 gfx::Size wcv_resize_insets_; 325 BrowserWindow* browser_window_; // Weak ptr. 326 327 DISALLOW_COPY_AND_ASSIGN(RenderViewSizeObserver); 328 }; 329 330 } // namespace 331 332 class BrowserTest : public ExtensionBrowserTest { 333 protected: 334 // In RTL locales wrap the page title with RTL embedding characters so that it 335 // matches the value returned by GetWindowTitle(). 336 base::string16 LocaleWindowCaptionFromPageTitle( 337 const base::string16& expected_title) { 338 base::string16 page_title = WindowCaptionFromPageTitle(expected_title); 339 #if defined(OS_WIN) 340 std::string locale = g_browser_process->GetApplicationLocale(); 341 if (base::i18n::GetTextDirectionForLocale(locale.c_str()) == 342 base::i18n::RIGHT_TO_LEFT) { 343 base::i18n::WrapStringWithLTRFormatting(&page_title); 344 } 345 346 return page_title; 347 #else 348 // Do we need to use the above code on POSIX as well? 349 return page_title; 350 #endif 351 } 352 353 // Returns the app extension aptly named "App Test". 354 const Extension* GetExtension() { 355 const ExtensionSet* extensions = extensions::ExtensionSystem::Get( 356 browser()->profile())->extension_service()->extensions(); 357 for (ExtensionSet::const_iterator it = extensions->begin(); 358 it != extensions->end(); ++it) { 359 if ((*it)->name() == "App Test") 360 return it->get(); 361 } 362 NOTREACHED(); 363 return NULL; 364 } 365 }; 366 367 // Launch the app on a page with no title, check that the app title was set 368 // correctly. 369 IN_PROC_BROWSER_TEST_F(BrowserTest, NoTitle) { 370 #if defined(OS_WIN) && defined(USE_ASH) 371 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 372 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 373 return; 374 #endif 375 376 ui_test_utils::NavigateToURL( 377 browser(), ui_test_utils::GetTestUrl( 378 base::FilePath(base::FilePath::kCurrentDirectory), 379 base::FilePath(kTitle1File))); 380 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")), 381 browser()->GetWindowTitleForCurrentTab()); 382 base::string16 tab_title; 383 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title)); 384 EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title); 385 } 386 387 // Launch the app, navigate to a page with a title, check that the app title 388 // was set correctly. 389 IN_PROC_BROWSER_TEST_F(BrowserTest, Title) { 390 #if defined(OS_WIN) && defined(USE_ASH) 391 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 392 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 393 return; 394 #endif 395 396 ui_test_utils::NavigateToURL( 397 browser(), ui_test_utils::GetTestUrl( 398 base::FilePath(base::FilePath::kCurrentDirectory), 399 base::FilePath(kTitle2File))); 400 const base::string16 test_title(ASCIIToUTF16("Title Of Awesomeness")); 401 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(test_title), 402 browser()->GetWindowTitleForCurrentTab()); 403 base::string16 tab_title; 404 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title)); 405 EXPECT_EQ(test_title, tab_title); 406 } 407 408 IN_PROC_BROWSER_TEST_F(BrowserTest, JavascriptAlertActivatesTab) { 409 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 410 base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File))); 411 ui_test_utils::NavigateToURL(browser(), url); 412 AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED); 413 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 414 EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); 415 WebContents* second_tab = browser()->tab_strip_model()->GetWebContentsAt(1); 416 ASSERT_TRUE(second_tab); 417 second_tab->GetRenderViewHost()->ExecuteJavascriptInWebFrame( 418 base::string16(), 419 ASCIIToUTF16("alert('Activate!');")); 420 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 421 alert->CloseModalDialog(); 422 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 423 EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); 424 } 425 426 427 #if defined(OS_WIN) && !defined(NDEBUG) 428 // http://crbug.com/114859. Times out frequently on Windows. 429 #define MAYBE_ThirtyFourTabs DISABLED_ThirtyFourTabs 430 #else 431 #define MAYBE_ThirtyFourTabs ThirtyFourTabs 432 #endif 433 434 // Create 34 tabs and verify that a lot of processes have been created. The 435 // exact number of processes depends on the amount of memory. Previously we 436 // had a hard limit of 31 processes and this test is mainly directed at 437 // verifying that we don't crash when we pass this limit. 438 // Warning: this test can take >30 seconds when running on a slow (low 439 // memory?) Mac builder. 440 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_ThirtyFourTabs) { 441 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 442 base::FilePath::kCurrentDirectory), base::FilePath(kTitle2File))); 443 444 // There is one initial tab. 445 const int kTabCount = 34; 446 for (int ix = 0; ix != (kTabCount - 1); ++ix) { 447 chrome::AddSelectedTabWithURL(browser(), url, 448 content::PAGE_TRANSITION_TYPED); 449 } 450 EXPECT_EQ(kTabCount, browser()->tab_strip_model()->count()); 451 452 // See GetMaxRendererProcessCount() in 453 // content/browser/renderer_host/render_process_host_impl.cc 454 // for the algorithm to decide how many processes to create. 455 const int kExpectedProcessCount = 456 #if defined(ARCH_CPU_64_BITS) 457 17; 458 #else 459 25; 460 #endif 461 if (base::SysInfo::AmountOfPhysicalMemoryMB() >= 2048) { 462 EXPECT_GE(CountRenderProcessHosts(), kExpectedProcessCount); 463 } else { 464 EXPECT_LT(CountRenderProcessHosts(), kExpectedProcessCount); 465 } 466 } 467 468 // Test for crbug.com/297289. Ensure that modal dialogs are closed when a 469 // cross-process navigation is ready to commit. 470 IN_PROC_BROWSER_TEST_F(BrowserTest, CrossProcessNavCancelsDialogs) { 471 ASSERT_TRUE(test_server()->Start()); 472 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 473 GURL url(test_server()->GetURL("empty.html")); 474 ui_test_utils::NavigateToURL(browser(), url); 475 476 // Test this with multiple alert dialogs to ensure that we can navigate away 477 // even if the renderer tries to synchronously create more. 478 // See http://crbug.com/312490. 479 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 480 contents->GetRenderViewHost()->ExecuteJavascriptInWebFrame( 481 base::string16(), 482 ASCIIToUTF16("alert('one'); alert('two');")); 483 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 484 EXPECT_TRUE(alert->IsValid()); 485 AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance(); 486 EXPECT_TRUE(dialog_queue->HasActiveDialog()); 487 488 // A cross-site navigation should force the dialog to close. 489 GURL url2("http://www.example.com/empty.html"); 490 ui_test_utils::NavigateToURL(browser(), url2); 491 EXPECT_FALSE(dialog_queue->HasActiveDialog()); 492 493 // Make sure input events still work in the renderer process. 494 EXPECT_FALSE(contents->GetRenderProcessHost()->IgnoreInputEvents()); 495 } 496 497 // Make sure that dialogs are closed after a renderer process dies, and that 498 // subsequent navigations work. See http://crbug/com/343265. 499 IN_PROC_BROWSER_TEST_F(BrowserTest, SadTabCancelsDialogs) { 500 ASSERT_TRUE(test_server()->Start()); 501 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 502 GURL beforeunload_url(test_server()->GetURL("files/beforeunload.html")); 503 ui_test_utils::NavigateToURL(browser(), beforeunload_url); 504 505 // Start a navigation to trigger the beforeunload dialog. 506 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 507 contents->GetRenderViewHost()->ExecuteJavascriptInWebFrame( 508 base::string16(), 509 ASCIIToUTF16("window.location.href = 'data:text/html,foo'")); 510 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 511 EXPECT_TRUE(alert->IsValid()); 512 AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance(); 513 EXPECT_TRUE(dialog_queue->HasActiveDialog()); 514 515 // Crash the renderer process and ensure the dialog is gone. 516 content::RenderProcessHost* child_process = contents->GetRenderProcessHost(); 517 content::WindowedNotificationObserver crash_observer( 518 content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 519 content::Source<content::RenderProcessHost>(child_process)); 520 base::KillProcess(child_process->GetHandle(), 0, false); 521 crash_observer.Wait(); 522 EXPECT_FALSE(dialog_queue->HasActiveDialog()); 523 524 // Make sure subsequent navigations work. 525 GURL url2("http://www.example.com/files/empty.html"); 526 ui_test_utils::NavigateToURL(browser(), url2); 527 } 528 529 // Test for crbug.com/22004. Reloading a page with a before unload handler and 530 // then canceling the dialog should not leave the throbber spinning. 531 IN_PROC_BROWSER_TEST_F(BrowserTest, ReloadThenCancelBeforeUnload) { 532 GURL url(std::string("data:text/html,") + kBeforeUnloadHTML); 533 ui_test_utils::NavigateToURL(browser(), url); 534 535 // Navigate to another page, but click cancel in the dialog. Make sure that 536 // the throbber stops spinning. 537 chrome::Reload(browser(), CURRENT_TAB); 538 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 539 alert->CloseModalDialog(); 540 EXPECT_FALSE( 541 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading()); 542 543 // Clear the beforeunload handler so the test can easily exit. 544 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost()-> 545 ExecuteJavascriptInWebFrame(base::string16(), 546 ASCIIToUTF16("onbeforeunload=null;")); 547 } 548 549 class RedirectObserver : public content::WebContentsObserver { 550 public: 551 explicit RedirectObserver(content::WebContents* web_contents) 552 : WebContentsObserver(web_contents) { 553 } 554 555 virtual void DidNavigateAnyFrame( 556 const content::LoadCommittedDetails& details, 557 const content::FrameNavigateParams& params) OVERRIDE { 558 params_ = params; 559 } 560 561 virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE { 562 // Make sure we don't close the tab while the observer is in scope. 563 // See http://crbug.com/314036. 564 FAIL() << "WebContents closed during navigation (http://crbug.com/314036)."; 565 } 566 567 const content::FrameNavigateParams& params() const { 568 return params_; 569 } 570 571 private: 572 content::FrameNavigateParams params_; 573 574 DISALLOW_COPY_AND_ASSIGN(RedirectObserver); 575 }; 576 577 // Ensure that a transferred cross-process navigation does not generate 578 // DidStopLoading events until the navigation commits. If it did, then 579 // ui_test_utils::NavigateToURL would proceed before the URL had committed. 580 // http://crbug.com/243957. 581 IN_PROC_BROWSER_TEST_F(BrowserTest, NoStopDuringTransferUntilCommit) { 582 // Create HTTP and HTTPS servers for a cross-site transition. 583 ASSERT_TRUE(test_server()->Start()); 584 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 585 net::SpawnedTestServer::kLocalhost, 586 base::FilePath(kDocRoot)); 587 ASSERT_TRUE(https_test_server.Start()); 588 589 // Temporarily replace ContentBrowserClient with one that will cause a 590 // process swap on all redirects to HTTPS URLs. 591 TransferHttpsRedirectsContentBrowserClient new_client; 592 content::ContentBrowserClient* old_client = 593 SetBrowserClientForTesting(&new_client); 594 595 GURL init_url(test_server()->GetURL("files/title1.html")); 596 ui_test_utils::NavigateToURL(browser(), init_url); 597 598 // Navigate to a same-site page that redirects, causing a transfer. 599 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 600 601 // Create a RedirectObserver that goes away before we close the tab. 602 { 603 RedirectObserver redirect_observer(contents); 604 GURL dest_url(https_test_server.GetURL("files/title2.html")); 605 GURL redirect_url(test_server()->GetURL("server-redirect?" + 606 dest_url.spec())); 607 ui_test_utils::NavigateToURL(browser(), redirect_url); 608 609 // We should immediately see the new committed entry. 610 EXPECT_FALSE(contents->GetController().GetPendingEntry()); 611 EXPECT_EQ(dest_url, 612 contents->GetController().GetLastCommittedEntry()->GetURL()); 613 614 // We should keep track of the original request URL, redirect chain, and 615 // page transition type during a transfer, since these are necessary for 616 // history autocomplete to work. 617 EXPECT_EQ(redirect_url, contents->GetController().GetLastCommittedEntry()-> 618 GetOriginalRequestURL()); 619 EXPECT_EQ(2U, redirect_observer.params().redirects.size()); 620 EXPECT_EQ(redirect_url, redirect_observer.params().redirects.at(0)); 621 EXPECT_EQ(dest_url, redirect_observer.params().redirects.at(1)); 622 EXPECT_TRUE(PageTransitionCoreTypeIs(redirect_observer.params().transition, 623 content::PAGE_TRANSITION_TYPED)); 624 } 625 626 // Restore previous browser client. 627 SetBrowserClientForTesting(old_client); 628 } 629 630 // Tests that a cross-process redirect will only cause the beforeunload 631 // handler to run once. 632 IN_PROC_BROWSER_TEST_F(BrowserTest, SingleBeforeUnloadAfterRedirect) { 633 // Create HTTP and HTTPS servers for a cross-site transition. 634 ASSERT_TRUE(test_server()->Start()); 635 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 636 net::SpawnedTestServer::kLocalhost, 637 base::FilePath(kDocRoot)); 638 ASSERT_TRUE(https_test_server.Start()); 639 640 // Temporarily replace ContentBrowserClient with one that will cause a 641 // process swap on all redirects to HTTPS URLs. 642 TransferHttpsRedirectsContentBrowserClient new_client; 643 content::ContentBrowserClient* old_client = 644 SetBrowserClientForTesting(&new_client); 645 646 // Navigate to a page with a beforeunload handler. 647 GURL url(test_server()->GetURL("files/beforeunload.html")); 648 ui_test_utils::NavigateToURL(browser(), url); 649 650 // Navigate to a URL that redirects to another process and approve the 651 // beforeunload dialog that pops up. 652 content::WindowedNotificationObserver nav_observer( 653 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 654 content::NotificationService::AllSources()); 655 GURL https_url(https_test_server.GetURL("files/title1.html")); 656 GURL redirect_url(test_server()->GetURL("server-redirect?" + 657 https_url.spec())); 658 browser()->OpenURL(OpenURLParams(redirect_url, Referrer(), CURRENT_TAB, 659 content::PAGE_TRANSITION_TYPED, false)); 660 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 661 EXPECT_TRUE( 662 static_cast<JavaScriptAppModalDialog*>(alert)->is_before_unload_dialog()); 663 alert->native_dialog()->AcceptAppModalDialog(); 664 nav_observer.Wait(); 665 666 // Restore previous browser client. 667 SetBrowserClientForTesting(old_client); 668 } 669 670 // Test for crbug.com/80401. Canceling a before unload dialog should reset 671 // the URL to the previous page's URL. 672 IN_PROC_BROWSER_TEST_F(BrowserTest, CancelBeforeUnloadResetsURL) { 673 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 674 base::FilePath::kCurrentDirectory), base::FilePath(kBeforeUnloadFile))); 675 ui_test_utils::NavigateToURL(browser(), url); 676 677 // Navigate to a page that triggers a cross-site transition. 678 ASSERT_TRUE(test_server()->Start()); 679 GURL url2(test_server()->GetURL("files/title1.html")); 680 browser()->OpenURL(OpenURLParams( 681 url2, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false)); 682 683 content::WindowedNotificationObserver host_destroyed_observer( 684 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 685 content::NotificationService::AllSources()); 686 687 // Cancel the dialog. 688 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 689 alert->CloseModalDialog(); 690 EXPECT_FALSE( 691 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading()); 692 693 // Verify there are no pending history items after the dialog is cancelled. 694 // (see crbug.com/93858) 695 NavigationEntry* entry = browser()->tab_strip_model()-> 696 GetActiveWebContents()->GetController().GetPendingEntry(); 697 EXPECT_EQ(NULL, entry); 698 699 // Wait for the ShouldClose_ACK to arrive. We can detect it by waiting for 700 // the pending RVH to be destroyed. 701 host_destroyed_observer.Wait(); 702 EXPECT_EQ(url, browser()->toolbar_model()->GetURL()); 703 704 // Clear the beforeunload handler so the test can easily exit. 705 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost()-> 706 ExecuteJavascriptInWebFrame(base::string16(), 707 ASCIIToUTF16("onbeforeunload=null;")); 708 } 709 710 // Crashy on mac. http://crbug.com/38522 Crashy on win too (after 3 years). 711 #if defined(OS_MACOSX) || defined(OS_WIN) 712 #define MAYBE_SingleBeforeUnloadAfterWindowClose \ 713 DISABLED_SingleBeforeUnloadAfterWindowClose 714 #else 715 #define MAYBE_SingleBeforeUnloadAfterWindowClose \ 716 SingleBeforeUnloadAfterWindowClose 717 #endif 718 719 // Test for crbug.com/11647. A page closed with window.close() should not have 720 // two beforeunload dialogs shown. 721 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_SingleBeforeUnloadAfterWindowClose) { 722 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost()-> 723 ExecuteJavascriptInWebFrame(base::string16(), 724 ASCIIToUTF16(kOpenNewBeforeUnloadPage)); 725 726 // Close the new window with JavaScript, which should show a single 727 // beforeunload dialog. Then show another alert, to make it easy to verify 728 // that a second beforeunload dialog isn't shown. 729 browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderViewHost()-> 730 ExecuteJavascriptInWebFrame(base::string16(), 731 ASCIIToUTF16("w.close(); alert('bar');")); 732 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 733 alert->native_dialog()->AcceptAppModalDialog(); 734 735 alert = ui_test_utils::WaitForAppModalDialog(); 736 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog*>(alert)-> 737 is_before_unload_dialog()); 738 alert->native_dialog()->AcceptAppModalDialog(); 739 } 740 741 // BrowserTest.BeforeUnloadVsBeforeReload times out on Windows. 742 // http://crbug.com/130411 743 #if defined(OS_WIN) 744 #define MAYBE_BeforeUnloadVsBeforeReload DISABLED_BeforeUnloadVsBeforeReload 745 #else 746 #define MAYBE_BeforeUnloadVsBeforeReload BeforeUnloadVsBeforeReload 747 #endif 748 749 // Test that when a page has an onunload handler, reloading a page shows a 750 // different dialog than navigating to a different page. 751 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_BeforeUnloadVsBeforeReload) { 752 GURL url(std::string("data:text/html,") + kBeforeUnloadHTML); 753 ui_test_utils::NavigateToURL(browser(), url); 754 755 // Reload the page, and check that we get a "before reload" dialog. 756 chrome::Reload(browser(), CURRENT_TAB); 757 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 758 EXPECT_TRUE(static_cast<JavaScriptAppModalDialog*>(alert)->is_reload()); 759 760 // Cancel the reload. 761 alert->native_dialog()->CancelAppModalDialog(); 762 763 // Navigate to another url, and check that we get a "before unload" dialog. 764 GURL url2(std::string("about:blank")); 765 browser()->OpenURL(OpenURLParams( 766 url2, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false)); 767 768 alert = ui_test_utils::WaitForAppModalDialog(); 769 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog*>(alert)->is_reload()); 770 771 // Accept the navigation so we end up on a page without a beforeunload hook. 772 alert->native_dialog()->AcceptAppModalDialog(); 773 } 774 775 // BeforeUnloadAtQuitWithTwoWindows is a regression test for 776 // http://crbug.com/11842. It opens two windows, one of which has a 777 // beforeunload handler and attempts to exit cleanly. 778 class BeforeUnloadAtQuitWithTwoWindows : public InProcessBrowserTest { 779 public: 780 // This test is for testing a specific shutdown behavior. This mimics what 781 // happens in InProcessBrowserTest::RunTestOnMainThread and QuitBrowsers, but 782 // ensures that it happens through the single IDC_EXIT of the test. 783 virtual void CleanUpOnMainThread() OVERRIDE { 784 // Cycle both the MessageLoop and the Cocoa runloop twice to flush out any 785 // Chrome work that generates Cocoa work. Do this twice since there are two 786 // Browsers that must be closed. 787 CycleRunLoops(); 788 CycleRunLoops(); 789 790 // Run the application event loop to completion, which will cycle the 791 // native MessagePump on all platforms. 792 base::MessageLoop::current()->PostTask(FROM_HERE, 793 base::MessageLoop::QuitClosure()); 794 base::MessageLoop::current()->Run(); 795 796 // Take care of any remaining Cocoa work. 797 CycleRunLoops(); 798 799 // At this point, quit should be for real now. 800 ASSERT_EQ(0u, chrome::GetTotalBrowserCount()); 801 } 802 803 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run 804 // loop. It also drains the NSAutoreleasePool. 805 void CycleRunLoops() { 806 content::RunAllPendingInMessageLoop(); 807 #if defined(OS_MACOSX) 808 chrome::testing::NSRunLoopRunAllPending(); 809 AutoreleasePool()->Recycle(); 810 #endif 811 } 812 }; 813 814 // Disabled, http://crbug.com/159214 . 815 IN_PROC_BROWSER_TEST_F(BeforeUnloadAtQuitWithTwoWindows, 816 DISABLED_IfThisTestTimesOutItIndicatesFAILURE) { 817 // In the first browser, set up a page that has a beforeunload handler. 818 GURL url(std::string("data:text/html,") + kBeforeUnloadHTML); 819 ui_test_utils::NavigateToURL(browser(), url); 820 821 // Open a second browser window at about:blank. 822 ui_test_utils::BrowserAddedObserver browser_added_observer; 823 chrome::NewEmptyWindow(browser()->profile(), chrome::GetActiveDesktop()); 824 Browser* second_window = browser_added_observer.WaitForSingleNewBrowser(); 825 ui_test_utils::NavigateToURL(second_window, GURL("about:blank")); 826 827 // Tell the application to quit. IDC_EXIT calls AttemptUserExit, which on 828 // everything but ChromeOS allows unload handlers to block exit. On that 829 // platform, though, it exits unconditionally. See the comment and bug ID 830 // in AttemptUserExit() in application_lifetime.cc. 831 #if defined(OS_CHROMEOS) 832 chrome::AttemptExit(); 833 #else 834 chrome::ExecuteCommand(second_window, IDC_EXIT); 835 #endif 836 837 // The beforeunload handler will run at exit, ensure it does, and then accept 838 // it to allow shutdown to proceed. 839 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 840 ASSERT_TRUE(alert); 841 EXPECT_TRUE( 842 static_cast<JavaScriptAppModalDialog*>(alert)->is_before_unload_dialog()); 843 alert->native_dialog()->AcceptAppModalDialog(); 844 845 // But wait there's more! If this test times out, it likely means that the 846 // browser has not been able to quit correctly, indicating there's a 847 // regression of the bug noted above. 848 } 849 850 // Test that scripts can fork a new renderer process for a cross-site popup, 851 // based on http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab. 852 // The script must open a new tab, set its window.opener to null, and navigate 853 // it to a cross-site URL. It should also work for meta-refreshes. 854 // See http://crbug.com/93517. 855 IN_PROC_BROWSER_TEST_F(BrowserTest, NullOpenerRedirectForksProcess) { 856 CommandLine::ForCurrentProcess()->AppendSwitch( 857 switches::kDisablePopupBlocking); 858 859 // Create http and https servers for a cross-site transition. 860 ASSERT_TRUE(test_server()->Start()); 861 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 862 net::SpawnedTestServer::kLocalhost, 863 base::FilePath(kDocRoot)); 864 ASSERT_TRUE(https_test_server.Start()); 865 GURL http_url(test_server()->GetURL("files/title1.html")); 866 GURL https_url(https_test_server.GetURL(std::string())); 867 868 // Start with an http URL. 869 ui_test_utils::NavigateToURL(browser(), http_url); 870 WebContents* oldtab = browser()->tab_strip_model()->GetActiveWebContents(); 871 content::RenderProcessHost* process = oldtab->GetRenderProcessHost(); 872 873 // Now open a tab to a blank page, set its opener to null, and redirect it 874 // cross-site. 875 std::string redirect_popup = "w=window.open();"; 876 redirect_popup += "w.opener=null;"; 877 redirect_popup += "w.document.location=\""; 878 redirect_popup += https_url.spec(); 879 redirect_popup += "\";"; 880 881 content::WindowedNotificationObserver popup_observer( 882 chrome::NOTIFICATION_TAB_ADDED, 883 content::NotificationService::AllSources()); 884 content::WindowedNotificationObserver nav_observer( 885 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 886 content::NotificationService::AllSources()); 887 oldtab->GetRenderViewHost()->ExecuteJavascriptInWebFrame( 888 base::string16(), ASCIIToUTF16(redirect_popup)); 889 890 // Wait for popup window to appear and finish navigating. 891 popup_observer.Wait(); 892 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 893 WebContents* newtab = browser()->tab_strip_model()->GetActiveWebContents(); 894 EXPECT_TRUE(newtab); 895 EXPECT_NE(oldtab, newtab); 896 nav_observer.Wait(); 897 ASSERT_TRUE(newtab->GetController().GetLastCommittedEntry()); 898 EXPECT_EQ(https_url.spec(), 899 newtab->GetController().GetLastCommittedEntry()->GetURL().spec()); 900 901 // Popup window should not be in the opener's process. 902 content::RenderProcessHost* popup_process = 903 newtab->GetRenderProcessHost(); 904 EXPECT_NE(process, popup_process); 905 906 // Now open a tab to a blank page, set its opener to null, and use a 907 // meta-refresh to navigate it instead. 908 std::string refresh_popup = "w=window.open();"; 909 refresh_popup += "w.opener=null;"; 910 refresh_popup += "w.document.write("; 911 refresh_popup += "'<META HTTP-EQUIV=\"refresh\" content=\"0; url="; 912 refresh_popup += https_url.spec(); 913 refresh_popup += "\">');w.document.close();"; 914 915 content::WindowedNotificationObserver popup_observer2( 916 chrome::NOTIFICATION_TAB_ADDED, 917 content::NotificationService::AllSources()); 918 content::WindowedNotificationObserver nav_observer2( 919 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 920 content::NotificationService::AllSources()); 921 oldtab->GetRenderViewHost()->ExecuteJavascriptInWebFrame( 922 base::string16(), ASCIIToUTF16(refresh_popup)); 923 924 // Wait for popup window to appear and finish navigating. 925 popup_observer2.Wait(); 926 ASSERT_EQ(3, browser()->tab_strip_model()->count()); 927 WebContents* newtab2 = browser()->tab_strip_model()->GetActiveWebContents(); 928 EXPECT_TRUE(newtab2); 929 EXPECT_NE(oldtab, newtab2); 930 nav_observer2.Wait(); 931 ASSERT_TRUE(newtab2->GetController().GetLastCommittedEntry()); 932 EXPECT_EQ(https_url.spec(), 933 newtab2->GetController().GetLastCommittedEntry()->GetURL().spec()); 934 935 // This popup window should also not be in the opener's process. 936 content::RenderProcessHost* popup_process2 = 937 newtab2->GetRenderProcessHost(); 938 EXPECT_NE(process, popup_process2); 939 } 940 941 // Tests that other popup navigations that do not follow the steps at 942 // http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab will not 943 // fork a new renderer process. 944 IN_PROC_BROWSER_TEST_F(BrowserTest, OtherRedirectsDontForkProcess) { 945 CommandLine::ForCurrentProcess()->AppendSwitch( 946 switches::kDisablePopupBlocking); 947 948 // Create http and https servers for a cross-site transition. 949 ASSERT_TRUE(test_server()->Start()); 950 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 951 net::SpawnedTestServer::kLocalhost, 952 base::FilePath(kDocRoot)); 953 ASSERT_TRUE(https_test_server.Start()); 954 GURL http_url(test_server()->GetURL("files/title1.html")); 955 GURL https_url(https_test_server.GetURL(std::string())); 956 957 // Start with an http URL. 958 ui_test_utils::NavigateToURL(browser(), http_url); 959 WebContents* oldtab = browser()->tab_strip_model()->GetActiveWebContents(); 960 content::RenderProcessHost* process = oldtab->GetRenderProcessHost(); 961 962 // Now open a tab to a blank page, set its opener to null, and redirect it 963 // cross-site. 964 std::string dont_fork_popup = "w=window.open();"; 965 dont_fork_popup += "w.document.location=\""; 966 dont_fork_popup += https_url.spec(); 967 dont_fork_popup += "\";"; 968 969 content::WindowedNotificationObserver popup_observer( 970 chrome::NOTIFICATION_TAB_ADDED, 971 content::NotificationService::AllSources()); 972 content::WindowedNotificationObserver nav_observer( 973 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 974 content::NotificationService::AllSources()); 975 oldtab->GetRenderViewHost()->ExecuteJavascriptInWebFrame( 976 base::string16(), ASCIIToUTF16(dont_fork_popup)); 977 978 // Wait for popup window to appear and finish navigating. 979 popup_observer.Wait(); 980 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 981 WebContents* newtab = browser()->tab_strip_model()->GetActiveWebContents(); 982 EXPECT_TRUE(newtab); 983 EXPECT_NE(oldtab, newtab); 984 nav_observer.Wait(); 985 ASSERT_TRUE(newtab->GetController().GetLastCommittedEntry()); 986 EXPECT_EQ(https_url.spec(), 987 newtab->GetController().GetLastCommittedEntry()->GetURL().spec()); 988 989 // Popup window should still be in the opener's process. 990 content::RenderProcessHost* popup_process = 991 newtab->GetRenderProcessHost(); 992 EXPECT_EQ(process, popup_process); 993 994 // Same thing if the current tab tries to navigate itself. 995 std::string navigate_str = "document.location=\""; 996 navigate_str += https_url.spec(); 997 navigate_str += "\";"; 998 999 content::WindowedNotificationObserver nav_observer2( 1000 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 1001 content::NotificationService::AllSources()); 1002 oldtab->GetRenderViewHost()-> 1003 ExecuteJavascriptInWebFrame(base::string16(), ASCIIToUTF16(navigate_str)); 1004 nav_observer2.Wait(); 1005 ASSERT_TRUE(oldtab->GetController().GetLastCommittedEntry()); 1006 EXPECT_EQ(https_url.spec(), 1007 oldtab->GetController().GetLastCommittedEntry()->GetURL().spec()); 1008 1009 // Original window should still be in the original process. 1010 content::RenderProcessHost* new_process = newtab->GetRenderProcessHost(); 1011 EXPECT_EQ(process, new_process); 1012 } 1013 1014 // Test that get_process_idle_time() returns reasonable values when compared 1015 // with time deltas measured locally. 1016 IN_PROC_BROWSER_TEST_F(BrowserTest, RenderIdleTime) { 1017 base::TimeTicks start = base::TimeTicks::Now(); 1018 ui_test_utils::NavigateToURL( 1019 browser(), ui_test_utils::GetTestUrl( 1020 base::FilePath(base::FilePath::kCurrentDirectory), 1021 base::FilePath(kTitle1File))); 1022 content::RenderProcessHost::iterator it( 1023 content::RenderProcessHost::AllHostsIterator()); 1024 for (; !it.IsAtEnd(); it.Advance()) { 1025 base::TimeDelta renderer_td = 1026 it.GetCurrentValue()->GetChildProcessIdleTime(); 1027 base::TimeDelta browser_td = base::TimeTicks::Now() - start; 1028 EXPECT_TRUE(browser_td >= renderer_td); 1029 } 1030 } 1031 1032 // Test IDC_CREATE_SHORTCUTS command is enabled for url scheme file, ftp, http 1033 // and https and disabled for chrome://, about:// etc. 1034 // TODO(pinkerton): Disable app-mode in the model until we implement it 1035 // on the Mac. http://crbug.com/13148 1036 #if !defined(OS_MACOSX) 1037 IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutFile) { 1038 CommandUpdater* command_updater = 1039 browser()->command_controller()->command_updater(); 1040 1041 static const base::FilePath::CharType* kEmptyFile = 1042 FILE_PATH_LITERAL("empty.html"); 1043 GURL file_url(ui_test_utils::GetTestUrl(base::FilePath( 1044 base::FilePath::kCurrentDirectory), base::FilePath(kEmptyFile))); 1045 ASSERT_TRUE(file_url.SchemeIs(chrome::kFileScheme)); 1046 ui_test_utils::NavigateToURL(browser(), file_url); 1047 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 1048 } 1049 1050 IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutHttp) { 1051 CommandUpdater* command_updater = 1052 browser()->command_controller()->command_updater(); 1053 1054 ASSERT_TRUE(test_server()->Start()); 1055 GURL http_url(test_server()->GetURL(std::string())); 1056 ASSERT_TRUE(http_url.SchemeIs(content::kHttpScheme)); 1057 ui_test_utils::NavigateToURL(browser(), http_url); 1058 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 1059 } 1060 1061 IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutHttps) { 1062 CommandUpdater* command_updater = 1063 browser()->command_controller()->command_updater(); 1064 1065 net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTPS, 1066 net::SpawnedTestServer::kLocalhost, 1067 base::FilePath(kDocRoot)); 1068 ASSERT_TRUE(test_server.Start()); 1069 GURL https_url(test_server.GetURL("/")); 1070 ASSERT_TRUE(https_url.SchemeIs(content::kHttpsScheme)); 1071 ui_test_utils::NavigateToURL(browser(), https_url); 1072 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 1073 } 1074 1075 IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutFtp) { 1076 CommandUpdater* command_updater = 1077 browser()->command_controller()->command_updater(); 1078 1079 net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_FTP, 1080 net::SpawnedTestServer::kLocalhost, 1081 base::FilePath(kDocRoot)); 1082 ASSERT_TRUE(test_server.Start()); 1083 GURL ftp_url(test_server.GetURL(std::string())); 1084 ASSERT_TRUE(ftp_url.SchemeIs(content::kFtpScheme)); 1085 ui_test_utils::NavigateToURL(browser(), ftp_url); 1086 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 1087 } 1088 1089 IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutInvalid) { 1090 CommandUpdater* command_updater = 1091 browser()->command_controller()->command_updater(); 1092 1093 // Urls that should not have shortcuts. 1094 GURL new_tab_url(chrome::kChromeUINewTabURL); 1095 ui_test_utils::NavigateToURL(browser(), new_tab_url); 1096 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 1097 1098 GURL history_url(chrome::kChromeUIHistoryURL); 1099 ui_test_utils::NavigateToURL(browser(), history_url); 1100 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 1101 1102 GURL downloads_url(chrome::kChromeUIDownloadsURL); 1103 ui_test_utils::NavigateToURL(browser(), downloads_url); 1104 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 1105 1106 GURL blank_url(content::kAboutBlankURL); 1107 ui_test_utils::NavigateToURL(browser(), blank_url); 1108 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 1109 } 1110 1111 // Change a tab into an application window. 1112 // DISABLED: http://crbug.com/72310 1113 IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_ConvertTabToAppShortcut) { 1114 ASSERT_TRUE(test_server()->Start()); 1115 GURL http_url(test_server()->GetURL(std::string())); 1116 ASSERT_TRUE(http_url.SchemeIs(content::kHttpScheme)); 1117 1118 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 1119 WebContents* initial_tab = browser()->tab_strip_model()->GetWebContentsAt(0); 1120 WebContents* app_tab = chrome::AddSelectedTabWithURL( 1121 browser(), http_url, content::PAGE_TRANSITION_TYPED); 1122 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 1123 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 1124 browser()->host_desktop_type())); 1125 1126 // Normal tabs should accept load drops. 1127 EXPECT_TRUE(initial_tab->GetMutableRendererPrefs()->can_accept_load_drops); 1128 EXPECT_TRUE(app_tab->GetMutableRendererPrefs()->can_accept_load_drops); 1129 1130 // Turn |app_tab| into a tab in an app panel. 1131 chrome::ConvertTabToAppWindow(browser(), app_tab); 1132 1133 // The launch should have created a new browser. 1134 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 1135 browser()->host_desktop_type())); 1136 1137 // Find the new browser. 1138 Browser* app_browser = NULL; 1139 for (chrome::BrowserIterator it; !it.done() && !app_browser; it.Next()) { 1140 if (*it != browser()) 1141 app_browser = *it; 1142 } 1143 ASSERT_TRUE(app_browser); 1144 1145 // Check that the tab contents is in the new browser, and not in the old. 1146 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 1147 ASSERT_EQ(initial_tab, browser()->tab_strip_model()->GetWebContentsAt(0)); 1148 1149 // Check that the appliaction browser has a single tab, and that tab contains 1150 // the content that we app-ified. 1151 ASSERT_EQ(1, app_browser->tab_strip_model()->count()); 1152 ASSERT_EQ(app_tab, app_browser->tab_strip_model()->GetWebContentsAt(0)); 1153 1154 // Normal tabs should accept load drops. 1155 EXPECT_TRUE(initial_tab->GetMutableRendererPrefs()->can_accept_load_drops); 1156 1157 // The tab in an app window should not. 1158 EXPECT_FALSE(app_tab->GetMutableRendererPrefs()->can_accept_load_drops); 1159 } 1160 1161 #endif // !defined(OS_MACOSX) 1162 1163 // Test RenderView correctly send back favicon url for web page that redirects 1164 // to an anchor in javascript body.onload handler. 1165 IN_PROC_BROWSER_TEST_F(BrowserTest, 1166 DISABLED_FaviconOfOnloadRedirectToAnchorPage) { 1167 ASSERT_TRUE(test_server()->Start()); 1168 GURL url(test_server()->GetURL("files/onload_redirect_to_anchor.html")); 1169 GURL expected_favicon_url(test_server()->GetURL("files/test.png")); 1170 1171 ui_test_utils::NavigateToURL(browser(), url); 1172 1173 NavigationEntry* entry = browser()->tab_strip_model()-> 1174 GetActiveWebContents()->GetController().GetActiveEntry(); 1175 EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec()); 1176 } 1177 1178 #if defined(OS_MACOSX) || defined(OS_LINUX) || defined (OS_WIN) 1179 // http://crbug.com/83828. On Mac 10.6, the failure rate is 14% 1180 #define MAYBE_FaviconChange DISABLED_FaviconChange 1181 #else 1182 #define MAYBE_FaviconChange FaviconChange 1183 #endif 1184 // Test that an icon can be changed from JS. 1185 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_FaviconChange) { 1186 static const base::FilePath::CharType* kFile = 1187 FILE_PATH_LITERAL("onload_change_favicon.html"); 1188 GURL file_url(ui_test_utils::GetTestUrl(base::FilePath( 1189 base::FilePath::kCurrentDirectory), base::FilePath(kFile))); 1190 ASSERT_TRUE(file_url.SchemeIs(chrome::kFileScheme)); 1191 ui_test_utils::NavigateToURL(browser(), file_url); 1192 1193 NavigationEntry* entry = browser()->tab_strip_model()-> 1194 GetActiveWebContents()->GetController().GetActiveEntry(); 1195 static const base::FilePath::CharType* kIcon = 1196 FILE_PATH_LITERAL("test1.png"); 1197 GURL expected_favicon_url(ui_test_utils::GetTestUrl(base::FilePath( 1198 base::FilePath::kCurrentDirectory), base::FilePath(kIcon))); 1199 EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec()); 1200 } 1201 1202 // http://crbug.com/172336 1203 #if defined(OS_WIN) 1204 #define MAYBE_TabClosingWhenRemovingExtension \ 1205 DISABLED_TabClosingWhenRemovingExtension 1206 #else 1207 #define MAYBE_TabClosingWhenRemovingExtension TabClosingWhenRemovingExtension 1208 #endif 1209 // Makes sure TabClosing is sent when uninstalling an extension that is an app 1210 // tab. 1211 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_TabClosingWhenRemovingExtension) { 1212 ASSERT_TRUE(test_server()->Start()); 1213 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1214 GURL url(test_server()->GetURL("empty.html")); 1215 TabStripModel* model = browser()->tab_strip_model(); 1216 1217 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); 1218 1219 const Extension* extension_app = GetExtension(); 1220 1221 ui_test_utils::NavigateToURL(browser(), url); 1222 1223 WebContents* app_contents = WebContents::Create( 1224 WebContents::CreateParams(browser()->profile())); 1225 extensions::TabHelper::CreateForWebContents(app_contents); 1226 extensions::TabHelper* extensions_tab_helper = 1227 extensions::TabHelper::FromWebContents(app_contents); 1228 extensions_tab_helper->SetExtensionApp(extension_app); 1229 1230 model->AddWebContents(app_contents, 0, content::PageTransitionFromInt(0), 1231 TabStripModel::ADD_NONE); 1232 model->SetTabPinned(0, true); 1233 ui_test_utils::NavigateToURL(browser(), url); 1234 1235 MockTabStripModelObserver observer; 1236 model->AddObserver(&observer); 1237 1238 // Uninstall the extension and make sure TabClosing is sent. 1239 ExtensionService* service = extensions::ExtensionSystem::Get( 1240 browser()->profile())->extension_service(); 1241 service->UninstallExtension(GetExtension()->id(), false, NULL); 1242 EXPECT_EQ(1, observer.closing_count()); 1243 1244 model->RemoveObserver(&observer); 1245 1246 // There should only be one tab now. 1247 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 1248 } 1249 1250 #if !defined(OS_MACOSX) 1251 // Open with --app-id=<id>, and see that an app window opens. 1252 IN_PROC_BROWSER_TEST_F(BrowserTest, AppIdSwitch) { 1253 ASSERT_TRUE(test_server()->Start()); 1254 1255 // Load an app. 1256 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1257 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); 1258 const Extension* extension_app = GetExtension(); 1259 1260 CommandLine command_line(CommandLine::NO_PROGRAM); 1261 command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); 1262 1263 chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? 1264 chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; 1265 StartupBrowserCreatorImpl launch(base::FilePath(), command_line, first_run); 1266 ASSERT_TRUE(launch.OpenApplicationWindow(browser()->profile(), NULL)); 1267 1268 // Check that the new browser has an app name. 1269 // The launch should have created a new browser. 1270 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 1271 browser()->host_desktop_type())); 1272 1273 // Find the new browser. 1274 Browser* new_browser = NULL; 1275 for (chrome::BrowserIterator it; !it.done() && !new_browser; it.Next()) { 1276 if (*it != browser()) 1277 new_browser = *it; 1278 } 1279 ASSERT_TRUE(new_browser); 1280 ASSERT_TRUE(new_browser != browser()); 1281 1282 // The browser's app_name should include the app's ID. 1283 ASSERT_NE( 1284 new_browser->app_name_.find(extension_app->id()), 1285 std::string::npos) << new_browser->app_name_; 1286 } 1287 #endif 1288 1289 // Tests that the CLD (Compact Language Detection) works properly. 1290 IN_PROC_BROWSER_TEST_F(BrowserTest, PageLanguageDetection) { 1291 ASSERT_TRUE(test_server()->Start()); 1292 1293 //std::string lang; 1294 LanguageDetectionDetails details; 1295 1296 // Open a new tab with a page in English. 1297 AddTabAtIndex(0, GURL(test_server()->GetURL("files/english_page.html")), 1298 content::PAGE_TRANSITION_TYPED); 1299 1300 WebContents* current_web_contents = 1301 browser()->tab_strip_model()->GetActiveWebContents(); 1302 TranslateTabHelper* translate_tab_helper = 1303 TranslateTabHelper::FromWebContents(current_web_contents); 1304 content::Source<WebContents> source(current_web_contents); 1305 1306 ui_test_utils::WindowedNotificationObserverWithDetails< 1307 LanguageDetectionDetails> 1308 en_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, 1309 source); 1310 EXPECT_EQ("", translate_tab_helper->language_state().original_language()); 1311 en_language_detected_signal.Wait(); 1312 EXPECT_TRUE(en_language_detected_signal.GetDetailsFor( 1313 source.map_key(), &details)); 1314 EXPECT_EQ("en", details.adopted_language); 1315 EXPECT_EQ("en", translate_tab_helper->language_state().original_language()); 1316 1317 // Now navigate to a page in French. 1318 ui_test_utils::WindowedNotificationObserverWithDetails< 1319 LanguageDetectionDetails> 1320 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, 1321 source); 1322 ui_test_utils::NavigateToURL( 1323 browser(), GURL(test_server()->GetURL("files/french_page.html"))); 1324 fr_language_detected_signal.Wait(); 1325 details.adopted_language.clear(); 1326 EXPECT_TRUE(fr_language_detected_signal.GetDetailsFor( 1327 source.map_key(), &details)); 1328 EXPECT_EQ("fr", details.adopted_language); 1329 EXPECT_EQ("fr", translate_tab_helper->language_state().original_language()); 1330 } 1331 1332 // Chromeos defaults to restoring the last session, so this test isn't 1333 // applicable. 1334 #if !defined(OS_CHROMEOS) 1335 #if defined(OS_MACOSX) 1336 // Crashy, http://crbug.com/38522 1337 #define RestorePinnedTabs DISABLED_RestorePinnedTabs 1338 #endif 1339 // Makes sure pinned tabs are restored correctly on start. 1340 IN_PROC_BROWSER_TEST_F(BrowserTest, RestorePinnedTabs) { 1341 ASSERT_TRUE(test_server()->Start()); 1342 1343 // Add an pinned app tab. 1344 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1345 GURL url(test_server()->GetURL("empty.html")); 1346 TabStripModel* model = browser()->tab_strip_model(); 1347 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); 1348 const Extension* extension_app = GetExtension(); 1349 ui_test_utils::NavigateToURL(browser(), url); 1350 WebContents* app_contents = WebContents::Create( 1351 WebContents::CreateParams(browser()->profile())); 1352 extensions::TabHelper::CreateForWebContents(app_contents); 1353 extensions::TabHelper* extensions_tab_helper = 1354 extensions::TabHelper::FromWebContents(app_contents); 1355 extensions_tab_helper->SetExtensionApp(extension_app); 1356 model->AddWebContents(app_contents, 0, content::PageTransitionFromInt(0), 1357 TabStripModel::ADD_NONE); 1358 model->SetTabPinned(0, true); 1359 ui_test_utils::NavigateToURL(browser(), url); 1360 1361 // Add a non pinned tab. 1362 chrome::NewTab(browser()); 1363 1364 // Add a pinned non-app tab. 1365 chrome::NewTab(browser()); 1366 ui_test_utils::NavigateToURL(browser(), GURL(content::kAboutBlankURL)); 1367 model->SetTabPinned(2, true); 1368 1369 // Write out the pinned tabs. 1370 PinnedTabCodec::WritePinnedTabs(browser()->profile()); 1371 1372 // Simulate launching again. 1373 CommandLine dummy(CommandLine::NO_PROGRAM); 1374 chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? 1375 chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; 1376 StartupBrowserCreatorImpl launch(base::FilePath(), dummy, first_run); 1377 launch.profile_ = browser()->profile(); 1378 launch.ProcessStartupURLs(std::vector<GURL>(), 1379 browser()->host_desktop_type()); 1380 1381 // The launch should have created a new browser. 1382 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 1383 browser()->host_desktop_type())); 1384 1385 // Find the new browser. 1386 Browser* new_browser = NULL; 1387 for (chrome::BrowserIterator it; !it.done() && !new_browser; it.Next()) { 1388 if (*it != browser()) 1389 new_browser = *it; 1390 } 1391 ASSERT_TRUE(new_browser); 1392 ASSERT_TRUE(new_browser != browser()); 1393 1394 // We should get back an additional tab for the app, and another for the 1395 // default home page. 1396 ASSERT_EQ(3, new_browser->tab_strip_model()->count()); 1397 1398 // Make sure the state matches. 1399 TabStripModel* new_model = new_browser->tab_strip_model(); 1400 EXPECT_TRUE(new_model->IsAppTab(0)); 1401 EXPECT_FALSE(new_model->IsAppTab(1)); 1402 EXPECT_FALSE(new_model->IsAppTab(2)); 1403 1404 EXPECT_TRUE(new_model->IsTabPinned(0)); 1405 EXPECT_TRUE(new_model->IsTabPinned(1)); 1406 EXPECT_FALSE(new_model->IsTabPinned(2)); 1407 1408 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), 1409 new_model->GetWebContentsAt(2)->GetURL()); 1410 1411 EXPECT_TRUE( 1412 extensions::TabHelper::FromWebContents( 1413 new_model->GetWebContentsAt(0))->extension_app() == extension_app); 1414 } 1415 #endif // !defined(OS_CHROMEOS) 1416 1417 // This test verifies we don't crash when closing the last window and the app 1418 // menu is showing. 1419 // TODO(linux_aura) http://crbug.com/163931 1420 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) 1421 #define MAYBE_CloseWithAppMenuOpen DISABLED_CloseWithAppMenuOpen 1422 #else 1423 #define MAYBE_CloseWithAppMenuOpen CloseWithAppMenuOpen 1424 #endif 1425 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_CloseWithAppMenuOpen) { 1426 if (browser_defaults::kBrowserAliveWithNoWindows) 1427 return; 1428 1429 // We need a message loop running for menus on windows. 1430 base::MessageLoop::current()->PostTask( 1431 FROM_HERE, base::Bind(&RunCloseWithAppMenuCallback, browser())); 1432 } 1433 1434 #if !defined(OS_MACOSX) 1435 IN_PROC_BROWSER_TEST_F(BrowserTest, OpenAppWindowLikeNtp) { 1436 ASSERT_TRUE(test_server()->Start()); 1437 1438 // Load an app 1439 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1440 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); 1441 const Extension* extension_app = GetExtension(); 1442 1443 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would. 1444 WebContents* app_window = OpenApplication( 1445 AppLaunchParams(browser()->profile(), extension_app, 1446 extensions::LAUNCH_CONTAINER_WINDOW, NEW_WINDOW)); 1447 ASSERT_TRUE(app_window); 1448 1449 // Apps launched in a window from the NTP have an extensions tab helper but 1450 // do not have extension_app set in it. 1451 ASSERT_TRUE(extensions::TabHelper::FromWebContents(app_window)); 1452 EXPECT_FALSE( 1453 extensions::TabHelper::FromWebContents(app_window)->extension_app()); 1454 EXPECT_EQ(extensions::AppLaunchInfo::GetFullLaunchURL(extension_app), 1455 app_window->GetURL()); 1456 1457 // The launch should have created a new browser. 1458 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 1459 browser()->host_desktop_type())); 1460 1461 // Find the new browser. 1462 Browser* new_browser = NULL; 1463 for (chrome::BrowserIterator it; !it.done() && !new_browser; it.Next()) { 1464 if (*it != browser()) 1465 new_browser = *it; 1466 } 1467 ASSERT_TRUE(new_browser); 1468 ASSERT_TRUE(new_browser != browser()); 1469 1470 EXPECT_TRUE(new_browser->is_app()); 1471 1472 // The browser's app name should include the extension's id. 1473 std::string app_name = new_browser->app_name_; 1474 EXPECT_NE(app_name.find(extension_app->id()), std::string::npos) 1475 << "Name " << app_name << " should contain id "<< extension_app->id(); 1476 } 1477 #endif // !defined(OS_MACOSX) 1478 1479 // Makes sure the browser doesn't crash when 1480 // set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked. 1481 IN_PROC_BROWSER_TEST_F(BrowserTest, StartMaximized) { 1482 Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP }; 1483 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(types); ++i) { 1484 Browser::CreateParams params(types[i], browser()->profile(), 1485 browser()->host_desktop_type()); 1486 params.initial_show_state = ui::SHOW_STATE_MAXIMIZED; 1487 AddBlankTabAndShow(new Browser(params)); 1488 } 1489 } 1490 1491 // Aura doesn't support minimized window. crbug.com/104571. 1492 #if defined(USE_AURA) 1493 #define MAYBE_StartMinimized DISABLED_StartMinimized 1494 #else 1495 #define MAYBE_StartMinimized StartMinimized 1496 #endif 1497 // Makes sure the browser doesn't crash when 1498 // set_show_state(ui::SHOW_STATE_MINIMIZED) has been invoked. 1499 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_StartMinimized) { 1500 Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP }; 1501 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(types); ++i) { 1502 Browser::CreateParams params(types[i], browser()->profile(), 1503 browser()->host_desktop_type()); 1504 params.initial_show_state = ui::SHOW_STATE_MINIMIZED; 1505 AddBlankTabAndShow(new Browser(params)); 1506 } 1507 } 1508 1509 // Makes sure the forward button is disabled immediately when navigating 1510 // forward to a slow-to-commit page. 1511 IN_PROC_BROWSER_TEST_F(BrowserTest, ForwardDisabledOnForward) { 1512 GURL blank_url(content::kAboutBlankURL); 1513 ui_test_utils::NavigateToURL(browser(), blank_url); 1514 1515 ui_test_utils::NavigateToURL( 1516 browser(), ui_test_utils::GetTestUrl( 1517 base::FilePath(base::FilePath::kCurrentDirectory), 1518 base::FilePath(kTitle1File))); 1519 1520 content::WindowedNotificationObserver back_nav_load_observer( 1521 content::NOTIFICATION_LOAD_STOP, 1522 content::Source<NavigationController>( 1523 &browser()->tab_strip_model()->GetActiveWebContents()-> 1524 GetController())); 1525 chrome::GoBack(browser(), CURRENT_TAB); 1526 back_nav_load_observer.Wait(); 1527 CommandUpdater* command_updater = 1528 browser()->command_controller()->command_updater(); 1529 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_FORWARD)); 1530 1531 content::WindowedNotificationObserver forward_nav_load_observer( 1532 content::NOTIFICATION_LOAD_STOP, 1533 content::Source<NavigationController>( 1534 &browser()->tab_strip_model()->GetActiveWebContents()-> 1535 GetController())); 1536 chrome::GoForward(browser(), CURRENT_TAB); 1537 // This check will happen before the navigation completes, since the browser 1538 // won't process the renderer's response until the Wait() call below. 1539 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_FORWARD)); 1540 forward_nav_load_observer.Wait(); 1541 } 1542 1543 // Makes sure certain commands are disabled when Incognito mode is forced. 1544 IN_PROC_BROWSER_TEST_F(BrowserTest, DisableMenuItemsWhenIncognitoIsForced) { 1545 CommandUpdater* command_updater = 1546 browser()->command_controller()->command_updater(); 1547 // At the beginning, all commands are enabled. 1548 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1549 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1550 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1551 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1552 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1553 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1554 1555 // Set Incognito to FORCED. 1556 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(), 1557 IncognitoModePrefs::FORCED); 1558 // Bookmarks & Settings commands should get disabled. 1559 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1560 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1561 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1562 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1563 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1564 // New Incognito Window command, however, should be enabled. 1565 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1566 1567 // Create a new browser. 1568 Browser* new_browser = 1569 new Browser(Browser::CreateParams( 1570 browser()->profile()->GetOffTheRecordProfile(), 1571 browser()->host_desktop_type())); 1572 CommandUpdater* new_command_updater = 1573 new_browser->command_controller()->command_updater(); 1574 // It should have Bookmarks & Settings commands disabled by default. 1575 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1576 EXPECT_FALSE(new_command_updater->IsCommandEnabled( 1577 IDC_SHOW_BOOKMARK_MANAGER)); 1578 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1579 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1580 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_OPTIONS)); 1581 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1582 } 1583 1584 // Makes sure New Incognito Window command is disabled when Incognito mode is 1585 // not available. 1586 IN_PROC_BROWSER_TEST_F(BrowserTest, 1587 NoNewIncognitoWindowWhenIncognitoIsDisabled) { 1588 CommandUpdater* command_updater = 1589 browser()->command_controller()->command_updater(); 1590 // Set Incognito to DISABLED. 1591 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(), 1592 IncognitoModePrefs::DISABLED); 1593 // Make sure New Incognito Window command is disabled. All remaining commands 1594 // should be enabled. 1595 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1596 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1597 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1598 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1599 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1600 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1601 1602 // Create a new browser. 1603 Browser* new_browser = 1604 new Browser(Browser::CreateParams(browser()->profile(), 1605 browser()->host_desktop_type())); 1606 CommandUpdater* new_command_updater = 1607 new_browser->command_controller()->command_updater(); 1608 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1609 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1610 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1611 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1612 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1613 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_OPTIONS)); 1614 } 1615 1616 // Makes sure Extensions and Settings commands are disabled in certain 1617 // circumstances even though normally they should stay enabled. 1618 IN_PROC_BROWSER_TEST_F(BrowserTest, 1619 DisableExtensionsAndSettingsWhenIncognitoIsDisabled) { 1620 CommandUpdater* command_updater = 1621 browser()->command_controller()->command_updater(); 1622 // Disable extensions. This should disable Extensions menu. 1623 extensions::ExtensionSystem::Get(browser()->profile())->extension_service()-> 1624 set_extensions_enabled(false); 1625 // Set Incognito to DISABLED. 1626 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(), 1627 IncognitoModePrefs::DISABLED); 1628 // Make sure Manage Extensions command is disabled. 1629 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1630 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1631 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1632 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1633 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1634 1635 // Create a popup (non-main-UI-type) browser. Settings command as well 1636 // as Extensions should be disabled. 1637 Browser* popup_browser = new Browser( 1638 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), 1639 browser()->host_desktop_type())); 1640 CommandUpdater* popup_command_updater = 1641 popup_browser->command_controller()->command_updater(); 1642 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1643 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_OPTIONS)); 1644 EXPECT_TRUE(popup_command_updater->IsCommandEnabled( 1645 IDC_SHOW_BOOKMARK_MANAGER)); 1646 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1647 } 1648 1649 // Makes sure Extensions and Settings commands are disabled in certain 1650 // circumstances even though normally they should stay enabled. 1651 IN_PROC_BROWSER_TEST_F(BrowserTest, 1652 DisableOptionsAndImportMenuItemsConsistently) { 1653 // Create a popup browser. 1654 Browser* popup_browser = new Browser( 1655 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), 1656 browser()->host_desktop_type())); 1657 CommandUpdater* command_updater = 1658 popup_browser->command_controller()->command_updater(); 1659 // OPTIONS and IMPORT_SETTINGS are disabled for a non-normal UI. 1660 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1661 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1662 1663 // Set Incognito to FORCED. 1664 IncognitoModePrefs::SetAvailability(popup_browser->profile()->GetPrefs(), 1665 IncognitoModePrefs::FORCED); 1666 // OPTIONS and IMPORT_SETTINGS are disabled when Incognito is forced. 1667 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1668 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1669 // Set Incognito to AVAILABLE. 1670 IncognitoModePrefs::SetAvailability(popup_browser->profile()->GetPrefs(), 1671 IncognitoModePrefs::ENABLED); 1672 // OPTIONS and IMPORT_SETTINGS are still disabled since it is a non-normal UI. 1673 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1674 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1675 } 1676 1677 namespace { 1678 1679 void OnZoomLevelChanged(const base::Closure& callback, 1680 const HostZoomMap::ZoomLevelChange& host) { 1681 callback.Run(); 1682 } 1683 1684 } // namespace 1685 1686 #if defined(OS_WIN) 1687 // Flakes regularly on Windows XP 1688 // http://crbug.com/146040 1689 #define MAYBE_PageZoom DISABLED_PageZoom 1690 #else 1691 #define MAYBE_PageZoom PageZoom 1692 #endif 1693 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_PageZoom) { 1694 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 1695 bool enable_plus, enable_minus; 1696 1697 { 1698 scoped_refptr<content::MessageLoopRunner> loop_runner( 1699 new content::MessageLoopRunner); 1700 content::HostZoomMap::ZoomLevelChangedCallback callback( 1701 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure())); 1702 scoped_ptr<content::HostZoomMap::Subscription> sub = 1703 content::HostZoomMap::GetForBrowserContext( 1704 browser()->profile())->AddZoomLevelChangedCallback(callback); 1705 chrome::Zoom(browser(), content::PAGE_ZOOM_IN); 1706 loop_runner->Run(); 1707 sub.reset(); 1708 EXPECT_EQ(contents->GetZoomPercent(&enable_plus, &enable_minus), 110); 1709 EXPECT_TRUE(enable_plus); 1710 EXPECT_TRUE(enable_minus); 1711 } 1712 1713 { 1714 scoped_refptr<content::MessageLoopRunner> loop_runner( 1715 new content::MessageLoopRunner); 1716 content::HostZoomMap::ZoomLevelChangedCallback callback( 1717 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure())); 1718 scoped_ptr<content::HostZoomMap::Subscription> sub = 1719 content::HostZoomMap::GetForBrowserContext( 1720 browser()->profile())->AddZoomLevelChangedCallback(callback); 1721 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET); 1722 loop_runner->Run(); 1723 sub.reset(); 1724 EXPECT_EQ(contents->GetZoomPercent(&enable_plus, &enable_minus), 100); 1725 EXPECT_TRUE(enable_plus); 1726 EXPECT_TRUE(enable_minus); 1727 } 1728 1729 { 1730 scoped_refptr<content::MessageLoopRunner> loop_runner( 1731 new content::MessageLoopRunner); 1732 content::HostZoomMap::ZoomLevelChangedCallback callback( 1733 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure())); 1734 scoped_ptr<content::HostZoomMap::Subscription> sub = 1735 content::HostZoomMap::GetForBrowserContext( 1736 browser()->profile())->AddZoomLevelChangedCallback(callback); 1737 chrome::Zoom(browser(), content::PAGE_ZOOM_OUT); 1738 loop_runner->Run(); 1739 sub.reset(); 1740 EXPECT_EQ(contents->GetZoomPercent(&enable_plus, &enable_minus), 90); 1741 EXPECT_TRUE(enable_plus); 1742 EXPECT_TRUE(enable_minus); 1743 } 1744 1745 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET); 1746 } 1747 1748 IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCommandDisable) { 1749 ASSERT_TRUE(test_server()->Start()); 1750 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1751 GURL url(test_server()->GetURL("empty.html")); 1752 ui_test_utils::NavigateToURL(browser(), url); 1753 1754 CommandUpdater* command_updater = 1755 browser()->command_controller()->command_updater(); 1756 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE)); 1757 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_PRINT)); 1758 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE)); 1759 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU)); 1760 1761 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 1762 1763 TestInterstitialPage* interstitial = NULL; 1764 { 1765 scoped_refptr<content::MessageLoopRunner> loop_runner( 1766 new content::MessageLoopRunner); 1767 1768 InterstitialObserver observer(contents, 1769 loop_runner->QuitClosure(), 1770 base::Closure()); 1771 interstitial = new TestInterstitialPage(contents, false, GURL()); 1772 loop_runner->Run(); 1773 } 1774 1775 EXPECT_TRUE(contents->ShowingInterstitialPage()); 1776 1777 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE)); 1778 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_PRINT)); 1779 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE)); 1780 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU)); 1781 1782 { 1783 scoped_refptr<content::MessageLoopRunner> loop_runner( 1784 new content::MessageLoopRunner); 1785 1786 InterstitialObserver observer(contents, 1787 base::Closure(), 1788 loop_runner->QuitClosure()); 1789 interstitial->Proceed(); 1790 loop_runner->Run(); 1791 // interstitial is deleted now. 1792 } 1793 1794 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE)); 1795 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_PRINT)); 1796 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE)); 1797 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU)); 1798 } 1799 1800 // Ensure that creating an interstitial page closes any JavaScript dialogs 1801 // that were present on the previous page. See http://crbug.com/295695. 1802 IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialClosesDialogs) { 1803 ASSERT_TRUE(test_server()->Start()); 1804 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1805 GURL url(test_server()->GetURL("empty.html")); 1806 ui_test_utils::NavigateToURL(browser(), url); 1807 1808 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 1809 contents->GetRenderViewHost()->ExecuteJavascriptInWebFrame( 1810 base::string16(), 1811 ASCIIToUTF16("alert('Dialog showing!');")); 1812 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 1813 EXPECT_TRUE(alert->IsValid()); 1814 AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance(); 1815 EXPECT_TRUE(dialog_queue->HasActiveDialog()); 1816 1817 TestInterstitialPage* interstitial = NULL; 1818 { 1819 scoped_refptr<content::MessageLoopRunner> loop_runner( 1820 new content::MessageLoopRunner); 1821 1822 InterstitialObserver observer(contents, 1823 loop_runner->QuitClosure(), 1824 base::Closure()); 1825 interstitial = new TestInterstitialPage(contents, false, GURL()); 1826 loop_runner->Run(); 1827 } 1828 1829 // The interstitial should have closed the dialog. 1830 EXPECT_TRUE(contents->ShowingInterstitialPage()); 1831 EXPECT_FALSE(dialog_queue->HasActiveDialog()); 1832 1833 { 1834 scoped_refptr<content::MessageLoopRunner> loop_runner( 1835 new content::MessageLoopRunner); 1836 1837 InterstitialObserver observer(contents, 1838 base::Closure(), 1839 loop_runner->QuitClosure()); 1840 interstitial->DontProceed(); 1841 loop_runner->Run(); 1842 // interstitial is deleted now. 1843 } 1844 1845 // Make sure input events still work in the renderer process. 1846 EXPECT_FALSE(contents->GetRenderProcessHost()->IgnoreInputEvents()); 1847 } 1848 1849 1850 IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCloseTab) { 1851 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 1852 1853 { 1854 scoped_refptr<content::MessageLoopRunner> loop_runner( 1855 new content::MessageLoopRunner); 1856 1857 InterstitialObserver observer(contents, 1858 loop_runner->QuitClosure(), 1859 base::Closure()); 1860 // Interstitial will delete itself when we close the tab. 1861 new TestInterstitialPage(contents, false, GURL()); 1862 loop_runner->Run(); 1863 } 1864 1865 EXPECT_TRUE(contents->ShowingInterstitialPage()); 1866 1867 { 1868 scoped_refptr<content::MessageLoopRunner> loop_runner( 1869 new content::MessageLoopRunner); 1870 1871 InterstitialObserver observer(contents, 1872 base::Closure(), 1873 loop_runner->QuitClosure()); 1874 chrome::CloseTab(browser()); 1875 loop_runner->Run(); 1876 // interstitial is deleted now. 1877 } 1878 } 1879 1880 class MockWebContentsObserver : public WebContentsObserver { 1881 public: 1882 explicit MockWebContentsObserver(WebContents* web_contents) 1883 : WebContentsObserver(web_contents), 1884 got_user_gesture_(false) { 1885 } 1886 1887 virtual void DidGetUserGesture() OVERRIDE { 1888 got_user_gesture_ = true; 1889 } 1890 1891 bool got_user_gesture() const { 1892 return got_user_gesture_; 1893 } 1894 1895 void set_got_user_gesture(bool got_it) { 1896 got_user_gesture_ = got_it; 1897 } 1898 1899 private: 1900 bool got_user_gesture_; 1901 1902 DISALLOW_COPY_AND_ASSIGN(MockWebContentsObserver); 1903 }; 1904 1905 IN_PROC_BROWSER_TEST_F(BrowserTest, UserGesturesReported) { 1906 // Regression test for http://crbug.com/110707. Also tests that a user 1907 // gesture is sent when a normal navigation (via e.g. the omnibox) is 1908 // performed. 1909 WebContents* web_contents = 1910 browser()->tab_strip_model()->GetActiveWebContents(); 1911 MockWebContentsObserver mock_observer(web_contents); 1912 1913 ASSERT_TRUE(test_server()->Start()); 1914 GURL url(test_server()->GetURL("empty.html")); 1915 1916 ui_test_utils::NavigateToURL(browser(), url); 1917 EXPECT_TRUE(mock_observer.got_user_gesture()); 1918 1919 mock_observer.set_got_user_gesture(false); 1920 chrome::Reload(browser(), CURRENT_TAB); 1921 EXPECT_TRUE(mock_observer.got_user_gesture()); 1922 } 1923 1924 // TODO(ben): this test was never enabled. It has bit-rotted since being added. 1925 // It originally lived in browser_unittest.cc, but has been moved here to make 1926 // room for real browser unit tests. 1927 #if 0 1928 class BrowserTest2 : public InProcessBrowserTest { 1929 public: 1930 BrowserTest2() { 1931 host_resolver_proc_ = new net::RuleBasedHostResolverProc(NULL); 1932 // Avoid making external DNS lookups. In this test we don't need this 1933 // to succeed. 1934 host_resolver_proc_->AddSimulatedFailure("*.google.com"); 1935 scoped_host_resolver_proc_.Init(host_resolver_proc_.get()); 1936 } 1937 1938 private: 1939 scoped_refptr<net::RuleBasedHostResolverProc> host_resolver_proc_; 1940 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc_; 1941 }; 1942 1943 IN_PROC_BROWSER_TEST_F(BrowserTest2, NoTabsInPopups) { 1944 chrome::RegisterAppPrefs(L"Test"); 1945 1946 // We start with a normal browser with one tab. 1947 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 1948 1949 // Open a popup browser with a single blank foreground tab. 1950 Browser* popup_browser = new Browser( 1951 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); 1952 chrome::AddTabAt(popup_browser, GURL(), -1, true); 1953 EXPECT_EQ(1, popup_browser->tab_strip_model()->count()); 1954 1955 // Now try opening another tab in the popup browser. 1956 AddTabWithURLParams params1(url, content::PAGE_TRANSITION_TYPED); 1957 popup_browser->AddTabWithURL(¶ms1); 1958 EXPECT_EQ(popup_browser, params1.target); 1959 1960 // The popup should still only have one tab. 1961 EXPECT_EQ(1, popup_browser->tab_strip_model()->count()); 1962 1963 // The normal browser should now have two. 1964 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 1965 1966 // Open an app frame browser with a single blank foreground tab. 1967 Browser* app_browser = new Browser(Browser::CreateParams::CreateForApp( 1968 L"Test", browser()->profile(), false)); 1969 chrome::AddTabAt(app_browser, GURL(), -1, true); 1970 EXPECT_EQ(1, app_browser->tab_strip_model()->count()); 1971 1972 // Now try opening another tab in the app browser. 1973 AddTabWithURLParams params2(GURL(content::kAboutBlankURL), 1974 content::PAGE_TRANSITION_TYPED); 1975 app_browser->AddTabWithURL(¶ms2); 1976 EXPECT_EQ(app_browser, params2.target); 1977 1978 // The popup should still only have one tab. 1979 EXPECT_EQ(1, app_browser->tab_strip_model()->count()); 1980 1981 // The normal browser should now have three. 1982 EXPECT_EQ(3, browser()->tab_strip_model()->count()); 1983 1984 // Open an app frame popup browser with a single blank foreground tab. 1985 Browser* app_popup_browser = new Browser(Browser::CreateParams::CreateForApp( 1986 L"Test", browser()->profile(), false)); 1987 chrome::AddTabAt(app_popup_browser, GURL(), -1, true); 1988 EXPECT_EQ(1, app_popup_browser->tab_strip_model()->count()); 1989 1990 // Now try opening another tab in the app popup browser. 1991 AddTabWithURLParams params3(GURL(content::kAboutBlankURL), 1992 content::PAGE_TRANSITION_TYPED); 1993 app_popup_browser->AddTabWithURL(¶ms3); 1994 EXPECT_EQ(app_popup_browser, params3.target); 1995 1996 // The popup should still only have one tab. 1997 EXPECT_EQ(1, app_popup_browser->tab_strip_model()->count()); 1998 1999 // The normal browser should now have four. 2000 EXPECT_EQ(4, browser()->tab_strip_model()->count()); 2001 2002 // Close the additional browsers. 2003 popup_browser->tab_strip_model()->CloseAllTabs(); 2004 app_browser->tab_strip_model()->CloseAllTabs(); 2005 app_popup_browser->tab_strip_model()->CloseAllTabs(); 2006 } 2007 #endif 2008 2009 IN_PROC_BROWSER_TEST_F(BrowserTest, WindowOpenClose) { 2010 CommandLine::ForCurrentProcess()->AppendSwitch( 2011 switches::kDisablePopupBlocking); 2012 GURL url = ui_test_utils::GetTestUrl( 2013 base::FilePath(), base::FilePath().AppendASCII("window.close.html")); 2014 2015 base::string16 title = ASCIIToUTF16("Title Of Awesomeness"); 2016 content::TitleWatcher title_watcher( 2017 browser()->tab_strip_model()->GetActiveWebContents(), title); 2018 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 2); 2019 EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); 2020 } 2021 2022 // GTK doesn't use the Browser's fullscreen state. 2023 // TODO(linux_aura) http://crbug.com/163931 2024 // Mac disabled: http://crbug.com/169820 2025 #if !defined(TOOLKIT_GTK) && !defined(OS_MACOSX) && \ 2026 !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)) 2027 IN_PROC_BROWSER_TEST_F(BrowserTest, FullscreenBookmarkBar) { 2028 #if defined(OS_WIN) && defined(USE_ASH) 2029 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 2030 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 2031 return; 2032 #endif 2033 2034 chrome::ToggleBookmarkBar(browser()); 2035 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state()); 2036 chrome::ToggleFullscreenMode(browser()); 2037 EXPECT_TRUE(browser()->window()->IsFullscreen()); 2038 #if defined(OS_MACOSX) 2039 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state()); 2040 #elif defined(OS_CHROMEOS) 2041 // TODO(jamescook): If immersive fullscreen is disabled by default, test 2042 // for BookmarkBar::HIDDEN. 2043 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state()); 2044 #else 2045 EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state()); 2046 #endif 2047 } 2048 #endif 2049 2050 class ShowModalDialogTest : public BrowserTest { 2051 public: 2052 ShowModalDialogTest() {} 2053 2054 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2055 command_line->AppendSwitch(switches::kDisablePopupBlocking); 2056 } 2057 }; 2058 2059 IN_PROC_BROWSER_TEST_F(ShowModalDialogTest, BasicTest) { 2060 // This navigation should show a modal dialog that will be immediately 2061 // closed, but the fact that it was shown should be recorded. 2062 GURL url = ui_test_utils::GetTestUrl( 2063 base::FilePath(), base::FilePath().AppendASCII("showmodaldialog.html")); 2064 2065 base::string16 expected_title(ASCIIToUTF16("SUCCESS")); 2066 content::TitleWatcher title_watcher( 2067 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 2068 ui_test_utils::NavigateToURL(browser(), url); 2069 2070 // Verify that we set a mark on successful dialog show. 2071 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 2072 } 2073 2074 IN_PROC_BROWSER_TEST_F(BrowserTest, DisallowFileUrlUniversalAccessTest) { 2075 GURL url = ui_test_utils::GetTestUrl( 2076 base::FilePath(), 2077 base::FilePath().AppendASCII("fileurl_universalaccess.html")); 2078 2079 base::string16 expected_title(ASCIIToUTF16("Disallowed")); 2080 content::TitleWatcher title_watcher( 2081 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 2082 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("Allowed")); 2083 ui_test_utils::NavigateToURL(browser(), url); 2084 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 2085 } 2086 2087 class KioskModeTest : public BrowserTest { 2088 public: 2089 KioskModeTest() {} 2090 2091 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2092 command_line->AppendSwitch(switches::kKioskMode); 2093 } 2094 }; 2095 2096 #if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)) 2097 // http://crbug.com/103912 2098 // TODO(linux_aura) http://crbug.com/163931 2099 #define MAYBE_EnableKioskModeTest DISABLED_EnableKioskModeTest 2100 #else 2101 #define MAYBE_EnableKioskModeTest EnableKioskModeTest 2102 #endif 2103 IN_PROC_BROWSER_TEST_F(KioskModeTest, MAYBE_EnableKioskModeTest) { 2104 // Check if browser is in fullscreen mode. 2105 ASSERT_TRUE(browser()->window()->IsFullscreen()); 2106 ASSERT_FALSE(browser()->window()->IsFullscreenBubbleVisible()); 2107 } 2108 2109 #if defined(OS_WIN) 2110 // This test verifies that Chrome can be launched with a user-data-dir path 2111 // which contains non ASCII characters. 2112 class LaunchBrowserWithNonAsciiUserDatadir : public BrowserTest { 2113 public: 2114 LaunchBrowserWithNonAsciiUserDatadir() {} 2115 2116 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2117 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 2118 base::FilePath tmp_profile = temp_dir_.path().AppendASCII("tmp_profile"); 2119 tmp_profile = tmp_profile.Append(L"Test Chrome G\u00E9raldine"); 2120 2121 ASSERT_TRUE(base::CreateDirectory(tmp_profile)); 2122 command_line->AppendSwitchPath(switches::kUserDataDir, tmp_profile); 2123 } 2124 2125 base::ScopedTempDir temp_dir_; 2126 }; 2127 2128 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithNonAsciiUserDatadir, 2129 TestNonAsciiUserDataDir) { 2130 // Verify that the window is present. 2131 ASSERT_TRUE(browser()); 2132 } 2133 #endif // defined(OS_WIN) 2134 2135 // Tests to ensure that the browser continues running in the background after 2136 // the last window closes. 2137 class RunInBackgroundTest : public BrowserTest { 2138 public: 2139 RunInBackgroundTest() {} 2140 2141 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2142 command_line->AppendSwitch(switches::kKeepAliveForTest); 2143 } 2144 }; 2145 2146 IN_PROC_BROWSER_TEST_F(RunInBackgroundTest, RunInBackgroundBasicTest) { 2147 // Close the browser window, then open a new one - the browser should keep 2148 // running. 2149 Profile* profile = browser()->profile(); 2150 EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); 2151 content::WindowedNotificationObserver observer( 2152 chrome::NOTIFICATION_BROWSER_CLOSED, 2153 content::Source<Browser>(browser())); 2154 chrome::CloseWindow(browser()); 2155 observer.Wait(); 2156 EXPECT_EQ(0u, chrome::GetTotalBrowserCount()); 2157 2158 ui_test_utils::BrowserAddedObserver browser_added_observer; 2159 chrome::NewEmptyWindow(profile, chrome::GetActiveDesktop()); 2160 browser_added_observer.WaitForSingleNewBrowser(); 2161 2162 EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); 2163 } 2164 2165 // Tests to ensure that the browser continues running in the background after 2166 // the last window closes. 2167 class NoStartupWindowTest : public BrowserTest { 2168 public: 2169 NoStartupWindowTest() {} 2170 2171 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2172 command_line->AppendSwitch(switches::kNoStartupWindow); 2173 command_line->AppendSwitch(switches::kKeepAliveForTest); 2174 } 2175 }; 2176 2177 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest, NoStartupWindowBasicTest) { 2178 #if defined(OS_WIN) && defined(USE_ASH) 2179 // kNoStartupWindow doesn't make sense in Metro+Ash. 2180 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 2181 return; 2182 #endif 2183 2184 // No browser window should be started by default. 2185 EXPECT_EQ(0u, chrome::GetTotalBrowserCount()); 2186 2187 // Starting a browser window should work just fine. 2188 ui_test_utils::BrowserAddedObserver browser_added_observer; 2189 CreateBrowser(ProfileManager::GetDefaultProfile()); 2190 browser_added_observer.WaitForSingleNewBrowser(); 2191 2192 EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); 2193 } 2194 2195 // Chromeos needs to track app windows because it considers them to be part of 2196 // session state. 2197 #if !defined(OS_CHROMEOS) 2198 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest, DontInitSessionServiceForApps) { 2199 #if defined(OS_WIN) && defined(USE_ASH) 2200 // kNoStartupWindow doesn't make sense in Metro+Ash. 2201 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 2202 return; 2203 #endif 2204 2205 Profile* profile = ProfileManager::GetDefaultProfile(); 2206 2207 SessionService* session_service = 2208 SessionServiceFactory::GetForProfile(profile); 2209 ASSERT_FALSE(session_service->processed_any_commands()); 2210 2211 ui_test_utils::BrowserAddedObserver browser_added_observer; 2212 CreateBrowserForApp("blah", profile); 2213 browser_added_observer.WaitForSingleNewBrowser(); 2214 2215 ASSERT_FALSE(session_service->processed_any_commands()); 2216 } 2217 #endif // !defined(OS_CHROMEOS) 2218 2219 // This test needs to be placed outside the anonymous namespace because we 2220 // need to access private type of Browser. 2221 class AppModeTest : public BrowserTest { 2222 public: 2223 AppModeTest() {} 2224 2225 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 2226 GURL url = ui_test_utils::GetTestUrl( 2227 base::FilePath(), base::FilePath().AppendASCII("title1.html")); 2228 command_line->AppendSwitchASCII(switches::kApp, url.spec()); 2229 } 2230 }; 2231 2232 IN_PROC_BROWSER_TEST_F(AppModeTest, EnableAppModeTest) { 2233 #if defined(OS_WIN) && defined(USE_ASH) 2234 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 2235 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 2236 return; 2237 #endif 2238 2239 // Test that an application browser window loads correctly. 2240 2241 // Verify the browser is in application mode. 2242 EXPECT_TRUE(browser()->is_app()); 2243 } 2244 2245 // Confirm about:version contains some expected content. 2246 IN_PROC_BROWSER_TEST_F(BrowserTest, AboutVersion) { 2247 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutVersionURL)); 2248 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 2249 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("WebKit"), true, true, 2250 NULL, NULL), 2251 0); 2252 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("OS"), true, true, 2253 NULL, NULL), 2254 0); 2255 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("JavaScript"), true, 2256 true, NULL, NULL), 2257 0); 2258 } 2259 2260 static const base::FilePath::CharType* kTestDir = 2261 FILE_PATH_LITERAL("click_modifier"); 2262 static const char kFirstPageTitle[] = "First window"; 2263 static const char kSecondPageTitle[] = "New window!"; 2264 2265 class ClickModifierTest : public InProcessBrowserTest { 2266 public: 2267 ClickModifierTest() { 2268 } 2269 2270 // Returns a url that opens a new window or tab when clicked, via javascript. 2271 GURL GetWindowOpenURL() { 2272 return ui_test_utils::GetTestUrl( 2273 base::FilePath(kTestDir), 2274 base::FilePath(FILE_PATH_LITERAL("window_open.html"))); 2275 } 2276 2277 // Returns a url that follows a simple link when clicked, unless affected by 2278 // modifiers. 2279 GURL GetHrefURL() { 2280 return ui_test_utils::GetTestUrl( 2281 base::FilePath(kTestDir), 2282 base::FilePath(FILE_PATH_LITERAL("href.html"))); 2283 } 2284 2285 base::string16 getFirstPageTitle() { 2286 return ASCIIToUTF16(kFirstPageTitle); 2287 } 2288 2289 base::string16 getSecondPageTitle() { 2290 return ASCIIToUTF16(kSecondPageTitle); 2291 } 2292 2293 // Loads our test page and simulates a single click using the supplied button 2294 // and modifiers. The click will cause either a navigation or the creation of 2295 // a new window or foreground or background tab. We verify that the expected 2296 // disposition occurs. 2297 void RunTest(Browser* browser, 2298 const GURL& url, 2299 int modifiers, 2300 blink::WebMouseEvent::Button button, 2301 WindowOpenDisposition disposition) { 2302 ui_test_utils::NavigateToURL(browser, url); 2303 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(), 2304 browser->host_desktop_type())); 2305 EXPECT_EQ(1, browser->tab_strip_model()->count()); 2306 content::WebContents* web_contents = 2307 browser->tab_strip_model()->GetActiveWebContents(); 2308 EXPECT_EQ(url, web_contents->GetURL()); 2309 2310 if (disposition == CURRENT_TAB) { 2311 content::WebContents* web_contents = 2312 browser->tab_strip_model()->GetActiveWebContents(); 2313 content::TestNavigationObserver same_tab_observer(web_contents); 2314 SimulateMouseClick(web_contents, modifiers, button); 2315 same_tab_observer.Wait(); 2316 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(), 2317 browser->host_desktop_type())); 2318 EXPECT_EQ(1, browser->tab_strip_model()->count()); 2319 EXPECT_EQ(getSecondPageTitle(), web_contents->GetTitle()); 2320 return; 2321 } 2322 2323 content::WindowedNotificationObserver observer( 2324 chrome::NOTIFICATION_TAB_ADDED, 2325 content::NotificationService::AllSources()); 2326 SimulateMouseClick(web_contents, modifiers, button); 2327 observer.Wait(); 2328 2329 if (disposition == NEW_WINDOW) { 2330 EXPECT_EQ(2u, chrome::GetBrowserCount(browser->profile(), 2331 browser->host_desktop_type())); 2332 return; 2333 } 2334 2335 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(), 2336 browser->host_desktop_type())); 2337 EXPECT_EQ(2, browser->tab_strip_model()->count()); 2338 web_contents = browser->tab_strip_model()->GetActiveWebContents(); 2339 WaitForLoadStop(web_contents); 2340 if (disposition == NEW_FOREGROUND_TAB) { 2341 EXPECT_EQ(getSecondPageTitle(), web_contents->GetTitle()); 2342 } else { 2343 ASSERT_EQ(NEW_BACKGROUND_TAB, disposition); 2344 EXPECT_EQ(getFirstPageTitle(), web_contents->GetTitle()); 2345 } 2346 } 2347 2348 private: 2349 DISALLOW_COPY_AND_ASSIGN(ClickModifierTest); 2350 }; 2351 2352 // Tests for clicking on elements with handlers that run window.open. 2353 2354 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenBasicClickTest) { 2355 int modifiers = 0; 2356 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft; 2357 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2358 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2359 } 2360 2361 // TODO(ericu): Alt-click behavior on window.open is platform-dependent and not 2362 // well defined. Should we add tests so we know if it changes? 2363 2364 // Shift-clicks open in a new window. 2365 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenShiftClickTest) { 2366 int modifiers = blink::WebInputEvent::ShiftKey; 2367 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft; 2368 WindowOpenDisposition disposition = NEW_WINDOW; 2369 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2370 } 2371 2372 // Control-clicks open in a background tab. 2373 // On OSX meta [the command key] takes the place of control. 2374 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenControlClickTest) { 2375 #if defined(OS_MACOSX) 2376 int modifiers = blink::WebInputEvent::MetaKey; 2377 #else 2378 int modifiers = blink::WebInputEvent::ControlKey; 2379 #endif 2380 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft; 2381 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; 2382 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2383 } 2384 2385 // Control-shift-clicks open in a foreground tab. 2386 // On OSX meta [the command key] takes the place of control. 2387 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenControlShiftClickTest) { 2388 #if defined(OS_MACOSX) 2389 int modifiers = blink::WebInputEvent::MetaKey; 2390 #else 2391 int modifiers = blink::WebInputEvent::ControlKey; 2392 #endif 2393 modifiers |= blink::WebInputEvent::ShiftKey; 2394 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft; 2395 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2396 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2397 } 2398 2399 // Middle-clicks open in a background tab. 2400 // TODO(linux_aura) http://crbug.com/163931 2401 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) 2402 #define MAYBE_WindowOpenMiddleClickTest DISABLED_WindowOpenMiddleClickTest 2403 #else 2404 #define MAYBE_WindowOpenMiddleClickTest WindowOpenMiddleClickTest 2405 #endif 2406 IN_PROC_BROWSER_TEST_F(ClickModifierTest, MAYBE_WindowOpenMiddleClickTest) { 2407 int modifiers = 0; 2408 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonMiddle; 2409 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; 2410 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2411 } 2412 2413 // Shift-middle-clicks open in a foreground tab. 2414 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenShiftMiddleClickTest) { 2415 int modifiers = blink::WebInputEvent::ShiftKey; 2416 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonMiddle; 2417 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2418 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2419 } 2420 2421 // Tests for clicking on normal links. 2422 2423 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefBasicClickTest) { 2424 int modifiers = 0; 2425 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft; 2426 WindowOpenDisposition disposition = CURRENT_TAB; 2427 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2428 } 2429 2430 // TODO(ericu): Alt-click behavior on links is platform-dependent and not well 2431 // defined. Should we add tests so we know if it changes? 2432 2433 // Shift-clicks open in a new window. 2434 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefShiftClickTest) { 2435 int modifiers = blink::WebInputEvent::ShiftKey; 2436 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft; 2437 WindowOpenDisposition disposition = NEW_WINDOW; 2438 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2439 } 2440 2441 // Control-clicks open in a background tab. 2442 // On OSX meta [the command key] takes the place of control. 2443 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefControlClickTest) { 2444 #if defined(OS_MACOSX) 2445 int modifiers = blink::WebInputEvent::MetaKey; 2446 #else 2447 int modifiers = blink::WebInputEvent::ControlKey; 2448 #endif 2449 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft; 2450 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; 2451 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2452 } 2453 2454 // Control-shift-clicks open in a foreground tab. 2455 // On OSX meta [the command key] takes the place of control. 2456 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefControlShiftClickTest) { 2457 #if defined(OS_MACOSX) 2458 int modifiers = blink::WebInputEvent::MetaKey; 2459 #else 2460 int modifiers = blink::WebInputEvent::ControlKey; 2461 #endif 2462 modifiers |= blink::WebInputEvent::ShiftKey; 2463 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft; 2464 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2465 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2466 } 2467 2468 // Middle-clicks open in a background tab. 2469 // TODO(linux_aura) http://crbug.com/163931 2470 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) 2471 #define MAYBE_HrefMiddleClickTest DISABLED_HrefMiddleClickTest 2472 #else 2473 #define MAYBE_HrefMiddleClickTest HrefMiddleClickTest 2474 #endif 2475 IN_PROC_BROWSER_TEST_F(ClickModifierTest, MAYBE_HrefMiddleClickTest) { 2476 int modifiers = 0; 2477 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonMiddle; 2478 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; 2479 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2480 } 2481 2482 // Shift-middle-clicks open in a foreground tab. 2483 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefShiftMiddleClickTest) { 2484 int modifiers = blink::WebInputEvent::ShiftKey; 2485 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonMiddle; 2486 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2487 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2488 } 2489 2490 // Does not work with Instant Extended. http://crbug.com/317760. 2491 // // TODO(sail): enable this for MAC when 2492 // // BrowserWindowCocoa::GetRenderViewHeightInsetWithDetachedBookmarkBar 2493 // // is fixed. 2494 // #if defined(OS_MACOSX) 2495 // #define MAYBE_GetSizeForNewRenderView DISABLED_GetSizeForNewRenderView 2496 // #else 2497 // #define MAYBE_GetSizeForNewRenderView GetSizeForNewRenderView 2498 // #endif 2499 IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_GetSizeForNewRenderView) { 2500 ASSERT_TRUE(test_server()->Start()); 2501 // Create an HTTPS server for cross-site transition. 2502 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 2503 net::SpawnedTestServer::kLocalhost, 2504 base::FilePath(kDocRoot)); 2505 ASSERT_TRUE(https_test_server.Start()); 2506 2507 // Start with NTP. 2508 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab")); 2509 ASSERT_EQ(BookmarkBar::DETACHED, browser()->bookmark_bar_state()); 2510 WebContents* web_contents = 2511 browser()->tab_strip_model()->GetActiveWebContents(); 2512 content::RenderViewHost* prev_rvh = web_contents->GetRenderViewHost(); 2513 const int height_inset = 2514 browser()->window()->GetRenderViewHeightInsetWithDetachedBookmarkBar(); 2515 const gfx::Size initial_wcv_size = 2516 web_contents->GetView()->GetContainerSize(); 2517 RenderViewSizeObserver observer(web_contents, browser()->window()); 2518 2519 // Navigate to a non-NTP page, without resizing WebContentsView. 2520 ui_test_utils::NavigateToURL(browser(), 2521 test_server()->GetURL("files/title1.html")); 2522 ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state()); 2523 // A new RenderViewHost should be created. 2524 EXPECT_NE(prev_rvh, web_contents->GetRenderViewHost()); 2525 prev_rvh = web_contents->GetRenderViewHost(); 2526 gfx::Size rwhv_create_size0, rwhv_commit_size0, wcv_commit_size0; 2527 observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(), 2528 &rwhv_create_size0, 2529 &rwhv_commit_size0, 2530 &wcv_commit_size0); 2531 // The create height of RenderWidgetHostView should include the height inset. 2532 EXPECT_EQ(gfx::Size(initial_wcv_size.width(), 2533 initial_wcv_size.height() + height_inset), 2534 rwhv_create_size0); 2535 // When a navigation entry is committed, the size of RenderWidgetHostView 2536 // should be the same as when it was first created. 2537 EXPECT_EQ(rwhv_create_size0, rwhv_commit_size0); 2538 // Sizes of the current RenderWidgetHostView and WebContentsView should not 2539 // change before and after WebContentsDelegate::DidNavigateMainFramePostCommit 2540 // (implemented by Browser); we obtain the sizes before PostCommit via 2541 // WebContentsObserver::NavigationEntryCommitted (implemented by 2542 // RenderViewSizeObserver). 2543 EXPECT_EQ(rwhv_commit_size0, 2544 web_contents->GetRenderWidgetHostView()->GetViewBounds().size()); 2545 EXPECT_EQ(wcv_commit_size0, web_contents->GetView()->GetContainerSize()); 2546 2547 // Navigate to another non-NTP page, without resizing WebContentsView. 2548 ui_test_utils::NavigateToURL(browser(), 2549 https_test_server.GetURL("files/title2.html")); 2550 ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state()); 2551 // A new RenderVieHost should be created. 2552 EXPECT_NE(prev_rvh, web_contents->GetRenderViewHost()); 2553 gfx::Size rwhv_create_size1, rwhv_commit_size1, wcv_commit_size1; 2554 observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(), 2555 &rwhv_create_size1, 2556 &rwhv_commit_size1, 2557 &wcv_commit_size1); 2558 EXPECT_EQ(rwhv_create_size1, rwhv_commit_size1); 2559 EXPECT_EQ(rwhv_commit_size1, 2560 web_contents->GetRenderWidgetHostView()->GetViewBounds().size()); 2561 EXPECT_EQ(wcv_commit_size1, web_contents->GetView()->GetContainerSize()); 2562 2563 // Navigate from NTP to a non-NTP page, resizing WebContentsView while 2564 // navigation entry is pending. 2565 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab")); 2566 gfx::Size wcv_resize_insets(-34, -57); 2567 observer.set_wcv_resize_insets(wcv_resize_insets); 2568 ui_test_utils::NavigateToURL(browser(), 2569 test_server()->GetURL("files/title2.html")); 2570 ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state()); 2571 gfx::Size rwhv_create_size2, rwhv_commit_size2, wcv_commit_size2; 2572 observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(), 2573 &rwhv_create_size2, 2574 &rwhv_commit_size2, 2575 &wcv_commit_size2); 2576 // The create height of RenderWidgetHostView should include the height inset. 2577 EXPECT_EQ(gfx::Size(initial_wcv_size.width(), 2578 initial_wcv_size.height() + height_inset), 2579 rwhv_create_size2); 2580 // WebContentsView was resized in 2581 // RenderViewSizeObserver::DidStartNavigationToPendingEntry after 2582 // RenderWidgetHostView was created, so the commit size should be resized 2583 // accordingly. 2584 gfx::Size exp_commit_size(initial_wcv_size); 2585 exp_commit_size.Enlarge(wcv_resize_insets.width(), 2586 wcv_resize_insets.height() + height_inset); 2587 EXPECT_EQ(exp_commit_size, rwhv_commit_size2); 2588 EXPECT_EQ(exp_commit_size, wcv_commit_size2); 2589 // Sizes of RenderWidgetHostView and WebContentsView before and after 2590 // WebContentsDelegate::DidNavigateMainFramePostCommit should be the same. 2591 EXPECT_EQ(rwhv_commit_size2, 2592 web_contents->GetRenderWidgetHostView()->GetViewBounds().size()); 2593 EXPECT_EQ(wcv_commit_size2, web_contents->GetView()->GetContainerSize()); 2594 } 2595