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