Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / ui / browser_browsertest.cc
blob43a21db92f901632ef5e79170cafe7221805aa74
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.
5 #include <string>
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/compiler_specific.h"
10 #include "base/files/file_path.h"
11 #include "base/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/security_state_model.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"
109 #endif
111 #if defined(OS_WIN)
112 #include "base/i18n/rtl.h"
113 #include "chrome/browser/browser_process.h"
114 #endif
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;
130 namespace {
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>"
137 "</body></html>";
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);
158 return page_title;
159 #else
160 if (page_title.empty())
161 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
163 return l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT,
164 page_title);
165 #endif
168 // Returns the number of active RenderProcessHosts.
169 int CountRenderProcessHosts() {
170 int result = 0;
171 for (content::RenderProcessHost::iterator i(
172 content::RenderProcessHost::AllHostsIterator());
173 !i.IsAtEnd(); i.Advance())
174 ++result;
175 return result;
178 class MockTabStripModelObserver : public TabStripModelObserver {
179 public:
180 MockTabStripModelObserver() : closing_count_(0) {}
182 void TabClosingAt(TabStripModel* tab_strip_model,
183 WebContents* contents,
184 int index) override {
185 ++closing_count_;
188 int closing_count() const { return closing_count_; }
190 private:
191 int 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 ChromeContentBrowserClient {
199 public:
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
214 // menu.
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 {
226 public:
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 {}
233 void Proceed() {
234 interstitial_page_->Proceed();
236 void DontProceed() {
237 interstitial_page_->DontProceed();
240 std::string GetHTMLContents() override { return "<h1>INTERSTITIAL</h1>"; }
242 private:
243 InterstitialPage* interstitial_page_; // Owns us.
246 class RenderViewSizeObserver : public content::WebContentsObserver {
247 public:
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
279 // is pending.
280 void DidStartNavigationToPendingEntry(
281 const GURL& url,
282 NavigationController::ReloadType reload_type) override {
283 if (wcv_resize_insets_.IsEmpty())
284 return;
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();
312 private:
313 struct Sizes {
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();
337 observer.Wait();
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
353 // that was fired.
354 class SecurityStyleTestObserver : public WebContentsObserver {
355 public:
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();
381 private:
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,
391 int error,
392 Browser* browser) {
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;
413 EXPECT_EQ(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,
422 Browser* browser) {
423 if (cert_status != VALID_CERTIFICATE) {
424 EXPECT_EQ(0u, secure_explanations.size());
425 return;
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);
438 } // namespace
440 class BrowserTest : public ExtensionBrowserTest {
441 protected:
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);
447 #if defined(OS_WIN)
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);
454 return page_title;
455 #else
456 // Do we need to use the above code on POSIX as well?
457 return page_title;
458 #endif
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();
470 NOTREACHED();
471 return NULL;
475 // Launch the app on a page with no title, check that the app title was set
476 // correctly.
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))
482 return;
483 #endif
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))
506 return;
507 #endif
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
515 // navigation.
516 struct {
517 std::string suffix;
518 std::string message;
519 } cases[]{
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))
554 return;
555 #endif
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
590 #else
591 #define MAYBE_ThirtyFourTabs ThirtyFourTabs
592 #endif
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)
618 #else
620 #endif
621 if (base::SysInfo::AmountOfPhysicalMemoryMB() >= 2048) {
622 EXPECT_GE(CountRenderProcessHosts(), kExpectedProcessCount);
623 } else {
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(
721 child_process,
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(
748 child_process,
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();
796 EXPECT_FALSE(
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 {
805 public:
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 {
814 params_ = params;
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 {
824 return params_;
827 private:
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?" +
862 dest_url.spec()));
863 ui_test_utils::NavigateToURL(browser(), redirect_url);
865 // We should immediately see the new committed entry.
866 EXPECT_FALSE(contents->GetController().GetPendingEntry());
867 EXPECT_EQ(dest_url,
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?" +
913 https_url.spec()));
914 browser()->OpenURL(OpenURLParams(redirect_url, Referrer(), CURRENT_TAB,
915 ui::PAGE_TRANSITION_TYPED, false));
916 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
917 EXPECT_TRUE(
918 static_cast<JavaScriptAppModalDialog*>(alert)->is_before_unload_dialog());
919 alert->native_dialog()->AcceptAppModalDialog();
920 nav_observer.Wait();
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();
946 EXPECT_FALSE(
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) {
970 browser()
971 ->tab_strip_model()
972 ->GetActiveWebContents()
973 ->GetMainFrame()
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.
980 browser()
981 ->tab_strip_model()
982 ->GetWebContentsAt(0)
983 ->GetMainFrame()
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
997 #if defined(OS_WIN)
998 #define MAYBE_BeforeUnloadVsBeforeReload DISABLED_BeforeUnloadVsBeforeReload
999 #else
1000 #define MAYBE_BeforeUnloadVsBeforeReload BeforeUnloadVsBeforeReload
1001 #endif
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 {
1033 public:
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.
1041 CycleRunLoops();
1042 CycleRunLoops();
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.
1051 CycleRunLoops();
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();
1064 #endif
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();
1087 #else
1088 chrome::ExecuteCommand(second_window, IDC_EXIT);
1089 #endif
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();
1094 ASSERT_TRUE(alert);
1095 EXPECT_TRUE(
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
1128 // cross-site.
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
1217 // cross-site.
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())
1391 app_browser = *it;
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
1431 #else
1432 #define MAYBE_FaviconChange FaviconChange
1433 #endif
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
1453 #if defined(OS_WIN)
1454 #define MAYBE_TabClosingWhenRemovingExtension \
1455 DISABLED_TabClosingWhenRemovingExtension
1456 #else
1457 #define MAYBE_TabClosingWhenRemovingExtension TabClosingWhenRemovingExtension
1458 #endif
1459 // Makes sure TabClosing is sent when uninstalling an extension that is an app
1460 // tab.
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),
1494 NULL);
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());
1510 // Load an app.
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());
1547 // Load an app.
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.
1562 ASSERT_EQ(3u,
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()) {
1571 continue;
1572 } else if ((*it)->app_name() == DevToolsWindow::kDevToolsApp) {
1573 dev_tools_browser = *it;
1574 } else {
1575 app_browser = *it;
1578 ASSERT_TRUE(dev_tools_browser);
1579 ASSERT_TRUE(app_browser);
1580 ASSERT_TRUE(app_browser != browser());
1582 EXPECT_FALSE(
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.
1587 EXPECT_TRUE(
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,
1615 source);
1616 EXPECT_EQ("",
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);
1622 EXPECT_EQ("en",
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,
1629 source);
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);
1637 EXPECT_EQ("fr",
1638 chrome_translate_client->GetLanguageState().original_language());
1641 // Chromeos defaults to restoring the last session, so this test isn't
1642 // applicable.
1643 #if !defined(OS_CHROMEOS)
1644 // Makes sure pinned tabs are restored correctly on start.
1645 IN_PROC_BROWSER_TEST_F(BrowserTest, RestorePinnedTabs) {
1646 ASSERT_TRUE(test_server()->Start());
1648 // Add a pinned tab.
1649 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1650 GURL url(test_server()->GetURL("empty.html"));
1651 TabStripModel* model = browser()->tab_strip_model();
1652 ui_test_utils::NavigateToURL(browser(), url);
1653 model->SetTabPinned(0, true);
1655 // Add a non pinned tab.
1656 chrome::NewTab(browser());
1657 ui_test_utils::NavigateToURL(browser(), url);
1659 // Add another pinned tab.
1660 chrome::NewTab(browser());
1661 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
1662 model->SetTabPinned(2, true);
1664 // Write out the pinned tabs.
1665 PinnedTabCodec::WritePinnedTabs(browser()->profile());
1667 // Simulate launching again.
1668 base::CommandLine dummy(base::CommandLine::NO_PROGRAM);
1669 chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ?
1670 chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN;
1671 StartupBrowserCreatorImpl launch(base::FilePath(), dummy, first_run);
1672 launch.profile_ = browser()->profile();
1673 launch.ProcessStartupURLs(std::vector<GURL>(),
1674 browser()->host_desktop_type());
1676 // The launch should have created a new browser.
1677 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1678 browser()->host_desktop_type()));
1680 // Find the new browser.
1681 Browser* new_browser = NULL;
1682 for (chrome::BrowserIterator it; !it.done() && !new_browser; it.Next()) {
1683 if (*it != browser())
1684 new_browser = *it;
1686 ASSERT_TRUE(new_browser);
1687 ASSERT_TRUE(new_browser != browser());
1689 // We should get back an additional tab for the app, and another for the
1690 // default home page.
1691 ASSERT_EQ(3, new_browser->tab_strip_model()->count());
1693 // Make sure the state matches.
1694 TabStripModel* new_model = new_browser->tab_strip_model();
1695 EXPECT_TRUE(new_model->IsTabPinned(0));
1696 EXPECT_TRUE(new_model->IsTabPinned(1));
1697 EXPECT_FALSE(new_model->IsTabPinned(2));
1699 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
1700 new_model->GetWebContentsAt(2)->GetURL());
1702 #endif // !defined(OS_CHROMEOS)
1704 // This test verifies we don't crash when closing the last window and the app
1705 // menu is showing.
1706 IN_PROC_BROWSER_TEST_F(BrowserTest, CloseWithAppMenuOpen) {
1707 if (browser_defaults::kBrowserAliveWithNoWindows)
1708 return;
1710 // We need a message loop running for menus on windows.
1711 base::MessageLoop::current()->task_runner()->PostTask(
1712 FROM_HERE, base::Bind(&RunCloseWithAppMenuCallback, browser()));
1715 #if !defined(OS_MACOSX)
1716 IN_PROC_BROWSER_TEST_F(BrowserTest, OpenAppWindowLikeNtp) {
1717 ASSERT_TRUE(test_server()->Start());
1719 // Load an app
1720 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1721 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/")));
1722 const Extension* extension_app = GetExtension();
1724 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1725 WebContents* app_window = OpenApplication(AppLaunchParams(
1726 browser()->profile(), extension_app, extensions::LAUNCH_CONTAINER_WINDOW,
1727 NEW_WINDOW, extensions::SOURCE_TEST));
1728 ASSERT_TRUE(app_window);
1730 // Apps launched in a window from the NTP have an extensions tab helper but
1731 // do not have extension_app set in it.
1732 ASSERT_TRUE(extensions::TabHelper::FromWebContents(app_window));
1733 EXPECT_FALSE(
1734 extensions::TabHelper::FromWebContents(app_window)->extension_app());
1735 EXPECT_EQ(extensions::AppLaunchInfo::GetFullLaunchURL(extension_app),
1736 app_window->GetURL());
1738 // The launch should have created a new browser.
1739 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1740 browser()->host_desktop_type()));
1742 // Find the new browser.
1743 Browser* new_browser = NULL;
1744 for (chrome::BrowserIterator it; !it.done() && !new_browser; it.Next()) {
1745 if (*it != browser())
1746 new_browser = *it;
1748 ASSERT_TRUE(new_browser);
1749 ASSERT_TRUE(new_browser != browser());
1751 EXPECT_TRUE(new_browser->is_app());
1753 // The browser's app name should include the extension's id.
1754 std::string app_name = new_browser->app_name_;
1755 EXPECT_NE(app_name.find(extension_app->id()), std::string::npos)
1756 << "Name " << app_name << " should contain id "<< extension_app->id();
1758 #endif // !defined(OS_MACOSX)
1760 // Makes sure the browser doesn't crash when
1761 // set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked.
1762 IN_PROC_BROWSER_TEST_F(BrowserTest, StartMaximized) {
1763 Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP };
1764 for (size_t i = 0; i < arraysize(types); ++i) {
1765 Browser::CreateParams params(types[i], browser()->profile(),
1766 browser()->host_desktop_type());
1767 params.initial_show_state = ui::SHOW_STATE_MAXIMIZED;
1768 AddBlankTabAndShow(new Browser(params));
1772 // Aura doesn't support minimized window. crbug.com/104571.
1773 #if defined(USE_AURA)
1774 #define MAYBE_StartMinimized DISABLED_StartMinimized
1775 #else
1776 #define MAYBE_StartMinimized StartMinimized
1777 #endif
1778 // Makes sure the browser doesn't crash when
1779 // set_show_state(ui::SHOW_STATE_MINIMIZED) has been invoked.
1780 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_StartMinimized) {
1781 Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP };
1782 for (size_t i = 0; i < arraysize(types); ++i) {
1783 Browser::CreateParams params(types[i], browser()->profile(),
1784 browser()->host_desktop_type());
1785 params.initial_show_state = ui::SHOW_STATE_MINIMIZED;
1786 AddBlankTabAndShow(new Browser(params));
1790 // Makes sure the forward button is disabled immediately when navigating
1791 // forward to a slow-to-commit page.
1792 IN_PROC_BROWSER_TEST_F(BrowserTest, ForwardDisabledOnForward) {
1793 GURL blank_url(url::kAboutBlankURL);
1794 ui_test_utils::NavigateToURL(browser(), blank_url);
1796 ui_test_utils::NavigateToURL(
1797 browser(), ui_test_utils::GetTestUrl(
1798 base::FilePath(base::FilePath::kCurrentDirectory),
1799 base::FilePath(kTitle1File)));
1801 content::WindowedNotificationObserver back_nav_load_observer(
1802 content::NOTIFICATION_LOAD_STOP,
1803 content::Source<NavigationController>(
1804 &browser()->tab_strip_model()->GetActiveWebContents()->
1805 GetController()));
1806 chrome::GoBack(browser(), CURRENT_TAB);
1807 back_nav_load_observer.Wait();
1808 CommandUpdater* command_updater =
1809 browser()->command_controller()->command_updater();
1810 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_FORWARD));
1812 content::WindowedNotificationObserver forward_nav_load_observer(
1813 content::NOTIFICATION_LOAD_STOP,
1814 content::Source<NavigationController>(
1815 &browser()->tab_strip_model()->GetActiveWebContents()->
1816 GetController()));
1817 chrome::GoForward(browser(), CURRENT_TAB);
1818 // This check will happen before the navigation completes, since the browser
1819 // won't process the renderer's response until the Wait() call below.
1820 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_FORWARD));
1821 forward_nav_load_observer.Wait();
1824 // Makes sure certain commands are disabled when Incognito mode is forced.
1825 IN_PROC_BROWSER_TEST_F(BrowserTest, DisableMenuItemsWhenIncognitoIsForced) {
1826 CommandUpdater* command_updater =
1827 browser()->command_controller()->command_updater();
1828 // At the beginning, all commands are enabled.
1829 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW));
1830 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW));
1831 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER));
1832 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1833 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
1834 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS));
1836 // Set Incognito to FORCED.
1837 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1838 IncognitoModePrefs::FORCED);
1839 // Bookmarks & Settings commands should get disabled.
1840 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW));
1841 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER));
1842 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1843 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
1844 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS));
1845 // New Incognito Window command, however, should be enabled.
1846 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW));
1848 // Create a new browser.
1849 Browser* new_browser =
1850 new Browser(Browser::CreateParams(
1851 browser()->profile()->GetOffTheRecordProfile(),
1852 browser()->host_desktop_type()));
1853 CommandUpdater* new_command_updater =
1854 new_browser->command_controller()->command_updater();
1855 // It should have Bookmarks & Settings commands disabled by default.
1856 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_WINDOW));
1857 EXPECT_FALSE(new_command_updater->IsCommandEnabled(
1858 IDC_SHOW_BOOKMARK_MANAGER));
1859 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1860 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
1861 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_OPTIONS));
1862 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW));
1865 // Makes sure New Incognito Window command is disabled when Incognito mode is
1866 // not available.
1867 IN_PROC_BROWSER_TEST_F(BrowserTest,
1868 NoNewIncognitoWindowWhenIncognitoIsDisabled) {
1869 CommandUpdater* command_updater =
1870 browser()->command_controller()->command_updater();
1871 // Set Incognito to DISABLED.
1872 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1873 IncognitoModePrefs::DISABLED);
1874 // Make sure New Incognito Window command is disabled. All remaining commands
1875 // should be enabled.
1876 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW));
1877 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW));
1878 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER));
1879 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1880 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
1881 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS));
1883 // Create a new browser.
1884 Browser* new_browser =
1885 new Browser(Browser::CreateParams(browser()->profile(),
1886 browser()->host_desktop_type()));
1887 CommandUpdater* new_command_updater =
1888 new_browser->command_controller()->command_updater();
1889 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW));
1890 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_NEW_WINDOW));
1891 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER));
1892 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1893 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
1894 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_OPTIONS));
1897 // Makes sure Extensions and Settings commands are disabled in certain
1898 // circumstances even though normally they should stay enabled.
1899 IN_PROC_BROWSER_TEST_F(BrowserTest,
1900 DisableExtensionsAndSettingsWhenIncognitoIsDisabled) {
1901 CommandUpdater* command_updater =
1902 browser()->command_controller()->command_updater();
1903 // Disable extensions. This should disable Extensions menu.
1904 extensions::ExtensionSystem::Get(browser()->profile())->extension_service()->
1905 set_extensions_enabled(false);
1906 // Set Incognito to DISABLED.
1907 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1908 IncognitoModePrefs::DISABLED);
1909 // Make sure Manage Extensions command is disabled.
1910 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
1911 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW));
1912 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER));
1913 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1914 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS));
1916 // Create a popup (non-main-UI-type) browser. Settings command as well
1917 // as Extensions should be disabled.
1918 Browser* popup_browser = new Browser(
1919 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(),
1920 browser()->host_desktop_type()));
1921 CommandUpdater* popup_command_updater =
1922 popup_browser->command_controller()->command_updater();
1923 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
1924 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_OPTIONS));
1925 EXPECT_TRUE(popup_command_updater->IsCommandEnabled(
1926 IDC_SHOW_BOOKMARK_MANAGER));
1927 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1930 // Makes sure Extensions and Settings commands are disabled in certain
1931 // circumstances even though normally they should stay enabled.
1932 IN_PROC_BROWSER_TEST_F(BrowserTest,
1933 DisableOptionsAndImportMenuItemsConsistently) {
1934 // Create a popup browser.
1935 Browser* popup_browser = new Browser(
1936 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(),
1937 browser()->host_desktop_type()));
1938 CommandUpdater* command_updater =
1939 popup_browser->command_controller()->command_updater();
1940 // OPTIONS and IMPORT_SETTINGS are disabled for a non-normal UI.
1941 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS));
1942 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1944 // Set Incognito to FORCED.
1945 IncognitoModePrefs::SetAvailability(popup_browser->profile()->GetPrefs(),
1946 IncognitoModePrefs::FORCED);
1947 // OPTIONS and IMPORT_SETTINGS are disabled when Incognito is forced.
1948 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS));
1949 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1950 // Set Incognito to AVAILABLE.
1951 IncognitoModePrefs::SetAvailability(popup_browser->profile()->GetPrefs(),
1952 IncognitoModePrefs::ENABLED);
1953 // OPTIONS and IMPORT_SETTINGS are still disabled since it is a non-normal UI.
1954 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS));
1955 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
1958 namespace {
1960 void OnZoomLevelChanged(const base::Closure& callback,
1961 const HostZoomMap::ZoomLevelChange& host) {
1962 callback.Run();
1965 } // namespace
1967 #if defined(OS_WIN)
1968 // Flakes regularly on Windows XP
1969 // http://crbug.com/146040
1970 #define MAYBE_PageZoom DISABLED_PageZoom
1971 #else
1972 #define MAYBE_PageZoom PageZoom
1973 #endif
1975 namespace {
1977 int GetZoomPercent(const content::WebContents* contents,
1978 bool* enable_plus,
1979 bool* enable_minus) {
1980 int percent =
1981 ui_zoom::ZoomController::FromWebContents(contents)->GetZoomPercent();
1982 *enable_plus = percent < contents->GetMaximumZoomPercent();
1983 *enable_minus = percent > contents->GetMinimumZoomPercent();
1984 return percent;
1987 } // namespace
1989 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_PageZoom) {
1990 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
1991 bool enable_plus, enable_minus;
1994 scoped_refptr<content::MessageLoopRunner> loop_runner(
1995 new content::MessageLoopRunner);
1996 content::HostZoomMap::ZoomLevelChangedCallback callback(
1997 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure()));
1998 scoped_ptr<content::HostZoomMap::Subscription> sub =
1999 content::HostZoomMap::GetDefaultForBrowserContext(
2000 browser()->profile())->AddZoomLevelChangedCallback(callback);
2001 chrome::Zoom(browser(), content::PAGE_ZOOM_IN);
2002 loop_runner->Run();
2003 sub.reset();
2004 EXPECT_EQ(GetZoomPercent(contents, &enable_plus, &enable_minus), 110);
2005 EXPECT_TRUE(enable_plus);
2006 EXPECT_TRUE(enable_minus);
2010 scoped_refptr<content::MessageLoopRunner> loop_runner(
2011 new content::MessageLoopRunner);
2012 content::HostZoomMap::ZoomLevelChangedCallback callback(
2013 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure()));
2014 scoped_ptr<content::HostZoomMap::Subscription> sub =
2015 content::HostZoomMap::GetDefaultForBrowserContext(
2016 browser()->profile())->AddZoomLevelChangedCallback(callback);
2017 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET);
2018 loop_runner->Run();
2019 sub.reset();
2020 EXPECT_EQ(GetZoomPercent(contents, &enable_plus, &enable_minus), 100);
2021 EXPECT_TRUE(enable_plus);
2022 EXPECT_TRUE(enable_minus);
2026 scoped_refptr<content::MessageLoopRunner> loop_runner(
2027 new content::MessageLoopRunner);
2028 content::HostZoomMap::ZoomLevelChangedCallback callback(
2029 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure()));
2030 scoped_ptr<content::HostZoomMap::Subscription> sub =
2031 content::HostZoomMap::GetDefaultForBrowserContext(
2032 browser()->profile())->AddZoomLevelChangedCallback(callback);
2033 chrome::Zoom(browser(), content::PAGE_ZOOM_OUT);
2034 loop_runner->Run();
2035 sub.reset();
2036 EXPECT_EQ(GetZoomPercent(contents, &enable_plus, &enable_minus), 90);
2037 EXPECT_TRUE(enable_plus);
2038 EXPECT_TRUE(enable_minus);
2041 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET);
2044 IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCommandDisable) {
2045 ASSERT_TRUE(test_server()->Start());
2046 host_resolver()->AddRule("www.example.com", "127.0.0.1");
2047 GURL url(test_server()->GetURL("empty.html"));
2048 ui_test_utils::NavigateToURL(browser(), url);
2050 CommandUpdater* command_updater =
2051 browser()->command_controller()->command_updater();
2052 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE));
2053 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_PRINT));
2054 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE));
2055 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU));
2056 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_DUPLICATE_TAB));
2058 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
2060 TestInterstitialPage* interstitial =
2061 new TestInterstitialPage(contents, false, GURL());
2062 content::WaitForInterstitialAttach(contents);
2064 EXPECT_TRUE(contents->ShowingInterstitialPage());
2066 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE));
2067 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_PRINT));
2068 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE));
2069 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU));
2070 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_DUPLICATE_TAB));
2072 // Proceed and wait for interstitial to detach. This doesn't destroy
2073 // |contents|.
2074 interstitial->Proceed();
2075 content::WaitForInterstitialDetach(contents);
2076 // interstitial is deleted now.
2078 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE));
2079 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_PRINT));
2080 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE));
2081 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU));
2082 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_DUPLICATE_TAB));
2085 // Ensure that creating an interstitial page closes any JavaScript dialogs
2086 // that were present on the previous page. See http://crbug.com/295695.
2087 IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialClosesDialogs) {
2088 ASSERT_TRUE(test_server()->Start());
2089 host_resolver()->AddRule("www.example.com", "127.0.0.1");
2090 GURL url(test_server()->GetURL("empty.html"));
2091 ui_test_utils::NavigateToURL(browser(), url);
2093 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
2094 contents->GetMainFrame()->ExecuteJavaScriptForTests(
2095 ASCIIToUTF16("alert('Dialog showing!');"));
2096 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
2097 EXPECT_TRUE(alert->IsValid());
2098 AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance();
2099 EXPECT_TRUE(dialog_queue->HasActiveDialog());
2101 TestInterstitialPage* interstitial =
2102 new TestInterstitialPage(contents, false, GURL());
2103 content::WaitForInterstitialAttach(contents);
2105 // The interstitial should have closed the dialog.
2106 EXPECT_TRUE(contents->ShowingInterstitialPage());
2107 EXPECT_FALSE(dialog_queue->HasActiveDialog());
2109 // Don't proceed and wait for interstitial to detach. This doesn't destroy
2110 // |contents|.
2111 interstitial->DontProceed();
2112 content::WaitForInterstitialDetach(contents);
2113 // interstitial is deleted now.
2115 // Make sure input events still work in the renderer process.
2116 EXPECT_FALSE(contents->GetRenderProcessHost()->IgnoreInputEvents());
2120 IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCloseTab) {
2121 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
2123 // Interstitial will delete itself when we close the tab.
2124 new TestInterstitialPage(contents, false, GURL());
2125 content::WaitForInterstitialAttach(contents);
2127 EXPECT_TRUE(contents->ShowingInterstitialPage());
2129 // Close the tab and wait for interstitial detach. This destroys |contents|.
2130 content::RunTaskAndWaitForInterstitialDetach(
2131 contents, base::Bind(&chrome::CloseTab, browser()));
2132 // interstitial is deleted now.
2135 class MockWebContentsObserver : public WebContentsObserver {
2136 public:
2137 explicit MockWebContentsObserver(WebContents* web_contents)
2138 : WebContentsObserver(web_contents),
2139 got_user_gesture_(false) {
2142 void DidGetUserGesture() override { got_user_gesture_ = true; }
2144 bool got_user_gesture() const {
2145 return got_user_gesture_;
2148 void set_got_user_gesture(bool got_it) {
2149 got_user_gesture_ = got_it;
2152 private:
2153 bool got_user_gesture_;
2155 DISALLOW_COPY_AND_ASSIGN(MockWebContentsObserver);
2158 IN_PROC_BROWSER_TEST_F(BrowserTest, UserGesturesReported) {
2159 // Regression test for http://crbug.com/110707. Also tests that a user
2160 // gesture is sent when a normal navigation (via e.g. the omnibox) is
2161 // performed.
2162 WebContents* web_contents =
2163 browser()->tab_strip_model()->GetActiveWebContents();
2164 MockWebContentsObserver mock_observer(web_contents);
2166 ASSERT_TRUE(test_server()->Start());
2167 GURL url(test_server()->GetURL("empty.html"));
2169 ui_test_utils::NavigateToURL(browser(), url);
2170 EXPECT_TRUE(mock_observer.got_user_gesture());
2172 mock_observer.set_got_user_gesture(false);
2173 chrome::Reload(browser(), CURRENT_TAB);
2174 EXPECT_TRUE(mock_observer.got_user_gesture());
2177 // TODO(ben): this test was never enabled. It has bit-rotted since being added.
2178 // It originally lived in browser_unittest.cc, but has been moved here to make
2179 // room for real browser unit tests.
2180 #if 0
2181 class BrowserTest2 : public InProcessBrowserTest {
2182 public:
2183 BrowserTest2() {
2184 host_resolver_proc_ = new net::RuleBasedHostResolverProc(NULL);
2185 // Avoid making external DNS lookups. In this test we don't need this
2186 // to succeed.
2187 host_resolver_proc_->AddSimulatedFailure("*.google.com");
2188 scoped_host_resolver_proc_.Init(host_resolver_proc_.get());
2191 private:
2192 scoped_refptr<net::RuleBasedHostResolverProc> host_resolver_proc_;
2193 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc_;
2196 IN_PROC_BROWSER_TEST_F(BrowserTest2, NoTabsInPopups) {
2197 chrome::RegisterAppPrefs(L"Test");
2199 // We start with a normal browser with one tab.
2200 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2202 // Open a popup browser with a single blank foreground tab.
2203 Browser* popup_browser = new Browser(
2204 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile()));
2205 chrome::AddTabAt(popup_browser, GURL(), -1, true);
2206 EXPECT_EQ(1, popup_browser->tab_strip_model()->count());
2208 // Now try opening another tab in the popup browser.
2209 AddTabWithURLParams params1(url, ui::PAGE_TRANSITION_TYPED);
2210 popup_browser->AddTabWithURL(&params1);
2211 EXPECT_EQ(popup_browser, params1.target);
2213 // The popup should still only have one tab.
2214 EXPECT_EQ(1, popup_browser->tab_strip_model()->count());
2216 // The normal browser should now have two.
2217 EXPECT_EQ(2, browser()->tab_strip_model()->count());
2219 // Open an app frame browser with a single blank foreground tab.
2220 Browser* app_browser = new Browser(Browser::CreateParams::CreateForApp(
2221 L"Test", browser()->profile(), false));
2222 chrome::AddTabAt(app_browser, GURL(), -1, true);
2223 EXPECT_EQ(1, app_browser->tab_strip_model()->count());
2225 // Now try opening another tab in the app browser.
2226 AddTabWithURLParams params2(GURL(url::kAboutBlankURL),
2227 ui::PAGE_TRANSITION_TYPED);
2228 app_browser->AddTabWithURL(&params2);
2229 EXPECT_EQ(app_browser, params2.target);
2231 // The popup should still only have one tab.
2232 EXPECT_EQ(1, app_browser->tab_strip_model()->count());
2234 // The normal browser should now have three.
2235 EXPECT_EQ(3, browser()->tab_strip_model()->count());
2237 // Open an app frame popup browser with a single blank foreground tab.
2238 Browser* app_popup_browser = new Browser(Browser::CreateParams::CreateForApp(
2239 L"Test", browser()->profile(), false));
2240 chrome::AddTabAt(app_popup_browser, GURL(), -1, true);
2241 EXPECT_EQ(1, app_popup_browser->tab_strip_model()->count());
2243 // Now try opening another tab in the app popup browser.
2244 AddTabWithURLParams params3(GURL(url::kAboutBlankURL),
2245 ui::PAGE_TRANSITION_TYPED);
2246 app_popup_browser->AddTabWithURL(&params3);
2247 EXPECT_EQ(app_popup_browser, params3.target);
2249 // The popup should still only have one tab.
2250 EXPECT_EQ(1, app_popup_browser->tab_strip_model()->count());
2252 // The normal browser should now have four.
2253 EXPECT_EQ(4, browser()->tab_strip_model()->count());
2255 // Close the additional browsers.
2256 popup_browser->tab_strip_model()->CloseAllTabs();
2257 app_browser->tab_strip_model()->CloseAllTabs();
2258 app_popup_browser->tab_strip_model()->CloseAllTabs();
2260 #endif
2262 IN_PROC_BROWSER_TEST_F(BrowserTest, WindowOpenClose) {
2263 base::CommandLine::ForCurrentProcess()->AppendSwitch(
2264 switches::kDisablePopupBlocking);
2265 GURL url = ui_test_utils::GetTestUrl(
2266 base::FilePath(), base::FilePath().AppendASCII("window.close.html"));
2268 base::string16 title = ASCIIToUTF16("Title Of Awesomeness");
2269 content::TitleWatcher title_watcher(
2270 browser()->tab_strip_model()->GetActiveWebContents(), title);
2271 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 2);
2272 EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
2275 // TODO(linux_aura) http://crbug.com/163931
2276 // Mac disabled: http://crbug.com/169820
2277 #if !defined(OS_MACOSX) && \
2278 !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
2279 IN_PROC_BROWSER_TEST_F(BrowserTest, FullscreenBookmarkBar) {
2280 #if defined(OS_WIN) && defined(USE_ASH)
2281 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2282 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2283 switches::kAshBrowserTests))
2284 return;
2285 #endif
2287 chrome::ToggleBookmarkBar(browser());
2288 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
2289 chrome::ToggleFullscreenMode(browser());
2290 EXPECT_TRUE(browser()->window()->IsFullscreen());
2291 #if defined(OS_MACOSX)
2292 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
2293 #elif defined(OS_CHROMEOS)
2294 // TODO(jamescook): If immersive fullscreen is disabled by default, test
2295 // for BookmarkBar::HIDDEN.
2296 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
2297 #else
2298 EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
2299 #endif
2301 #endif
2303 IN_PROC_BROWSER_TEST_F(BrowserTest, DisallowFileUrlUniversalAccessTest) {
2304 GURL url = ui_test_utils::GetTestUrl(
2305 base::FilePath(),
2306 base::FilePath().AppendASCII("fileurl_universalaccess.html"));
2308 base::string16 expected_title(ASCIIToUTF16("Disallowed"));
2309 content::TitleWatcher title_watcher(
2310 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
2311 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("Allowed"));
2312 ui_test_utils::NavigateToURL(browser(), url);
2313 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
2316 class KioskModeTest : public BrowserTest {
2317 public:
2318 KioskModeTest() {}
2320 void SetUpCommandLine(base::CommandLine* command_line) override {
2321 command_line->AppendSwitch(switches::kKioskMode);
2325 #if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
2326 // Mac: http://crbug.com/103912
2327 // Linux: http://crbug.com/163931
2328 #define MAYBE_EnableKioskModeTest DISABLED_EnableKioskModeTest
2329 #else
2330 #define MAYBE_EnableKioskModeTest EnableKioskModeTest
2331 #endif
2332 IN_PROC_BROWSER_TEST_F(KioskModeTest, MAYBE_EnableKioskModeTest) {
2333 // Check if browser is in fullscreen mode.
2334 ASSERT_TRUE(browser()->window()->IsFullscreen());
2335 ASSERT_FALSE(browser()->window()->IsFullscreenBubbleVisible());
2338 #if defined(OS_WIN)
2339 // This test verifies that Chrome can be launched with a user-data-dir path
2340 // which contains non ASCII characters.
2341 class LaunchBrowserWithNonAsciiUserDatadir : public BrowserTest {
2342 public:
2343 LaunchBrowserWithNonAsciiUserDatadir() {}
2345 void SetUpCommandLine(base::CommandLine* command_line) override {
2346 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
2347 base::FilePath tmp_profile = temp_dir_.path().AppendASCII("tmp_profile");
2348 tmp_profile = tmp_profile.Append(L"Test Chrome G\u00E9raldine");
2350 ASSERT_TRUE(base::CreateDirectory(tmp_profile));
2351 command_line->AppendSwitchPath(switches::kUserDataDir, tmp_profile);
2354 base::ScopedTempDir temp_dir_;
2357 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithNonAsciiUserDatadir,
2358 TestNonAsciiUserDataDir) {
2359 // Verify that the window is present.
2360 ASSERT_TRUE(browser());
2361 ASSERT_TRUE(browser()->profile());
2362 // Verify that the profile has been added correctly to the ProfileInfoCache.
2363 ASSERT_EQ(1u, g_browser_process->profile_manager()->
2364 GetProfileInfoCache().GetNumberOfProfiles());
2366 #endif // defined(OS_WIN)
2368 #if defined(OS_WIN)
2369 // This test verifies that Chrome can be launched with a user-data-dir path
2370 // which trailing slashes.
2371 class LaunchBrowserWithTrailingSlashDatadir : public BrowserTest {
2372 public:
2373 LaunchBrowserWithTrailingSlashDatadir() {}
2375 void SetUpCommandLine(base::CommandLine* command_line) override {
2376 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
2377 base::FilePath tmp_profile = temp_dir_.path().AppendASCII("tmp_profile");
2378 tmp_profile = tmp_profile.Append(L"Test Chrome\\");
2380 ASSERT_TRUE(base::CreateDirectory(tmp_profile));
2381 command_line->AppendSwitchPath(switches::kUserDataDir, tmp_profile);
2384 base::ScopedTempDir temp_dir_;
2387 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithTrailingSlashDatadir,
2388 TestTrailingSlashUserDataDir) {
2389 // Verify that the window is present.
2390 ASSERT_TRUE(browser());
2391 ASSERT_TRUE(browser()->profile());
2392 // Verify that the profile has been added correctly to the ProfileInfoCache.
2393 ASSERT_EQ(1u, g_browser_process->profile_manager()->
2394 GetProfileInfoCache().GetNumberOfProfiles());
2396 #endif // defined(OS_WIN)
2398 // Tests to ensure that the browser continues running in the background after
2399 // the last window closes.
2400 class RunInBackgroundTest : public BrowserTest {
2401 public:
2402 RunInBackgroundTest() {}
2404 void SetUpCommandLine(base::CommandLine* command_line) override {
2405 command_line->AppendSwitch(switches::kKeepAliveForTest);
2409 IN_PROC_BROWSER_TEST_F(RunInBackgroundTest, RunInBackgroundBasicTest) {
2410 // Close the browser window, then open a new one - the browser should keep
2411 // running.
2412 Profile* profile = browser()->profile();
2413 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2414 content::WindowedNotificationObserver observer(
2415 chrome::NOTIFICATION_BROWSER_CLOSED,
2416 content::Source<Browser>(browser()));
2417 chrome::CloseWindow(browser());
2418 observer.Wait();
2419 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
2421 ui_test_utils::BrowserAddedObserver browser_added_observer;
2422 chrome::NewEmptyWindow(profile, chrome::GetActiveDesktop());
2423 browser_added_observer.WaitForSingleNewBrowser();
2425 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2428 // Tests to ensure that the browser continues running in the background after
2429 // the last window closes.
2430 class NoStartupWindowTest : public BrowserTest {
2431 public:
2432 NoStartupWindowTest() {}
2434 void SetUpCommandLine(base::CommandLine* command_line) override {
2435 command_line->AppendSwitch(switches::kNoStartupWindow);
2436 command_line->AppendSwitch(switches::kKeepAliveForTest);
2439 // Returns true if any commands were processed.
2440 bool ProcessedAnyCommands(
2441 sessions::BaseSessionService* base_session_service) {
2442 sessions::BaseSessionServiceTestHelper test_helper(base_session_service);
2443 return test_helper.ProcessedAnyCommands();
2447 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest, NoStartupWindowBasicTest) {
2448 #if defined(OS_WIN) && defined(USE_ASH)
2449 // kNoStartupWindow doesn't make sense in Metro+Ash.
2450 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2451 switches::kAshBrowserTests))
2452 return;
2453 #endif
2455 // No browser window should be started by default.
2456 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
2458 // Starting a browser window should work just fine.
2459 ui_test_utils::BrowserAddedObserver browser_added_observer;
2460 CreateBrowser(ProfileManager::GetActiveUserProfile());
2461 browser_added_observer.WaitForSingleNewBrowser();
2463 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2466 // Chromeos needs to track app windows because it considers them to be part of
2467 // session state.
2468 #if !defined(OS_CHROMEOS)
2469 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest, DontInitSessionServiceForApps) {
2470 #if defined(OS_WIN) && defined(USE_ASH)
2471 // kNoStartupWindow doesn't make sense in Metro+Ash.
2472 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2473 switches::kAshBrowserTests))
2474 return;
2475 #endif
2477 Profile* profile = ProfileManager::GetActiveUserProfile();
2479 SessionService* session_service =
2480 SessionServiceFactory::GetForProfile(profile);
2481 sessions::BaseSessionService* base_session_service =
2482 session_service->GetBaseSessionServiceForTest();
2483 ASSERT_FALSE(ProcessedAnyCommands(base_session_service));
2485 ui_test_utils::BrowserAddedObserver browser_added_observer;
2486 CreateBrowserForApp("blah", profile);
2487 browser_added_observer.WaitForSingleNewBrowser();
2489 ASSERT_FALSE(ProcessedAnyCommands(base_session_service));
2491 #endif // !defined(OS_CHROMEOS)
2493 // This test needs to be placed outside the anonymous namespace because we
2494 // need to access private type of Browser.
2495 class AppModeTest : public BrowserTest {
2496 public:
2497 AppModeTest() {}
2499 void SetUpCommandLine(base::CommandLine* command_line) override {
2500 GURL url = ui_test_utils::GetTestUrl(
2501 base::FilePath(), base::FilePath().AppendASCII("title1.html"));
2502 command_line->AppendSwitchASCII(switches::kApp, url.spec());
2506 IN_PROC_BROWSER_TEST_F(AppModeTest, EnableAppModeTest) {
2507 #if defined(OS_WIN) && defined(USE_ASH)
2508 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2509 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2510 switches::kAshBrowserTests))
2511 return;
2512 #endif
2514 // Test that an application browser window loads correctly.
2516 // Verify the browser is in application mode.
2517 EXPECT_TRUE(browser()->is_app());
2520 // Confirm chrome://version contains some expected content.
2521 IN_PROC_BROWSER_TEST_F(BrowserTest, AboutVersion) {
2522 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL));
2523 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2524 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("WebKit"), true, true,
2525 NULL, NULL),
2527 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("OS"), true, true,
2528 NULL, NULL),
2530 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("JavaScript"), true,
2531 true, NULL, NULL),
2535 static const base::FilePath::CharType* kTestDir =
2536 FILE_PATH_LITERAL("click_modifier");
2537 static const char kFirstPageTitle[] = "First window";
2538 static const char kSecondPageTitle[] = "New window!";
2540 class ClickModifierTest : public InProcessBrowserTest {
2541 public:
2542 ClickModifierTest() {
2545 // Returns a url that opens a new window or tab when clicked, via javascript.
2546 GURL GetWindowOpenURL() {
2547 return ui_test_utils::GetTestUrl(
2548 base::FilePath(kTestDir),
2549 base::FilePath(FILE_PATH_LITERAL("window_open.html")));
2552 // Returns a url that follows a simple link when clicked, unless affected by
2553 // modifiers.
2554 GURL GetHrefURL() {
2555 return ui_test_utils::GetTestUrl(
2556 base::FilePath(kTestDir),
2557 base::FilePath(FILE_PATH_LITERAL("href.html")));
2560 base::string16 getFirstPageTitle() {
2561 return ASCIIToUTF16(kFirstPageTitle);
2564 base::string16 getSecondPageTitle() {
2565 return ASCIIToUTF16(kSecondPageTitle);
2568 // Loads our test page and simulates a single click using the supplied button
2569 // and modifiers. The click will cause either a navigation or the creation of
2570 // a new window or foreground or background tab. We verify that the expected
2571 // disposition occurs.
2572 void RunTest(Browser* browser,
2573 const GURL& url,
2574 int modifiers,
2575 blink::WebMouseEvent::Button button,
2576 WindowOpenDisposition disposition) {
2577 ui_test_utils::NavigateToURL(browser, url);
2578 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(),
2579 browser->host_desktop_type()));
2580 EXPECT_EQ(1, browser->tab_strip_model()->count());
2581 content::WebContents* web_contents =
2582 browser->tab_strip_model()->GetActiveWebContents();
2583 EXPECT_EQ(url, web_contents->GetURL());
2585 if (disposition == CURRENT_TAB) {
2586 content::WebContents* web_contents =
2587 browser->tab_strip_model()->GetActiveWebContents();
2588 content::TestNavigationObserver same_tab_observer(web_contents);
2589 SimulateMouseClick(web_contents, modifiers, button);
2590 same_tab_observer.Wait();
2591 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(),
2592 browser->host_desktop_type()));
2593 EXPECT_EQ(1, browser->tab_strip_model()->count());
2594 EXPECT_EQ(getSecondPageTitle(), web_contents->GetTitle());
2595 return;
2598 content::WindowedNotificationObserver observer(
2599 chrome::NOTIFICATION_TAB_ADDED,
2600 content::NotificationService::AllSources());
2601 SimulateMouseClick(web_contents, modifiers, button);
2602 observer.Wait();
2604 if (disposition == NEW_WINDOW) {
2605 EXPECT_EQ(2u, chrome::GetBrowserCount(browser->profile(),
2606 browser->host_desktop_type()));
2607 return;
2610 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(),
2611 browser->host_desktop_type()));
2612 EXPECT_EQ(2, browser->tab_strip_model()->count());
2613 web_contents = browser->tab_strip_model()->GetActiveWebContents();
2614 WaitForLoadStop(web_contents);
2615 if (disposition == NEW_FOREGROUND_TAB) {
2616 EXPECT_EQ(getSecondPageTitle(), web_contents->GetTitle());
2617 } else {
2618 ASSERT_EQ(NEW_BACKGROUND_TAB, disposition);
2619 EXPECT_EQ(getFirstPageTitle(), web_contents->GetTitle());
2623 private:
2624 DISALLOW_COPY_AND_ASSIGN(ClickModifierTest);
2627 // Tests for clicking on elements with handlers that run window.open.
2629 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenBasicClickTest) {
2630 int modifiers = 0;
2631 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft;
2632 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB;
2633 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition);
2636 // TODO(ericu): Alt-click behavior on window.open is platform-dependent and not
2637 // well defined. Should we add tests so we know if it changes?
2639 // Shift-clicks open in a new window.
2640 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenShiftClickTest) {
2641 int modifiers = blink::WebInputEvent::ShiftKey;
2642 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft;
2643 WindowOpenDisposition disposition = NEW_WINDOW;
2644 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition);
2647 // Control-clicks open in a background tab.
2648 // On OSX meta [the command key] takes the place of control.
2649 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenControlClickTest) {
2650 #if defined(OS_MACOSX)
2651 int modifiers = blink::WebInputEvent::MetaKey;
2652 #else
2653 int modifiers = blink::WebInputEvent::ControlKey;
2654 #endif
2655 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft;
2656 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB;
2657 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition);
2660 // Control-shift-clicks open in a foreground tab.
2661 // On OSX meta [the command key] takes the place of control.
2662 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenControlShiftClickTest) {
2663 #if defined(OS_MACOSX)
2664 int modifiers = blink::WebInputEvent::MetaKey;
2665 #else
2666 int modifiers = blink::WebInputEvent::ControlKey;
2667 #endif
2668 modifiers |= blink::WebInputEvent::ShiftKey;
2669 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft;
2670 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB;
2671 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition);
2674 // Middle-clicks open in a background tab.
2675 #if defined(OS_LINUX)
2676 // http://crbug.com/396347
2677 #define MAYBE_WindowOpenMiddleClickTest DISABLED_WindowOpenMiddleClickTest
2678 #else
2679 #define MAYBE_WindowOpenMiddleClickTest WindowOpenMiddleClickTest
2680 #endif
2681 IN_PROC_BROWSER_TEST_F(ClickModifierTest, MAYBE_WindowOpenMiddleClickTest) {
2682 int modifiers = 0;
2683 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonMiddle;
2684 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB;
2685 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition);
2688 // Shift-middle-clicks open in a foreground tab.
2689 IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenShiftMiddleClickTest) {
2690 int modifiers = blink::WebInputEvent::ShiftKey;
2691 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonMiddle;
2692 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB;
2693 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition);
2696 // Tests for clicking on normal links.
2698 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefBasicClickTest) {
2699 int modifiers = 0;
2700 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft;
2701 WindowOpenDisposition disposition = CURRENT_TAB;
2702 RunTest(browser(), GetHrefURL(), modifiers, button, disposition);
2705 // TODO(ericu): Alt-click behavior on links is platform-dependent and not well
2706 // defined. Should we add tests so we know if it changes?
2708 // Shift-clicks open in a new window.
2709 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefShiftClickTest) {
2710 int modifiers = blink::WebInputEvent::ShiftKey;
2711 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft;
2712 WindowOpenDisposition disposition = NEW_WINDOW;
2713 RunTest(browser(), GetHrefURL(), modifiers, button, disposition);
2716 // Control-clicks open in a background tab.
2717 // On OSX meta [the command key] takes the place of control.
2718 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefControlClickTest) {
2719 #if defined(OS_MACOSX)
2720 int modifiers = blink::WebInputEvent::MetaKey;
2721 #else
2722 int modifiers = blink::WebInputEvent::ControlKey;
2723 #endif
2724 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft;
2725 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB;
2726 RunTest(browser(), GetHrefURL(), modifiers, button, disposition);
2729 // Control-shift-clicks open in a foreground tab.
2730 // On OSX meta [the command key] takes the place of control.
2731 // http://crbug.com/396347
2732 IN_PROC_BROWSER_TEST_F(ClickModifierTest, DISABLED_HrefControlShiftClickTest) {
2733 #if defined(OS_MACOSX)
2734 int modifiers = blink::WebInputEvent::MetaKey;
2735 #else
2736 int modifiers = blink::WebInputEvent::ControlKey;
2737 #endif
2738 modifiers |= blink::WebInputEvent::ShiftKey;
2739 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonLeft;
2740 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB;
2741 RunTest(browser(), GetHrefURL(), modifiers, button, disposition);
2744 // Middle-clicks open in a background tab.
2745 IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefMiddleClickTest) {
2746 int modifiers = 0;
2747 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonMiddle;
2748 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB;
2749 RunTest(browser(), GetHrefURL(), modifiers, button, disposition);
2752 // Shift-middle-clicks open in a foreground tab.
2753 // http://crbug.com/396347
2754 IN_PROC_BROWSER_TEST_F(ClickModifierTest, DISABLED_HrefShiftMiddleClickTest) {
2755 int modifiers = blink::WebInputEvent::ShiftKey;
2756 blink::WebMouseEvent::Button button = blink::WebMouseEvent::ButtonMiddle;
2757 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB;
2758 RunTest(browser(), GetHrefURL(), modifiers, button, disposition);
2761 IN_PROC_BROWSER_TEST_F(BrowserTest, GetSizeForNewRenderView) {
2762 #if defined(OS_MACOSX) && !defined(OS_IOS)
2763 // TODO(erikchen): This behavior has regressed on OSX 10.7 and 10.8 and should
2764 // be fixed. http://crbug.com/503185
2765 if (base::mac::IsOSMountainLion() || base::mac::IsOSLion())
2766 return;
2767 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
2768 // The instant extended NTP has javascript that does not work with
2769 // ui_test_utils::NavigateToURL. The NTP rvh reloads when the browser tries
2770 // to navigate away from the page, which causes the WebContents to end up in
2771 // an inconsistent state. (is_loaded = true, last_commited_url=ntp,
2772 // visible_url=title1.html)
2773 browser()->profile()->GetPrefs()->SetBoolean(prefs::kWebKitJavascriptEnabled,
2774 false);
2775 ASSERT_TRUE(test_server()->Start());
2776 // Create an HTTPS server for cross-site transition.
2777 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS,
2778 net::SpawnedTestServer::kLocalhost,
2779 base::FilePath(kDocRoot));
2780 ASSERT_TRUE(https_test_server.Start());
2782 // Start with NTP.
2783 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
2784 ASSERT_EQ(BookmarkBar::DETACHED, browser()->bookmark_bar_state());
2785 WebContents* web_contents =
2786 browser()->tab_strip_model()->GetActiveWebContents();
2787 content::RenderViewHost* prev_rvh = web_contents->GetRenderViewHost();
2788 const int height_inset =
2789 browser()->window()->GetRenderViewHeightInsetWithDetachedBookmarkBar();
2790 const gfx::Size initial_wcv_size =
2791 web_contents->GetContainerBounds().size();
2792 RenderViewSizeObserver observer(web_contents, browser()->window());
2794 // Navigate to a non-NTP page, without resizing WebContentsView.
2795 ui_test_utils::NavigateToURL(browser(),
2796 test_server()->GetURL("files/title1.html"));
2797 ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
2798 // A new RenderViewHost should be created.
2799 EXPECT_NE(prev_rvh, web_contents->GetRenderViewHost());
2800 prev_rvh = web_contents->GetRenderViewHost();
2801 gfx::Size rwhv_create_size0, rwhv_commit_size0, wcv_commit_size0;
2802 observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(),
2803 &rwhv_create_size0,
2804 &rwhv_commit_size0,
2805 &wcv_commit_size0);
2806 // The create height of RenderWidgetHostView should include the height inset.
2807 EXPECT_EQ(gfx::Size(initial_wcv_size.width(),
2808 initial_wcv_size.height() + height_inset),
2809 rwhv_create_size0);
2810 // When a navigation entry is committed, the size of RenderWidgetHostView
2811 // should be the same as when it was first created.
2812 EXPECT_EQ(rwhv_create_size0, rwhv_commit_size0);
2813 // Sizes of the current RenderWidgetHostView and WebContentsView should not
2814 // change before and after WebContentsDelegate::DidNavigateMainFramePostCommit
2815 // (implemented by Browser); we obtain the sizes before PostCommit via
2816 // WebContentsObserver::NavigationEntryCommitted (implemented by
2817 // RenderViewSizeObserver).
2818 EXPECT_EQ(rwhv_commit_size0,
2819 web_contents->GetRenderWidgetHostView()->GetViewBounds().size());
2820 // The behavior differs between OSX and views.
2821 // In OSX, the wcv does not change size until after the commit, when the
2822 // bookmark bar disappears (correct).
2823 // In views, the wcv changes size at commit time.
2824 #if defined(OS_MACOSX)
2825 EXPECT_EQ(gfx::Size(wcv_commit_size0.width(),
2826 wcv_commit_size0.height() + height_inset),
2827 web_contents->GetContainerBounds().size());
2828 #else
2829 EXPECT_EQ(wcv_commit_size0, web_contents->GetContainerBounds().size());
2830 #endif
2832 // Navigate to another non-NTP page, without resizing WebContentsView.
2833 ui_test_utils::NavigateToURL(browser(),
2834 https_test_server.GetURL("files/title2.html"));
2835 ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
2836 // A new RenderVieHost should be created.
2837 EXPECT_NE(prev_rvh, web_contents->GetRenderViewHost());
2838 gfx::Size rwhv_create_size1, rwhv_commit_size1, wcv_commit_size1;
2839 observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(),
2840 &rwhv_create_size1,
2841 &rwhv_commit_size1,
2842 &wcv_commit_size1);
2843 EXPECT_EQ(rwhv_create_size1, rwhv_commit_size1);
2844 EXPECT_EQ(rwhv_commit_size1,
2845 web_contents->GetRenderWidgetHostView()->GetViewBounds().size());
2846 EXPECT_EQ(wcv_commit_size1, web_contents->GetContainerBounds().size());
2848 // Navigate from NTP to a non-NTP page, resizing WebContentsView while
2849 // navigation entry is pending.
2850 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
2851 gfx::Size wcv_resize_insets(1, 1);
2852 observer.set_wcv_resize_insets(wcv_resize_insets);
2853 ui_test_utils::NavigateToURL(browser(),
2854 test_server()->GetURL("files/title2.html"));
2855 ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
2856 gfx::Size rwhv_create_size2, rwhv_commit_size2, wcv_commit_size2;
2857 observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(),
2858 &rwhv_create_size2,
2859 &rwhv_commit_size2,
2860 &wcv_commit_size2);
2862 // The behavior on OSX and Views is incorrect in this edge case, but they are
2863 // differently incorrect.
2864 // The behavior should be:
2865 // initial wcv size: (100,100) (to choose random numbers)
2866 // initial rwhv size: (100,140)
2867 // commit wcv size: (101, 101)
2868 // commit rwhv size: (101, 141)
2869 // final wcv size: (101, 141)
2870 // final rwhv size: (101, 141)
2872 // On OSX, the commit rwhv size is (101, 101)
2873 // On views, the commit wcv size is (101, 141)
2874 // All other sizes are correct.
2876 // The create height of RenderWidgetHostView should include the height inset.
2877 EXPECT_EQ(gfx::Size(initial_wcv_size.width(),
2878 initial_wcv_size.height() + height_inset),
2879 rwhv_create_size2);
2880 gfx::Size exp_commit_size(initial_wcv_size);
2882 #if defined(OS_MACOSX)
2883 exp_commit_size.Enlarge(wcv_resize_insets.width(),
2884 wcv_resize_insets.height());
2885 #else
2886 exp_commit_size.Enlarge(wcv_resize_insets.width(),
2887 wcv_resize_insets.height() + height_inset);
2888 #endif
2889 EXPECT_EQ(exp_commit_size, rwhv_commit_size2);
2890 EXPECT_EQ(exp_commit_size, wcv_commit_size2);
2891 gfx::Size exp_final_size(initial_wcv_size);
2892 exp_final_size.Enlarge(wcv_resize_insets.width(),
2893 wcv_resize_insets.height() + height_inset);
2894 EXPECT_EQ(exp_final_size,
2895 web_contents->GetRenderWidgetHostView()->GetViewBounds().size());
2896 EXPECT_EQ(exp_final_size, web_contents->GetContainerBounds().size());
2899 IN_PROC_BROWSER_TEST_F(BrowserTest, CanDuplicateTab) {
2900 GURL url(ui_test_utils::GetTestUrl(
2901 base::FilePath(base::FilePath::kCurrentDirectory),
2902 base::FilePath(kTitle1File)));
2903 ui_test_utils::NavigateToURL(browser(), url);
2905 AddTabAtIndex(0, url, ui::PAGE_TRANSITION_TYPED);
2907 int active_index = browser()->tab_strip_model()->active_index();
2908 EXPECT_EQ(0, active_index);
2910 EXPECT_TRUE(chrome::CanDuplicateTab(browser()));
2911 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 0));
2912 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2914 content::WebContents* web_contents =
2915 browser()->tab_strip_model()->GetActiveWebContents();
2917 TestInterstitialPage* interstitial =
2918 new TestInterstitialPage(web_contents, false, GURL());
2919 content::WaitForInterstitialAttach(web_contents);
2921 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
2923 // Verify that the "Duplicate tab" command is disabled on interstitial
2924 // pages. Regression test for crbug.com/310812
2925 EXPECT_FALSE(chrome::CanDuplicateTab(browser()));
2926 EXPECT_FALSE(chrome::CanDuplicateTabAt(browser(), 0));
2927 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2929 // Don't proceed and wait for interstitial to detach. This doesn't
2930 // destroy |contents|.
2931 interstitial->DontProceed();
2932 content::WaitForInterstitialDetach(web_contents);
2933 // interstitial is deleted now.
2935 EXPECT_TRUE(chrome::CanDuplicateTab(browser()));
2936 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 0));
2937 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2940 // Tests that the WebContentsObserver::SecurityStyleChanged event fires
2941 // with the current style on HTTP, broken HTTPS, and valid HTTPS pages.
2942 IN_PROC_BROWSER_TEST_F(BrowserTest, SecurityStyleChangedObserver) {
2943 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS,
2944 net::SpawnedTestServer::kLocalhost,
2945 base::FilePath(kDocRoot));
2946 net::SpawnedTestServer https_test_server_expired(
2947 net::SpawnedTestServer::TYPE_HTTPS,
2948 net::SpawnedTestServer::SSLOptions(
2949 net::SpawnedTestServer::SSLOptions::CERT_EXPIRED),
2950 base::FilePath(kDocRoot));
2952 ASSERT_TRUE(https_test_server.Start());
2953 ASSERT_TRUE(https_test_server_expired.Start());
2954 ASSERT_TRUE(test_server()->Start());
2956 content::WebContents* web_contents =
2957 browser()->tab_strip_model()->GetActiveWebContents();
2958 SecurityStyleTestObserver observer(web_contents);
2960 // Visit an HTTP url.
2961 GURL http_url(test_server()->GetURL(std::string()));
2962 ui_test_utils::NavigateToURL(browser(), http_url);
2963 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
2964 observer.latest_security_style());
2965 EXPECT_EQ(0u, observer.latest_explanations().warning_explanations.size());
2966 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
2967 EXPECT_EQ(0u, observer.latest_explanations().secure_explanations.size());
2968 EXPECT_FALSE(observer.latest_explanations().scheme_is_cryptographic);
2969 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
2970 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
2972 // Visit an (otherwise valid) HTTPS page that displays mixed content.
2973 std::string replacement_path;
2974 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2975 "files/ssl/page_displays_insecure_content.html",
2976 test_server()->host_port_pair(), &replacement_path));
2978 GURL mixed_content_url(https_test_server.GetURL(replacement_path));
2979 ui_test_utils::NavigateToURL(browser(), mixed_content_url);
2980 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
2981 observer.latest_security_style());
2983 const content::SecurityStyleExplanations& mixed_content_explanation =
2984 observer.latest_explanations();
2985 ASSERT_EQ(0u, mixed_content_explanation.warning_explanations.size());
2986 ASSERT_EQ(0u, mixed_content_explanation.broken_explanations.size());
2987 CheckSecureExplanations(mixed_content_explanation.secure_explanations,
2988 VALID_CERTIFICATE, browser());
2989 EXPECT_TRUE(mixed_content_explanation.scheme_is_cryptographic);
2990 EXPECT_TRUE(mixed_content_explanation.displayed_insecure_content);
2991 EXPECT_FALSE(mixed_content_explanation.ran_insecure_content);
2992 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
2993 mixed_content_explanation.displayed_insecure_content_style);
2994 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
2995 mixed_content_explanation.ran_insecure_content_style);
2997 // Visit a broken HTTPS url.
2998 GURL expired_url(https_test_server_expired.GetURL(std::string()));
2999 ui_test_utils::NavigateToURL(browser(), expired_url);
3001 // An interstitial should show, and an event for the lock icon on the
3002 // interstitial should fire.
3003 content::WaitForInterstitialAttach(web_contents);
3004 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
3005 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
3006 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
3007 INVALID_CERTIFICATE, browser());
3008 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
3009 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
3010 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
3012 // Before clicking through, navigate to a different page, and then go
3013 // back to the interstitial.
3014 GURL valid_https_url(https_test_server.GetURL(std::string()));
3015 ui_test_utils::NavigateToURL(browser(), valid_https_url);
3016 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
3017 observer.latest_security_style());
3018 EXPECT_EQ(0u, observer.latest_explanations().warning_explanations.size());
3019 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
3020 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
3021 VALID_CERTIFICATE, browser());
3022 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
3023 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
3024 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
3026 // After going back to the interstitial, an event for a broken lock
3027 // icon should fire again.
3028 ui_test_utils::NavigateToURL(browser(), expired_url);
3029 content::WaitForInterstitialAttach(web_contents);
3030 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
3031 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
3032 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
3033 INVALID_CERTIFICATE, browser());
3034 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
3035 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
3036 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
3038 // Since the next expected style is the same as the previous, clear
3039 // the observer (to make sure that the event fires twice and we don't
3040 // just see the previous event's style).
3041 observer.ClearLatestSecurityStyleAndExplanations();
3043 // Other conditions cannot be tested on this host after clicking
3044 // through because once the interstitial is clicked through, all URLs
3045 // for this host will remain in a broken state.
3046 ProceedThroughInterstitial(web_contents);
3047 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
3048 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
3049 INVALID_CERTIFICATE, browser());
3050 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
3051 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
3052 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
3055 // Visit a valid HTTPS page, then a broken HTTPS page, and then go back,
3056 // and test that the observed security style matches.
3057 IN_PROC_BROWSER_TEST_F(BrowserTest, SecurityStyleChangedObserverGoBack) {
3058 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS,
3059 net::SpawnedTestServer::kLocalhost,
3060 base::FilePath(kDocRoot));
3062 // Use a separate server to work around a mysterious SSL handshake
3063 // timeout when both requests go to the same server. See
3064 // https://crbug.com/515906.
3065 net::SpawnedTestServer https_test_server_expired(
3066 net::SpawnedTestServer::TYPE_HTTPS,
3067 net::SpawnedTestServer::SSLOptions(
3068 net::SpawnedTestServer::SSLOptions::CERT_EXPIRED),
3069 base::FilePath(kDocRoot));
3071 ASSERT_TRUE(https_test_server.Start());
3072 ASSERT_TRUE(https_test_server_expired.Start());
3074 content::WebContents* web_contents =
3075 browser()->tab_strip_model()->GetActiveWebContents();
3076 SecurityStyleTestObserver observer(web_contents);
3078 // Visit a valid HTTPS url.
3079 GURL valid_https_url(https_test_server.GetURL(std::string()));
3080 ui_test_utils::NavigateToURL(browser(), valid_https_url);
3081 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
3082 observer.latest_security_style());
3083 EXPECT_EQ(0u, observer.latest_explanations().warning_explanations.size());
3084 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
3085 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
3086 VALID_CERTIFICATE, browser());
3087 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
3088 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
3089 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
3091 // Navigate to a bad HTTPS page on a different host, and then click
3092 // Back to verify that the previous good security style is seen again.
3093 GURL expired_https_url(https_test_server_expired.GetURL(std::string()));
3094 host_resolver()->AddRule("www.example_broken.test", "127.0.0.1");
3095 GURL::Replacements replace_host;
3096 replace_host.SetHostStr("www.example_broken.test");
3097 GURL https_url_different_host =
3098 expired_https_url.ReplaceComponents(replace_host);
3100 ui_test_utils::NavigateToURL(browser(), https_url_different_host);
3102 content::WaitForInterstitialAttach(web_contents);
3103 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
3104 CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID,
3105 browser());
3106 ProceedThroughInterstitial(web_contents);
3107 CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID,
3108 browser());
3109 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
3110 INVALID_CERTIFICATE, browser());
3111 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
3112 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
3113 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
3115 content::WindowedNotificationObserver back_nav_load_observer(
3116 content::NOTIFICATION_LOAD_STOP,
3117 content::Source<NavigationController>(&web_contents->GetController()));
3118 chrome::GoBack(browser(), CURRENT_TAB);
3119 back_nav_load_observer.Wait();
3121 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
3122 observer.latest_security_style());
3123 EXPECT_EQ(0u, observer.latest_explanations().warning_explanations.size());
3124 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
3125 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
3126 VALID_CERTIFICATE, browser());
3127 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
3128 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
3129 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
3132 namespace {
3133 class JSBooleanResultGetter {
3134 public:
3135 JSBooleanResultGetter() = default;
3136 void OnJsExecutionDone(base::Closure callback, const base::Value* value) {
3137 js_result_.reset(value->DeepCopy());
3138 callback.Run();
3140 bool GetResult() const {
3141 bool res;
3142 CHECK(js_result_);
3143 CHECK(js_result_->GetAsBoolean(&res));
3144 return res;
3147 private:
3148 scoped_ptr<base::Value> js_result_;
3149 DISALLOW_COPY_AND_ASSIGN(JSBooleanResultGetter);
3152 void CheckDisplayModeMQ(
3153 const base::string16& display_mode,
3154 content::WebContents* web_contents) {
3155 base::string16 funtcion =
3156 ASCIIToUTF16("(function() {return window.matchMedia('(display-mode: ") +
3157 display_mode + ASCIIToUTF16(")').matches;})();");
3158 JSBooleanResultGetter js_result_getter;
3159 // Execute the JS to run the tests, and wait until it has finished.
3160 base::RunLoop run_loop;
3161 web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
3162 funtcion,
3163 base::Bind(&JSBooleanResultGetter::OnJsExecutionDone,
3164 base::Unretained(&js_result_getter), run_loop.QuitClosure()));
3165 run_loop.Run();
3166 EXPECT_TRUE(js_result_getter.GetResult());
3168 } // namespace
3170 // flaky new test: http://crbug.com/471703
3171 IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_ChangeDisplayMode) {
3172 CheckDisplayModeMQ(
3173 ASCIIToUTF16("browser"),
3174 browser()->tab_strip_model()->GetActiveWebContents());
3176 Profile* profile = ProfileManager::GetActiveUserProfile();
3177 ui_test_utils::BrowserAddedObserver browser_added_observer;
3178 Browser* app_browser = CreateBrowserForApp("blah", profile);
3179 browser_added_observer.WaitForSingleNewBrowser();
3180 auto app_contents = app_browser->tab_strip_model()->GetActiveWebContents();
3181 CheckDisplayModeMQ(ASCIIToUTF16("standalone"), app_contents);
3183 app_browser->window()->EnterFullscreen(
3184 GURL(), EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION,
3185 false);
3187 // Sync navigation just to make sure IPC has passed (updated
3188 // display mode is delivered to RP).
3189 content::TestNavigationObserver observer(app_contents, 1);
3190 ui_test_utils::NavigateToURL(app_browser, GURL(url::kAboutBlankURL));
3191 observer.Wait();
3193 CheckDisplayModeMQ(ASCIIToUTF16("fullscreen"), app_contents);