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