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