1 // Copyright 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.
8 #include "base/command_line.h"
9 #include "base/compiler_specific.h"
10 #include "base/files/file_path.h"
11 #include "base/location.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/sys_info.h"
17 #include "chrome/app/chrome_command_ids.h"
18 #include "chrome/browser/chrome_content_browser_client.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/command_updater.h"
21 #include "chrome/browser/defaults.h"
22 #include "chrome/browser/devtools/devtools_window_testing.h"
23 #include "chrome/browser/extensions/extension_browsertest.h"
24 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/extensions/extension_util.h"
26 #include "chrome/browser/extensions/tab_helper.h"
27 #include "chrome/browser/first_run/first_run.h"
28 #include "chrome/browser/lifetime/application_lifetime.h"
29 #include "chrome/browser/prefs/incognito_mode_prefs.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/profiles/profile_info_cache.h"
32 #include "chrome/browser/profiles/profile_manager.h"
33 #include "chrome/browser/search/search.h"
34 #include "chrome/browser/sessions/session_service_factory.h"
35 #include "chrome/browser/ssl/connection_security.h"
36 #include "chrome/browser/translate/chrome_translate_client.h"
37 #include "chrome/browser/translate/cld_data_harness.h"
38 #include "chrome/browser/translate/cld_data_harness_factory.h"
39 #include "chrome/browser/ui/browser.h"
40 #include "chrome/browser/ui/browser_command_controller.h"
41 #include "chrome/browser/ui/browser_commands.h"
42 #include "chrome/browser/ui/browser_finder.h"
43 #include "chrome/browser/ui/browser_iterator.h"
44 #include "chrome/browser/ui/browser_navigator.h"
45 #include "chrome/browser/ui/browser_tabstrip.h"
46 #include "chrome/browser/ui/browser_ui_prefs.h"
47 #include "chrome/browser/ui/browser_window.h"
48 #include "chrome/browser/ui/extensions/app_launch_params.h"
49 #include "chrome/browser/ui/extensions/application_launch.h"
50 #include "chrome/browser/ui/host_desktop.h"
51 #include "chrome/browser/ui/startup/startup_browser_creator.h"
52 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
53 #include "chrome/browser/ui/tabs/pinned_tab_codec.h"
54 #include "chrome/browser/ui/tabs/tab_strip_model.h"
55 #include "chrome/common/chrome_switches.h"
56 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
57 #include "chrome/common/pref_names.h"
58 #include "chrome/common/url_constants.h"
59 #include "chrome/grit/chromium_strings.h"
60 #include "chrome/grit/generated_resources.h"
61 #include "chrome/test/base/in_process_browser_test.h"
62 #include "chrome/test/base/test_switches.h"
63 #include "chrome/test/base/ui_test_utils.h"
64 #include "components/app_modal/app_modal_dialog.h"
65 #include "components/app_modal/app_modal_dialog_queue.h"
66 #include "components/app_modal/javascript_app_modal_dialog.h"
67 #include "components/app_modal/native_app_modal_dialog.h"
68 #include "components/content_settings/core/browser/host_content_settings_map.h"
69 #include "components/sessions/base_session_service_test_helper.h"
70 #include "components/translate/core/browser/language_state.h"
71 #include "components/translate/core/common/language_detection_details.h"
72 #include "content/public/browser/favicon_status.h"
73 #include "content/public/browser/host_zoom_map.h"
74 #include "content/public/browser/interstitial_page.h"
75 #include "content/public/browser/interstitial_page_delegate.h"
76 #include "content/public/browser/navigation_entry.h"
77 #include "content/public/browser/notification_service.h"
78 #include "content/public/browser/render_frame_host.h"
79 #include "content/public/browser/render_process_host.h"
80 #include "content/public/browser/render_view_host.h"
81 #include "content/public/browser/render_widget_host_view.h"
82 #include "content/public/browser/resource_context.h"
83 #include "content/public/browser/security_style_explanation.h"
84 #include "content/public/browser/security_style_explanations.h"
85 #include "content/public/browser/web_contents.h"
86 #include "content/public/browser/web_contents_observer.h"
87 #include "content/public/common/frame_navigate_params.h"
88 #include "content/public/common/renderer_preferences.h"
89 #include "content/public/common/ssl_status.h"
90 #include "content/public/common/url_constants.h"
91 #include "content/public/test/browser_test_utils.h"
92 #include "content/public/test/test_navigation_observer.h"
93 #include "extensions/browser/extension_registry.h"
94 #include "extensions/browser/extension_system.h"
95 #include "extensions/browser/uninstall_reason.h"
96 #include "extensions/common/constants.h"
97 #include "extensions/common/extension.h"
98 #include "extensions/common/extension_set.h"
99 #include "net/base/net_errors.h"
100 #include "net/dns/mock_host_resolver.h"
101 #include "net/test/spawned_test_server/spawned_test_server.h"
102 #include "ui/base/l10n/l10n_util.h"
103 #include "ui/base/page_transition_types.h"
105 #if defined(OS_MACOSX)
106 #include "base/mac/mac_util.h"
107 #include "base/mac/scoped_nsautorelease_pool.h"
108 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
112 #include "base/i18n/rtl.h"
113 #include "chrome/browser/browser_process.h"
116 using app_modal::AppModalDialog
;
117 using app_modal::AppModalDialogQueue
;
118 using app_modal::JavaScriptAppModalDialog
;
119 using base::ASCIIToUTF16
;
120 using content::InterstitialPage
;
121 using content::HostZoomMap
;
122 using content::NavigationController
;
123 using content::NavigationEntry
;
124 using content::OpenURLParams
;
125 using content::Referrer
;
126 using content::WebContents
;
127 using content::WebContentsObserver
;
128 using extensions::Extension
;
132 enum CertificateStatus
{ VALID_CERTIFICATE
, INVALID_CERTIFICATE
};
134 const char* kBeforeUnloadHTML
=
135 "<html><head><title>beforeunload</title></head><body>"
136 "<script>window.onbeforeunload=function(e){return 'foo'}</script>"
139 const char* kOpenNewBeforeUnloadPage
=
140 "w=window.open(); w.onbeforeunload=function(e){return 'foo'};";
142 const base::FilePath::CharType
* kBeforeUnloadFile
=
143 FILE_PATH_LITERAL("beforeunload.html");
145 const base::FilePath::CharType
* kTitle1File
= FILE_PATH_LITERAL("title1.html");
146 const base::FilePath::CharType
* kTitle2File
= FILE_PATH_LITERAL("title2.html");
148 const base::FilePath::CharType kDocRoot
[] =
149 FILE_PATH_LITERAL("chrome/test/data");
151 // Given a page title, returns the expected window caption string.
152 base::string16
WindowCaptionFromPageTitle(const base::string16
& page_title
) {
153 #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
154 // On Mac or ChromeOS, we don't want to suffix the page title with
155 // the application name.
156 if (page_title
.empty())
157 return l10n_util::GetStringUTF16(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED
);
160 if (page_title
.empty())
161 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME
);
163 return l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT
,
168 // Returns the number of active RenderProcessHosts.
169 int CountRenderProcessHosts() {
171 for (content::RenderProcessHost::iterator
i(
172 content::RenderProcessHost::AllHostsIterator());
173 !i
.IsAtEnd(); i
.Advance())
178 class MockTabStripModelObserver
: public TabStripModelObserver
{
180 MockTabStripModelObserver() : closing_count_(0) {}
182 void TabClosingAt(TabStripModel
* tab_strip_model
,
183 WebContents
* contents
,
184 int index
) override
{
188 int closing_count() const { return closing_count_
; }
193 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver
);
196 // Causes the browser to swap processes on a redirect to an HTTPS URL.
197 class TransferHttpsRedirectsContentBrowserClient
198 : public chrome::ChromeContentBrowserClient
{
200 bool ShouldSwapProcessesForRedirect(
201 content::ResourceContext
* resource_context
,
202 const GURL
& current_url
,
203 const GURL
& new_url
) override
{
204 return new_url
.SchemeIs(url::kHttpsScheme
);
208 // Used by CloseWithAppMenuOpen. Invokes CloseWindow on the supplied browser.
209 void CloseWindowCallback(Browser
* browser
) {
210 chrome::CloseWindow(browser
);
213 // Used by CloseWithAppMenuOpen. Posts a CloseWindowCallback and shows the app
215 void RunCloseWithAppMenuCallback(Browser
* browser
) {
216 // ShowAppMenu is modal under views. Schedule a task that closes the window.
217 base::MessageLoop::current()->task_runner()->PostTask(
218 FROM_HERE
, base::Bind(&CloseWindowCallback
, browser
));
219 chrome::ShowAppMenu(browser
);
222 // Displays "INTERSTITIAL" while the interstitial is attached.
223 // (InterstitialPage can be used in a test directly, but there would be no way
224 // to visually tell if it is showing or not.)
225 class TestInterstitialPage
: public content::InterstitialPageDelegate
{
227 TestInterstitialPage(WebContents
* tab
, bool new_navigation
, const GURL
& url
) {
228 interstitial_page_
= InterstitialPage::Create(
229 tab
, new_navigation
, url
, this);
230 interstitial_page_
->Show();
232 ~TestInterstitialPage() override
{}
234 interstitial_page_
->Proceed();
237 interstitial_page_
->DontProceed();
240 std::string
GetHTMLContents() override
{ return "<h1>INTERSTITIAL</h1>"; }
243 InterstitialPage
* interstitial_page_
; // Owns us.
246 class RenderViewSizeObserver
: public content::WebContentsObserver
{
248 RenderViewSizeObserver(content::WebContents
* web_contents
,
249 BrowserWindow
* browser_window
)
250 : WebContentsObserver(web_contents
),
251 browser_window_(browser_window
) {
254 void GetSizeForRenderViewHost(
255 content::RenderViewHost
* render_view_host
,
256 gfx::Size
* rwhv_create_size
,
257 gfx::Size
* rwhv_commit_size
,
258 gfx::Size
* wcv_commit_size
) {
259 RenderViewSizes::const_iterator result
= render_view_sizes_
.end();
260 result
= render_view_sizes_
.find(render_view_host
);
261 if (result
!= render_view_sizes_
.end()) {
262 *rwhv_create_size
= result
->second
.rwhv_create_size
;
263 *rwhv_commit_size
= result
->second
.rwhv_commit_size
;
264 *wcv_commit_size
= result
->second
.wcv_commit_size
;
268 void set_wcv_resize_insets(const gfx::Size
& wcv_resize_insets
) {
269 wcv_resize_insets_
= wcv_resize_insets
;
272 // Cache the size when RenderViewHost is first created.
273 void RenderViewCreated(content::RenderViewHost
* render_view_host
) override
{
274 render_view_sizes_
[render_view_host
].rwhv_create_size
=
275 render_view_host
->GetView()->GetViewBounds().size();
278 // Enlarge WebContentsView by |wcv_resize_insets_| while the navigation entry
280 void DidStartNavigationToPendingEntry(
282 NavigationController::ReloadType reload_type
) override
{
283 if (wcv_resize_insets_
.IsEmpty())
285 // Resizing the main browser window by |wcv_resize_insets_| will
286 // automatically resize the WebContentsView by the same amount.
287 // Just resizing WebContentsView directly doesn't work on Linux, because the
288 // next automatic layout of the browser window will resize WebContentsView
289 // back to the previous size. To make it consistent, resize main browser
290 // window on all platforms.
291 gfx::Rect
bounds(browser_window_
->GetBounds());
292 gfx::Size
size(bounds
.size());
293 size
.Enlarge(wcv_resize_insets_
.width(), wcv_resize_insets_
.height());
294 bounds
.set_size(size
);
295 browser_window_
->SetBounds(bounds
);
296 // Let the message loop run so that resize actually takes effect.
297 content::RunAllPendingInMessageLoop();
300 // Cache the sizes of RenderWidgetHostView and WebContentsView when the
301 // navigation entry is committed, which is before
302 // WebContentsDelegate::DidNavigateMainFramePostCommit is called.
303 void NavigationEntryCommitted(
304 const content::LoadCommittedDetails
& details
) override
{
305 content::RenderViewHost
* rvh
= web_contents()->GetRenderViewHost();
306 render_view_sizes_
[rvh
].rwhv_commit_size
=
307 web_contents()->GetRenderWidgetHostView()->GetViewBounds().size();
308 render_view_sizes_
[rvh
].wcv_commit_size
=
309 web_contents()->GetContainerBounds().size();
314 gfx::Size rwhv_create_size
; // Size of RenderWidgetHostView when created.
315 gfx::Size rwhv_commit_size
; // Size of RenderWidgetHostView when committed.
316 gfx::Size wcv_commit_size
; // Size of WebContentsView when committed.
319 typedef std::map
<content::RenderViewHost
*, Sizes
> RenderViewSizes
;
320 RenderViewSizes render_view_sizes_
;
321 // Enlarge WebContentsView by this size insets in
322 // DidStartNavigationToPendingEntry.
323 gfx::Size wcv_resize_insets_
;
324 BrowserWindow
* browser_window_
; // Weak ptr.
326 DISALLOW_COPY_AND_ASSIGN(RenderViewSizeObserver
);
329 void ProceedThroughInterstitial(content::WebContents
* web_contents
) {
330 InterstitialPage
* interstitial_page
= web_contents
->GetInterstitialPage();
331 ASSERT_TRUE(interstitial_page
);
333 content::WindowedNotificationObserver
observer(
334 content::NOTIFICATION_LOAD_STOP
,
335 content::Source
<NavigationController
>(&web_contents
->GetController()));
336 interstitial_page
->Proceed();
340 bool GetFilePathWithHostAndPortReplacement(
341 const std::string
& original_file_path
,
342 const net::HostPortPair
& host_port_pair
,
343 std::string
* replacement_path
) {
344 std::vector
<net::SpawnedTestServer::StringPair
> replacement_text
;
345 replacement_text
.push_back(
346 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair
.ToString()));
347 return net::SpawnedTestServer::GetFilePathWithReplacements(
348 original_file_path
, replacement_text
, replacement_path
);
351 // A WebContentsObserver useful for testing the SecurityStyleChanged()
352 // method: it keeps track of the latest security style and explanation
354 class SecurityStyleTestObserver
: public WebContentsObserver
{
356 explicit SecurityStyleTestObserver(content::WebContents
* web_contents
)
357 : content::WebContentsObserver(web_contents
),
358 latest_security_style_(content::SECURITY_STYLE_UNKNOWN
) {}
359 ~SecurityStyleTestObserver() override
{}
361 void SecurityStyleChanged(content::SecurityStyle security_style
,
362 const content::SecurityStyleExplanations
&
363 security_style_explanations
) override
{
364 latest_security_style_
= security_style
;
365 latest_explanations_
= security_style_explanations
;
368 content::SecurityStyle
latest_security_style() const {
369 return latest_security_style_
;
372 const content::SecurityStyleExplanations
& latest_explanations() const {
373 return latest_explanations_
;
376 void ClearLatestSecurityStyleAndExplanations() {
377 latest_security_style_
= content::SECURITY_STYLE_UNKNOWN
;
378 latest_explanations_
= content::SecurityStyleExplanations();
382 content::SecurityStyle latest_security_style_
;
383 content::SecurityStyleExplanations latest_explanations_
;
385 DISALLOW_COPY_AND_ASSIGN(SecurityStyleTestObserver
);
388 // Check that |observer|'s latest event was for an expired certificate
389 // and that it saw the proper SecurityStyle and explanations.
390 void CheckBrokenSecurityStyle(const SecurityStyleTestObserver
& observer
,
393 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN
,
394 observer
.latest_security_style());
396 const content::SecurityStyleExplanations
& expired_explanation
=
397 observer
.latest_explanations();
398 EXPECT_EQ(0u, expired_explanation
.warning_explanations
.size());
399 ASSERT_EQ(1u, expired_explanation
.broken_explanations
.size());
401 // Check that the summary and description are as expected.
402 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_CERTIFICATE_CHAIN_ERROR
),
403 expired_explanation
.broken_explanations
[0].summary
);
405 base::string16 error_string
= base::UTF8ToUTF16(net::ErrorToString(error
));
406 EXPECT_EQ(l10n_util::GetStringFUTF8(
407 IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT
, error_string
),
408 expired_explanation
.broken_explanations
[0].description
);
410 // Check the associated certificate id.
411 int cert_id
= browser
->tab_strip_model()->GetActiveWebContents()->
412 GetController().GetActiveEntry()->GetSSL().cert_id
;
414 expired_explanation
.broken_explanations
[0].cert_id
);
417 // Checks that the given |secure_explanations| contains appropriate
418 // an appropriate explanation if the certificate status is valid.
419 void CheckSecureExplanations(
420 const std::vector
<content::SecurityStyleExplanation
>& secure_explanations
,
421 CertificateStatus cert_status
,
423 if (cert_status
!= VALID_CERTIFICATE
) {
424 EXPECT_EQ(0u, secure_explanations
.size());
428 EXPECT_EQ(1u, secure_explanations
.size());
429 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE
),
430 secure_explanations
[0].summary
);
431 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION
),
432 secure_explanations
[0].description
);
433 int cert_id
= browser
->tab_strip_model()->GetActiveWebContents()->
434 GetController().GetActiveEntry()->GetSSL().cert_id
;
435 EXPECT_EQ(cert_id
, secure_explanations
[0].cert_id
);
440 class BrowserTest
: public ExtensionBrowserTest
{
442 // In RTL locales wrap the page title with RTL embedding characters so that it
443 // matches the value returned by GetWindowTitle().
444 base::string16
LocaleWindowCaptionFromPageTitle(
445 const base::string16
& expected_title
) {
446 base::string16 page_title
= WindowCaptionFromPageTitle(expected_title
);
448 std::string locale
= g_browser_process
->GetApplicationLocale();
449 if (base::i18n::GetTextDirectionForLocale(locale
.c_str()) ==
450 base::i18n::RIGHT_TO_LEFT
) {
451 base::i18n::WrapStringWithLTRFormatting(&page_title
);
456 // Do we need to use the above code on POSIX as well?
461 // Returns the app extension aptly named "App Test".
462 const Extension
* GetExtension() {
463 extensions::ExtensionRegistry
* registry
=
464 extensions::ExtensionRegistry::Get(browser()->profile());
465 for (const scoped_refptr
<const extensions::Extension
>& extension
:
466 registry
->enabled_extensions()) {
467 if (extension
->name() == "App Test")
468 return extension
.get();
475 // Launch the app on a page with no title, check that the app title was set
477 IN_PROC_BROWSER_TEST_F(BrowserTest
, NoTitle
) {
478 #if defined(OS_WIN) && defined(USE_ASH)
479 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
480 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
481 switches::kAshBrowserTests
))
485 ui_test_utils::NavigateToURL(
486 browser(), ui_test_utils::GetTestUrl(
487 base::FilePath(base::FilePath::kCurrentDirectory
),
488 base::FilePath(kTitle1File
)));
489 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")),
490 browser()->GetWindowTitleForCurrentTab());
491 base::string16 tab_title
;
492 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title
));
493 EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title
);
496 // Check that a file:// URL displays the filename, but no path, with any ref or
497 // query parameters following it if the content does not have a <title> tag.
498 // Specifically verify the cases where the ref or query parameters have a '/'
499 // character in them. This is a regression test for
500 // https://crbug.com/503003.
501 IN_PROC_BROWSER_TEST_F(BrowserTest
, NoTitleFileUrl
) {
502 #if defined(OS_WIN) && defined(USE_ASH)
503 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
504 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
505 switches::kAshBrowserTests
))
509 // Note that the host names used and the order of these cases are by design.
510 // There must be unique query parameters and references per case (i.e. the
511 // indexed foo*.com hosts) because if the same query parameter is repeated in
512 // a row, then the navigation may not actually happen, as it will only appear
513 // as a reference change. Additionally, cases with references first must
514 // appear after a query parameter case since otherwise it will not be a
520 {"#https://foo1.com", "file:/// URL with slash in ref"},
521 {"?x=https://foo2.com", "file:/// URL with slash in query parameter"},
522 {"?x=https://foo3.com#https://foo3.com",
523 "file:/// URL with slashes in query parameter and ref"},
524 {"#https://foo4.com?x=https://foo4.com",
525 "file:/// URL with slashes in ref and query parameter"},
526 {"?x=https://foo6.com?x=https://foo6.com",
527 "file:/// URL with slashes in multiple query parameter"},
528 {"#https://foo5.com#https://foo5.com",
529 "file:/// URL with slashes in multiple refs"}};
531 GURL prefix_url
= ui_test_utils::GetTestUrl(
532 base::FilePath(base::FilePath::kCurrentDirectory
),
533 base::FilePath(kTitle1File
));
534 base::string16 tab_title
;
535 base::string16 test_title
;
536 for (const auto& c
: cases
) {
537 SCOPED_TRACE(c
.message
);
538 GURL
url(prefix_url
.spec() + c
.suffix
);
539 test_title
= ASCIIToUTF16("title1.html" + c
.suffix
);
540 content::TitleWatcher
title_watcher(
541 browser()->tab_strip_model()->GetActiveWebContents(), test_title
);
542 ui_test_utils::NavigateToURL(browser(), url
);
543 EXPECT_EQ(test_title
, title_watcher
.WaitAndGetTitle());
547 // Launch the app, navigate to a page with a title, check that the app title
548 // was set correctly.
549 IN_PROC_BROWSER_TEST_F(BrowserTest
, Title
) {
550 #if defined(OS_WIN) && defined(USE_ASH)
551 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
552 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
553 switches::kAshBrowserTests
))
557 ui_test_utils::NavigateToURL(
558 browser(), ui_test_utils::GetTestUrl(
559 base::FilePath(base::FilePath::kCurrentDirectory
),
560 base::FilePath(kTitle2File
)));
561 const base::string16
test_title(ASCIIToUTF16("Title Of Awesomeness"));
562 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(test_title
),
563 browser()->GetWindowTitleForCurrentTab());
564 base::string16 tab_title
;
565 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title
));
566 EXPECT_EQ(test_title
, tab_title
);
569 IN_PROC_BROWSER_TEST_F(BrowserTest
, JavascriptAlertActivatesTab
) {
570 GURL
url(ui_test_utils::GetTestUrl(base::FilePath(
571 base::FilePath::kCurrentDirectory
), base::FilePath(kTitle1File
)));
572 ui_test_utils::NavigateToURL(browser(), url
);
573 AddTabAtIndex(0, url
, ui::PAGE_TRANSITION_TYPED
);
574 EXPECT_EQ(2, browser()->tab_strip_model()->count());
575 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
576 WebContents
* second_tab
= browser()->tab_strip_model()->GetWebContentsAt(1);
577 ASSERT_TRUE(second_tab
);
578 second_tab
->GetMainFrame()->ExecuteJavaScriptForTests(
579 ASCIIToUTF16("alert('Activate!');"));
580 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
581 alert
->CloseModalDialog();
582 EXPECT_EQ(2, browser()->tab_strip_model()->count());
583 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
587 #if defined(OS_WIN) && !defined(NDEBUG)
588 // http://crbug.com/114859. Times out frequently on Windows.
589 #define MAYBE_ThirtyFourTabs DISABLED_ThirtyFourTabs
591 #define MAYBE_ThirtyFourTabs ThirtyFourTabs
594 // Create 34 tabs and verify that a lot of processes have been created. The
595 // exact number of processes depends on the amount of memory. Previously we
596 // had a hard limit of 31 processes and this test is mainly directed at
597 // verifying that we don't crash when we pass this limit.
598 // Warning: this test can take >30 seconds when running on a slow (low
599 // memory?) Mac builder.
600 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_ThirtyFourTabs
) {
601 GURL
url(ui_test_utils::GetTestUrl(base::FilePath(
602 base::FilePath::kCurrentDirectory
), base::FilePath(kTitle2File
)));
604 // There is one initial tab.
605 const int kTabCount
= 34;
606 for (int ix
= 0; ix
!= (kTabCount
- 1); ++ix
) {
607 chrome::AddSelectedTabWithURL(browser(), url
,
608 ui::PAGE_TRANSITION_TYPED
);
610 EXPECT_EQ(kTabCount
, browser()->tab_strip_model()->count());
612 // See GetMaxRendererProcessCount() in
613 // content/browser/renderer_host/render_process_host_impl.cc
614 // for the algorithm to decide how many processes to create.
615 const int kExpectedProcessCount
=
616 #if defined(ARCH_CPU_64_BITS)
621 if (base::SysInfo::AmountOfPhysicalMemoryMB() >= 2048) {
622 EXPECT_GE(CountRenderProcessHosts(), kExpectedProcessCount
);
624 EXPECT_LT(CountRenderProcessHosts(), kExpectedProcessCount
);
628 // Test that a browser-initiated navigation to an aborted URL load leaves around
629 // a pending entry if we start from the NTP but not from a normal page.
630 // See http://crbug.com/355537.
631 IN_PROC_BROWSER_TEST_F(BrowserTest
, ClearPendingOnFailUnlessNTP
) {
632 ASSERT_TRUE(test_server()->Start());
633 WebContents
* web_contents
=
634 browser()->tab_strip_model()->GetActiveWebContents();
635 GURL
ntp_url(search::GetNewTabPageURL(browser()->profile()));
636 ui_test_utils::NavigateToURL(browser(), ntp_url
);
638 // Navigate to a 204 URL (aborts with no content) on the NTP and make sure it
639 // sticks around so that the user can edit it.
640 GURL
abort_url(test_server()->GetURL("nocontent"));
642 content::WindowedNotificationObserver
stop_observer(
643 content::NOTIFICATION_LOAD_STOP
,
644 content::Source
<NavigationController
>(
645 &web_contents
->GetController()));
646 browser()->OpenURL(OpenURLParams(abort_url
, Referrer(), CURRENT_TAB
,
647 ui::PAGE_TRANSITION_TYPED
, false));
648 stop_observer
.Wait();
649 EXPECT_TRUE(web_contents
->GetController().GetPendingEntry());
650 EXPECT_EQ(abort_url
, web_contents
->GetVisibleURL());
653 // Navigate to a real URL.
654 GURL
real_url(test_server()->GetURL("title1.html"));
655 ui_test_utils::NavigateToURL(browser(), real_url
);
656 EXPECT_EQ(real_url
, web_contents
->GetVisibleURL());
658 // Now navigating to a 204 URL should clear the pending entry.
660 content::WindowedNotificationObserver
stop_observer(
661 content::NOTIFICATION_LOAD_STOP
,
662 content::Source
<NavigationController
>(
663 &web_contents
->GetController()));
664 browser()->OpenURL(OpenURLParams(abort_url
, Referrer(), CURRENT_TAB
,
665 ui::PAGE_TRANSITION_TYPED
, false));
666 stop_observer
.Wait();
667 EXPECT_FALSE(web_contents
->GetController().GetPendingEntry());
668 EXPECT_EQ(real_url
, web_contents
->GetVisibleURL());
672 // Test for crbug.com/297289. Ensure that modal dialogs are closed when a
673 // cross-process navigation is ready to commit.
674 // Flaky test, see https://crbug.com/445155.
675 IN_PROC_BROWSER_TEST_F(BrowserTest
, DISABLED_CrossProcessNavCancelsDialogs
) {
676 ASSERT_TRUE(test_server()->Start());
677 host_resolver()->AddRule("www.example.com", "127.0.0.1");
678 GURL
url(test_server()->GetURL("empty.html"));
679 ui_test_utils::NavigateToURL(browser(), url
);
681 // Test this with multiple alert dialogs to ensure that we can navigate away
682 // even if the renderer tries to synchronously create more.
683 // See http://crbug.com/312490.
684 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
685 contents
->GetMainFrame()->ExecuteJavaScriptForTests(
686 ASCIIToUTF16("alert('one'); alert('two');"));
687 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
688 EXPECT_TRUE(alert
->IsValid());
689 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
690 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
692 // A cross-site navigation should force the dialog to close.
693 GURL
url2("http://www.example.com/empty.html");
694 ui_test_utils::NavigateToURL(browser(), url2
);
695 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
697 // Make sure input events still work in the renderer process.
698 EXPECT_FALSE(contents
->GetRenderProcessHost()->IgnoreInputEvents());
701 // Make sure that dialogs are closed after a renderer process dies, and that
702 // subsequent navigations work. See http://crbug/com/343265.
703 IN_PROC_BROWSER_TEST_F(BrowserTest
, SadTabCancelsDialogs
) {
704 ASSERT_TRUE(test_server()->Start());
705 host_resolver()->AddRule("www.example.com", "127.0.0.1");
706 GURL
beforeunload_url(test_server()->GetURL("files/beforeunload.html"));
707 ui_test_utils::NavigateToURL(browser(), beforeunload_url
);
709 // Start a navigation to trigger the beforeunload dialog.
710 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
711 contents
->GetMainFrame()->ExecuteJavaScriptForTests(
712 ASCIIToUTF16("window.location.href = 'data:text/html,foo'"));
713 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
714 EXPECT_TRUE(alert
->IsValid());
715 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
716 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
718 // Crash the renderer process and ensure the dialog is gone.
719 content::RenderProcessHost
* child_process
= contents
->GetRenderProcessHost();
720 content::RenderProcessHostWatcher
crash_observer(
722 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT
);
723 child_process
->Shutdown(0, false);
724 crash_observer
.Wait();
725 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
727 // Make sure subsequent navigations work.
728 GURL
url2("http://www.example.com/files/empty.html");
729 ui_test_utils::NavigateToURL(browser(), url2
);
732 // Make sure that dialogs opened by subframes are closed when the process dies.
733 // See http://crbug.com/366510.
734 IN_PROC_BROWSER_TEST_F(BrowserTest
, SadTabCancelsSubframeDialogs
) {
735 // Navigate to an iframe that opens an alert dialog.
736 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
737 contents
->GetMainFrame()->ExecuteJavaScriptForTests(
738 ASCIIToUTF16("window.location.href = 'data:text/html,"
739 "<iframe srcdoc=\"<script>alert(1)</script>\">'"));
740 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
741 EXPECT_TRUE(alert
->IsValid());
742 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
743 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
745 // Crash the renderer process and ensure the dialog is gone.
746 content::RenderProcessHost
* child_process
= contents
->GetRenderProcessHost();
747 content::RenderProcessHostWatcher
crash_observer(
749 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT
);
750 child_process
->Shutdown(0, false);
751 crash_observer
.Wait();
752 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
754 // Make sure subsequent navigations work.
755 GURL
url2("data:text/html,foo");
756 ui_test_utils::NavigateToURL(browser(), url2
);
759 // Make sure modal dialogs within a guestview are closed when an interstitial
760 // page is showing. See crbug.com/482380.
761 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialCancelsGuestViewDialogs
) {
762 // Navigate to a PDF, which is loaded within a guestview.
763 ASSERT_TRUE(test_server()->Start());
764 GURL
pdf_with_dialog(test_server()->GetURL("files/alert_dialog.pdf"));
765 ui_test_utils::NavigateToURL(browser(), pdf_with_dialog
);
767 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
768 EXPECT_TRUE(alert
->IsValid());
769 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
770 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
772 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
774 TestInterstitialPage
* interstitial
=
775 new TestInterstitialPage(contents
, false, GURL());
776 content::WaitForInterstitialAttach(contents
);
778 // The interstitial should have closed the dialog.
779 EXPECT_TRUE(contents
->ShowingInterstitialPage());
780 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
782 interstitial
->DontProceed();
785 // Test for crbug.com/22004. Reloading a page with a before unload handler and
786 // then canceling the dialog should not leave the throbber spinning.
787 IN_PROC_BROWSER_TEST_F(BrowserTest
, ReloadThenCancelBeforeUnload
) {
788 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
789 ui_test_utils::NavigateToURL(browser(), url
);
791 // Navigate to another page, but click cancel in the dialog. Make sure that
792 // the throbber stops spinning.
793 chrome::Reload(browser(), CURRENT_TAB
);
794 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
795 alert
->CloseModalDialog();
797 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading());
799 // Clear the beforeunload handler so the test can easily exit.
800 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()->
801 ExecuteJavaScriptForTests(ASCIIToUTF16("onbeforeunload=null;"));
804 class RedirectObserver
: public content::WebContentsObserver
{
806 explicit RedirectObserver(content::WebContents
* web_contents
)
807 : WebContentsObserver(web_contents
) {
810 void DidNavigateAnyFrame(
811 content::RenderFrameHost
* render_frame_host
,
812 const content::LoadCommittedDetails
& details
,
813 const content::FrameNavigateParams
& params
) override
{
817 void WebContentsDestroyed() override
{
818 // Make sure we don't close the tab while the observer is in scope.
819 // See http://crbug.com/314036.
820 FAIL() << "WebContents closed during navigation (http://crbug.com/314036).";
823 const content::FrameNavigateParams
& params() const {
828 content::FrameNavigateParams params_
;
830 DISALLOW_COPY_AND_ASSIGN(RedirectObserver
);
833 // Ensure that a transferred cross-process navigation does not generate
834 // DidStopLoading events until the navigation commits. If it did, then
835 // ui_test_utils::NavigateToURL would proceed before the URL had committed.
836 // http://crbug.com/243957.
837 IN_PROC_BROWSER_TEST_F(BrowserTest
, NoStopDuringTransferUntilCommit
) {
838 // Create HTTP and HTTPS servers for a cross-site transition.
839 ASSERT_TRUE(test_server()->Start());
840 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
841 net::SpawnedTestServer::kLocalhost
,
842 base::FilePath(kDocRoot
));
843 ASSERT_TRUE(https_test_server
.Start());
845 // Temporarily replace ContentBrowserClient with one that will cause a
846 // process swap on all redirects to HTTPS URLs.
847 TransferHttpsRedirectsContentBrowserClient new_client
;
848 content::ContentBrowserClient
* old_client
=
849 SetBrowserClientForTesting(&new_client
);
851 GURL
init_url(test_server()->GetURL("files/title1.html"));
852 ui_test_utils::NavigateToURL(browser(), init_url
);
854 // Navigate to a same-site page that redirects, causing a transfer.
855 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
857 // Create a RedirectObserver that goes away before we close the tab.
859 RedirectObserver
redirect_observer(contents
);
860 GURL
dest_url(https_test_server
.GetURL("files/title2.html"));
861 GURL
redirect_url(test_server()->GetURL("server-redirect?" +
863 ui_test_utils::NavigateToURL(browser(), redirect_url
);
865 // We should immediately see the new committed entry.
866 EXPECT_FALSE(contents
->GetController().GetPendingEntry());
868 contents
->GetController().GetLastCommittedEntry()->GetURL());
870 // We should keep track of the original request URL, redirect chain, and
871 // page transition type during a transfer, since these are necessary for
872 // history autocomplete to work.
873 EXPECT_EQ(redirect_url
, contents
->GetController().GetLastCommittedEntry()->
874 GetOriginalRequestURL());
875 EXPECT_EQ(2U, redirect_observer
.params().redirects
.size());
876 EXPECT_EQ(redirect_url
, redirect_observer
.params().redirects
.at(0));
877 EXPECT_EQ(dest_url
, redirect_observer
.params().redirects
.at(1));
878 EXPECT_TRUE(ui::PageTransitionCoreTypeIs(
879 redirect_observer
.params().transition
, ui::PAGE_TRANSITION_TYPED
));
882 // Restore previous browser client.
883 SetBrowserClientForTesting(old_client
);
886 // Tests that a cross-process redirect will only cause the beforeunload
887 // handler to run once.
888 IN_PROC_BROWSER_TEST_F(BrowserTest
, SingleBeforeUnloadAfterRedirect
) {
889 // Create HTTP and HTTPS servers for a cross-site transition.
890 ASSERT_TRUE(test_server()->Start());
891 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
892 net::SpawnedTestServer::kLocalhost
,
893 base::FilePath(kDocRoot
));
894 ASSERT_TRUE(https_test_server
.Start());
896 // Temporarily replace ContentBrowserClient with one that will cause a
897 // process swap on all redirects to HTTPS URLs.
898 TransferHttpsRedirectsContentBrowserClient new_client
;
899 content::ContentBrowserClient
* old_client
=
900 SetBrowserClientForTesting(&new_client
);
902 // Navigate to a page with a beforeunload handler.
903 GURL
url(test_server()->GetURL("files/beforeunload.html"));
904 ui_test_utils::NavigateToURL(browser(), url
);
906 // Navigate to a URL that redirects to another process and approve the
907 // beforeunload dialog that pops up.
908 content::WindowedNotificationObserver
nav_observer(
909 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
910 content::NotificationService::AllSources());
911 GURL
https_url(https_test_server
.GetURL("files/title1.html"));
912 GURL
redirect_url(test_server()->GetURL("server-redirect?" +
914 browser()->OpenURL(OpenURLParams(redirect_url
, Referrer(), CURRENT_TAB
,
915 ui::PAGE_TRANSITION_TYPED
, false));
916 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
918 static_cast<JavaScriptAppModalDialog
*>(alert
)->is_before_unload_dialog());
919 alert
->native_dialog()->AcceptAppModalDialog();
922 // Restore previous browser client.
923 SetBrowserClientForTesting(old_client
);
926 // Test for crbug.com/80401. Canceling a before unload dialog should reset
927 // the URL to the previous page's URL.
928 IN_PROC_BROWSER_TEST_F(BrowserTest
, CancelBeforeUnloadResetsURL
) {
929 GURL
url(ui_test_utils::GetTestUrl(base::FilePath(
930 base::FilePath::kCurrentDirectory
), base::FilePath(kBeforeUnloadFile
)));
931 ui_test_utils::NavigateToURL(browser(), url
);
933 // Navigate to a page that triggers a cross-site transition.
934 ASSERT_TRUE(test_server()->Start());
935 GURL
url2(test_server()->GetURL("files/title1.html"));
936 browser()->OpenURL(OpenURLParams(
937 url2
, Referrer(), CURRENT_TAB
, ui::PAGE_TRANSITION_TYPED
, false));
939 content::WindowedNotificationObserver
host_destroyed_observer(
940 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED
,
941 content::NotificationService::AllSources());
943 // Cancel the dialog.
944 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
945 alert
->CloseModalDialog();
947 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading());
949 // Verify there are no pending history items after the dialog is cancelled.
950 // (see crbug.com/93858)
951 NavigationEntry
* entry
= browser()->tab_strip_model()->
952 GetActiveWebContents()->GetController().GetPendingEntry();
953 EXPECT_EQ(NULL
, entry
);
955 // Wait for the ShouldClose_ACK to arrive. We can detect it by waiting for
956 // the pending RVH to be destroyed.
957 host_destroyed_observer
.Wait();
958 EXPECT_EQ(url
, browser()->toolbar_model()->GetURL());
960 // Clear the beforeunload handler so the test can easily exit.
961 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()->
962 ExecuteJavaScriptForTests(ASCIIToUTF16("onbeforeunload=null;"));
965 // Test for crbug.com/11647. A page closed with window.close() should not have
966 // two beforeunload dialogs shown.
967 // http://crbug.com/410891
968 IN_PROC_BROWSER_TEST_F(BrowserTest
,
969 DISABLED_SingleBeforeUnloadAfterWindowClose
) {
972 ->GetActiveWebContents()
974 ->ExecuteJavaScriptWithUserGestureForTests(
975 ASCIIToUTF16(kOpenNewBeforeUnloadPage
));
977 // Close the new window with JavaScript, which should show a single
978 // beforeunload dialog. Then show another alert, to make it easy to verify
979 // that a second beforeunload dialog isn't shown.
982 ->GetWebContentsAt(0)
984 ->ExecuteJavaScriptWithUserGestureForTests(
985 ASCIIToUTF16("w.close(); alert('bar');"));
986 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
987 alert
->native_dialog()->AcceptAppModalDialog();
989 alert
= ui_test_utils::WaitForAppModalDialog();
990 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog
*>(alert
)->
991 is_before_unload_dialog());
992 alert
->native_dialog()->AcceptAppModalDialog();
995 // BrowserTest.BeforeUnloadVsBeforeReload times out on Windows.
996 // http://crbug.com/130411
998 #define MAYBE_BeforeUnloadVsBeforeReload DISABLED_BeforeUnloadVsBeforeReload
1000 #define MAYBE_BeforeUnloadVsBeforeReload BeforeUnloadVsBeforeReload
1003 // Test that when a page has an onunload handler, reloading a page shows a
1004 // different dialog than navigating to a different page.
1005 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_BeforeUnloadVsBeforeReload
) {
1006 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
1007 ui_test_utils::NavigateToURL(browser(), url
);
1009 // Reload the page, and check that we get a "before reload" dialog.
1010 chrome::Reload(browser(), CURRENT_TAB
);
1011 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
1012 EXPECT_TRUE(static_cast<JavaScriptAppModalDialog
*>(alert
)->is_reload());
1014 // Cancel the reload.
1015 alert
->native_dialog()->CancelAppModalDialog();
1017 // Navigate to another url, and check that we get a "before unload" dialog.
1018 GURL
url2(url::kAboutBlankURL
);
1019 browser()->OpenURL(OpenURLParams(
1020 url2
, Referrer(), CURRENT_TAB
, ui::PAGE_TRANSITION_TYPED
, false));
1022 alert
= ui_test_utils::WaitForAppModalDialog();
1023 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog
*>(alert
)->is_reload());
1025 // Accept the navigation so we end up on a page without a beforeunload hook.
1026 alert
->native_dialog()->AcceptAppModalDialog();
1029 // BeforeUnloadAtQuitWithTwoWindows is a regression test for
1030 // http://crbug.com/11842. It opens two windows, one of which has a
1031 // beforeunload handler and attempts to exit cleanly.
1032 class BeforeUnloadAtQuitWithTwoWindows
: public InProcessBrowserTest
{
1034 // This test is for testing a specific shutdown behavior. This mimics what
1035 // happens in InProcessBrowserTest::RunTestOnMainThread and QuitBrowsers, but
1036 // ensures that it happens through the single IDC_EXIT of the test.
1037 void TearDownOnMainThread() override
{
1038 // Cycle both the MessageLoop and the Cocoa runloop twice to flush out any
1039 // Chrome work that generates Cocoa work. Do this twice since there are two
1040 // Browsers that must be closed.
1044 // Run the application event loop to completion, which will cycle the
1045 // native MessagePump on all platforms.
1046 base::MessageLoop::current()->task_runner()->PostTask(
1047 FROM_HERE
, base::MessageLoop::QuitClosure());
1048 base::MessageLoop::current()->Run();
1050 // Take care of any remaining Cocoa work.
1053 // At this point, quit should be for real now.
1054 ASSERT_EQ(0u, chrome::GetTotalBrowserCount());
1057 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run
1058 // loop. It also drains the NSAutoreleasePool.
1059 void CycleRunLoops() {
1060 content::RunAllPendingInMessageLoop();
1061 #if defined(OS_MACOSX)
1062 chrome::testing::NSRunLoopRunAllPending();
1063 AutoreleasePool()->Recycle();
1068 // Disabled, http://crbug.com/159214 .
1069 IN_PROC_BROWSER_TEST_F(BeforeUnloadAtQuitWithTwoWindows
,
1070 DISABLED_IfThisTestTimesOutItIndicatesFAILURE
) {
1071 // In the first browser, set up a page that has a beforeunload handler.
1072 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
1073 ui_test_utils::NavigateToURL(browser(), url
);
1075 // Open a second browser window at about:blank.
1076 ui_test_utils::BrowserAddedObserver browser_added_observer
;
1077 chrome::NewEmptyWindow(browser()->profile(), chrome::GetActiveDesktop());
1078 Browser
* second_window
= browser_added_observer
.WaitForSingleNewBrowser();
1079 ui_test_utils::NavigateToURL(second_window
, GURL(url::kAboutBlankURL
));
1081 // Tell the application to quit. IDC_EXIT calls AttemptUserExit, which on
1082 // everything but ChromeOS allows unload handlers to block exit. On that
1083 // platform, though, it exits unconditionally. See the comment and bug ID
1084 // in AttemptUserExit() in application_lifetime.cc.
1085 #if defined(OS_CHROMEOS)
1086 chrome::AttemptExit();
1088 chrome::ExecuteCommand(second_window
, IDC_EXIT
);
1091 // The beforeunload handler will run at exit, ensure it does, and then accept
1092 // it to allow shutdown to proceed.
1093 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
1096 static_cast<JavaScriptAppModalDialog
*>(alert
)->is_before_unload_dialog());
1097 alert
->native_dialog()->AcceptAppModalDialog();
1099 // But wait there's more! If this test times out, it likely means that the
1100 // browser has not been able to quit correctly, indicating there's a
1101 // regression of the bug noted above.
1104 // Test that scripts can fork a new renderer process for a cross-site popup,
1105 // based on http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab.
1106 // The script must open a new tab, set its window.opener to null, and navigate
1107 // it to a cross-site URL. It should also work for meta-refreshes.
1108 // See http://crbug.com/93517.
1109 IN_PROC_BROWSER_TEST_F(BrowserTest
, NullOpenerRedirectForksProcess
) {
1110 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1111 switches::kDisablePopupBlocking
);
1113 // Create http and https servers for a cross-site transition.
1114 ASSERT_TRUE(test_server()->Start());
1115 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
1116 net::SpawnedTestServer::kLocalhost
,
1117 base::FilePath(kDocRoot
));
1118 ASSERT_TRUE(https_test_server
.Start());
1119 GURL
http_url(test_server()->GetURL("files/title1.html"));
1120 GURL
https_url(https_test_server
.GetURL(std::string()));
1122 // Start with an http URL.
1123 ui_test_utils::NavigateToURL(browser(), http_url
);
1124 WebContents
* oldtab
= browser()->tab_strip_model()->GetActiveWebContents();
1125 content::RenderProcessHost
* process
= oldtab
->GetRenderProcessHost();
1127 // Now open a tab to a blank page, set its opener to null, and redirect it
1129 std::string redirect_popup
= "w=window.open();";
1130 redirect_popup
+= "w.opener=null;";
1131 redirect_popup
+= "w.document.location=\"";
1132 redirect_popup
+= https_url
.spec();
1133 redirect_popup
+= "\";";
1135 content::WindowedNotificationObserver
popup_observer(
1136 chrome::NOTIFICATION_TAB_ADDED
,
1137 content::NotificationService::AllSources());
1138 content::WindowedNotificationObserver
nav_observer(
1139 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1140 content::NotificationService::AllSources());
1141 oldtab
->GetMainFrame()->
1142 ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(redirect_popup
));
1144 // Wait for popup window to appear and finish navigating.
1145 popup_observer
.Wait();
1146 ASSERT_EQ(2, browser()->tab_strip_model()->count());
1147 WebContents
* newtab
= browser()->tab_strip_model()->GetActiveWebContents();
1148 EXPECT_TRUE(newtab
);
1149 EXPECT_NE(oldtab
, newtab
);
1150 nav_observer
.Wait();
1151 ASSERT_TRUE(newtab
->GetController().GetLastCommittedEntry());
1152 EXPECT_EQ(https_url
.spec(),
1153 newtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
1155 // Popup window should not be in the opener's process.
1156 content::RenderProcessHost
* popup_process
=
1157 newtab
->GetRenderProcessHost();
1158 EXPECT_NE(process
, popup_process
);
1160 // Now open a tab to a blank page, set its opener to null, and use a
1161 // meta-refresh to navigate it instead.
1162 std::string refresh_popup
= "w=window.open();";
1163 refresh_popup
+= "w.opener=null;";
1164 refresh_popup
+= "w.document.write(";
1165 refresh_popup
+= "'<META HTTP-EQUIV=\"refresh\" content=\"0; url=";
1166 refresh_popup
+= https_url
.spec();
1167 refresh_popup
+= "\">');w.document.close();";
1169 content::WindowedNotificationObserver
popup_observer2(
1170 chrome::NOTIFICATION_TAB_ADDED
,
1171 content::NotificationService::AllSources());
1172 content::WindowedNotificationObserver
nav_observer2(
1173 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1174 content::NotificationService::AllSources());
1175 oldtab
->GetMainFrame()->
1176 ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(refresh_popup
));
1178 // Wait for popup window to appear and finish navigating.
1179 popup_observer2
.Wait();
1180 ASSERT_EQ(3, browser()->tab_strip_model()->count());
1181 WebContents
* newtab2
= browser()->tab_strip_model()->GetActiveWebContents();
1182 EXPECT_TRUE(newtab2
);
1183 EXPECT_NE(oldtab
, newtab2
);
1184 nav_observer2
.Wait();
1185 ASSERT_TRUE(newtab2
->GetController().GetLastCommittedEntry());
1186 EXPECT_EQ(https_url
.spec(),
1187 newtab2
->GetController().GetLastCommittedEntry()->GetURL().spec());
1189 // This popup window should also not be in the opener's process.
1190 content::RenderProcessHost
* popup_process2
=
1191 newtab2
->GetRenderProcessHost();
1192 EXPECT_NE(process
, popup_process2
);
1195 // Tests that other popup navigations that do not follow the steps at
1196 // http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab will not
1197 // fork a new renderer process.
1198 IN_PROC_BROWSER_TEST_F(BrowserTest
, OtherRedirectsDontForkProcess
) {
1199 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1200 switches::kDisablePopupBlocking
);
1202 // Create http and https servers for a cross-site transition.
1203 ASSERT_TRUE(test_server()->Start());
1204 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
1205 net::SpawnedTestServer::kLocalhost
,
1206 base::FilePath(kDocRoot
));
1207 ASSERT_TRUE(https_test_server
.Start());
1208 GURL
http_url(test_server()->GetURL("files/title1.html"));
1209 GURL
https_url(https_test_server
.GetURL(std::string()));
1211 // Start with an http URL.
1212 ui_test_utils::NavigateToURL(browser(), http_url
);
1213 WebContents
* oldtab
= browser()->tab_strip_model()->GetActiveWebContents();
1214 content::RenderProcessHost
* process
= oldtab
->GetRenderProcessHost();
1216 // Now open a tab to a blank page, set its opener to null, and redirect it
1218 std::string dont_fork_popup
= "w=window.open();";
1219 dont_fork_popup
+= "w.document.location=\"";
1220 dont_fork_popup
+= https_url
.spec();
1221 dont_fork_popup
+= "\";";
1223 content::WindowedNotificationObserver
popup_observer(
1224 chrome::NOTIFICATION_TAB_ADDED
,
1225 content::NotificationService::AllSources());
1226 content::WindowedNotificationObserver
nav_observer(
1227 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1228 content::NotificationService::AllSources());
1229 oldtab
->GetMainFrame()->
1230 ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(dont_fork_popup
));
1232 // Wait for popup window to appear and finish navigating.
1233 popup_observer
.Wait();
1234 ASSERT_EQ(2, browser()->tab_strip_model()->count());
1235 WebContents
* newtab
= browser()->tab_strip_model()->GetActiveWebContents();
1236 EXPECT_TRUE(newtab
);
1237 EXPECT_NE(oldtab
, newtab
);
1238 nav_observer
.Wait();
1239 ASSERT_TRUE(newtab
->GetController().GetLastCommittedEntry());
1240 EXPECT_EQ(https_url
.spec(),
1241 newtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
1243 // Popup window should still be in the opener's process.
1244 content::RenderProcessHost
* popup_process
=
1245 newtab
->GetRenderProcessHost();
1246 EXPECT_EQ(process
, popup_process
);
1248 // Same thing if the current tab tries to navigate itself.
1249 std::string navigate_str
= "document.location=\"";
1250 navigate_str
+= https_url
.spec();
1251 navigate_str
+= "\";";
1253 content::WindowedNotificationObserver
nav_observer2(
1254 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1255 content::NotificationService::AllSources());
1256 oldtab
->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
1257 ASCIIToUTF16(navigate_str
));
1258 nav_observer2
.Wait();
1259 ASSERT_TRUE(oldtab
->GetController().GetLastCommittedEntry());
1260 EXPECT_EQ(https_url
.spec(),
1261 oldtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
1263 // Original window should still be in the original process.
1264 content::RenderProcessHost
* new_process
= newtab
->GetRenderProcessHost();
1265 EXPECT_EQ(process
, new_process
);
1268 // Test that get_process_idle_time() returns reasonable values when compared
1269 // with time deltas measured locally.
1270 IN_PROC_BROWSER_TEST_F(BrowserTest
, RenderIdleTime
) {
1271 base::TimeTicks start
= base::TimeTicks::Now();
1272 ui_test_utils::NavigateToURL(
1273 browser(), ui_test_utils::GetTestUrl(
1274 base::FilePath(base::FilePath::kCurrentDirectory
),
1275 base::FilePath(kTitle1File
)));
1276 content::RenderProcessHost::iterator
it(
1277 content::RenderProcessHost::AllHostsIterator());
1278 for (; !it
.IsAtEnd(); it
.Advance()) {
1279 base::TimeDelta renderer_td
=
1280 it
.GetCurrentValue()->GetChildProcessIdleTime();
1281 base::TimeDelta browser_td
= base::TimeTicks::Now() - start
;
1282 EXPECT_TRUE(browser_td
>= renderer_td
);
1286 // Test IDC_CREATE_SHORTCUTS command is enabled for url scheme file, ftp, http
1287 // and https and disabled for chrome://, about:// etc.
1288 // TODO(pinkerton): Disable app-mode in the model until we implement it
1289 // on the Mac. http://crbug.com/13148
1290 #if !defined(OS_MACOSX)
1291 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutFile
) {
1292 CommandUpdater
* command_updater
=
1293 browser()->command_controller()->command_updater();
1295 static const base::FilePath::CharType
* kEmptyFile
=
1296 FILE_PATH_LITERAL("empty.html");
1297 GURL
file_url(ui_test_utils::GetTestUrl(base::FilePath(
1298 base::FilePath::kCurrentDirectory
), base::FilePath(kEmptyFile
)));
1299 ASSERT_TRUE(file_url
.SchemeIs(url::kFileScheme
));
1300 ui_test_utils::NavigateToURL(browser(), file_url
);
1301 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1304 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutHttp
) {
1305 CommandUpdater
* command_updater
=
1306 browser()->command_controller()->command_updater();
1308 ASSERT_TRUE(test_server()->Start());
1309 GURL
http_url(test_server()->GetURL(std::string()));
1310 ASSERT_TRUE(http_url
.SchemeIs(url::kHttpScheme
));
1311 ui_test_utils::NavigateToURL(browser(), http_url
);
1312 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1315 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutHttps
) {
1316 CommandUpdater
* command_updater
=
1317 browser()->command_controller()->command_updater();
1319 net::SpawnedTestServer
test_server(net::SpawnedTestServer::TYPE_HTTPS
,
1320 net::SpawnedTestServer::kLocalhost
,
1321 base::FilePath(kDocRoot
));
1322 ASSERT_TRUE(test_server
.Start());
1323 GURL
https_url(test_server
.GetURL("/"));
1324 ASSERT_TRUE(https_url
.SchemeIs(url::kHttpsScheme
));
1325 ui_test_utils::NavigateToURL(browser(), https_url
);
1326 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1329 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutFtp
) {
1330 CommandUpdater
* command_updater
=
1331 browser()->command_controller()->command_updater();
1333 net::SpawnedTestServer
test_server(net::SpawnedTestServer::TYPE_FTP
,
1334 net::SpawnedTestServer::kLocalhost
,
1335 base::FilePath(kDocRoot
));
1336 ASSERT_TRUE(test_server
.Start());
1337 GURL
ftp_url(test_server
.GetURL(std::string()));
1338 ASSERT_TRUE(ftp_url
.SchemeIs(url::kFtpScheme
));
1339 ui_test_utils::NavigateToURL(browser(), ftp_url
);
1340 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1343 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutInvalid
) {
1344 CommandUpdater
* command_updater
=
1345 browser()->command_controller()->command_updater();
1347 // Urls that should not have shortcuts.
1348 GURL
new_tab_url(chrome::kChromeUINewTabURL
);
1349 ui_test_utils::NavigateToURL(browser(), new_tab_url
);
1350 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1352 GURL
history_url(chrome::kChromeUIHistoryURL
);
1353 ui_test_utils::NavigateToURL(browser(), history_url
);
1354 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1356 GURL
blank_url(url::kAboutBlankURL
);
1357 ui_test_utils::NavigateToURL(browser(), blank_url
);
1358 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1361 // Change a tab into an application window.
1362 // DISABLED: http://crbug.com/72310
1363 IN_PROC_BROWSER_TEST_F(BrowserTest
, DISABLED_ConvertTabToAppShortcut
) {
1364 ASSERT_TRUE(test_server()->Start());
1365 GURL
http_url(test_server()->GetURL(std::string()));
1366 ASSERT_TRUE(http_url
.SchemeIs(url::kHttpScheme
));
1368 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1369 WebContents
* initial_tab
= browser()->tab_strip_model()->GetWebContentsAt(0);
1370 WebContents
* app_tab
= chrome::AddSelectedTabWithURL(
1371 browser(), http_url
, ui::PAGE_TRANSITION_TYPED
);
1372 ASSERT_EQ(2, browser()->tab_strip_model()->count());
1373 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
1374 browser()->host_desktop_type()));
1376 // Normal tabs should accept load drops.
1377 EXPECT_TRUE(initial_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1378 EXPECT_TRUE(app_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1380 // Turn |app_tab| into a tab in an app panel.
1381 chrome::ConvertTabToAppWindow(browser(), app_tab
);
1383 // The launch should have created a new browser.
1384 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1385 browser()->host_desktop_type()));
1387 // Find the new browser.
1388 Browser
* app_browser
= NULL
;
1389 for (chrome::BrowserIterator it
; !it
.done() && !app_browser
; it
.Next()) {
1390 if (*it
!= browser())
1393 ASSERT_TRUE(app_browser
);
1395 // Check that the tab contents is in the new browser, and not in the old.
1396 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1397 ASSERT_EQ(initial_tab
, browser()->tab_strip_model()->GetWebContentsAt(0));
1399 // Check that the appliaction browser has a single tab, and that tab contains
1400 // the content that we app-ified.
1401 ASSERT_EQ(1, app_browser
->tab_strip_model()->count());
1402 ASSERT_EQ(app_tab
, app_browser
->tab_strip_model()->GetWebContentsAt(0));
1404 // Normal tabs should accept load drops.
1405 EXPECT_TRUE(initial_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1407 // The tab in an app window should not.
1408 EXPECT_FALSE(app_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1411 #endif // !defined(OS_MACOSX)
1413 // Test RenderView correctly send back favicon url for web page that redirects
1414 // to an anchor in javascript body.onload handler.
1415 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1416 DISABLED_FaviconOfOnloadRedirectToAnchorPage
) {
1417 ASSERT_TRUE(test_server()->Start());
1418 GURL
url(test_server()->GetURL("files/onload_redirect_to_anchor.html"));
1419 GURL
expected_favicon_url(test_server()->GetURL("files/test.png"));
1421 ui_test_utils::NavigateToURL(browser(), url
);
1423 NavigationEntry
* entry
= browser()->tab_strip_model()->
1424 GetActiveWebContents()->GetController().GetLastCommittedEntry();
1425 EXPECT_EQ(expected_favicon_url
.spec(), entry
->GetFavicon().url
.spec());
1428 #if defined(OS_MACOSX) || defined(OS_LINUX) || defined (OS_WIN)
1429 // http://crbug.com/83828. On Mac 10.6, the failure rate is 14%
1430 #define MAYBE_FaviconChange DISABLED_FaviconChange
1432 #define MAYBE_FaviconChange FaviconChange
1434 // Test that an icon can be changed from JS.
1435 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_FaviconChange
) {
1436 static const base::FilePath::CharType
* kFile
=
1437 FILE_PATH_LITERAL("onload_change_favicon.html");
1438 GURL
file_url(ui_test_utils::GetTestUrl(base::FilePath(
1439 base::FilePath::kCurrentDirectory
), base::FilePath(kFile
)));
1440 ASSERT_TRUE(file_url
.SchemeIs(url::kFileScheme
));
1441 ui_test_utils::NavigateToURL(browser(), file_url
);
1443 NavigationEntry
* entry
= browser()->tab_strip_model()->
1444 GetActiveWebContents()->GetController().GetLastCommittedEntry();
1445 static const base::FilePath::CharType
* kIcon
=
1446 FILE_PATH_LITERAL("test1.png");
1447 GURL
expected_favicon_url(ui_test_utils::GetTestUrl(base::FilePath(
1448 base::FilePath::kCurrentDirectory
), base::FilePath(kIcon
)));
1449 EXPECT_EQ(expected_favicon_url
.spec(), entry
->GetFavicon().url
.spec());
1452 // http://crbug.com/172336
1454 #define MAYBE_TabClosingWhenRemovingExtension \
1455 DISABLED_TabClosingWhenRemovingExtension
1457 #define MAYBE_TabClosingWhenRemovingExtension TabClosingWhenRemovingExtension
1459 // Makes sure TabClosing is sent when uninstalling an extension that is an app
1461 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_TabClosingWhenRemovingExtension
) {
1462 ASSERT_TRUE(test_server()->Start());
1463 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1464 GURL
url(test_server()->GetURL("empty.html"));
1465 TabStripModel
* model
= browser()->tab_strip_model();
1467 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1469 const Extension
* extension_app
= GetExtension();
1471 ui_test_utils::NavigateToURL(browser(), url
);
1473 WebContents
* app_contents
= WebContents::Create(
1474 WebContents::CreateParams(browser()->profile()));
1475 extensions::TabHelper::CreateForWebContents(app_contents
);
1476 extensions::TabHelper
* extensions_tab_helper
=
1477 extensions::TabHelper::FromWebContents(app_contents
);
1478 extensions_tab_helper
->SetExtensionApp(extension_app
);
1480 model
->AddWebContents(app_contents
, 0, ui::PageTransitionFromInt(0),
1481 TabStripModel::ADD_NONE
);
1482 model
->SetTabPinned(0, true);
1483 ui_test_utils::NavigateToURL(browser(), url
);
1485 MockTabStripModelObserver observer
;
1486 model
->AddObserver(&observer
);
1488 // Uninstall the extension and make sure TabClosing is sent.
1489 ExtensionService
* service
= extensions::ExtensionSystem::Get(
1490 browser()->profile())->extension_service();
1491 service
->UninstallExtension(GetExtension()->id(),
1492 extensions::UNINSTALL_REASON_FOR_TESTING
,
1493 base::Bind(&base::DoNothing
),
1495 EXPECT_EQ(1, observer
.closing_count());
1497 model
->RemoveObserver(&observer
);
1499 // There should only be one tab now.
1500 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1503 // Open with --app-id=<id>, and see that an application tab opens by default.
1504 IN_PROC_BROWSER_TEST_F(BrowserTest
, AppIdSwitch
) {
1505 ASSERT_TRUE(test_server()->Start());
1507 // There should be one tab to start with.
1508 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1511 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1512 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1513 const Extension
* extension_app
= GetExtension();
1515 base::CommandLine
command_line(base::CommandLine::NO_PROGRAM
);
1516 command_line
.AppendSwitchASCII(switches::kAppId
, extension_app
->id());
1518 chrome::startup::IsFirstRun first_run
= first_run::IsChromeFirstRun() ?
1519 chrome::startup::IS_FIRST_RUN
: chrome::startup::IS_NOT_FIRST_RUN
;
1520 StartupBrowserCreatorImpl
launch(base::FilePath(), command_line
, first_run
);
1522 bool new_bookmark_apps_enabled
= extensions::util::IsNewBookmarkAppsEnabled();
1524 // If the new bookmark app flow is enabled, the app should open as an tab.
1525 // Otherwise the app should open as an app window.
1526 EXPECT_EQ(!new_bookmark_apps_enabled
,
1527 launch
.OpenApplicationWindow(browser()->profile()));
1528 EXPECT_EQ(new_bookmark_apps_enabled
,
1529 launch
.OpenApplicationTab(browser()->profile()));
1531 // Check that a the number of browsers and tabs is correct.
1532 unsigned int expected_browsers
= 1;
1533 int expected_tabs
= 1;
1534 new_bookmark_apps_enabled
? expected_tabs
++ : expected_browsers
++;
1536 EXPECT_EQ(expected_browsers
,
1537 chrome::GetBrowserCount(browser()->profile(),
1538 browser()->host_desktop_type()));
1539 EXPECT_EQ(expected_tabs
, browser()->tab_strip_model()->count());
1542 // Open an app window and the dev tools window and ensure that the location
1543 // bar settings are correct.
1544 IN_PROC_BROWSER_TEST_F(BrowserTest
, ShouldShowLocationBar
) {
1545 ASSERT_TRUE(test_server()->Start());
1548 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1549 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1550 const Extension
* extension_app
= GetExtension();
1552 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1553 WebContents
* app_window
= OpenApplication(AppLaunchParams(
1554 browser()->profile(), extension_app
, extensions::LAUNCH_CONTAINER_WINDOW
,
1555 NEW_WINDOW
, extensions::SOURCE_TEST
));
1556 ASSERT_TRUE(app_window
);
1558 DevToolsWindow
* devtools_window
=
1559 DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), false);
1561 // The launch should have created a new app browser and a dev tools browser.
1563 chrome::GetBrowserCount(browser()->profile(),
1564 browser()->host_desktop_type()));
1566 // Find the new browsers.
1567 Browser
* app_browser
= NULL
;
1568 Browser
* dev_tools_browser
= NULL
;
1569 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1570 if (*it
== browser()) {
1572 } else if ((*it
)->app_name() == DevToolsWindow::kDevToolsApp
) {
1573 dev_tools_browser
= *it
;
1578 ASSERT_TRUE(dev_tools_browser
);
1579 ASSERT_TRUE(app_browser
);
1580 ASSERT_TRUE(app_browser
!= browser());
1583 dev_tools_browser
->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR
));
1585 // App windows can show location bars, for example when they navigate away
1586 // from their starting origin.
1588 app_browser
->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR
));
1590 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window
);
1593 // Tests that the CLD (Compact Language Detection) works properly.
1594 IN_PROC_BROWSER_TEST_F(BrowserTest
, PageLanguageDetection
) {
1595 scoped_ptr
<test::CldDataHarness
> cld_data_harness
=
1596 test::CldDataHarnessFactory::Get()->CreateCldDataHarness();
1597 ASSERT_NO_FATAL_FAILURE(cld_data_harness
->Init());
1598 ASSERT_TRUE(test_server()->Start());
1600 translate::LanguageDetectionDetails details
;
1602 // Open a new tab with a page in English.
1603 AddTabAtIndex(0, GURL(test_server()->GetURL("files/english_page.html")),
1604 ui::PAGE_TRANSITION_TYPED
);
1606 WebContents
* current_web_contents
=
1607 browser()->tab_strip_model()->GetActiveWebContents();
1608 ChromeTranslateClient
* chrome_translate_client
=
1609 ChromeTranslateClient::FromWebContents(current_web_contents
);
1610 content::Source
<WebContents
> source(current_web_contents
);
1612 ui_test_utils::WindowedNotificationObserverWithDetails
<
1613 translate::LanguageDetectionDetails
>
1614 en_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED
,
1617 chrome_translate_client
->GetLanguageState().original_language());
1618 en_language_detected_signal
.Wait();
1619 EXPECT_TRUE(en_language_detected_signal
.GetDetailsFor(
1620 source
.map_key(), &details
));
1621 EXPECT_EQ("en", details
.adopted_language
);
1623 chrome_translate_client
->GetLanguageState().original_language());
1625 // Now navigate to a page in French.
1626 ui_test_utils::WindowedNotificationObserverWithDetails
<
1627 translate::LanguageDetectionDetails
>
1628 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED
,
1630 ui_test_utils::NavigateToURL(
1631 browser(), GURL(test_server()->GetURL("files/french_page.html")));
1632 fr_language_detected_signal
.Wait();
1633 details
.adopted_language
.clear();
1634 EXPECT_TRUE(fr_language_detected_signal
.GetDetailsFor(
1635 source
.map_key(), &details
));
1636 EXPECT_EQ("fr", details
.adopted_language
);
1638 chrome_translate_client
->GetLanguageState().original_language());
1641 // Chromeos defaults to restoring the last session, so this test isn't
1643 #if !defined(OS_CHROMEOS)
1644 #if defined(OS_MACOSX)
1645 // Crashy, http://crbug.com/38522
1646 #define RestorePinnedTabs DISABLED_RestorePinnedTabs
1648 // Makes sure pinned tabs are restored correctly on start.
1649 IN_PROC_BROWSER_TEST_F(BrowserTest
, RestorePinnedTabs
) {
1650 ASSERT_TRUE(test_server()->Start());
1652 // Add a pinned tab.
1653 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1654 GURL
url(test_server()->GetURL("empty.html"));
1655 TabStripModel
* model
= browser()->tab_strip_model();
1656 ui_test_utils::NavigateToURL(browser(), url
);
1657 model
->SetTabPinned(0, true);
1659 // Add a non pinned tab.
1660 chrome::NewTab(browser());
1661 ui_test_utils::NavigateToURL(browser(), url
);
1663 // Add another pinned tab.
1664 chrome::NewTab(browser());
1665 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL
));
1666 model
->SetTabPinned(2, true);
1668 // Write out the pinned tabs.
1669 PinnedTabCodec::WritePinnedTabs(browser()->profile());
1671 // Simulate launching again.
1672 base::CommandLine
dummy(base::CommandLine::NO_PROGRAM
);
1673 chrome::startup::IsFirstRun first_run
= first_run::IsChromeFirstRun() ?
1674 chrome::startup::IS_FIRST_RUN
: chrome::startup::IS_NOT_FIRST_RUN
;
1675 StartupBrowserCreatorImpl
launch(base::FilePath(), dummy
, first_run
);
1676 launch
.profile_
= browser()->profile();
1677 launch
.ProcessStartupURLs(std::vector
<GURL
>(),
1678 browser()->host_desktop_type());
1680 // The launch should have created a new browser.
1681 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1682 browser()->host_desktop_type()));
1684 // Find the new browser.
1685 Browser
* new_browser
= NULL
;
1686 for (chrome::BrowserIterator it
; !it
.done() && !new_browser
; it
.Next()) {
1687 if (*it
!= browser())
1690 ASSERT_TRUE(new_browser
);
1691 ASSERT_TRUE(new_browser
!= browser());
1693 // We should get back an additional tab for the app, and another for the
1694 // default home page.
1695 ASSERT_EQ(3, new_browser
->tab_strip_model()->count());
1697 // Make sure the state matches.
1698 TabStripModel
* new_model
= new_browser
->tab_strip_model();
1699 EXPECT_TRUE(new_model
->IsTabPinned(0));
1700 EXPECT_TRUE(new_model
->IsTabPinned(1));
1701 EXPECT_FALSE(new_model
->IsTabPinned(2));
1703 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL
),
1704 new_model
->GetWebContentsAt(2)->GetURL());
1706 #endif // !defined(OS_CHROMEOS)
1708 // This test verifies we don't crash when closing the last window and the app
1710 IN_PROC_BROWSER_TEST_F(BrowserTest
, CloseWithAppMenuOpen
) {
1711 if (browser_defaults::kBrowserAliveWithNoWindows
)
1714 // We need a message loop running for menus on windows.
1715 base::MessageLoop::current()->task_runner()->PostTask(
1716 FROM_HERE
, base::Bind(&RunCloseWithAppMenuCallback
, browser()));
1719 #if !defined(OS_MACOSX)
1720 IN_PROC_BROWSER_TEST_F(BrowserTest
, OpenAppWindowLikeNtp
) {
1721 ASSERT_TRUE(test_server()->Start());
1724 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1725 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1726 const Extension
* extension_app
= GetExtension();
1728 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1729 WebContents
* app_window
= OpenApplication(AppLaunchParams(
1730 browser()->profile(), extension_app
, extensions::LAUNCH_CONTAINER_WINDOW
,
1731 NEW_WINDOW
, extensions::SOURCE_TEST
));
1732 ASSERT_TRUE(app_window
);
1734 // Apps launched in a window from the NTP have an extensions tab helper but
1735 // do not have extension_app set in it.
1736 ASSERT_TRUE(extensions::TabHelper::FromWebContents(app_window
));
1738 extensions::TabHelper::FromWebContents(app_window
)->extension_app());
1739 EXPECT_EQ(extensions::AppLaunchInfo::GetFullLaunchURL(extension_app
),
1740 app_window
->GetURL());
1742 // The launch should have created a new browser.
1743 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1744 browser()->host_desktop_type()));
1746 // Find the new browser.
1747 Browser
* new_browser
= NULL
;
1748 for (chrome::BrowserIterator it
; !it
.done() && !new_browser
; it
.Next()) {
1749 if (*it
!= browser())
1752 ASSERT_TRUE(new_browser
);
1753 ASSERT_TRUE(new_browser
!= browser());
1755 EXPECT_TRUE(new_browser
->is_app());
1757 // The browser's app name should include the extension's id.
1758 std::string app_name
= new_browser
->app_name_
;
1759 EXPECT_NE(app_name
.find(extension_app
->id()), std::string::npos
)
1760 << "Name " << app_name
<< " should contain id "<< extension_app
->id();
1762 #endif // !defined(OS_MACOSX)
1764 // Makes sure the browser doesn't crash when
1765 // set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked.
1766 IN_PROC_BROWSER_TEST_F(BrowserTest
, StartMaximized
) {
1767 Browser::Type types
[] = { Browser::TYPE_TABBED
, Browser::TYPE_POPUP
};
1768 for (size_t i
= 0; i
< arraysize(types
); ++i
) {
1769 Browser::CreateParams
params(types
[i
], browser()->profile(),
1770 browser()->host_desktop_type());
1771 params
.initial_show_state
= ui::SHOW_STATE_MAXIMIZED
;
1772 AddBlankTabAndShow(new Browser(params
));
1776 // Aura doesn't support minimized window. crbug.com/104571.
1777 #if defined(USE_AURA)
1778 #define MAYBE_StartMinimized DISABLED_StartMinimized
1780 #define MAYBE_StartMinimized StartMinimized
1782 // Makes sure the browser doesn't crash when
1783 // set_show_state(ui::SHOW_STATE_MINIMIZED) has been invoked.
1784 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_StartMinimized
) {
1785 Browser::Type types
[] = { Browser::TYPE_TABBED
, Browser::TYPE_POPUP
};
1786 for (size_t i
= 0; i
< arraysize(types
); ++i
) {
1787 Browser::CreateParams
params(types
[i
], browser()->profile(),
1788 browser()->host_desktop_type());
1789 params
.initial_show_state
= ui::SHOW_STATE_MINIMIZED
;
1790 AddBlankTabAndShow(new Browser(params
));
1794 // Makes sure the forward button is disabled immediately when navigating
1795 // forward to a slow-to-commit page.
1796 IN_PROC_BROWSER_TEST_F(BrowserTest
, ForwardDisabledOnForward
) {
1797 GURL
blank_url(url::kAboutBlankURL
);
1798 ui_test_utils::NavigateToURL(browser(), blank_url
);
1800 ui_test_utils::NavigateToURL(
1801 browser(), ui_test_utils::GetTestUrl(
1802 base::FilePath(base::FilePath::kCurrentDirectory
),
1803 base::FilePath(kTitle1File
)));
1805 content::WindowedNotificationObserver
back_nav_load_observer(
1806 content::NOTIFICATION_LOAD_STOP
,
1807 content::Source
<NavigationController
>(
1808 &browser()->tab_strip_model()->GetActiveWebContents()->
1810 chrome::GoBack(browser(), CURRENT_TAB
);
1811 back_nav_load_observer
.Wait();
1812 CommandUpdater
* command_updater
=
1813 browser()->command_controller()->command_updater();
1814 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_FORWARD
));
1816 content::WindowedNotificationObserver
forward_nav_load_observer(
1817 content::NOTIFICATION_LOAD_STOP
,
1818 content::Source
<NavigationController
>(
1819 &browser()->tab_strip_model()->GetActiveWebContents()->
1821 chrome::GoForward(browser(), CURRENT_TAB
);
1822 // This check will happen before the navigation completes, since the browser
1823 // won't process the renderer's response until the Wait() call below.
1824 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_FORWARD
));
1825 forward_nav_load_observer
.Wait();
1828 // Makes sure certain commands are disabled when Incognito mode is forced.
1829 IN_PROC_BROWSER_TEST_F(BrowserTest
, DisableMenuItemsWhenIncognitoIsForced
) {
1830 CommandUpdater
* command_updater
=
1831 browser()->command_controller()->command_updater();
1832 // At the beginning, all commands are enabled.
1833 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1834 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1835 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1836 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1837 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1838 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1840 // Set Incognito to FORCED.
1841 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1842 IncognitoModePrefs::FORCED
);
1843 // Bookmarks & Settings commands should get disabled.
1844 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1845 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1846 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1847 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1848 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1849 // New Incognito Window command, however, should be enabled.
1850 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1852 // Create a new browser.
1853 Browser
* new_browser
=
1854 new Browser(Browser::CreateParams(
1855 browser()->profile()->GetOffTheRecordProfile(),
1856 browser()->host_desktop_type()));
1857 CommandUpdater
* new_command_updater
=
1858 new_browser
->command_controller()->command_updater();
1859 // It should have Bookmarks & Settings commands disabled by default.
1860 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1861 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(
1862 IDC_SHOW_BOOKMARK_MANAGER
));
1863 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1864 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1865 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1866 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1869 // Makes sure New Incognito Window command is disabled when Incognito mode is
1871 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1872 NoNewIncognitoWindowWhenIncognitoIsDisabled
) {
1873 CommandUpdater
* command_updater
=
1874 browser()->command_controller()->command_updater();
1875 // Set Incognito to DISABLED.
1876 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1877 IncognitoModePrefs::DISABLED
);
1878 // Make sure New Incognito Window command is disabled. All remaining commands
1879 // should be enabled.
1880 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1881 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1882 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1883 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1884 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1885 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1887 // Create a new browser.
1888 Browser
* new_browser
=
1889 new Browser(Browser::CreateParams(browser()->profile(),
1890 browser()->host_desktop_type()));
1891 CommandUpdater
* new_command_updater
=
1892 new_browser
->command_controller()->command_updater();
1893 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1894 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1895 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1896 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1897 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1898 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1901 // Makes sure Extensions and Settings commands are disabled in certain
1902 // circumstances even though normally they should stay enabled.
1903 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1904 DisableExtensionsAndSettingsWhenIncognitoIsDisabled
) {
1905 CommandUpdater
* command_updater
=
1906 browser()->command_controller()->command_updater();
1907 // Disable extensions. This should disable Extensions menu.
1908 extensions::ExtensionSystem::Get(browser()->profile())->extension_service()->
1909 set_extensions_enabled(false);
1910 // Set Incognito to DISABLED.
1911 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1912 IncognitoModePrefs::DISABLED
);
1913 // Make sure Manage Extensions command is disabled.
1914 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1915 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1916 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1917 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1918 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1920 // Create a popup (non-main-UI-type) browser. Settings command as well
1921 // as Extensions should be disabled.
1922 Browser
* popup_browser
= new Browser(
1923 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
1924 browser()->host_desktop_type()));
1925 CommandUpdater
* popup_command_updater
=
1926 popup_browser
->command_controller()->command_updater();
1927 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1928 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1929 EXPECT_TRUE(popup_command_updater
->IsCommandEnabled(
1930 IDC_SHOW_BOOKMARK_MANAGER
));
1931 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1934 // Makes sure Extensions and Settings commands are disabled in certain
1935 // circumstances even though normally they should stay enabled.
1936 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1937 DisableOptionsAndImportMenuItemsConsistently
) {
1938 // Create a popup browser.
1939 Browser
* popup_browser
= new Browser(
1940 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
1941 browser()->host_desktop_type()));
1942 CommandUpdater
* command_updater
=
1943 popup_browser
->command_controller()->command_updater();
1944 // OPTIONS and IMPORT_SETTINGS are disabled for a non-normal UI.
1945 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1946 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1948 // Set Incognito to FORCED.
1949 IncognitoModePrefs::SetAvailability(popup_browser
->profile()->GetPrefs(),
1950 IncognitoModePrefs::FORCED
);
1951 // OPTIONS and IMPORT_SETTINGS are disabled when Incognito is forced.
1952 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1953 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1954 // Set Incognito to AVAILABLE.
1955 IncognitoModePrefs::SetAvailability(popup_browser
->profile()->GetPrefs(),
1956 IncognitoModePrefs::ENABLED
);
1957 // OPTIONS and IMPORT_SETTINGS are still disabled since it is a non-normal UI.
1958 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1959 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1964 void OnZoomLevelChanged(const base::Closure
& callback
,
1965 const HostZoomMap::ZoomLevelChange
& host
) {
1972 // Flakes regularly on Windows XP
1973 // http://crbug.com/146040
1974 #define MAYBE_PageZoom DISABLED_PageZoom
1976 #define MAYBE_PageZoom PageZoom
1981 int GetZoomPercent(const content::WebContents
* contents
,
1983 bool* enable_minus
) {
1985 ui_zoom::ZoomController::FromWebContents(contents
)->GetZoomPercent();
1986 *enable_plus
= percent
< contents
->GetMaximumZoomPercent();
1987 *enable_minus
= percent
> contents
->GetMinimumZoomPercent();
1993 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_PageZoom
) {
1994 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
1995 bool enable_plus
, enable_minus
;
1998 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
1999 new content::MessageLoopRunner
);
2000 content::HostZoomMap::ZoomLevelChangedCallback
callback(
2001 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
2002 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
2003 content::HostZoomMap::GetDefaultForBrowserContext(
2004 browser()->profile())->AddZoomLevelChangedCallback(callback
);
2005 chrome::Zoom(browser(), content::PAGE_ZOOM_IN
);
2008 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 110);
2009 EXPECT_TRUE(enable_plus
);
2010 EXPECT_TRUE(enable_minus
);
2014 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
2015 new content::MessageLoopRunner
);
2016 content::HostZoomMap::ZoomLevelChangedCallback
callback(
2017 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
2018 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
2019 content::HostZoomMap::GetDefaultForBrowserContext(
2020 browser()->profile())->AddZoomLevelChangedCallback(callback
);
2021 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET
);
2024 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 100);
2025 EXPECT_TRUE(enable_plus
);
2026 EXPECT_TRUE(enable_minus
);
2030 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
2031 new content::MessageLoopRunner
);
2032 content::HostZoomMap::ZoomLevelChangedCallback
callback(
2033 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
2034 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
2035 content::HostZoomMap::GetDefaultForBrowserContext(
2036 browser()->profile())->AddZoomLevelChangedCallback(callback
);
2037 chrome::Zoom(browser(), content::PAGE_ZOOM_OUT
);
2040 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 90);
2041 EXPECT_TRUE(enable_plus
);
2042 EXPECT_TRUE(enable_minus
);
2045 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET
);
2048 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialCommandDisable
) {
2049 ASSERT_TRUE(test_server()->Start());
2050 host_resolver()->AddRule("www.example.com", "127.0.0.1");
2051 GURL
url(test_server()->GetURL("empty.html"));
2052 ui_test_utils::NavigateToURL(browser(), url
);
2054 CommandUpdater
* command_updater
=
2055 browser()->command_controller()->command_updater();
2056 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2057 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2058 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2059 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2060 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_DUPLICATE_TAB
));
2062 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2064 TestInterstitialPage
* interstitial
=
2065 new TestInterstitialPage(contents
, false, GURL());
2066 content::WaitForInterstitialAttach(contents
);
2068 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2070 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2071 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2072 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2073 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2074 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_DUPLICATE_TAB
));
2076 // Proceed and wait for interstitial to detach. This doesn't destroy
2078 interstitial
->Proceed();
2079 content::WaitForInterstitialDetach(contents
);
2080 // interstitial is deleted now.
2082 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2083 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2084 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2085 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2086 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_DUPLICATE_TAB
));
2089 // Ensure that creating an interstitial page closes any JavaScript dialogs
2090 // that were present on the previous page. See http://crbug.com/295695.
2091 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialClosesDialogs
) {
2092 ASSERT_TRUE(test_server()->Start());
2093 host_resolver()->AddRule("www.example.com", "127.0.0.1");
2094 GURL
url(test_server()->GetURL("empty.html"));
2095 ui_test_utils::NavigateToURL(browser(), url
);
2097 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2098 contents
->GetMainFrame()->ExecuteJavaScriptForTests(
2099 ASCIIToUTF16("alert('Dialog showing!');"));
2100 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
2101 EXPECT_TRUE(alert
->IsValid());
2102 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
2103 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
2105 TestInterstitialPage
* interstitial
=
2106 new TestInterstitialPage(contents
, false, GURL());
2107 content::WaitForInterstitialAttach(contents
);
2109 // The interstitial should have closed the dialog.
2110 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2111 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
2113 // Don't proceed and wait for interstitial to detach. This doesn't destroy
2115 interstitial
->DontProceed();
2116 content::WaitForInterstitialDetach(contents
);
2117 // interstitial is deleted now.
2119 // Make sure input events still work in the renderer process.
2120 EXPECT_FALSE(contents
->GetRenderProcessHost()->IgnoreInputEvents());
2124 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialCloseTab
) {
2125 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2127 // Interstitial will delete itself when we close the tab.
2128 new TestInterstitialPage(contents
, false, GURL());
2129 content::WaitForInterstitialAttach(contents
);
2131 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2133 // Close the tab and wait for interstitial detach. This destroys |contents|.
2134 content::RunTaskAndWaitForInterstitialDetach(
2135 contents
, base::Bind(&chrome::CloseTab
, browser()));
2136 // interstitial is deleted now.
2139 class MockWebContentsObserver
: public WebContentsObserver
{
2141 explicit MockWebContentsObserver(WebContents
* web_contents
)
2142 : WebContentsObserver(web_contents
),
2143 got_user_gesture_(false) {
2146 void DidGetUserGesture() override
{ got_user_gesture_
= true; }
2148 bool got_user_gesture() const {
2149 return got_user_gesture_
;
2152 void set_got_user_gesture(bool got_it
) {
2153 got_user_gesture_
= got_it
;
2157 bool got_user_gesture_
;
2159 DISALLOW_COPY_AND_ASSIGN(MockWebContentsObserver
);
2162 IN_PROC_BROWSER_TEST_F(BrowserTest
, UserGesturesReported
) {
2163 // Regression test for http://crbug.com/110707. Also tests that a user
2164 // gesture is sent when a normal navigation (via e.g. the omnibox) is
2166 WebContents
* web_contents
=
2167 browser()->tab_strip_model()->GetActiveWebContents();
2168 MockWebContentsObserver
mock_observer(web_contents
);
2170 ASSERT_TRUE(test_server()->Start());
2171 GURL
url(test_server()->GetURL("empty.html"));
2173 ui_test_utils::NavigateToURL(browser(), url
);
2174 EXPECT_TRUE(mock_observer
.got_user_gesture());
2176 mock_observer
.set_got_user_gesture(false);
2177 chrome::Reload(browser(), CURRENT_TAB
);
2178 EXPECT_TRUE(mock_observer
.got_user_gesture());
2181 // TODO(ben): this test was never enabled. It has bit-rotted since being added.
2182 // It originally lived in browser_unittest.cc, but has been moved here to make
2183 // room for real browser unit tests.
2185 class BrowserTest2
: public InProcessBrowserTest
{
2188 host_resolver_proc_
= new net::RuleBasedHostResolverProc(NULL
);
2189 // Avoid making external DNS lookups. In this test we don't need this
2191 host_resolver_proc_
->AddSimulatedFailure("*.google.com");
2192 scoped_host_resolver_proc_
.Init(host_resolver_proc_
.get());
2196 scoped_refptr
<net::RuleBasedHostResolverProc
> host_resolver_proc_
;
2197 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc_
;
2200 IN_PROC_BROWSER_TEST_F(BrowserTest2
, NoTabsInPopups
) {
2201 chrome::RegisterAppPrefs(L
"Test");
2203 // We start with a normal browser with one tab.
2204 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2206 // Open a popup browser with a single blank foreground tab.
2207 Browser
* popup_browser
= new Browser(
2208 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile()));
2209 chrome::AddTabAt(popup_browser
, GURL(), -1, true);
2210 EXPECT_EQ(1, popup_browser
->tab_strip_model()->count());
2212 // Now try opening another tab in the popup browser.
2213 AddTabWithURLParams
params1(url
, ui::PAGE_TRANSITION_TYPED
);
2214 popup_browser
->AddTabWithURL(¶ms1
);
2215 EXPECT_EQ(popup_browser
, params1
.target
);
2217 // The popup should still only have one tab.
2218 EXPECT_EQ(1, popup_browser
->tab_strip_model()->count());
2220 // The normal browser should now have two.
2221 EXPECT_EQ(2, browser()->tab_strip_model()->count());
2223 // Open an app frame browser with a single blank foreground tab.
2224 Browser
* app_browser
= new Browser(Browser::CreateParams::CreateForApp(
2225 L
"Test", browser()->profile(), false));
2226 chrome::AddTabAt(app_browser
, GURL(), -1, true);
2227 EXPECT_EQ(1, app_browser
->tab_strip_model()->count());
2229 // Now try opening another tab in the app browser.
2230 AddTabWithURLParams
params2(GURL(url::kAboutBlankURL
),
2231 ui::PAGE_TRANSITION_TYPED
);
2232 app_browser
->AddTabWithURL(¶ms2
);
2233 EXPECT_EQ(app_browser
, params2
.target
);
2235 // The popup should still only have one tab.
2236 EXPECT_EQ(1, app_browser
->tab_strip_model()->count());
2238 // The normal browser should now have three.
2239 EXPECT_EQ(3, browser()->tab_strip_model()->count());
2241 // Open an app frame popup browser with a single blank foreground tab.
2242 Browser
* app_popup_browser
= new Browser(Browser::CreateParams::CreateForApp(
2243 L
"Test", browser()->profile(), false));
2244 chrome::AddTabAt(app_popup_browser
, GURL(), -1, true);
2245 EXPECT_EQ(1, app_popup_browser
->tab_strip_model()->count());
2247 // Now try opening another tab in the app popup browser.
2248 AddTabWithURLParams
params3(GURL(url::kAboutBlankURL
),
2249 ui::PAGE_TRANSITION_TYPED
);
2250 app_popup_browser
->AddTabWithURL(¶ms3
);
2251 EXPECT_EQ(app_popup_browser
, params3
.target
);
2253 // The popup should still only have one tab.
2254 EXPECT_EQ(1, app_popup_browser
->tab_strip_model()->count());
2256 // The normal browser should now have four.
2257 EXPECT_EQ(4, browser()->tab_strip_model()->count());
2259 // Close the additional browsers.
2260 popup_browser
->tab_strip_model()->CloseAllTabs();
2261 app_browser
->tab_strip_model()->CloseAllTabs();
2262 app_popup_browser
->tab_strip_model()->CloseAllTabs();
2266 IN_PROC_BROWSER_TEST_F(BrowserTest
, WindowOpenClose
) {
2267 base::CommandLine::ForCurrentProcess()->AppendSwitch(
2268 switches::kDisablePopupBlocking
);
2269 GURL url
= ui_test_utils::GetTestUrl(
2270 base::FilePath(), base::FilePath().AppendASCII("window.close.html"));
2272 base::string16 title
= ASCIIToUTF16("Title Of Awesomeness");
2273 content::TitleWatcher
title_watcher(
2274 browser()->tab_strip_model()->GetActiveWebContents(), title
);
2275 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url
, 2);
2276 EXPECT_EQ(title
, title_watcher
.WaitAndGetTitle());
2279 // TODO(linux_aura) http://crbug.com/163931
2280 // Mac disabled: http://crbug.com/169820
2281 #if !defined(OS_MACOSX) && \
2282 !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
2283 IN_PROC_BROWSER_TEST_F(BrowserTest
, FullscreenBookmarkBar
) {
2284 #if defined(OS_WIN) && defined(USE_ASH)
2285 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2286 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2287 switches::kAshBrowserTests
))
2291 chrome::ToggleBookmarkBar(browser());
2292 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2293 chrome::ToggleFullscreenMode(browser());
2294 EXPECT_TRUE(browser()->window()->IsFullscreen());
2295 #if defined(OS_MACOSX)
2296 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2297 #elif defined(OS_CHROMEOS)
2298 // TODO(jamescook): If immersive fullscreen is disabled by default, test
2299 // for BookmarkBar::HIDDEN.
2300 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2302 EXPECT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2307 IN_PROC_BROWSER_TEST_F(BrowserTest
, DisallowFileUrlUniversalAccessTest
) {
2308 GURL url
= ui_test_utils::GetTestUrl(
2310 base::FilePath().AppendASCII("fileurl_universalaccess.html"));
2312 base::string16
expected_title(ASCIIToUTF16("Disallowed"));
2313 content::TitleWatcher
title_watcher(
2314 browser()->tab_strip_model()->GetActiveWebContents(), expected_title
);
2315 title_watcher
.AlsoWaitForTitle(ASCIIToUTF16("Allowed"));
2316 ui_test_utils::NavigateToURL(browser(), url
);
2317 ASSERT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
2320 class KioskModeTest
: public BrowserTest
{
2324 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2325 command_line
->AppendSwitch(switches::kKioskMode
);
2329 #if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
2330 // Mac: http://crbug.com/103912
2331 // Linux: http://crbug.com/163931
2332 #define MAYBE_EnableKioskModeTest DISABLED_EnableKioskModeTest
2334 #define MAYBE_EnableKioskModeTest EnableKioskModeTest
2336 IN_PROC_BROWSER_TEST_F(KioskModeTest
, MAYBE_EnableKioskModeTest
) {
2337 // Check if browser is in fullscreen mode.
2338 ASSERT_TRUE(browser()->window()->IsFullscreen());
2339 ASSERT_FALSE(browser()->window()->IsFullscreenBubbleVisible());
2343 // This test verifies that Chrome can be launched with a user-data-dir path
2344 // which contains non ASCII characters.
2345 class LaunchBrowserWithNonAsciiUserDatadir
: public BrowserTest
{
2347 LaunchBrowserWithNonAsciiUserDatadir() {}
2349 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2350 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
2351 base::FilePath tmp_profile
= temp_dir_
.path().AppendASCII("tmp_profile");
2352 tmp_profile
= tmp_profile
.Append(L
"Test Chrome G\u00E9raldine");
2354 ASSERT_TRUE(base::CreateDirectory(tmp_profile
));
2355 command_line
->AppendSwitchPath(switches::kUserDataDir
, tmp_profile
);
2358 base::ScopedTempDir temp_dir_
;
2361 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithNonAsciiUserDatadir
,
2362 TestNonAsciiUserDataDir
) {
2363 // Verify that the window is present.
2364 ASSERT_TRUE(browser());
2365 ASSERT_TRUE(browser()->profile());
2366 // Verify that the profile has been added correctly to the ProfileInfoCache.
2367 ASSERT_EQ(1u, g_browser_process
->profile_manager()->
2368 GetProfileInfoCache().GetNumberOfProfiles());
2370 #endif // defined(OS_WIN)
2373 // This test verifies that Chrome can be launched with a user-data-dir path
2374 // which trailing slashes.
2375 class LaunchBrowserWithTrailingSlashDatadir
: public BrowserTest
{
2377 LaunchBrowserWithTrailingSlashDatadir() {}
2379 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2380 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
2381 base::FilePath tmp_profile
= temp_dir_
.path().AppendASCII("tmp_profile");
2382 tmp_profile
= tmp_profile
.Append(L
"Test Chrome\\");
2384 ASSERT_TRUE(base::CreateDirectory(tmp_profile
));
2385 command_line
->AppendSwitchPath(switches::kUserDataDir
, tmp_profile
);
2388 base::ScopedTempDir temp_dir_
;
2391 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithTrailingSlashDatadir
,
2392 TestTrailingSlashUserDataDir
) {
2393 // Verify that the window is present.
2394 ASSERT_TRUE(browser());
2395 ASSERT_TRUE(browser()->profile());
2396 // Verify that the profile has been added correctly to the ProfileInfoCache.
2397 ASSERT_EQ(1u, g_browser_process
->profile_manager()->
2398 GetProfileInfoCache().GetNumberOfProfiles());
2400 #endif // defined(OS_WIN)
2402 // Tests to ensure that the browser continues running in the background after
2403 // the last window closes.
2404 class RunInBackgroundTest
: public BrowserTest
{
2406 RunInBackgroundTest() {}
2408 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2409 command_line
->AppendSwitch(switches::kKeepAliveForTest
);
2413 IN_PROC_BROWSER_TEST_F(RunInBackgroundTest
, RunInBackgroundBasicTest
) {
2414 // Close the browser window, then open a new one - the browser should keep
2416 Profile
* profile
= browser()->profile();
2417 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2418 content::WindowedNotificationObserver
observer(
2419 chrome::NOTIFICATION_BROWSER_CLOSED
,
2420 content::Source
<Browser
>(browser()));
2421 chrome::CloseWindow(browser());
2423 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
2425 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2426 chrome::NewEmptyWindow(profile
, chrome::GetActiveDesktop());
2427 browser_added_observer
.WaitForSingleNewBrowser();
2429 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2432 // Tests to ensure that the browser continues running in the background after
2433 // the last window closes.
2434 class NoStartupWindowTest
: public BrowserTest
{
2436 NoStartupWindowTest() {}
2438 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2439 command_line
->AppendSwitch(switches::kNoStartupWindow
);
2440 command_line
->AppendSwitch(switches::kKeepAliveForTest
);
2443 // Returns true if any commands were processed.
2444 bool ProcessedAnyCommands(
2445 sessions::BaseSessionService
* base_session_service
) {
2446 sessions::BaseSessionServiceTestHelper
test_helper(base_session_service
);
2447 return test_helper
.ProcessedAnyCommands();
2451 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest
, NoStartupWindowBasicTest
) {
2452 #if defined(OS_WIN) && defined(USE_ASH)
2453 // kNoStartupWindow doesn't make sense in Metro+Ash.
2454 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2455 switches::kAshBrowserTests
))
2459 // No browser window should be started by default.
2460 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
2462 // Starting a browser window should work just fine.
2463 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2464 CreateBrowser(ProfileManager::GetActiveUserProfile());
2465 browser_added_observer
.WaitForSingleNewBrowser();
2467 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2470 // Chromeos needs to track app windows because it considers them to be part of
2472 #if !defined(OS_CHROMEOS)
2473 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest
, DontInitSessionServiceForApps
) {
2474 #if defined(OS_WIN) && defined(USE_ASH)
2475 // kNoStartupWindow doesn't make sense in Metro+Ash.
2476 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2477 switches::kAshBrowserTests
))
2481 Profile
* profile
= ProfileManager::GetActiveUserProfile();
2483 SessionService
* session_service
=
2484 SessionServiceFactory::GetForProfile(profile
);
2485 sessions::BaseSessionService
* base_session_service
=
2486 session_service
->GetBaseSessionServiceForTest();
2487 ASSERT_FALSE(ProcessedAnyCommands(base_session_service
));
2489 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2490 CreateBrowserForApp("blah", profile
);
2491 browser_added_observer
.WaitForSingleNewBrowser();
2493 ASSERT_FALSE(ProcessedAnyCommands(base_session_service
));
2495 #endif // !defined(OS_CHROMEOS)
2497 // This test needs to be placed outside the anonymous namespace because we
2498 // need to access private type of Browser.
2499 class AppModeTest
: public BrowserTest
{
2503 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2504 GURL url
= ui_test_utils::GetTestUrl(
2505 base::FilePath(), base::FilePath().AppendASCII("title1.html"));
2506 command_line
->AppendSwitchASCII(switches::kApp
, url
.spec());
2510 IN_PROC_BROWSER_TEST_F(AppModeTest
, EnableAppModeTest
) {
2511 #if defined(OS_WIN) && defined(USE_ASH)
2512 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2513 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2514 switches::kAshBrowserTests
))
2518 // Test that an application browser window loads correctly.
2520 // Verify the browser is in application mode.
2521 EXPECT_TRUE(browser()->is_app());
2524 // Confirm chrome://version contains some expected content.
2525 IN_PROC_BROWSER_TEST_F(BrowserTest
, AboutVersion
) {
2526 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL
));
2527 WebContents
* tab
= browser()->tab_strip_model()->GetActiveWebContents();
2528 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("WebKit"), true, true,
2531 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("OS"), true, true,
2534 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("JavaScript"), true,
2539 static const base::FilePath::CharType
* kTestDir
=
2540 FILE_PATH_LITERAL("click_modifier");
2541 static const char kFirstPageTitle
[] = "First window";
2542 static const char kSecondPageTitle
[] = "New window!";
2544 class ClickModifierTest
: public InProcessBrowserTest
{
2546 ClickModifierTest() {
2549 // Returns a url that opens a new window or tab when clicked, via javascript.
2550 GURL
GetWindowOpenURL() {
2551 return ui_test_utils::GetTestUrl(
2552 base::FilePath(kTestDir
),
2553 base::FilePath(FILE_PATH_LITERAL("window_open.html")));
2556 // Returns a url that follows a simple link when clicked, unless affected by
2559 return ui_test_utils::GetTestUrl(
2560 base::FilePath(kTestDir
),
2561 base::FilePath(FILE_PATH_LITERAL("href.html")));
2564 base::string16
getFirstPageTitle() {
2565 return ASCIIToUTF16(kFirstPageTitle
);
2568 base::string16
getSecondPageTitle() {
2569 return ASCIIToUTF16(kSecondPageTitle
);
2572 // Loads our test page and simulates a single click using the supplied button
2573 // and modifiers. The click will cause either a navigation or the creation of
2574 // a new window or foreground or background tab. We verify that the expected
2575 // disposition occurs.
2576 void RunTest(Browser
* browser
,
2579 blink::WebMouseEvent::Button button
,
2580 WindowOpenDisposition disposition
) {
2581 ui_test_utils::NavigateToURL(browser
, url
);
2582 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2583 browser
->host_desktop_type()));
2584 EXPECT_EQ(1, browser
->tab_strip_model()->count());
2585 content::WebContents
* web_contents
=
2586 browser
->tab_strip_model()->GetActiveWebContents();
2587 EXPECT_EQ(url
, web_contents
->GetURL());
2589 if (disposition
== CURRENT_TAB
) {
2590 content::WebContents
* web_contents
=
2591 browser
->tab_strip_model()->GetActiveWebContents();
2592 content::TestNavigationObserver
same_tab_observer(web_contents
);
2593 SimulateMouseClick(web_contents
, modifiers
, button
);
2594 same_tab_observer
.Wait();
2595 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2596 browser
->host_desktop_type()));
2597 EXPECT_EQ(1, browser
->tab_strip_model()->count());
2598 EXPECT_EQ(getSecondPageTitle(), web_contents
->GetTitle());
2602 content::WindowedNotificationObserver
observer(
2603 chrome::NOTIFICATION_TAB_ADDED
,
2604 content::NotificationService::AllSources());
2605 SimulateMouseClick(web_contents
, modifiers
, button
);
2608 if (disposition
== NEW_WINDOW
) {
2609 EXPECT_EQ(2u, chrome::GetBrowserCount(browser
->profile(),
2610 browser
->host_desktop_type()));
2614 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2615 browser
->host_desktop_type()));
2616 EXPECT_EQ(2, browser
->tab_strip_model()->count());
2617 web_contents
= browser
->tab_strip_model()->GetActiveWebContents();
2618 WaitForLoadStop(web_contents
);
2619 if (disposition
== NEW_FOREGROUND_TAB
) {
2620 EXPECT_EQ(getSecondPageTitle(), web_contents
->GetTitle());
2622 ASSERT_EQ(NEW_BACKGROUND_TAB
, disposition
);
2623 EXPECT_EQ(getFirstPageTitle(), web_contents
->GetTitle());
2628 DISALLOW_COPY_AND_ASSIGN(ClickModifierTest
);
2631 // Tests for clicking on elements with handlers that run window.open.
2633 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenBasicClickTest
) {
2635 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2636 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2637 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2640 // TODO(ericu): Alt-click behavior on window.open is platform-dependent and not
2641 // well defined. Should we add tests so we know if it changes?
2643 // Shift-clicks open in a new window.
2644 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenShiftClickTest
) {
2645 int modifiers
= blink::WebInputEvent::ShiftKey
;
2646 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2647 WindowOpenDisposition disposition
= NEW_WINDOW
;
2648 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2651 // Control-clicks open in a background tab.
2652 // On OSX meta [the command key] takes the place of control.
2653 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenControlClickTest
) {
2654 #if defined(OS_MACOSX)
2655 int modifiers
= blink::WebInputEvent::MetaKey
;
2657 int modifiers
= blink::WebInputEvent::ControlKey
;
2659 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2660 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2661 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2664 // Control-shift-clicks open in a foreground tab.
2665 // On OSX meta [the command key] takes the place of control.
2666 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenControlShiftClickTest
) {
2667 #if defined(OS_MACOSX)
2668 int modifiers
= blink::WebInputEvent::MetaKey
;
2670 int modifiers
= blink::WebInputEvent::ControlKey
;
2672 modifiers
|= blink::WebInputEvent::ShiftKey
;
2673 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2674 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2675 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2678 // Middle-clicks open in a background tab.
2679 #if defined(OS_LINUX)
2680 // http://crbug.com/396347
2681 #define MAYBE_WindowOpenMiddleClickTest DISABLED_WindowOpenMiddleClickTest
2683 #define MAYBE_WindowOpenMiddleClickTest WindowOpenMiddleClickTest
2685 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, MAYBE_WindowOpenMiddleClickTest
) {
2687 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2688 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2689 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2692 // Shift-middle-clicks open in a foreground tab.
2693 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenShiftMiddleClickTest
) {
2694 int modifiers
= blink::WebInputEvent::ShiftKey
;
2695 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2696 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2697 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2700 // Tests for clicking on normal links.
2702 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefBasicClickTest
) {
2704 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2705 WindowOpenDisposition disposition
= CURRENT_TAB
;
2706 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2709 // TODO(ericu): Alt-click behavior on links is platform-dependent and not well
2710 // defined. Should we add tests so we know if it changes?
2712 // Shift-clicks open in a new window.
2713 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefShiftClickTest
) {
2714 int modifiers
= blink::WebInputEvent::ShiftKey
;
2715 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2716 WindowOpenDisposition disposition
= NEW_WINDOW
;
2717 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2720 // Control-clicks open in a background tab.
2721 // On OSX meta [the command key] takes the place of control.
2722 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefControlClickTest
) {
2723 #if defined(OS_MACOSX)
2724 int modifiers
= blink::WebInputEvent::MetaKey
;
2726 int modifiers
= blink::WebInputEvent::ControlKey
;
2728 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2729 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2730 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2733 // Control-shift-clicks open in a foreground tab.
2734 // On OSX meta [the command key] takes the place of control.
2735 // http://crbug.com/396347
2736 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, DISABLED_HrefControlShiftClickTest
) {
2737 #if defined(OS_MACOSX)
2738 int modifiers
= blink::WebInputEvent::MetaKey
;
2740 int modifiers
= blink::WebInputEvent::ControlKey
;
2742 modifiers
|= blink::WebInputEvent::ShiftKey
;
2743 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2744 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2745 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2748 // Middle-clicks open in a background tab.
2749 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefMiddleClickTest
) {
2751 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2752 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2753 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2756 // Shift-middle-clicks open in a foreground tab.
2757 // http://crbug.com/396347
2758 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, DISABLED_HrefShiftMiddleClickTest
) {
2759 int modifiers
= blink::WebInputEvent::ShiftKey
;
2760 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2761 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2762 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2765 IN_PROC_BROWSER_TEST_F(BrowserTest
, GetSizeForNewRenderView
) {
2766 #if defined(OS_MACOSX) && !defined(OS_IOS)
2767 // TODO(erikchen): This behavior has regressed on OSX 10.7 and 10.8 and should
2768 // be fixed. http://crbug.com/503185
2769 if (base::mac::IsOSMountainLion() || base::mac::IsOSLion())
2771 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
2772 // The instant extended NTP has javascript that does not work with
2773 // ui_test_utils::NavigateToURL. The NTP rvh reloads when the browser tries
2774 // to navigate away from the page, which causes the WebContents to end up in
2775 // an inconsistent state. (is_loaded = true, last_commited_url=ntp,
2776 // visible_url=title1.html)
2777 browser()->profile()->GetPrefs()->SetBoolean(prefs::kWebKitJavascriptEnabled
,
2779 ASSERT_TRUE(test_server()->Start());
2780 // Create an HTTPS server for cross-site transition.
2781 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
2782 net::SpawnedTestServer::kLocalhost
,
2783 base::FilePath(kDocRoot
));
2784 ASSERT_TRUE(https_test_server
.Start());
2787 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
2788 ASSERT_EQ(BookmarkBar::DETACHED
, browser()->bookmark_bar_state());
2789 WebContents
* web_contents
=
2790 browser()->tab_strip_model()->GetActiveWebContents();
2791 content::RenderViewHost
* prev_rvh
= web_contents
->GetRenderViewHost();
2792 const int height_inset
=
2793 browser()->window()->GetRenderViewHeightInsetWithDetachedBookmarkBar();
2794 const gfx::Size initial_wcv_size
=
2795 web_contents
->GetContainerBounds().size();
2796 RenderViewSizeObserver
observer(web_contents
, browser()->window());
2798 // Navigate to a non-NTP page, without resizing WebContentsView.
2799 ui_test_utils::NavigateToURL(browser(),
2800 test_server()->GetURL("files/title1.html"));
2801 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2802 // A new RenderViewHost should be created.
2803 EXPECT_NE(prev_rvh
, web_contents
->GetRenderViewHost());
2804 prev_rvh
= web_contents
->GetRenderViewHost();
2805 gfx::Size rwhv_create_size0
, rwhv_commit_size0
, wcv_commit_size0
;
2806 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2810 // The create height of RenderWidgetHostView should include the height inset.
2811 EXPECT_EQ(gfx::Size(initial_wcv_size
.width(),
2812 initial_wcv_size
.height() + height_inset
),
2814 // When a navigation entry is committed, the size of RenderWidgetHostView
2815 // should be the same as when it was first created.
2816 EXPECT_EQ(rwhv_create_size0
, rwhv_commit_size0
);
2817 // Sizes of the current RenderWidgetHostView and WebContentsView should not
2818 // change before and after WebContentsDelegate::DidNavigateMainFramePostCommit
2819 // (implemented by Browser); we obtain the sizes before PostCommit via
2820 // WebContentsObserver::NavigationEntryCommitted (implemented by
2821 // RenderViewSizeObserver).
2822 EXPECT_EQ(rwhv_commit_size0
,
2823 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2824 // The behavior differs between OSX and views.
2825 // In OSX, the wcv does not change size until after the commit, when the
2826 // bookmark bar disappears (correct).
2827 // In views, the wcv changes size at commit time.
2828 #if defined(OS_MACOSX)
2829 EXPECT_EQ(gfx::Size(wcv_commit_size0
.width(),
2830 wcv_commit_size0
.height() + height_inset
),
2831 web_contents
->GetContainerBounds().size());
2833 EXPECT_EQ(wcv_commit_size0
, web_contents
->GetContainerBounds().size());
2836 // Navigate to another non-NTP page, without resizing WebContentsView.
2837 ui_test_utils::NavigateToURL(browser(),
2838 https_test_server
.GetURL("files/title2.html"));
2839 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2840 // A new RenderVieHost should be created.
2841 EXPECT_NE(prev_rvh
, web_contents
->GetRenderViewHost());
2842 gfx::Size rwhv_create_size1
, rwhv_commit_size1
, wcv_commit_size1
;
2843 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2847 EXPECT_EQ(rwhv_create_size1
, rwhv_commit_size1
);
2848 EXPECT_EQ(rwhv_commit_size1
,
2849 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2850 EXPECT_EQ(wcv_commit_size1
, web_contents
->GetContainerBounds().size());
2852 // Navigate from NTP to a non-NTP page, resizing WebContentsView while
2853 // navigation entry is pending.
2854 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
2855 gfx::Size
wcv_resize_insets(1, 1);
2856 observer
.set_wcv_resize_insets(wcv_resize_insets
);
2857 ui_test_utils::NavigateToURL(browser(),
2858 test_server()->GetURL("files/title2.html"));
2859 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2860 gfx::Size rwhv_create_size2
, rwhv_commit_size2
, wcv_commit_size2
;
2861 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2866 // The behavior on OSX and Views is incorrect in this edge case, but they are
2867 // differently incorrect.
2868 // The behavior should be:
2869 // initial wcv size: (100,100) (to choose random numbers)
2870 // initial rwhv size: (100,140)
2871 // commit wcv size: (101, 101)
2872 // commit rwhv size: (101, 141)
2873 // final wcv size: (101, 141)
2874 // final rwhv size: (101, 141)
2876 // On OSX, the commit rwhv size is (101, 101)
2877 // On views, the commit wcv size is (101, 141)
2878 // All other sizes are correct.
2880 // The create height of RenderWidgetHostView should include the height inset.
2881 EXPECT_EQ(gfx::Size(initial_wcv_size
.width(),
2882 initial_wcv_size
.height() + height_inset
),
2884 gfx::Size
exp_commit_size(initial_wcv_size
);
2886 #if defined(OS_MACOSX)
2887 exp_commit_size
.Enlarge(wcv_resize_insets
.width(),
2888 wcv_resize_insets
.height());
2890 exp_commit_size
.Enlarge(wcv_resize_insets
.width(),
2891 wcv_resize_insets
.height() + height_inset
);
2893 EXPECT_EQ(exp_commit_size
, rwhv_commit_size2
);
2894 EXPECT_EQ(exp_commit_size
, wcv_commit_size2
);
2895 gfx::Size
exp_final_size(initial_wcv_size
);
2896 exp_final_size
.Enlarge(wcv_resize_insets
.width(),
2897 wcv_resize_insets
.height() + height_inset
);
2898 EXPECT_EQ(exp_final_size
,
2899 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2900 EXPECT_EQ(exp_final_size
, web_contents
->GetContainerBounds().size());
2903 IN_PROC_BROWSER_TEST_F(BrowserTest
, CanDuplicateTab
) {
2904 GURL
url(ui_test_utils::GetTestUrl(
2905 base::FilePath(base::FilePath::kCurrentDirectory
),
2906 base::FilePath(kTitle1File
)));
2907 ui_test_utils::NavigateToURL(browser(), url
);
2909 AddTabAtIndex(0, url
, ui::PAGE_TRANSITION_TYPED
);
2911 int active_index
= browser()->tab_strip_model()->active_index();
2912 EXPECT_EQ(0, active_index
);
2914 EXPECT_TRUE(chrome::CanDuplicateTab(browser()));
2915 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 0));
2916 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2918 content::WebContents
* web_contents
=
2919 browser()->tab_strip_model()->GetActiveWebContents();
2921 TestInterstitialPage
* interstitial
=
2922 new TestInterstitialPage(web_contents
, false, GURL());
2923 content::WaitForInterstitialAttach(web_contents
);
2925 EXPECT_TRUE(web_contents
->ShowingInterstitialPage());
2927 // Verify that the "Duplicate tab" command is disabled on interstitial
2928 // pages. Regression test for crbug.com/310812
2929 EXPECT_FALSE(chrome::CanDuplicateTab(browser()));
2930 EXPECT_FALSE(chrome::CanDuplicateTabAt(browser(), 0));
2931 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2933 // Don't proceed and wait for interstitial to detach. This doesn't
2934 // destroy |contents|.
2935 interstitial
->DontProceed();
2936 content::WaitForInterstitialDetach(web_contents
);
2937 // interstitial is deleted now.
2939 EXPECT_TRUE(chrome::CanDuplicateTab(browser()));
2940 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 0));
2941 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2944 // Tests that the WebContentsObserver::SecurityStyleChanged event fires
2945 // with the current style on HTTP, broken HTTPS, and valid HTTPS pages.
2946 IN_PROC_BROWSER_TEST_F(BrowserTest
, SecurityStyleChangedObserver
) {
2947 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
2948 net::SpawnedTestServer::kLocalhost
,
2949 base::FilePath(kDocRoot
));
2950 net::SpawnedTestServer
https_test_server_expired(
2951 net::SpawnedTestServer::TYPE_HTTPS
,
2952 net::SpawnedTestServer::SSLOptions(
2953 net::SpawnedTestServer::SSLOptions::CERT_EXPIRED
),
2954 base::FilePath(kDocRoot
));
2956 ASSERT_TRUE(https_test_server
.Start());
2957 ASSERT_TRUE(https_test_server_expired
.Start());
2958 ASSERT_TRUE(test_server()->Start());
2960 content::WebContents
* web_contents
=
2961 browser()->tab_strip_model()->GetActiveWebContents();
2962 SecurityStyleTestObserver
observer(web_contents
);
2964 // Visit an HTTP url.
2965 GURL
http_url(test_server()->GetURL(std::string()));
2966 ui_test_utils::NavigateToURL(browser(), http_url
);
2967 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED
,
2968 observer
.latest_security_style());
2969 EXPECT_EQ(0u, observer
.latest_explanations().warning_explanations
.size());
2970 EXPECT_EQ(0u, observer
.latest_explanations().broken_explanations
.size());
2971 EXPECT_EQ(0u, observer
.latest_explanations().secure_explanations
.size());
2972 EXPECT_FALSE(observer
.latest_explanations().scheme_is_cryptographic
);
2973 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
2974 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
2976 // Visit an (otherwise valid) HTTPS page that displays mixed content.
2977 std::string replacement_path
;
2978 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2979 "files/ssl/page_displays_insecure_content.html",
2980 test_server()->host_port_pair(), &replacement_path
));
2982 GURL
mixed_content_url(https_test_server
.GetURL(replacement_path
));
2983 ui_test_utils::NavigateToURL(browser(), mixed_content_url
);
2984 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED
,
2985 observer
.latest_security_style());
2987 const content::SecurityStyleExplanations
& mixed_content_explanation
=
2988 observer
.latest_explanations();
2989 ASSERT_EQ(0u, mixed_content_explanation
.warning_explanations
.size());
2990 ASSERT_EQ(0u, mixed_content_explanation
.broken_explanations
.size());
2991 CheckSecureExplanations(mixed_content_explanation
.secure_explanations
,
2992 VALID_CERTIFICATE
, browser());
2993 EXPECT_TRUE(mixed_content_explanation
.scheme_is_cryptographic
);
2994 EXPECT_TRUE(mixed_content_explanation
.displayed_insecure_content
);
2995 EXPECT_FALSE(mixed_content_explanation
.ran_insecure_content
);
2996 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED
,
2997 mixed_content_explanation
.displayed_insecure_content_style
);
2998 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN
,
2999 mixed_content_explanation
.ran_insecure_content_style
);
3001 // Visit a broken HTTPS url.
3002 GURL
expired_url(https_test_server_expired
.GetURL(std::string()));
3003 ui_test_utils::NavigateToURL(browser(), expired_url
);
3005 // An interstitial should show, and an event for the lock icon on the
3006 // interstitial should fire.
3007 content::WaitForInterstitialAttach(web_contents
);
3008 EXPECT_TRUE(web_contents
->ShowingInterstitialPage());
3009 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_DATE_INVALID
, browser());
3010 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3011 INVALID_CERTIFICATE
, browser());
3012 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3013 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3014 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3016 // Before clicking through, navigate to a different page, and then go
3017 // back to the interstitial.
3018 GURL
valid_https_url(https_test_server
.GetURL(std::string()));
3019 ui_test_utils::NavigateToURL(browser(), valid_https_url
);
3020 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED
,
3021 observer
.latest_security_style());
3022 EXPECT_EQ(0u, observer
.latest_explanations().warning_explanations
.size());
3023 EXPECT_EQ(0u, observer
.latest_explanations().broken_explanations
.size());
3024 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3025 VALID_CERTIFICATE
, browser());
3026 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3027 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3028 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3030 // After going back to the interstitial, an event for a broken lock
3031 // icon should fire again.
3032 ui_test_utils::NavigateToURL(browser(), expired_url
);
3033 content::WaitForInterstitialAttach(web_contents
);
3034 EXPECT_TRUE(web_contents
->ShowingInterstitialPage());
3035 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_DATE_INVALID
, browser());
3036 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3037 INVALID_CERTIFICATE
, browser());
3038 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3039 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3040 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3042 // Since the next expected style is the same as the previous, clear
3043 // the observer (to make sure that the event fires twice and we don't
3044 // just see the previous event's style).
3045 observer
.ClearLatestSecurityStyleAndExplanations();
3047 // Other conditions cannot be tested on this host after clicking
3048 // through because once the interstitial is clicked through, all URLs
3049 // for this host will remain in a broken state.
3050 ProceedThroughInterstitial(web_contents
);
3051 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_DATE_INVALID
, browser());
3052 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3053 INVALID_CERTIFICATE
, browser());
3054 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3055 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3056 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3059 // Visit a valid HTTPS page, then a broken HTTPS page, and then go back,
3060 // and test that the observed security style matches.
3061 IN_PROC_BROWSER_TEST_F(BrowserTest
, SecurityStyleChangedObserverGoBack
) {
3062 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
3063 net::SpawnedTestServer::kLocalhost
,
3064 base::FilePath(kDocRoot
));
3066 // Use a separate server to work around a mysterious SSL handshake
3067 // timeout when both requests go to the same server. See
3068 // https://crbug.com/515906.
3069 net::SpawnedTestServer
https_test_server_expired(
3070 net::SpawnedTestServer::TYPE_HTTPS
,
3071 net::SpawnedTestServer::SSLOptions(
3072 net::SpawnedTestServer::SSLOptions::CERT_EXPIRED
),
3073 base::FilePath(kDocRoot
));
3075 ASSERT_TRUE(https_test_server
.Start());
3076 ASSERT_TRUE(https_test_server_expired
.Start());
3078 content::WebContents
* web_contents
=
3079 browser()->tab_strip_model()->GetActiveWebContents();
3080 SecurityStyleTestObserver
observer(web_contents
);
3082 // Visit a valid HTTPS url.
3083 GURL
valid_https_url(https_test_server
.GetURL(std::string()));
3084 ui_test_utils::NavigateToURL(browser(), valid_https_url
);
3085 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED
,
3086 observer
.latest_security_style());
3087 EXPECT_EQ(0u, observer
.latest_explanations().warning_explanations
.size());
3088 EXPECT_EQ(0u, observer
.latest_explanations().broken_explanations
.size());
3089 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3090 VALID_CERTIFICATE
, browser());
3091 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3092 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3093 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3095 // Navigate to a bad HTTPS page on a different host, and then click
3096 // Back to verify that the previous good security style is seen again.
3097 GURL
expired_https_url(https_test_server_expired
.GetURL(std::string()));
3098 host_resolver()->AddRule("www.example_broken.test", "127.0.0.1");
3099 GURL::Replacements replace_host
;
3100 replace_host
.SetHostStr("www.example_broken.test");
3101 GURL https_url_different_host
=
3102 expired_https_url
.ReplaceComponents(replace_host
);
3104 ui_test_utils::NavigateToURL(browser(), https_url_different_host
);
3106 content::WaitForInterstitialAttach(web_contents
);
3107 EXPECT_TRUE(web_contents
->ShowingInterstitialPage());
3108 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_COMMON_NAME_INVALID
,
3110 ProceedThroughInterstitial(web_contents
);
3111 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_COMMON_NAME_INVALID
,
3113 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3114 INVALID_CERTIFICATE
, browser());
3115 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3116 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3117 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3119 content::WindowedNotificationObserver
back_nav_load_observer(
3120 content::NOTIFICATION_LOAD_STOP
,
3121 content::Source
<NavigationController
>(&web_contents
->GetController()));
3122 chrome::GoBack(browser(), CURRENT_TAB
);
3123 back_nav_load_observer
.Wait();
3125 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED
,
3126 observer
.latest_security_style());
3127 EXPECT_EQ(0u, observer
.latest_explanations().warning_explanations
.size());
3128 EXPECT_EQ(0u, observer
.latest_explanations().broken_explanations
.size());
3129 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3130 VALID_CERTIFICATE
, browser());
3131 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3132 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3133 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3137 class JSBooleanResultGetter
{
3139 JSBooleanResultGetter() = default;
3140 void OnJsExecutionDone(base::Closure callback
, const base::Value
* value
) {
3141 js_result_
.reset(value
->DeepCopy());
3144 bool GetResult() const {
3147 CHECK(js_result_
->GetAsBoolean(&res
));
3152 scoped_ptr
<base::Value
> js_result_
;
3153 DISALLOW_COPY_AND_ASSIGN(JSBooleanResultGetter
);
3156 void CheckDisplayModeMQ(
3157 const base::string16
& display_mode
,
3158 content::WebContents
* web_contents
) {
3159 base::string16 funtcion
=
3160 ASCIIToUTF16("(function() {return window.matchMedia('(display-mode: ") +
3161 display_mode
+ ASCIIToUTF16(")').matches;})();");
3162 JSBooleanResultGetter js_result_getter
;
3163 // Execute the JS to run the tests, and wait until it has finished.
3164 base::RunLoop run_loop
;
3165 web_contents
->GetMainFrame()->ExecuteJavaScriptForTests(
3167 base::Bind(&JSBooleanResultGetter::OnJsExecutionDone
,
3168 base::Unretained(&js_result_getter
), run_loop
.QuitClosure()));
3170 EXPECT_TRUE(js_result_getter
.GetResult());
3174 // flaky new test: http://crbug.com/471703
3175 IN_PROC_BROWSER_TEST_F(BrowserTest
, DISABLED_ChangeDisplayMode
) {
3177 ASCIIToUTF16("browser"),
3178 browser()->tab_strip_model()->GetActiveWebContents());
3180 Profile
* profile
= ProfileManager::GetActiveUserProfile();
3181 ui_test_utils::BrowserAddedObserver browser_added_observer
;
3182 Browser
* app_browser
= CreateBrowserForApp("blah", profile
);
3183 browser_added_observer
.WaitForSingleNewBrowser();
3184 auto app_contents
= app_browser
->tab_strip_model()->GetActiveWebContents();
3185 CheckDisplayModeMQ(ASCIIToUTF16("standalone"), app_contents
);
3187 app_browser
->window()->EnterFullscreen(
3188 GURL(), EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION
,
3191 // Sync navigation just to make sure IPC has passed (updated
3192 // display mode is delivered to RP).
3193 content::TestNavigationObserver
observer(app_contents
, 1);
3194 ui_test_utils::NavigateToURL(app_browser
, GURL(url::kAboutBlankURL
));
3197 CheckDisplayModeMQ(ASCIIToUTF16("fullscreen"), app_contents
);