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.
5 #ifndef CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_
6 #define CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_
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"
34 const char kNonSigninURL
[] = "http://www.google.com";
37 class SigninBrowserTest
: public InProcessBrowserTest
{
39 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());
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
);
59 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();
72 void TearDown() override
{
73 if (fake_factory_
.get()) {
74 fake_factory_
->ClearFakeResponses();
75 fake_factory_
.reset();
78 // Cancel any outstanding URL fetches and destroy the URLFetcherImplFactory
80 net::URLFetcher::CancelAll();
82 InProcessBrowserTest::TearDown();
86 // Fake URLFetcher factory used to mock out GAIA signin.
87 scoped_ptr
<net::FakeURLFetcherFactory
> fake_factory_
;
89 // The URLFetcherImplFactory instance used to instantiate |fake_factory_|.
90 scoped_ptr
<net::URLFetcherImplFactory
> factory_
;
92 scoped_ptr
<net::SpawnedTestServer
> https_server_
;
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;
100 const bool kOneClickSigninEnabled
= false;
103 // Disabled on Windows due to flakiness. http://crbug.com/249055
105 #define MAYBE_ProcessIsolation DISABLED_ProcessIsolation
107 #define MAYBE_ProcessIsolation ProcessIsolation
109 IN_PROC_BROWSER_TEST_F(SigninBrowserTest
, MAYBE_ProcessIsolation
) {
110 SigninClient
* signin
=
111 ChromeSigninClientFactory::GetForProfile(browser()->profile());
112 EXPECT_FALSE(signin
->HasSigninProcess());
114 ui_test_utils::NavigateToURL(browser(), signin::GetPromoURL(
115 signin::SOURCE_NTP_LINK
, true));
116 EXPECT_EQ(kOneClickSigninEnabled
, signin
->HasSigninProcess());
118 // Navigating away should change the process.
119 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIOmniboxURL
));
120 EXPECT_FALSE(signin
->HasSigninProcess());
122 ui_test_utils::NavigateToURL(browser(), signin::GetPromoURL(
123 signin::SOURCE_NTP_LINK
, true));
124 EXPECT_EQ(kOneClickSigninEnabled
, signin
->HasSigninProcess());
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());
134 // Entry points to signin request "SINGLETON_TAB" mode, so a new request
135 // shouldn't change anything.
136 chrome::NavigateParams
params(chrome::GetSingletonTabNavigateParams(
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
));
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()));
151 #if defined (OS_MACOSX)
153 #define MAYBE_NotTrustedAfterRedirect DISABLED_NotTrustedAfterRedirect
155 #define MAYBE_NotTrustedAfterRedirect NotTrustedAfterRedirect
158 IN_PROC_BROWSER_TEST_F(SigninBrowserTest
, MAYBE_NotTrustedAfterRedirect
) {
159 SigninClient
* signin
=
160 ChromeSigninClientFactory::GetForProfile(browser()->profile());
161 EXPECT_FALSE(signin
->HasSigninProcess());
163 GURL url
= signin::GetPromoURL(signin::SOURCE_NTP_LINK
, true);
164 ui_test_utils::NavigateToURL(browser(), url
);
165 EXPECT_EQ(kOneClickSigninEnabled
, signin
->HasSigninProcess());
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());
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());
180 class BackOnNTPCommitObserver
: public content::WebContentsObserver
{
182 explicit BackOnNTPCommitObserver(content::WebContents
* web_contents
)
183 : content::WebContentsObserver(web_contents
) {
186 void DidCommitProvisionalLoadForFrame(
187 content::RenderFrameHost
* render_frame_host
,
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();
201 DISALLOW_COPY_AND_ASSIGN(BackOnNTPCommitObserver
);
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);
213 SigninClient
* signin
=
214 ChromeSigninClientFactory::GetForProfile(browser()->profile());
215 EXPECT_FALSE(signin
->HasSigninProcess());
217 ui_test_utils::NavigateToURL(browser(), start_url
);
218 EXPECT_EQ(kOneClickSigninEnabled
, signin
->HasSigninProcess());
220 content::WebContents
* web_contents
=
221 browser()->tab_strip_model()->GetActiveWebContents();
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
226 chrome::NavigateParams
navigate_params(browser(),
228 ui::PAGE_TRANSITION_LINK
);
229 ui_test_utils::NavigateToURL(&navigate_params
);
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
);
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());
244 content::WindowedNotificationObserver
observer(
245 content::NOTIFICATION_LOAD_STOP
,
246 content::NotificationService::AllSources());
248 EXPECT_EQ(start_url
, web_contents
->GetLastCommittedURL());
250 #endif // CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_