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