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