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 33 namespace { 34 const char kNonSigninURL[] = "http://www.google.com"; 35 } 36 37 class 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) 98 const bool kOneClickSigninEnabled = true; 99 #else 100 const 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 109 IN_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 158 IN_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 180 class 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 content::RenderFrameHost* render_frame_host, 188 const GURL& url, 189 ui::PageTransition transition_type) OVERRIDE { 190 if (url == GURL(chrome::kChromeUINewTabURL) || 191 url == GURL(chrome::kChromeSearchLocalNtpUrl)) { 192 content::WindowedNotificationObserver observer( 193 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 194 content::NotificationService::AllSources()); 195 web_contents()->GetController().GoBack(); 196 observer.Wait(); 197 } 198 } 199 200 private: 201 DISALLOW_COPY_AND_ASSIGN(BackOnNTPCommitObserver); 202 }; 203 204 // This is a test for http://crbug.com/257277. It simulates the navigations 205 // that occur if the user clicks on the "Skip for now" link at the signin page 206 // and initiates a back navigation between the point of Commit and 207 // DidStopLoading of the NTP. 208 IN_PROC_BROWSER_TEST_F(SigninBrowserTest, SigninSkipForNowAndGoBack) { 209 GURL ntp_url(chrome::kChromeUINewTabURL); 210 GURL start_url = signin::GetPromoURL(signin::SOURCE_START_PAGE, false); 211 GURL skip_url = signin::GetLandingURL("ntp", 1); 212 213 SigninClient* signin = 214 ChromeSigninClientFactory::GetForProfile(browser()->profile()); 215 EXPECT_FALSE(signin->HasSigninProcess()); 216 217 ui_test_utils::NavigateToURL(browser(), start_url); 218 EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess()); 219 220 content::WebContents* web_contents = 221 browser()->tab_strip_model()->GetActiveWebContents(); 222 223 // Simulate clicking on the Skip for now link. It's important to have a 224 // link transition so that OneClickSigninHelper removes the blank page 225 // from the history. 226 chrome::NavigateParams navigate_params(browser(), 227 skip_url, 228 ui::PAGE_TRANSITION_LINK); 229 ui_test_utils::NavigateToURL(&navigate_params); 230 231 // Register an observer that will navigate back immediately on the commit of 232 // the NTP. This will allow us to hit the race condition of navigating back 233 // before the DidStopLoading message of NTP gets delivered. This must be 234 // created after the navigation to the skip_url has finished loading, 235 // otherwise this observer will navigate back, before the history cleaner 236 // has had a chance to remove the navigation entry. 237 BackOnNTPCommitObserver commit_observer(web_contents); 238 239 // Since OneClickSigninHelper aborts redirect to NTP, thus we expect the 240 // visible URL to be the starting URL. 241 EXPECT_EQ(skip_url, web_contents->GetLastCommittedURL()); 242 EXPECT_EQ(start_url, web_contents->GetVisibleURL()); 243 244 content::WindowedNotificationObserver observer( 245 content::NOTIFICATION_LOAD_STOP, 246 content::NotificationService::AllSources()); 247 observer.Wait(); 248 EXPECT_EQ(start_url, web_contents->GetLastCommittedURL()); 249 } 250 #endif // CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_ 251