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