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