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