1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_ 6#define CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_ 7 8#include "base/command_line.h" 9#include "chrome/browser/signin/chrome_signin_client.h" 10#include "chrome/browser/signin/chrome_signin_client_factory.h" 11#include "chrome/browser/signin/signin_promo.h" 12#include "chrome/browser/ui/browser.h" 13#include "chrome/browser/ui/singleton_tabs.h" 14#include "chrome/browser/ui/tabs/tab_strip_model.h" 15#include "chrome/browser/ui/webui/signin/login_ui_service.h" 16#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" 17#include "chrome/common/chrome_switches.h" 18#include "chrome/common/url_constants.h" 19#include "chrome/test/base/in_process_browser_test.h" 20#include "chrome/test/base/ui_test_utils.h" 21#include "content/public/browser/notification_service.h" 22#include "content/public/browser/notification_types.h" 23#include "content/public/browser/render_process_host.h" 24#include "content/public/browser/render_view_host.h" 25#include "content/public/browser/web_contents.h" 26#include "content/public/browser/web_contents_observer.h" 27#include "content/public/common/content_switches.h" 28#include "google_apis/gaia/gaia_urls.h" 29#include "net/http/http_status_code.h" 30#include "net/url_request/test_url_fetcher_factory.h" 31#include "net/url_request/url_request_status.h" 32 33namespace { 34const char kNonSigninURL[] = "http://www.google.com"; 35} 36 37class SigninBrowserTest : public InProcessBrowserTest { 38 public: 39 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 40 https_server_.reset(new net::SpawnedTestServer( 41 net::SpawnedTestServer::TYPE_HTTPS, 42 net::SpawnedTestServer::kLocalhost, 43 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")))); 44 ASSERT_TRUE(https_server_->Start()); 45 46 // Add a host resolver rule to map all outgoing requests to the test server. 47 // This allows us to use "real" hostnames in URLs, which we can use to 48 // create arbitrary SiteInstances. 49 command_line->AppendSwitchASCII( 50 switches::kHostResolverRules, 51 "MAP * " + https_server_->host_port_pair().ToString() + 52 ",EXCLUDE localhost"); 53 command_line->AppendSwitch(switches::kIgnoreCertificateErrors); 54 // All tests in this file are for the web based sign in flows. 55 // TODO(guohui): fix tests for inline sign in flows. 56 command_line->AppendSwitch(switches::kEnableWebBasedSignin); 57 } 58 59 virtual void SetUp() OVERRIDE { 60 factory_.reset(new net::URLFetcherImplFactory()); 61 fake_factory_.reset(new net::FakeURLFetcherFactory(factory_.get())); 62 fake_factory_->SetFakeResponse( 63 GaiaUrls::GetInstance()->service_login_url(), std::string(), 64 net::HTTP_OK, net::URLRequestStatus::SUCCESS); 65 fake_factory_->SetFakeResponse( 66 GURL(kNonSigninURL), std::string(), net::HTTP_OK, 67 net::URLRequestStatus::SUCCESS); 68 // Yield control back to the InProcessBrowserTest framework. 69 InProcessBrowserTest::SetUp(); 70 } 71 72 virtual void TearDown() OVERRIDE { 73 if (fake_factory_.get()) { 74 fake_factory_->ClearFakeResponses(); 75 fake_factory_.reset(); 76 } 77 78 // Cancel any outstanding URL fetches and destroy the URLFetcherImplFactory 79 // we created. 80 net::URLFetcher::CancelAll(); 81 factory_.reset(); 82 InProcessBrowserTest::TearDown(); 83 } 84 85 private: 86 // Fake URLFetcher factory used to mock out GAIA signin. 87 scoped_ptr<net::FakeURLFetcherFactory> fake_factory_; 88 89 // The URLFetcherImplFactory instance used to instantiate |fake_factory_|. 90 scoped_ptr<net::URLFetcherImplFactory> factory_; 91 92 scoped_ptr<net::SpawnedTestServer> https_server_; 93}; 94 95// If the one-click-signin feature is not enabled (e.g Chrome OS), we 96// never grant signin privileges to any renderer processes. 97#if defined(ENABLE_ONE_CLICK_SIGNIN) 98const bool kOneClickSigninEnabled = true; 99#else 100const bool kOneClickSigninEnabled = false; 101#endif 102 103// Disabled on Windows due to flakiness. http://crbug.com/249055 104#if defined(OS_WIN) 105#define MAYBE_ProcessIsolation DISABLED_ProcessIsolation 106#else 107#define MAYBE_ProcessIsolation ProcessIsolation 108#endif 109IN_PROC_BROWSER_TEST_F(SigninBrowserTest, MAYBE_ProcessIsolation) { 110 SigninClient* signin = 111 ChromeSigninClientFactory::GetForProfile(browser()->profile()); 112 EXPECT_FALSE(signin->HasSigninProcess()); 113 114 ui_test_utils::NavigateToURL(browser(), signin::GetPromoURL( 115 signin::SOURCE_NTP_LINK, true)); 116 EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess()); 117 118 // Navigating away should change the process. 119 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIOmniboxURL)); 120 EXPECT_FALSE(signin->HasSigninProcess()); 121 122 ui_test_utils::NavigateToURL(browser(), signin::GetPromoURL( 123 signin::SOURCE_NTP_LINK, true)); 124 EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess()); 125 126 content::WebContents* active_tab = 127 browser()->tab_strip_model()->GetActiveWebContents(); 128 int active_tab_process_id = 129 active_tab->GetRenderProcessHost()->GetID(); 130 EXPECT_EQ(kOneClickSigninEnabled, 131 signin->IsSigninProcess(active_tab_process_id)); 132 EXPECT_EQ(0, active_tab->GetRenderViewHost()->GetEnabledBindings()); 133 134 // Entry points to signin request "SINGLETON_TAB" mode, so a new request 135 // shouldn't change anything. 136 chrome::NavigateParams params(chrome::GetSingletonTabNavigateParams( 137 browser(), 138 GURL(signin::GetPromoURL(signin::SOURCE_NTP_LINK, false)))); 139 params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE; 140 ShowSingletonTabOverwritingNTP(browser(), params); 141 EXPECT_EQ(active_tab, browser()->tab_strip_model()->GetActiveWebContents()); 142 EXPECT_EQ(kOneClickSigninEnabled, 143 signin->IsSigninProcess(active_tab_process_id)); 144 145 // Navigating away should change the process. 146 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL)); 147 EXPECT_FALSE(signin->IsSigninProcess( 148 active_tab->GetRenderProcessHost()->GetID())); 149} 150 151#if defined (OS_MACOSX) 152// crbug.com/375197 153#define MAYBE_NotTrustedAfterRedirect DISABLED_NotTrustedAfterRedirect 154#else 155#define MAYBE_NotTrustedAfterRedirect NotTrustedAfterRedirect 156#endif 157 158IN_PROC_BROWSER_TEST_F(SigninBrowserTest, MAYBE_NotTrustedAfterRedirect) { 159 SigninClient* signin = 160 ChromeSigninClientFactory::GetForProfile(browser()->profile()); 161 EXPECT_FALSE(signin->HasSigninProcess()); 162 163 GURL url = signin::GetPromoURL(signin::SOURCE_NTP_LINK, true); 164 ui_test_utils::NavigateToURL(browser(), url); 165 EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess()); 166 167 // Navigating in a different tab should not affect the sign-in process. 168 ui_test_utils::NavigateToURLWithDisposition( 169 browser(), GURL(kNonSigninURL), NEW_BACKGROUND_TAB, 170 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 171 EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess()); 172 173 // Navigating away should clear the sign-in process. 174 GURL redirect_url("https://accounts.google.com/server-redirect?" 175 "https://foo.com?service=chromiumsync"); 176 ui_test_utils::NavigateToURL(browser(), redirect_url); 177 EXPECT_FALSE(signin->HasSigninProcess()); 178} 179 180class BackOnNTPCommitObserver : public content::WebContentsObserver { 181 public: 182 explicit BackOnNTPCommitObserver(content::WebContents* web_contents) 183 : content::WebContentsObserver(web_contents) { 184 } 185 186 virtual void DidCommitProvisionalLoadForFrame( 187 int64 frame_id, 188 const base::string16& frame_unique_name, 189 bool is_main_frame, 190 const GURL& url, 191 content::PageTransition transition_type, 192 content::RenderViewHost* render_view_host) OVERRIDE { 193 if (url == GURL(chrome::kChromeUINewTabURL) || 194 url == GURL(chrome::kChromeSearchLocalNtpUrl)) { 195 content::WindowedNotificationObserver observer( 196 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 197 content::NotificationService::AllSources()); 198 web_contents()->GetController().GoBack(); 199 observer.Wait(); 200 } 201 } 202 203 private: 204 DISALLOW_COPY_AND_ASSIGN(BackOnNTPCommitObserver); 205}; 206 207// This is a test for http://crbug.com/257277. It simulates the navigations 208// that occur if the user clicks on the "Skip for now" link at the signin page 209// and initiates a back navigation between the point of Commit and 210// DidStopLoading of the NTP. 211IN_PROC_BROWSER_TEST_F(SigninBrowserTest, SigninSkipForNowAndGoBack) { 212 GURL ntp_url(chrome::kChromeUINewTabURL); 213 GURL start_url = signin::GetPromoURL(signin::SOURCE_START_PAGE, false); 214 GURL skip_url = signin::GetLandingURL("ntp", 1); 215 216 SigninClient* signin = 217 ChromeSigninClientFactory::GetForProfile(browser()->profile()); 218 EXPECT_FALSE(signin->HasSigninProcess()); 219 220 ui_test_utils::NavigateToURL(browser(), start_url); 221 EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess()); 222 223 content::WebContents* web_contents = 224 browser()->tab_strip_model()->GetActiveWebContents(); 225 226 // Simulate clicking on the Skip for now link. It's important to have a 227 // link transition so that OneClickSigninHelper removes the blank page 228 // from the history. 229 chrome::NavigateParams navigate_params(browser(), 230 skip_url, 231 content::PAGE_TRANSITION_LINK); 232 ui_test_utils::NavigateToURL(&navigate_params); 233 234 // Register an observer that will navigate back immediately on the commit of 235 // the NTP. This will allow us to hit the race condition of navigating back 236 // before the DidStopLoading message of NTP gets delivered. This must be 237 // created after the navigation to the skip_url has finished loading, 238 // otherwise this observer will navigate back, before the history cleaner 239 // has had a chance to remove the navigation entry. 240 BackOnNTPCommitObserver commit_observer(web_contents); 241 242 // Since OneClickSigninHelper aborts redirect to NTP, thus we expect the 243 // visible URL to be the starting URL. 244 EXPECT_EQ(skip_url, web_contents->GetLastCommittedURL()); 245 EXPECT_EQ(start_url, web_contents->GetVisibleURL()); 246 247 content::WindowedNotificationObserver observer( 248 content::NOTIFICATION_LOAD_STOP, 249 content::NotificationService::AllSources()); 250 observer.Wait(); 251 EXPECT_EQ(start_url, web_contents->GetLastCommittedURL()); 252} 253#endif // CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_ 254