Chromium Code Reviews
|
| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 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. | |
| 4 | |
| 5 #include <map> | |
| 6 #include <set> | |
| 7 | |
| 8 #include "base/basictypes.h" | |
| 9 #include "base/bind.h" | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/compiler_specific.h" | |
| 12 #include "base/file_path.h" | |
| 13 #include "base/message_loop.h" | |
| 14 #include "base/path_service.h" | |
| 15 #include "base/utf_string_conversions.h" | |
| 16 #include "chrome/browser/captive_portal/captive_portal_service.h" | |
| 17 #include "chrome/browser/captive_portal/captive_portal_service_factory.h" | |
| 18 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h" | |
| 19 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h" | |
| 20 #include "chrome/browser/net/url_request_mock_util.h" | |
| 21 #include "chrome/browser/prefs/pref_service.h" | |
| 22 #include "chrome/browser/profiles/profile.h" | |
| 23 #include "chrome/browser/ui/browser.h" | |
| 24 #include "chrome/browser/ui/browser_finder.h" | |
| 25 #include "chrome/browser/ui/browser_list.h" | |
| 26 #include "chrome/browser/ui/browser_navigator.h" | |
| 27 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
| 28 #include "chrome/common/chrome_notification_types.h" | |
| 29 #include "chrome/common/chrome_paths.h" | |
| 30 #include "chrome/common/chrome_switches.h" | |
| 31 #include "chrome/common/pref_names.h" | |
| 32 #include "chrome/test/base/in_process_browser_test.h" | |
| 33 #include "chrome/test/base/ui_test_utils.h" | |
| 34 #include "content/public/browser/browser_thread.h" | |
| 35 #include "content/public/browser/navigation_controller.h" | |
| 36 #include "content/public/browser/notification_observer.h" | |
| 37 #include "content/public/browser/notification_registrar.h" | |
| 38 #include "content/public/browser/notification_service.h" | |
| 39 #include "content/public/browser/notification_types.h" | |
| 40 #include "content/public/browser/render_view_host.h" | |
| 41 #include "content/public/browser/web_contents.h" | |
| 42 #include "content/public/common/url_constants.h" | |
| 43 #include "content/test/net/url_request_failed_job.h" | |
| 44 #include "content/test/net/url_request_mock_http_job.h" | |
| 45 #include "net/base/net_errors.h" | |
| 46 #include "net/url_request/url_request_filter.h" | |
| 47 #include "net/url_request/url_request_job.h" | |
| 48 #include "net/url_request/url_request_status.h" | |
| 49 #include "testing/gtest/include/gtest/gtest.h" | |
| 50 | |
| 51 using content::BrowserThread; | |
| 52 | |
| 53 namespace captive_portal { | |
| 54 | |
| 55 namespace { | |
| 56 | |
| 57 // Path of the fake login page, when using the TestServer. | |
| 58 const char* const kTestServerLoginPath = "files/captive_portal/login.html"; | |
| 59 | |
| 60 // Path of a page with an iframe that has a mock SSL timeout, when using the | |
| 61 // TestServer. | |
| 62 const char* const kTestServerIframeTimeoutPath = | |
| 63 "files/captive_portal/iframe_timeout.html"; | |
| 64 | |
| 65 // The following URLs each have two different behaviors, depending on whether | |
| 66 // URLRequestMockCaptivePortalJobFactory is currently simulating the presence | |
| 67 // of a captive portal or not. | |
| 68 | |
| 69 // A mock URL for the CaptivePortalService's |test_url|. When behind a captive | |
| 70 // portal, this URL return a mock login page. When connected to the Internet, | |
| 71 // it returns a 204 response. | |
| 72 const char* const kMockCaptivePortalTestUrl = | |
| 73 "http://mock.captive.portal/captive_portal_test/"; | |
| 74 | |
| 75 // When behind a captive portal, this URL hangs without committing until a call | |
| 76 // to URLRequestTimeoutOnDemandJob::FailRequests. When that function is called, | |
| 77 // the request will time out. | |
| 78 // | |
| 79 // When connected to the Internet, this URL returns a non-error page. | |
| 80 const char* const kMockHttpsUrl = "https://mock.captive.portal/"; | |
|
cbentzel
2012/05/30 18:48:02
Nit: perhaps https://mock.captive.portal/long_time
mmenke
2012/05/31 20:31:47
Done.
| |
| 81 | |
| 82 // Same as kMockHttpsUrl, except the timeout happens instantly. | |
| 83 const char* const kMockHttpsQuickTimeoutUrl = | |
| 84 "https://mock.captive.portal/quick_timeout/"; | |
| 85 | |
| 86 // Expected title of a tab once an HTTPS load completes, when not behind a | |
| 87 // captive portal. | |
| 88 const char* const kInternetConnectedTitle = "Title Of Awesomeness"; | |
| 89 | |
| 90 // A URL request job that hangs until FailRequests() is called. | |
| 91 class URLRequestTimeoutOnDemandJob : public net::URLRequestJob, | |
| 92 public base::NonThreadSafe { | |
| 93 public: | |
| 94 // net::URLRequestJob: | |
| 95 virtual void Start() OVERRIDE; | |
| 96 | |
| 97 // All the public static methods below can be called on any thread. | |
| 98 | |
| 99 // Fails all active URLRequestFailOnDemandJobs with connection timeouts. | |
| 100 // Must only be called when there are requests that have been started but not | |
| 101 // yet timed out. | |
| 102 static void FailRequests(); | |
| 103 | |
| 104 // Clears the |waiting_jobs_list_| without having the jobs return anything. | |
| 105 // Used to allow an assertion that jobs are not in the |waiting_jobs_list_| | |
| 106 // when destroyed. Must only be called when there are requests that have | |
| 107 // been started but not yet timed out. | |
| 108 static void AbandonRequests(); | |
| 109 | |
| 110 private: | |
| 111 friend class URLRequestMockCaptivePortalJobFactory; | |
| 112 | |
| 113 typedef std::set<URLRequestTimeoutOnDemandJob*> JobList; | |
| 114 | |
| 115 explicit URLRequestTimeoutOnDemandJob(net::URLRequest* request); | |
| 116 virtual ~URLRequestTimeoutOnDemandJob(); | |
| 117 | |
| 118 // These do all the work of the corresponding public functions, with the only | |
| 119 // difference being that they must be called on the IO thread. | |
| 120 static void FailRequestsOnIOThread(); | |
| 121 static void AbandonRequestsOnIOThread(); | |
| 122 | |
| 123 // List of SSL requests that are waiting to be explicitly timed out. | |
| 124 static JobList waiting_jobs_list_; | |
|
cbentzel
2012/05/30 18:48:02
Static class member variables must be POD only.
Y
mmenke
2012/05/31 20:31:47
Done. For some reason, had just assumed something
| |
| 125 | |
| 126 DISALLOW_COPY_AND_ASSIGN(URLRequestTimeoutOnDemandJob); | |
| 127 }; | |
| 128 | |
| 129 | |
| 130 URLRequestTimeoutOnDemandJob::JobList | |
| 131 URLRequestTimeoutOnDemandJob::waiting_jobs_list_; | |
| 132 | |
| 133 void URLRequestTimeoutOnDemandJob::Start() { | |
| 134 waiting_jobs_list_.insert(this); | |
| 135 } | |
| 136 | |
| 137 // static | |
| 138 void URLRequestTimeoutOnDemandJob::FailRequests() { | |
| 139 content::BrowserThread::PostTask( | |
| 140 content::BrowserThread::IO, FROM_HERE, | |
| 141 base::Bind(&URLRequestTimeoutOnDemandJob::FailRequestsOnIOThread)); | |
| 142 } | |
| 143 | |
| 144 // static | |
| 145 void URLRequestTimeoutOnDemandJob::AbandonRequests() { | |
| 146 content::BrowserThread::PostTask( | |
| 147 content::BrowserThread::IO, FROM_HERE, | |
| 148 base::Bind(&URLRequestTimeoutOnDemandJob::AbandonRequestsOnIOThread)); | |
| 149 } | |
| 150 | |
| 151 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob( | |
| 152 net::URLRequest* request) | |
| 153 : net::URLRequestJob(request) { | |
| 154 } | |
| 155 | |
| 156 URLRequestTimeoutOnDemandJob::~URLRequestTimeoutOnDemandJob() { | |
| 157 // |this| shouldn't be in the list, but if it is, go ahead and remove it. | |
| 158 EXPECT_EQ(0u, waiting_jobs_list_.count(this)); | |
| 159 waiting_jobs_list_.erase(this); | |
| 160 } | |
| 161 | |
| 162 // static | |
| 163 void URLRequestTimeoutOnDemandJob::FailRequestsOnIOThread() { | |
| 164 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 165 EXPECT_LT(0u, waiting_jobs_list_.size()); | |
| 166 while (!waiting_jobs_list_.empty()) { | |
| 167 URLRequestTimeoutOnDemandJob* job = *waiting_jobs_list_.begin(); | |
| 168 waiting_jobs_list_.erase(job); | |
| 169 ASSERT_TRUE(job->CalledOnValidThread()); | |
| 170 job->NotifyStartError(net::URLRequestStatus( | |
| 171 net::URLRequestStatus::FAILED, | |
| 172 net::ERR_CONNECTION_TIMED_OUT)); | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 // static | |
| 177 void URLRequestTimeoutOnDemandJob::AbandonRequestsOnIOThread() { | |
| 178 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 179 EXPECT_LT(0u, waiting_jobs_list_.size()); | |
| 180 waiting_jobs_list_.clear(); | |
| 181 } | |
| 182 | |
| 183 // URLRequestCaptivePortalJobFactory emulates captive portal behavior. | |
| 184 // Initially, it emulates being behind a captive portal. When | |
| 185 // SetBehindCaptivePortal(true) is called, it emulates behavior when not behind | |
|
cbentzel
2012/05/30 18:48:02
Is this meant to be SetBehindCaptivePortal(false)?
mmenke
2012/05/31 20:31:47
Indeed. Done.
| |
| 186 // a captive portal. The class itself is never instantiated. | |
| 187 // | |
| 188 // It handles requests for kMockCaptivePortalTestUrl, kMockHttpsUrl, and | |
| 189 // kMockHttpsQuickTimeoutUrl. | |
| 190 class URLRequestMockCaptivePortalJobFactory { | |
| 191 public: | |
| 192 // The public static methods below can be called on any thread. | |
| 193 | |
| 194 // Adds the testing URLs to the net::URLRequestFilter. Should only be called | |
| 195 // once. | |
| 196 static void AddUrlHandlers(); | |
| 197 | |
| 198 // Sets whether or not there is a captive portal. Outstanding requests are | |
| 199 // not affected. | |
| 200 static void SetBehindCaptivePortal(bool behind_captive_portal); | |
| 201 | |
| 202 private: | |
| 203 // The class is never instantiated. | |
| 204 URLRequestMockCaptivePortalJobFactory() {} | |
| 205 ~URLRequestMockCaptivePortalJobFactory() {} | |
| 206 | |
| 207 // These do all the work of the corresponding public functions, with the only | |
| 208 // difference being that they must be called on the IO thread. | |
| 209 static void AddUrlHandlersOnIOThread(); | |
| 210 static void SetBehindCaptivePortalOnIOThread(bool behind_captive_portal); | |
| 211 | |
| 212 // Returns a URLRequestJob that reflects the current captive portal state | |
| 213 // for the URLs: kMockCaptivePortalTestUrl, kMockHttpsUrl, and | |
| 214 // kMockHttpsQuickTimeoutUrl. See documentation of individual URLs for | |
| 215 // actual behavior. | |
| 216 static net::URLRequestJob* Factory(net::URLRequest* request, | |
| 217 const std::string& scheme); | |
| 218 | |
| 219 static bool behind_captive_portal_; | |
| 220 | |
| 221 DISALLOW_COPY_AND_ASSIGN(URLRequestMockCaptivePortalJobFactory); | |
|
cbentzel
2012/05/30 18:48:02
You could use DISALLOW_IMPLICIT_CONSTRUCTORS() her
mmenke
2012/05/31 20:31:47
Done.
| |
| 222 }; | |
| 223 | |
| 224 bool URLRequestMockCaptivePortalJobFactory::behind_captive_portal_ = true; | |
| 225 | |
| 226 // static | |
| 227 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlers() { | |
| 228 content::BrowserThread::PostTask( | |
| 229 content::BrowserThread::IO, FROM_HERE, | |
| 230 base::Bind( | |
| 231 &URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread)); | |
| 232 } | |
| 233 | |
| 234 // static | |
| 235 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal( | |
| 236 bool behind_captive_portal) { | |
| 237 content::BrowserThread::PostTask( | |
| 238 content::BrowserThread::IO, FROM_HERE, | |
| 239 base::Bind( | |
| 240 &URLRequestMockCaptivePortalJobFactory:: | |
| 241 SetBehindCaptivePortalOnIOThread, | |
| 242 behind_captive_portal)); | |
| 243 } | |
| 244 | |
| 245 // static | |
| 246 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread() { | |
| 247 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 248 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); | |
| 249 filter->AddHostnameHandler("http", "mock.captive.portal", | |
| 250 URLRequestMockCaptivePortalJobFactory::Factory); | |
| 251 filter->AddHostnameHandler("https", "mock.captive.portal", | |
| 252 URLRequestMockCaptivePortalJobFactory::Factory); | |
| 253 } | |
| 254 | |
| 255 // static | |
| 256 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread( | |
| 257 bool behind_captive_portal) { | |
| 258 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 259 behind_captive_portal_ = behind_captive_portal; | |
| 260 } | |
| 261 | |
| 262 // static | |
| 263 net::URLRequestJob* URLRequestMockCaptivePortalJobFactory::Factory( | |
| 264 net::URLRequest* request, | |
| 265 const std::string& scheme) { | |
| 266 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 267 | |
| 268 // The PathService is threadsafe. | |
| 269 FilePath root_http; | |
| 270 PathService::Get(chrome::DIR_TEST_DATA, &root_http); | |
| 271 | |
| 272 if (scheme == "https") { | |
| 273 if (behind_captive_portal_) { | |
| 274 // If not logged in to the captive portal, HTTPS requests will time out, | |
| 275 // either immediately on on demand. | |
| 276 if (request->url().spec() == kMockHttpsQuickTimeoutUrl) | |
|
cbentzel
2012/05/30 18:48:02
Is this doing a std::string comparison or just a c
mmenke
2012/05/31 20:31:47
std::string. Switched, as suggested.
| |
| 277 return new URLRequestFailedJob(request, net::ERR_CONNECTION_TIMED_OUT); | |
| 278 return new URLRequestTimeoutOnDemandJob(request); | |
| 279 } | |
| 280 // Once logged in to the portal, HTTPS requests return the page that was | |
| 281 // actually requested. | |
| 282 return new URLRequestMockHTTPJob( | |
| 283 request, | |
| 284 root_http.Append(FILE_PATH_LITERAL("title2.html"))); | |
| 285 } | |
| 286 | |
| 287 // The URL is the captive portal test URL. | |
| 288 | |
| 289 if (behind_captive_portal_) { | |
| 290 // Prior to logging in to the portal, HTTP requests go to the login page. | |
| 291 return new URLRequestMockHTTPJob( | |
| 292 request, | |
| 293 root_http.Append( | |
| 294 FILE_PATH_LITERAL("captive_portal/login.html"))); | |
| 295 } | |
| 296 // After logging in to the portal, the test URL returns a 204 response. | |
| 297 return new URLRequestMockHTTPJob( | |
| 298 request, | |
| 299 root_http.Append( | |
| 300 FILE_PATH_LITERAL("captive_portal/page204.html"))); | |
| 301 } | |
| 302 | |
| 303 // Creates a server-side redirect for use with the TestServer. | |
| 304 std::string CreateServerRedirect(const std::string& dest_url) { | |
| 305 const char* const kServerRedirectBase = "server-redirect?"; | |
| 306 return kServerRedirectBase + dest_url; | |
| 307 } | |
| 308 | |
| 309 // Returns the total number of loading tabs. | |
| 310 int NumLoadingTabs() { | |
| 311 int num_loading_tabs = 0; | |
| 312 for (TabContentsIterator tab_contents_it; | |
| 313 !tab_contents_it.done(); | |
| 314 ++tab_contents_it) { | |
| 315 if (tab_contents_it->web_contents()->IsLoading()) | |
|
cbentzel
2012/05/30 18:48:02
Does this go across all browser windows?
mmenke
2012/05/31 20:31:47
Yes. And all profiles, too. Updated comment.
| |
| 316 ++num_loading_tabs; | |
| 317 } | |
| 318 return num_loading_tabs; | |
| 319 } | |
| 320 | |
| 321 bool IsLoginTab(TabContentsWrapper* tab_contents) { | |
| 322 return tab_contents->captive_portal_tab_helper()->IsLoginTab(); | |
| 323 } | |
| 324 | |
| 325 // Tracks how many times each tab has been navigated since the Observer was | |
| 326 // created. The standard TestNavigationObserver can only watch specific | |
| 327 // pre-existing tabs or loads in serial for all tabs. | |
| 328 class MultiNavigationObserver : public content::NotificationObserver { | |
| 329 public: | |
| 330 MultiNavigationObserver(); | |
| 331 virtual ~MultiNavigationObserver(); | |
| 332 | |
| 333 // Waits for exactly least |num_navigations_to_wait_for| LOAD_STOP | |
|
cbentzel
2012/05/30 18:48:02
Nit: Should be "exactly" without the "least".
mmenke
2012/05/31 20:31:47
Done.
| |
| 334 // notifications to have occurred since the construction of |this|. More | |
| 335 // navigations than expected occuring will trigger a expect failure. | |
| 336 void WaitForNavigations(int num_navigations_to_wait_for); | |
| 337 | |
| 338 // Returns the number of LOAD_STOP events that have occurred for | |
| 339 // |web_contents| since this was constructed. | |
| 340 int NumNavigationsForTab(content::WebContents* web_contents) const; | |
| 341 | |
| 342 // The number of LOAD_STOP events since |this| was created. | |
| 343 int num_navigations() const { return num_navigations_; } | |
| 344 | |
| 345 private: | |
| 346 typedef std::map<content::WebContents*, int> TabNavigationMap; | |
| 347 | |
| 348 // content::NotificationObserver: | |
| 349 virtual void Observe(int type, const content::NotificationSource& source, | |
| 350 const content::NotificationDetails& details) OVERRIDE; | |
| 351 | |
| 352 int num_navigations_; | |
| 353 | |
| 354 // Total number of navigations to wait for. Zero, if not waiting for any | |
| 355 // navigations. | |
| 356 int num_navigations_to_wait_for_; | |
| 357 | |
| 358 // Map of how many times each tab has navigated since |this| was created. | |
| 359 TabNavigationMap tab_navigation_map_; | |
| 360 | |
| 361 content::NotificationRegistrar registrar_; | |
| 362 | |
| 363 DISALLOW_COPY_AND_ASSIGN(MultiNavigationObserver); | |
| 364 }; | |
| 365 | |
| 366 MultiNavigationObserver::MultiNavigationObserver() | |
| 367 : num_navigations_(0), | |
| 368 num_navigations_to_wait_for_(0) { | |
| 369 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, | |
| 370 content::NotificationService::AllSources()); | |
| 371 } | |
| 372 | |
| 373 MultiNavigationObserver::~MultiNavigationObserver() { | |
| 374 } | |
| 375 | |
| 376 void MultiNavigationObserver::WaitForNavigations( | |
| 377 int num_navigations_to_wait_for) { | |
| 378 // Shouldn't already be waiting for navigations. | |
| 379 EXPECT_EQ(0, num_navigations_to_wait_for_); | |
| 380 if (num_navigations_ < num_navigations_to_wait_for) { | |
| 381 num_navigations_to_wait_for_ = num_navigations_to_wait_for; | |
| 382 ui_test_utils::RunMessageLoop(); | |
| 383 num_navigations_to_wait_for_ = 0; | |
| 384 } | |
| 385 EXPECT_EQ(num_navigations_, num_navigations_to_wait_for); | |
| 386 } | |
| 387 | |
| 388 int MultiNavigationObserver::NumNavigationsForTab( | |
| 389 content::WebContents* web_contents) const { | |
| 390 TabNavigationMap::const_iterator tab_navigations = | |
| 391 tab_navigation_map_.find(web_contents); | |
| 392 if (tab_navigations == tab_navigation_map_.end()) | |
| 393 return 0; | |
| 394 return tab_navigations->second; | |
| 395 } | |
| 396 | |
| 397 void MultiNavigationObserver::Observe( | |
| 398 int type, | |
| 399 const content::NotificationSource& source, | |
| 400 const content::NotificationDetails& details) { | |
| 401 ASSERT_EQ(type, content::NOTIFICATION_LOAD_STOP); | |
| 402 content::NavigationController* controller = | |
| 403 content::Source<content::NavigationController>(source).ptr(); | |
| 404 ++num_navigations_; | |
| 405 ++tab_navigation_map_[controller->GetWebContents()]; | |
| 406 if (num_navigations_to_wait_for_ == num_navigations_) | |
|
cbentzel
2012/05/30 18:48:02
Should this only quit the loop if WaitForNavigatio
mmenke
2012/05/31 20:31:47
|num_navigations_to_wait_for_| is only non-zero if
| |
| 407 MessageLoopForUI::current()->Quit(); | |
| 408 } | |
| 409 | |
| 410 // An observer for watching the CaptivePortalService. It tracks the last | |
| 411 // received result and the total number of received results. | |
| 412 class CaptivePortalObserver : public content::NotificationObserver { | |
| 413 public: | |
| 414 explicit CaptivePortalObserver(Profile* profile); | |
| 415 | |
| 416 // Runs the message loop until until at exactly |update_count| capitive portal | |
| 417 // results have been received, since this creation of |this|. Expects no | |
| 418 // additional captive portal results. | |
| 419 void WaitForResults(int num_results_to_wait_for); | |
| 420 | |
| 421 int num_results_received() const { return num_results_received_; } | |
| 422 | |
| 423 Result captive_portal_result() const { | |
| 424 return captive_portal_result_; | |
| 425 } | |
| 426 | |
| 427 private: | |
| 428 // Records results and exits the message loop, if needed. | |
| 429 void Observe(int type, | |
| 430 const content::NotificationSource& source, | |
| 431 const content::NotificationDetails& details); | |
| 432 | |
| 433 // If WaitForResults was called, the total number of updates for which to | |
| 434 // wait. Zero, otherwise. | |
| 435 int num_results_to_wait_for_; | |
| 436 | |
| 437 // Number of times OnPortalResult has been called since construction. | |
| 438 int num_results_received_; | |
| 439 | |
| 440 Profile* profile_; | |
| 441 | |
| 442 CaptivePortalService* captive_portal_service_; | |
| 443 | |
| 444 // Last result received. | |
| 445 Result captive_portal_result_; | |
| 446 | |
| 447 content::NotificationRegistrar registrar_; | |
| 448 | |
| 449 DISALLOW_COPY_AND_ASSIGN(CaptivePortalObserver); | |
| 450 }; | |
| 451 | |
| 452 CaptivePortalObserver::CaptivePortalObserver(Profile* profile) | |
| 453 : num_results_to_wait_for_(0), | |
| 454 num_results_received_(0), | |
| 455 profile_(profile), | |
| 456 captive_portal_service_( | |
| 457 CaptivePortalServiceFactory::GetForProfile(profile)), | |
| 458 captive_portal_result_( | |
| 459 captive_portal_service_->last_detection_result()) { | |
| 460 registrar_.Add(this, | |
| 461 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, | |
| 462 content::Source<Profile>(profile_)); | |
| 463 } | |
| 464 | |
| 465 void CaptivePortalObserver::WaitForResults(int num_results_to_wait_for) { | |
| 466 EXPECT_EQ(0, num_results_to_wait_for_); | |
| 467 if (num_results_received_ < num_results_to_wait_for) { | |
| 468 num_results_to_wait_for_ = num_results_to_wait_for; | |
| 469 ui_test_utils::RunMessageLoop(); | |
| 470 num_results_to_wait_for_ = 0; | |
| 471 } | |
| 472 EXPECT_EQ(num_results_received_, num_results_to_wait_for); | |
| 473 } | |
| 474 | |
| 475 void CaptivePortalObserver::Observe( | |
| 476 int type, | |
| 477 const content::NotificationSource& source, | |
| 478 const content::NotificationDetails& details) { | |
| 479 ASSERT_EQ(type, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT); | |
| 480 ASSERT_EQ(profile_, content::Source<Profile>(source).ptr()); | |
| 481 | |
| 482 CaptivePortalService::Results* results = | |
| 483 content::Details<CaptivePortalService::Results>(details).ptr(); | |
| 484 | |
| 485 EXPECT_EQ(captive_portal_result_, results->previous_result); | |
| 486 EXPECT_EQ(captive_portal_service_->last_detection_result(), | |
| 487 results->result); | |
| 488 | |
| 489 captive_portal_result_ = results->result; | |
| 490 ++num_results_received_; | |
| 491 | |
| 492 if (num_results_to_wait_for_ == num_results_received_) | |
| 493 MessageLoop::current()->Quit(); | |
| 494 } | |
| 495 | |
| 496 } // namespace | |
| 497 | |
| 498 class CaptivePortalBrowserTest : public InProcessBrowserTest { | |
| 499 public: | |
| 500 CaptivePortalBrowserTest(); | |
| 501 | |
| 502 // InProcessBrowserTest: | |
| 503 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE; | |
| 504 virtual void SetUpOnMainThread() OVERRIDE; | |
| 505 virtual void CleanUpOnMainThread() OVERRIDE; | |
| 506 | |
| 507 // Sets the captive portal checking preference. Does not affect the command | |
| 508 // line flag, which is set in SetUpCommandLine. | |
| 509 void EnableCaptivePortalDetection(Profile* profile, bool enabled); | |
| 510 | |
| 511 // Sets up the captive portal service for the given profile so that | |
| 512 // all checks go to |test_url|. Also disables all timers. | |
| 513 void SetUpCaptivePortalService(Profile* profile, const GURL& test_url); | |
| 514 | |
| 515 // Returns true if |browser|'s profile is currently running a captive portal | |
| 516 // check. | |
| 517 bool CheckPending(Browser* browser); | |
| 518 | |
| 519 // Returns the CaptivePortalTabReloader::State of |tab_contents|. | |
| 520 CaptivePortalTabReloader::State GetStateOfTabReloader( | |
| 521 TabContentsWrapper* tab_contents) const; | |
| 522 | |
| 523 // Returns the CaptivePortalTabReloader::State of the indicated tab. | |
| 524 CaptivePortalTabReloader::State GetStateOfTabReloaderAt(Browser* browser, | |
| 525 int index) const; | |
| 526 | |
| 527 // Returns the number of tabs with the given state, across all profiles. | |
| 528 int NumTabsWithState(CaptivePortalTabReloader::State state) const; | |
| 529 | |
| 530 // Returns the number of tabs broken by captive portals, across all profiles. | |
| 531 int NumBrokenTabs() const; | |
| 532 | |
| 533 // Returns the number of tabs that need to be reloaded due to having logged | |
| 534 // in to a captive portal, across all profiles. | |
| 535 int NumNeedReloadTabs() const; | |
| 536 | |
| 537 // Navigates |browser|'s active tab to |url| and expects no captive portal | |
| 538 // test to be triggered. |expected_navigations| is the number of times the | |
| 539 // active tab will end up being navigated. It should be 1, except for the | |
| 540 // Link Doctor page, which acts like two navigations. | |
| 541 void NavigateToPageExpectNoTest(Browser* browser, | |
| 542 const GURL& url, | |
| 543 int expected_navigations); | |
| 544 | |
| 545 // Navigates |browser|'s active tab to an SSL tab that takes a while to load, | |
| 546 // triggering a captive portal check, which is expected to give the result | |
| 547 // |expected_result|. The page finishes loading, with a timeout, after the | |
| 548 // captive portal check. | |
| 549 void SlowLoadNoCaptivePortal(Browser* browser, Result expected_result); | |
| 550 | |
| 551 // Navigates |browser|'s active tab to an SSL timeout, expecting a captive | |
| 552 // portal check to be triggered and return a result which will indicates | |
| 553 // there's no detected captive portal. | |
| 554 void FastTimeoutNoCaptivePortal(Browser* browser, Result expected_result); | |
| 555 | |
| 556 // Navigates the active tab to a slow loading SSL page, which will then | |
| 557 // trigger a captive portal test. The test is expected to find a captive | |
| 558 // portal. The slow loading page will continue to load after the function | |
| 559 // returns, until URLRequestTimeoutOnDemandJob::FailRequests() is called, | |
| 560 // at which point it will timeout. | |
| 561 // | |
| 562 // When |expect_login_tab| is false, no login tab is expected to be opened, | |
| 563 // because one already exists, and the function returns once the captive | |
| 564 // portal test is complete. | |
| 565 // | |
| 566 // If |expect_login_tab| is true, a login tab is then expected to be opened. | |
| 567 // It waits until both the login tab has finished loading, and two captive | |
| 568 // portal tests complete. The second test is triggered by the load of the | |
| 569 // captive portal tab completing. | |
| 570 // | |
| 571 // This function must not be called when the active tab is currently loading. | |
| 572 void SlowLoadBehindCaptivePortal(Browser* browser, bool expect_login_tab); | |
| 573 | |
| 574 // Just like SlowLoadBehindCaptivePortal, except the navigated tab has | |
| 575 // a connection timeout rather having its time trigger, and the function | |
| 576 // waits until that timeout occurs. | |
| 577 void FastTimeoutBehindCaptivePortal(Browser* browser, | |
| 578 bool expect_open_login_tab); | |
| 579 | |
| 580 // Navigates the login tab without logging in. The login tab must be the | |
| 581 // specified browser's active tab. Expects no other tab to change state. | |
| 582 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks | |
| 583 // that nothing has gone wrong prior to the function call. | |
| 584 void NavigateLoginTab(Browser* browser, | |
| 585 int num_loading_tabs, | |
| 586 int num_timed_out_tabs); | |
| 587 | |
| 588 // Simulates a login by updating the URLRequestMockCaptivePortalJob's | |
| 589 // behind captive portal state, and navigating the login tab. Waits for | |
| 590 // all broken but not loading tabs to be reloaded. | |
| 591 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks | |
| 592 // that nothing has gone wrong prior to the function call. | |
| 593 void Login(Browser* browser, int num_loading_tabs, int num_timed_out_tabs); | |
| 594 | |
| 595 // Makes the slow SSL loads of all active tabs time out at once, and waits for | |
| 596 // them to finish both that load and the automatic reload it should trigger. | |
| 597 // There should be no timed out tabs when this is called. The former login | |
| 598 // tab should be the active tab. | |
| 599 void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs); | |
| 600 | |
| 601 // Makes the slow SSL loads of all active tabs time out at once, and waits for | |
| 602 // them to finish displaying their error pages. The login tab should be the | |
| 603 // active tab. There should be no timed out tabs when this is called. | |
| 604 void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs); | |
| 605 | |
| 606 // Sets the timeout used by a CaptivePortalTabReloader on slow SSL loads | |
| 607 // before a captive portal check. | |
| 608 void SetSlowSSLLoadTime(CaptivePortalTabReloader* tab_reloader, | |
| 609 base::TimeDelta slow_ssl_load_time); | |
| 610 | |
| 611 CaptivePortalTabReloader* GetTabReloader( | |
| 612 TabContentsWrapper* tab_contents) const; | |
| 613 | |
| 614 private: | |
| 615 DISALLOW_COPY_AND_ASSIGN(CaptivePortalBrowserTest); | |
| 616 }; | |
| 617 | |
| 618 CaptivePortalBrowserTest::CaptivePortalBrowserTest() { | |
| 619 } | |
| 620 | |
| 621 void CaptivePortalBrowserTest::SetUpOnMainThread() { | |
| 622 // Enable mock requests. | |
| 623 content::BrowserThread::PostTask( | |
| 624 content::BrowserThread::IO, FROM_HERE, | |
| 625 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); | |
| 626 URLRequestMockCaptivePortalJobFactory::AddUrlHandlers(); | |
| 627 | |
| 628 EnableCaptivePortalDetection(browser()->profile(), true); | |
| 629 | |
| 630 // Set the captive portal service to use URLRequestMockCaptivePortalJob's | |
| 631 // mock URL, by default. | |
| 632 SetUpCaptivePortalService(browser()->profile(), | |
| 633 GURL(kMockCaptivePortalTestUrl)); | |
| 634 } | |
| 635 | |
| 636 void CaptivePortalBrowserTest::CleanUpOnMainThread() { | |
| 637 // No test should have a captive portal check pending on quit. | |
| 638 EXPECT_FALSE(CheckPending(browser())); | |
| 639 } | |
| 640 | |
| 641 void CaptivePortalBrowserTest::SetUpCommandLine( | |
| 642 CommandLine* command_line) { | |
| 643 command_line->AppendSwitch(switches::kCaptivePortalDetection); | |
| 644 } | |
| 645 | |
| 646 void CaptivePortalBrowserTest::EnableCaptivePortalDetection( | |
| 647 Profile* profile, bool enabled) { | |
| 648 profile->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled); | |
| 649 } | |
| 650 | |
| 651 void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile, | |
| 652 const GURL& test_url) { | |
| 653 CaptivePortalService* captive_portal_service = | |
| 654 CaptivePortalServiceFactory::GetForProfile(profile); | |
| 655 captive_portal_service->set_test_url(test_url); | |
| 656 | |
| 657 // Don't use any non-zero timers. Timers are checked in unit tests. | |
| 658 CaptivePortalService::RecheckPolicy* recheck_policy = | |
| 659 &captive_portal_service->recheck_policy(); | |
| 660 recheck_policy->initial_backoff_no_portal_ms = 0; | |
| 661 recheck_policy->initial_backoff_portal_ms = 0; | |
| 662 recheck_policy->backoff_policy.maximum_backoff_ms = 0; | |
| 663 } | |
| 664 | |
| 665 bool CaptivePortalBrowserTest::CheckPending(Browser* browser) { | |
| 666 CaptivePortalService* captive_portal_service = | |
| 667 CaptivePortalServiceFactory::GetForProfile(browser->profile()); | |
| 668 | |
| 669 return captive_portal_service->FetchingURL() || | |
| 670 captive_portal_service->TimerRunning(); | |
| 671 } | |
| 672 | |
| 673 CaptivePortalTabReloader::State | |
| 674 CaptivePortalBrowserTest::GetStateOfTabReloader( | |
| 675 TabContentsWrapper* tab_contents) const { | |
| 676 return GetTabReloader(tab_contents)->state(); | |
| 677 } | |
| 678 | |
| 679 CaptivePortalTabReloader::State | |
| 680 CaptivePortalBrowserTest::GetStateOfTabReloaderAt( | |
| 681 Browser* browser, | |
| 682 int index) const { | |
| 683 return GetStateOfTabReloader(browser->GetTabContentsWrapperAt(index)); | |
| 684 } | |
| 685 | |
| 686 int CaptivePortalBrowserTest::NumTabsWithState( | |
| 687 CaptivePortalTabReloader::State state) const { | |
| 688 int num_tabs = 0; | |
| 689 for (TabContentsIterator tab_contents_it; | |
| 690 !tab_contents_it.done(); | |
| 691 ++tab_contents_it) { | |
| 692 if (GetStateOfTabReloader(*tab_contents_it) == state) | |
| 693 ++num_tabs; | |
| 694 } | |
| 695 return num_tabs; | |
| 696 } | |
| 697 | |
| 698 int CaptivePortalBrowserTest::NumBrokenTabs() const { | |
| 699 return NumTabsWithState(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL); | |
| 700 } | |
| 701 | |
| 702 int CaptivePortalBrowserTest::NumNeedReloadTabs() const { | |
| 703 return NumTabsWithState(CaptivePortalTabReloader::STATE_NEEDS_RELOAD); | |
| 704 } | |
| 705 | |
| 706 void CaptivePortalBrowserTest::NavigateToPageExpectNoTest( | |
| 707 Browser* browser, | |
| 708 const GURL& url, | |
| 709 int expected_navigations) { | |
| 710 MultiNavigationObserver navigation_observer; | |
| 711 CaptivePortalObserver portal_observer(browser->profile()); | |
| 712 | |
| 713 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( | |
| 714 browser, url, expected_navigations); | |
| 715 | |
| 716 // No captive portal checks should have ocurred or be pending, and there | |
| 717 // should be no new tabs. | |
| 718 EXPECT_EQ(0, portal_observer.num_results_received()); | |
| 719 EXPECT_FALSE(CheckPending(browser)); | |
| 720 EXPECT_EQ(1, browser->tab_count()); | |
| 721 EXPECT_EQ(expected_navigations, navigation_observer.num_navigations()); | |
| 722 EXPECT_EQ(0, NumLoadingTabs()); | |
| 723 } | |
| 724 | |
| 725 void CaptivePortalBrowserTest::SlowLoadNoCaptivePortal( | |
| 726 Browser* browser, Result expected_result) { | |
| 727 CaptivePortalTabReloader* tab_reloader = | |
| 728 GetTabReloader(browser->GetSelectedTabContentsWrapper()); | |
| 729 ASSERT_TRUE(tab_reloader); | |
| 730 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta()); | |
| 731 | |
| 732 MultiNavigationObserver navigation_observer; | |
| 733 CaptivePortalObserver portal_observer(browser->profile()); | |
| 734 ui_test_utils::NavigateToURLWithDisposition(browser, | |
| 735 GURL(kMockHttpsUrl), | |
| 736 CURRENT_TAB, | |
| 737 ui_test_utils::BROWSER_TEST_NONE); | |
| 738 | |
| 739 portal_observer.WaitForResults(1); | |
| 740 | |
| 741 ASSERT_EQ(1, browser->tab_count()); | |
| 742 EXPECT_EQ(expected_result, portal_observer.captive_portal_result()); | |
| 743 EXPECT_EQ(1, portal_observer.num_results_received()); | |
| 744 EXPECT_EQ(0, navigation_observer.num_navigations()); | |
| 745 EXPECT_FALSE(CheckPending(browser)); | |
| 746 | |
| 747 // First tab should still be loading. | |
| 748 EXPECT_EQ(1, NumLoadingTabs()); | |
| 749 | |
| 750 // Original request times out. | |
| 751 URLRequestTimeoutOnDemandJob::FailRequests(); | |
| 752 navigation_observer.WaitForNavigations(1); | |
| 753 | |
| 754 ASSERT_EQ(1, browser->tab_count()); | |
| 755 EXPECT_EQ(1, portal_observer.num_results_received()); | |
| 756 EXPECT_FALSE(CheckPending(browser)); | |
| 757 EXPECT_EQ(0, NumLoadingTabs()); | |
| 758 | |
| 759 // Set a slow SSL load time to prevent the timer from triggering. | |
| 760 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1)); | |
| 761 } | |
| 762 | |
| 763 void CaptivePortalBrowserTest::FastTimeoutNoCaptivePortal( | |
| 764 Browser* browser, Result expected_result) { | |
| 765 ASSERT_NE(expected_result, RESULT_BEHIND_CAPTIVE_PORTAL); | |
| 766 | |
| 767 // Set the load time to be large, so the timer won't trigger. The value is | |
| 768 // not restored at the end of the function. | |
| 769 CaptivePortalTabReloader* tab_reloader = | |
| 770 GetTabReloader(browser->GetSelectedTabContentsWrapper()); | |
| 771 ASSERT_TRUE(tab_reloader); | |
| 772 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1)); | |
| 773 | |
| 774 MultiNavigationObserver navigation_observer; | |
| 775 CaptivePortalObserver portal_observer(browser->profile()); | |
| 776 | |
| 777 // Neither of these should be changed by the navigation. | |
| 778 int active_index = browser->active_index(); | |
| 779 int expected_tab_count = browser->tab_count(); | |
| 780 | |
| 781 ui_test_utils::NavigateToURL( | |
| 782 browser, | |
| 783 URLRequestFailedJob::GetMockHttpsUrl(net::ERR_CONNECTION_TIMED_OUT)); | |
| 784 | |
| 785 // An attempt to detect a captive portal should have started by now. If not, | |
| 786 // abort early to prevent hanging. | |
| 787 ASSERT_TRUE(portal_observer.num_results_received() > 0 || | |
| 788 CheckPending(browser)); | |
| 789 | |
| 790 portal_observer.WaitForResults(1); | |
| 791 navigation_observer.WaitForNavigations(1); | |
| 792 | |
| 793 // Check the result. | |
| 794 EXPECT_EQ(1, portal_observer.num_results_received()); | |
| 795 EXPECT_EQ(expected_result, portal_observer.captive_portal_result()); | |
| 796 | |
| 797 // Check that the right tab was navigated, and there were no extra | |
| 798 // navigations. | |
| 799 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 800 browser->GetWebContentsAt(active_index))); | |
| 801 EXPECT_EQ(0, NumLoadingTabs()); | |
| 802 | |
| 803 // Check the tab's state, and verify no captive portal check is pending. | |
| 804 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 805 GetStateOfTabReloaderAt(browser, 0)); | |
| 806 EXPECT_FALSE(CheckPending(browser)); | |
| 807 | |
| 808 // Make sure no login tab was opened. | |
| 809 EXPECT_EQ(expected_tab_count, browser->tab_count()); | |
| 810 } | |
| 811 | |
| 812 void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal( | |
| 813 Browser* browser, | |
| 814 bool expect_open_login_tab) { | |
| 815 // Calling this on a tab that's waiting for a load to manually be timed out | |
| 816 // will result in a hang. | |
| 817 ASSERT_FALSE(browser->GetSelectedWebContents()->IsLoading()); | |
| 818 | |
| 819 // Trigger a captive portal check quickly. | |
| 820 CaptivePortalTabReloader* tab_reloader = | |
| 821 GetTabReloader(browser->GetSelectedTabContentsWrapper()); | |
| 822 ASSERT_TRUE(tab_reloader); | |
| 823 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta()); | |
| 824 | |
| 825 // Number of tabs expected to be open after the captive portal checks | |
| 826 // have completed. | |
| 827 int initial_tab_count = browser->tab_count(); | |
| 828 int initial_active_index = browser->active_index(); | |
| 829 int initial_loading_tabs = NumLoadingTabs(); | |
| 830 int expected_broken_tabs = NumBrokenTabs(); | |
| 831 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL != | |
| 832 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper())) { | |
| 833 ++expected_broken_tabs; | |
| 834 } | |
| 835 | |
| 836 MultiNavigationObserver navigation_observer; | |
| 837 CaptivePortalObserver portal_observer(browser->profile()); | |
| 838 ui_test_utils::NavigateToURLWithDisposition(browser, | |
| 839 GURL(kMockHttpsUrl), | |
| 840 CURRENT_TAB, | |
| 841 ui_test_utils::BROWSER_TEST_NONE); | |
| 842 | |
| 843 if (expect_open_login_tab) { | |
| 844 portal_observer.WaitForResults(2); | |
| 845 navigation_observer.WaitForNavigations(1); | |
| 846 EXPECT_EQ(2, portal_observer.num_results_received()); | |
| 847 | |
| 848 ASSERT_EQ(initial_tab_count + 1, browser->tab_count()); | |
| 849 EXPECT_EQ(initial_tab_count, browser->active_index()); | |
| 850 | |
| 851 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 852 browser->GetWebContentsAt(initial_tab_count))); | |
| 853 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 854 GetStateOfTabReloader(browser->GetTabContentsWrapperAt(1))); | |
| 855 EXPECT_TRUE(IsLoginTab(browser->GetTabContentsWrapperAt(1))); | |
| 856 } else { | |
| 857 portal_observer.WaitForResults(1); | |
| 858 EXPECT_EQ(0, navigation_observer.num_navigations()); | |
| 859 EXPECT_EQ(initial_active_index, browser->active_index()); | |
| 860 ASSERT_EQ(initial_tab_count, browser->tab_count()); | |
| 861 EXPECT_EQ(initial_active_index, browser->active_index()); | |
| 862 } | |
| 863 | |
| 864 EXPECT_EQ(initial_loading_tabs + 1, NumLoadingTabs()); | |
| 865 EXPECT_EQ(expected_broken_tabs, NumBrokenTabs()); | |
| 866 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL, | |
| 867 portal_observer.captive_portal_result()); | |
| 868 EXPECT_FALSE(CheckPending(browser)); | |
| 869 | |
| 870 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, | |
| 871 GetStateOfTabReloader( | |
| 872 browser->GetTabContentsWrapperAt(initial_active_index))); | |
| 873 | |
| 874 // Reset the load time to be large, so the timer won't trigger on a reload. | |
| 875 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1)); | |
| 876 } | |
| 877 | |
| 878 void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal( | |
|
cbentzel
2012/05/30 18:48:02
Is there a test for when the captive portal test r
mmenke
2012/05/31 20:31:47
The CaptivePortalServiceTests do that, since they
| |
| 879 Browser* browser, | |
| 880 bool expect_open_login_tab) { | |
| 881 // Calling this on a tab that's waiting for a load to manually be timed out | |
| 882 // will result in a hang. | |
| 883 ASSERT_FALSE(browser->GetSelectedWebContents()->IsLoading()); | |
| 884 | |
| 885 // Set the load time to be large, so the timer won't trigger. The value is | |
| 886 // not restored at the end of the function. | |
| 887 CaptivePortalTabReloader* tab_reloader = | |
| 888 GetTabReloader(browser->GetSelectedTabContentsWrapper()); | |
| 889 ASSERT_TRUE(tab_reloader); | |
| 890 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1)); | |
| 891 | |
| 892 // Number of tabs expected to be open after the captive portal checks | |
| 893 // have completed. | |
| 894 int initial_tab_count = browser->tab_count(); | |
| 895 int initial_active_index = browser->active_index(); | |
| 896 int initial_loading_tabs = NumLoadingTabs(); | |
| 897 int expected_broken_tabs = NumBrokenTabs(); | |
| 898 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL != | |
| 899 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper())) { | |
| 900 ++expected_broken_tabs; | |
| 901 } | |
| 902 | |
| 903 MultiNavigationObserver navigation_observer; | |
| 904 CaptivePortalObserver portal_observer(browser->profile()); | |
| 905 ui_test_utils::NavigateToURLWithDisposition(browser, | |
| 906 GURL(kMockHttpsQuickTimeoutUrl), | |
| 907 CURRENT_TAB, | |
| 908 ui_test_utils::BROWSER_TEST_NONE); | |
| 909 | |
| 910 if (expect_open_login_tab) { | |
| 911 portal_observer.WaitForResults(2); | |
| 912 navigation_observer.WaitForNavigations(2); | |
| 913 EXPECT_EQ(2, portal_observer.num_results_received()); | |
| 914 | |
| 915 ASSERT_EQ(initial_tab_count + 1, browser->tab_count()); | |
| 916 EXPECT_EQ(initial_tab_count, browser->active_index()); | |
| 917 // Make sure that the originally active tab and the captive portal tab have | |
| 918 // each loaded once. | |
| 919 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 920 browser->GetWebContentsAt(initial_active_index))); | |
| 921 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 922 browser->GetWebContentsAt(initial_tab_count))); | |
| 923 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 924 GetStateOfTabReloader(browser->GetTabContentsWrapperAt(1))); | |
| 925 EXPECT_TRUE(IsLoginTab(browser->GetTabContentsWrapperAt(1))); | |
| 926 } else { | |
| 927 portal_observer.WaitForResults(1); | |
| 928 navigation_observer.WaitForNavigations(1); | |
| 929 EXPECT_EQ(1, portal_observer.num_results_received()); | |
| 930 | |
| 931 EXPECT_EQ(initial_active_index, browser->active_index()); | |
| 932 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 933 browser->GetWebContentsAt(initial_active_index))); | |
| 934 ASSERT_EQ(initial_tab_count, browser->tab_count()); | |
| 935 EXPECT_EQ(initial_active_index, browser->active_index()); | |
| 936 } | |
| 937 | |
| 938 EXPECT_EQ(initial_loading_tabs, NumLoadingTabs()); | |
| 939 EXPECT_EQ(expected_broken_tabs, NumBrokenTabs()); | |
| 940 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL, | |
| 941 portal_observer.captive_portal_result()); | |
| 942 EXPECT_FALSE(CheckPending(browser)); | |
| 943 | |
| 944 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, | |
| 945 GetStateOfTabReloader( | |
| 946 browser->GetTabContentsWrapperAt(initial_active_index))); | |
| 947 } | |
| 948 | |
| 949 void CaptivePortalBrowserTest::NavigateLoginTab(Browser* browser, | |
| 950 int num_loading_tabs, | |
| 951 int num_timed_out_tabs) { | |
| 952 MultiNavigationObserver navigation_observer; | |
| 953 CaptivePortalObserver portal_observer(browser->profile()); | |
| 954 | |
| 955 int initial_tab_count = browser->tab_count(); | |
| 956 EXPECT_EQ(num_loading_tabs, NumLoadingTabs()); | |
| 957 EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs()); | |
| 958 | |
| 959 int login_tab_index = browser->active_index(); | |
| 960 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 961 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper())); | |
| 962 ASSERT_TRUE(IsLoginTab(browser->GetSelectedTabContentsWrapper())); | |
| 963 | |
| 964 // Do the navigation. | |
| 965 content::RenderViewHost* render_view_host = | |
| 966 browser->GetSelectedWebContents()->GetRenderViewHost(); | |
| 967 render_view_host->ExecuteJavascriptInWebFrame( | |
| 968 string16(), | |
| 969 ASCIIToUTF16("submitForm()")); | |
| 970 | |
| 971 portal_observer.WaitForResults(1); | |
| 972 navigation_observer.WaitForNavigations(1); | |
| 973 | |
| 974 // Check the captive portal result. | |
| 975 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL, | |
| 976 portal_observer.captive_portal_result()); | |
| 977 EXPECT_EQ(1, portal_observer.num_results_received()); | |
| 978 EXPECT_FALSE(CheckPending(browser)); | |
| 979 | |
| 980 // Make sure not much has changed. | |
| 981 EXPECT_EQ(initial_tab_count, browser->tab_count()); | |
| 982 EXPECT_EQ(num_loading_tabs, NumLoadingTabs()); | |
| 983 EXPECT_EQ(num_loading_tabs + num_timed_out_tabs, NumBrokenTabs()); | |
| 984 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 985 GetStateOfTabReloader(browser->GetTabContentsWrapperAt( | |
| 986 login_tab_index))); | |
| 987 EXPECT_TRUE(IsLoginTab(browser->GetTabContentsWrapperAt(login_tab_index))); | |
| 988 | |
| 989 // Make sure there were no unexpected navigations. | |
| 990 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 991 browser->GetWebContentsAt(login_tab_index))); | |
| 992 } | |
| 993 | |
| 994 void CaptivePortalBrowserTest::Login(Browser* browser, | |
| 995 int num_loading_tabs, | |
| 996 int num_timed_out_tabs) { | |
| 997 // Simulate logging in. | |
| 998 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false); | |
| 999 | |
| 1000 MultiNavigationObserver navigation_observer; | |
| 1001 CaptivePortalObserver portal_observer(browser->profile()); | |
| 1002 | |
| 1003 int initial_tab_count = browser->tab_count(); | |
| 1004 ASSERT_EQ(num_loading_tabs, NumLoadingTabs()); | |
| 1005 EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs()); | |
| 1006 | |
| 1007 // Verify that the login page is on top. | |
| 1008 int login_tab_index = browser->active_index(); | |
| 1009 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1010 GetStateOfTabReloader(browser->GetTabContentsWrapperAt( | |
| 1011 login_tab_index))); | |
| 1012 ASSERT_TRUE(IsLoginTab(browser->GetTabContentsWrapperAt(login_tab_index))); | |
| 1013 | |
| 1014 // Trigger a navigation. | |
| 1015 content::RenderViewHost* render_view_host = | |
| 1016 browser->GetSelectedWebContents()->GetRenderViewHost(); | |
| 1017 render_view_host->ExecuteJavascriptInWebFrame( | |
| 1018 string16(), | |
| 1019 ASCIIToUTF16("submitForm()")); | |
| 1020 | |
| 1021 portal_observer.WaitForResults(1); | |
| 1022 | |
| 1023 // Wait for all the timed out tabs to reload. | |
| 1024 navigation_observer.WaitForNavigations(1 + num_timed_out_tabs); | |
| 1025 EXPECT_EQ(1, portal_observer.num_results_received()); | |
| 1026 | |
| 1027 // The tabs that were loading before should still be loading, and now be in | |
| 1028 // STATE_NEEDS_RELOAD. | |
| 1029 EXPECT_EQ(0, NumBrokenTabs()); | |
| 1030 EXPECT_EQ(num_loading_tabs, NumLoadingTabs()); | |
| 1031 EXPECT_EQ(num_loading_tabs, NumNeedReloadTabs()); | |
| 1032 | |
| 1033 // Make sure that the broken tabs have reloaded, and there's no more | |
| 1034 // captive portal tab. | |
| 1035 EXPECT_EQ(initial_tab_count, browser->tab_count()); | |
| 1036 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1037 GetStateOfTabReloaderAt(browser, login_tab_index)); | |
| 1038 EXPECT_FALSE(IsLoginTab(browser->GetTabContentsWrapperAt(login_tab_index))); | |
| 1039 | |
| 1040 // Make sure there were no unexpected navigations of the login tab. | |
| 1041 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 1042 browser->GetWebContentsAt(login_tab_index))); | |
| 1043 } | |
| 1044 | |
| 1045 void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser, | |
| 1046 int num_loading_tabs) { | |
| 1047 ASSERT_EQ(num_loading_tabs, NumLoadingTabs()); | |
| 1048 ASSERT_EQ(num_loading_tabs, NumNeedReloadTabs()); | |
| 1049 EXPECT_EQ(0, NumBrokenTabs()); | |
| 1050 | |
| 1051 int initial_num_tabs = browser->tab_count(); | |
| 1052 int initial_active_tab = browser->active_index(); | |
| 1053 | |
| 1054 CaptivePortalObserver portal_observer(browser->profile()); | |
| 1055 MultiNavigationObserver navigation_observer; | |
| 1056 // Connection finally times out. | |
| 1057 URLRequestTimeoutOnDemandJob::FailRequests(); | |
| 1058 | |
| 1059 navigation_observer.WaitForNavigations(2 * num_loading_tabs); | |
| 1060 | |
| 1061 // No captive portal checks should have ocurred or be pending, and there | |
| 1062 // should be no new tabs. | |
| 1063 EXPECT_EQ(0, portal_observer.num_results_received()); | |
| 1064 EXPECT_FALSE(CheckPending(browser)); | |
| 1065 EXPECT_EQ(initial_num_tabs, browser->tab_count()); | |
| 1066 | |
| 1067 EXPECT_EQ(initial_active_tab, browser->active_index()); | |
| 1068 | |
| 1069 EXPECT_EQ(0, NumNeedReloadTabs()); | |
| 1070 EXPECT_EQ(0, NumLoadingTabs()); | |
| 1071 EXPECT_EQ(0, navigation_observer.NumNavigationsForTab( | |
| 1072 browser->GetSelectedWebContents())); | |
| 1073 } | |
| 1074 | |
| 1075 void CaptivePortalBrowserTest::FailLoadsWithoutLogin(Browser* browser, | |
| 1076 int num_loading_tabs) { | |
| 1077 ASSERT_EQ(num_loading_tabs, NumLoadingTabs()); | |
| 1078 ASSERT_EQ(0, NumNeedReloadTabs()); | |
| 1079 EXPECT_EQ(num_loading_tabs, NumBrokenTabs()); | |
| 1080 | |
| 1081 int initial_num_tabs = browser->tab_count(); | |
| 1082 int login_tab = browser->active_index(); | |
| 1083 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1084 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper())); | |
| 1085 ASSERT_TRUE(IsLoginTab(browser->GetSelectedTabContentsWrapper())); | |
| 1086 | |
| 1087 CaptivePortalObserver portal_observer(browser->profile()); | |
| 1088 MultiNavigationObserver navigation_observer; | |
| 1089 // Connection finally times out. | |
| 1090 URLRequestTimeoutOnDemandJob::FailRequests(); | |
| 1091 | |
| 1092 navigation_observer.WaitForNavigations(num_loading_tabs); | |
| 1093 | |
| 1094 // No captive portal checks should have ocurred or be pending, and there | |
| 1095 // should be no new tabs. | |
| 1096 EXPECT_EQ(0, portal_observer.num_results_received()); | |
| 1097 EXPECT_FALSE(CheckPending(browser)); | |
| 1098 EXPECT_EQ(initial_num_tabs, browser->tab_count()); | |
| 1099 | |
| 1100 EXPECT_EQ(0, NumNeedReloadTabs()); | |
| 1101 EXPECT_EQ(0, NumLoadingTabs()); | |
| 1102 EXPECT_EQ(num_loading_tabs, NumBrokenTabs()); | |
| 1103 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1104 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper())); | |
| 1105 EXPECT_TRUE(IsLoginTab(browser->GetSelectedTabContentsWrapper())); | |
| 1106 EXPECT_EQ(login_tab, browser->active_index()); | |
| 1107 | |
| 1108 EXPECT_EQ(0, navigation_observer.NumNavigationsForTab( | |
| 1109 browser->GetWebContentsAt(login_tab))); | |
| 1110 } | |
| 1111 | |
| 1112 void CaptivePortalBrowserTest::SetSlowSSLLoadTime( | |
| 1113 CaptivePortalTabReloader* tab_reloader, | |
| 1114 base::TimeDelta slow_ssl_load_time) { | |
| 1115 tab_reloader->set_slow_ssl_load_time(slow_ssl_load_time); | |
| 1116 } | |
| 1117 | |
| 1118 CaptivePortalTabReloader* CaptivePortalBrowserTest::GetTabReloader( | |
| 1119 TabContentsWrapper* tab_contents) const { | |
| 1120 return tab_contents->captive_portal_tab_helper()->GetTabReloaderForTest(); | |
| 1121 } | |
| 1122 | |
| 1123 // Make sure there's no test for a captive portal on HTTP timeouts. This will | |
| 1124 // also trigger the link doctor page, which results in the load of a second | |
| 1125 // error page. | |
| 1126 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpTimeout) { | |
| 1127 GURL url = URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT); | |
| 1128 NavigateToPageExpectNoTest(browser(), url, 2); | |
|
cbentzel
2012/05/30 18:48:02
Should there be a test for the case that the user
mmenke
2012/05/31 20:31:47
In that case, captive portal testing would be disa
| |
| 1129 } | |
| 1130 | |
| 1131 // Make sure there's no check for a captive portal on HTTPS errors other than | |
| 1132 // timeouts, when they preempt the slow load timer. | |
| 1133 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsNonTimeoutError) { | |
| 1134 GURL url = URLRequestFailedJob::GetMockHttpsUrl(net::ERR_UNEXPECTED); | |
| 1135 NavigateToPageExpectNoTest(browser(), url, 1); | |
| 1136 } | |
| 1137 | |
| 1138 // Make sure no captive portal test triggers on HTTPS timeouts of iframes. | |
| 1139 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsIframeTimeout) { | |
| 1140 CaptivePortalObserver portal_observer(browser()->profile()); | |
| 1141 | |
| 1142 // Use an HTTPS server for the top level page. | |
| 1143 net::TestServer https_server(net::TestServer::TYPE_HTTPS, | |
| 1144 net::TestServer::kLocalhost, | |
| 1145 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | |
| 1146 ASSERT_TRUE(https_server.Start()); | |
| 1147 | |
| 1148 GURL url = https_server.GetURL(kTestServerIframeTimeoutPath); | |
| 1149 NavigateToPageExpectNoTest(browser(), url, 1); | |
| 1150 } | |
| 1151 | |
| 1152 // Check the captive portal result when the test request reports a network | |
| 1153 // error. The check is triggered by a slow loading page, and the page | |
| 1154 // errors out only after getting a captive portal result. | |
| 1155 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFails) { | |
| 1156 SetUpCaptivePortalService( | |
| 1157 browser()->profile(), | |
| 1158 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED)); | |
| 1159 SlowLoadNoCaptivePortal(browser(), RESULT_NO_RESPONSE); | |
| 1160 } | |
| 1161 | |
| 1162 // Same as above, but for the rather unlikely case that the connection times out | |
| 1163 // before the timer triggers. | |
| 1164 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFailsFastTimout) { | |
| 1165 SetUpCaptivePortalService( | |
| 1166 browser()->profile(), | |
| 1167 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED)); | |
| 1168 FastTimeoutNoCaptivePortal(browser(), RESULT_NO_RESPONSE); | |
| 1169 } | |
| 1170 | |
| 1171 // Checks that we look for a captive portal on HTTPS timeouts and don't reload | |
| 1172 // the error tab when the captive portal probe gets a 204 response, indicating | |
| 1173 // there is no captive portal. | |
| 1174 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, InternetConnected) { | |
| 1175 // Can't just use SetBehindCaptivePortal(false), since then there wouldn't | |
| 1176 // be a timeout. | |
| 1177 ASSERT_TRUE(test_server()->Start()); | |
| 1178 SetUpCaptivePortalService(browser()->profile(), | |
| 1179 test_server()->GetURL("nocontent")); | |
| 1180 SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED); | |
| 1181 } | |
| 1182 | |
| 1183 // Checks that no login page is opened when the HTTP test URL redirects to an | |
| 1184 // SSL certificate error. | |
| 1185 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RedirectSSLCertError) { | |
| 1186 // Need an HTTP TestServer to handle a dynamically created server redirect. | |
| 1187 ASSERT_TRUE(test_server()->Start()); | |
| 1188 | |
| 1189 net::TestServer::HTTPSOptions https_options; | |
| 1190 https_options.server_certificate = | |
| 1191 net::TestServer::HTTPSOptions::CERT_MISMATCHED_NAME; | |
| 1192 net::TestServer https_server(https_options, | |
| 1193 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | |
| 1194 ASSERT_TRUE(https_server.Start()); | |
| 1195 | |
| 1196 GURL ssl_login_url = https_server.GetURL(kTestServerLoginPath); | |
| 1197 | |
| 1198 CaptivePortalService* captive_portal_service = | |
| 1199 CaptivePortalServiceFactory::GetForProfile(browser()->profile()); | |
| 1200 ASSERT_TRUE(captive_portal_service); | |
| 1201 SetUpCaptivePortalService( | |
| 1202 browser()->profile(), | |
| 1203 test_server()->GetURL(CreateServerRedirect(ssl_login_url.spec()))); | |
| 1204 | |
| 1205 SlowLoadNoCaptivePortal(browser(), RESULT_NO_RESPONSE); | |
| 1206 } | |
| 1207 | |
| 1208 // A slow SSL load triggers a captive portal check. The user logs on before | |
| 1209 // the SSL page times out. We wait for the timeout and subsequent reload. | |
| 1210 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Login) { | |
| 1211 // Load starts, detect captive portal and open up a login tab. | |
| 1212 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1213 | |
| 1214 // Log in. One loading tab, no timed out ones. | |
| 1215 Login(browser(), 1, 0); | |
| 1216 | |
| 1217 string16 expected_title = ASCIIToUTF16(kInternetConnectedTitle); | |
| 1218 ui_test_utils::TitleWatcher title_watcher( | |
| 1219 browser()->GetWebContentsAt(0), | |
| 1220 expected_title); | |
| 1221 | |
| 1222 // Timeout occurs, and page is automatically reloaded. | |
| 1223 FailLoadsAfterLogin(browser(), 1); | |
| 1224 | |
| 1225 // Double check the tab's title. | |
| 1226 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); | |
| 1227 } | |
| 1228 | |
| 1229 // Same as above, except we make sure everything works with an incognito | |
| 1230 // profile. Main issues it tests for are that the incognito has its own | |
| 1231 // non-NULL captive portal service, and we open the tab in the correct | |
|
cbentzel
2012/05/30 18:48:02
Let's make sure that this is desired behavior for
mmenke
2012/05/31 20:31:47
Done.
| |
| 1232 // window. | |
| 1233 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginIncognito) { | |
| 1234 // This will watch tabs for both profiles, but only used to make sure no | |
| 1235 // navigations occur for the non-incognito profile. | |
| 1236 MultiNavigationObserver navigation_observer; | |
| 1237 CaptivePortalObserver non_incognito_portal_observer(browser()->profile()); | |
| 1238 | |
| 1239 Browser* incognito_browser = CreateIncognitoBrowser(); | |
| 1240 EnableCaptivePortalDetection(incognito_browser->profile(), true); | |
| 1241 SetUpCaptivePortalService(incognito_browser->profile(), | |
| 1242 GURL(kMockCaptivePortalTestUrl)); | |
| 1243 | |
| 1244 SlowLoadBehindCaptivePortal(incognito_browser, true); | |
| 1245 | |
| 1246 EXPECT_EQ(1, browser()->tab_count()); | |
| 1247 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1248 GetStateOfTabReloaderAt(browser(), 0)); | |
| 1249 | |
| 1250 Login(incognito_browser, 1, 0); | |
| 1251 FailLoadsAfterLogin(incognito_browser, 1); | |
| 1252 | |
| 1253 EXPECT_EQ(1, browser()->tab_count()); | |
| 1254 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1255 GetStateOfTabReloaderAt(browser(), 0)); | |
| 1256 | |
| 1257 EXPECT_EQ(0, navigation_observer.NumNavigationsForTab( | |
| 1258 browser()->GetWebContentsAt(0))); | |
| 1259 EXPECT_EQ(0, non_incognito_portal_observer.num_results_received()); | |
| 1260 } | |
| 1261 | |
| 1262 // The captive portal page is opened before the SSL page times out, | |
| 1263 // but the user logs in only after the page times out. | |
| 1264 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginSlow) { | |
| 1265 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1266 FailLoadsWithoutLogin(browser(), 1); | |
| 1267 Login(browser(), 0, 1); | |
| 1268 } | |
| 1269 | |
| 1270 // Checks the unlikely case that the tab times out before the timer triggers. | |
| 1271 // This most likely won't happen, but should still work: | |
| 1272 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) { | |
| 1273 FastTimeoutBehindCaptivePortal(browser(), true); | |
| 1274 Login(browser(), 0, 1); | |
| 1275 } | |
| 1276 | |
| 1277 // Tries navigating both the tab that encounters an SSL timeout and the | |
| 1278 // login tab twice, only logging in the second time. | |
| 1279 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) { | |
| 1280 FastTimeoutBehindCaptivePortal(browser(), true); | |
| 1281 | |
| 1282 // Activate the timed out tab and navigate it to a timeout again. | |
| 1283 browser()->ActivateTabAt(0, true); | |
| 1284 FastTimeoutBehindCaptivePortal(browser(), false); | |
| 1285 | |
| 1286 // Activate and navigate the captive portal tab. This should not trigger a | |
| 1287 // reload of the tab with the error. | |
| 1288 browser()->ActivateTabAt(1, true); | |
| 1289 NavigateLoginTab(browser(), 0, 1); | |
| 1290 | |
| 1291 // Simulate logging in. | |
| 1292 Login(browser(), 0, 1); | |
| 1293 } | |
| 1294 | |
| 1295 // After the first SSL timeout, closes the login tab and makes sure it's opened | |
| 1296 // it again on a second timeout. | |
| 1297 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, CloseLoginTab) { | |
| 1298 // First load starts, opens a login tab, and then times out. | |
| 1299 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1300 FailLoadsWithoutLogin(browser(), 1); | |
| 1301 | |
| 1302 // Close login tab. | |
| 1303 browser()->CloseTab(); | |
| 1304 | |
| 1305 // Go through the standard slow load login, and make sure it still works. | |
| 1306 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1307 Login(browser(), 1, 0); | |
| 1308 FailLoadsAfterLogin(browser(), 1); | |
| 1309 } | |
| 1310 | |
| 1311 // Checks that two tabs with SSL timeouts in the same window work. Both | |
| 1312 // tabs only timeout after logging in. | |
| 1313 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, TwoBrokenTabs) { | |
| 1314 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1315 | |
| 1316 // Can't set the TabReloader HTTPS timeout on a new tab without doing some | |
| 1317 // acrobatics, so open a new tab at a normal page, and then navigate it to a | |
| 1318 // timeout. | |
| 1319 MultiNavigationObserver navigation_observer; | |
| 1320 CaptivePortalObserver portal_observer(browser()->profile()); | |
| 1321 ui_test_utils::NavigateToURLWithDisposition( | |
| 1322 browser(), | |
| 1323 URLRequestMockHTTPJob::GetMockUrl( | |
| 1324 FilePath(FILE_PATH_LITERAL("title2.html"))), | |
| 1325 NEW_FOREGROUND_TAB, | |
| 1326 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
| 1327 | |
| 1328 ASSERT_EQ(3, browser()->tab_count()); | |
| 1329 EXPECT_FALSE(CheckPending(browser())); | |
| 1330 EXPECT_EQ(0, portal_observer.num_results_received()); | |
| 1331 EXPECT_EQ(1, NumLoadingTabs()); | |
| 1332 EXPECT_EQ(1, navigation_observer.num_navigations()); | |
| 1333 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 1334 browser()->GetWebContentsAt(2))); | |
| 1335 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, | |
| 1336 GetStateOfTabReloaderAt(browser(), 0)); | |
| 1337 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1338 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(1))); | |
| 1339 ASSERT_TRUE(IsLoginTab(browser()->GetTabContentsWrapperAt(1))); | |
| 1340 ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1341 GetStateOfTabReloaderAt(browser(), 2)); | |
| 1342 ASSERT_EQ(2, browser()->active_index()); | |
| 1343 | |
| 1344 SlowLoadBehindCaptivePortal(browser(), false); | |
| 1345 | |
| 1346 browser()->ActivateTabAt(1, true); | |
| 1347 Login(browser(), 2, 0); | |
| 1348 FailLoadsAfterLogin(browser(), 2); | |
| 1349 } | |
| 1350 | |
| 1351 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, AbortLoad) { | |
| 1352 // Go to the error page. | |
| 1353 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1354 // The load will be destroyed without returning any result, so remove it from | |
| 1355 // the list of jobs that will timeout. | |
| 1356 URLRequestTimeoutOnDemandJob::AbandonRequests(); | |
| 1357 | |
| 1358 CaptivePortalObserver portal_observer(browser()->profile()); | |
| 1359 MultiNavigationObserver navigation_observer; | |
| 1360 | |
| 1361 // Switch back to the hung tab from the login tab, and abort the navigation. | |
| 1362 browser()->ActivateTabAt(0, true); | |
| 1363 browser()->Stop(); | |
| 1364 navigation_observer.WaitForNavigations(1); | |
| 1365 | |
| 1366 EXPECT_EQ(0, NumBrokenTabs()); | |
| 1367 EXPECT_EQ(0, portal_observer.num_results_received()); | |
| 1368 EXPECT_FALSE(CheckPending(browser())); | |
| 1369 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1370 GetStateOfTabReloaderAt(browser(), 0)); | |
| 1371 | |
| 1372 browser()->ActivateTabAt(1, true); | |
| 1373 Login(browser(), 0, 0); | |
| 1374 } | |
| 1375 | |
| 1376 // Checks the case where the timed out tab is successfully navigated before | |
| 1377 // logging in. | |
| 1378 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, NavigateBrokenTab) { | |
| 1379 // Go to the error page. | |
| 1380 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1381 FailLoadsWithoutLogin(browser(), 1); | |
| 1382 | |
| 1383 // Navigate the error tab to a non-error page. | |
| 1384 browser()->ActivateTabAt(0, true); | |
| 1385 ui_test_utils::NavigateToURL(browser(), | |
| 1386 URLRequestMockHTTPJob::GetMockUrl( | |
| 1387 FilePath(FILE_PATH_LITERAL("title2.html")))); | |
| 1388 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1389 GetStateOfTabReloaderAt(browser(), 0)); | |
| 1390 | |
| 1391 // Simulate logging in. | |
| 1392 browser()->ActivateTabAt(1, true); | |
| 1393 Login(browser(), 0, 0); | |
| 1394 } | |
| 1395 | |
| 1396 // Navigates a broken, but still loading, tab to another timeout before logging | |
| 1397 // in. | |
| 1398 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, | |
| 1399 NavigateBrokenToTimeoutTabWhileLoading) { | |
| 1400 // Go to the error page. | |
| 1401 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1402 URLRequestTimeoutOnDemandJob::AbandonRequests(); | |
| 1403 | |
| 1404 CaptivePortalTabReloader* tab_reloader = | |
| 1405 GetTabReloader(browser()->GetTabContentsWrapperAt(0)); | |
| 1406 ASSERT_TRUE(tab_reloader); | |
| 1407 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta()); | |
| 1408 | |
| 1409 CaptivePortalObserver portal_observer(browser()->profile()); | |
| 1410 MultiNavigationObserver navigation_observer; | |
| 1411 | |
| 1412 // Navigate the error tab to a non-error page. Can't have ui_test_utils | |
| 1413 // do the navigation because it will wait for loading tabs to stop loading | |
| 1414 // before navigating. | |
| 1415 browser()->ActivateTabAt(0, true); | |
| 1416 browser()->OpenURL(content::OpenURLParams(GURL(kMockHttpsUrl), | |
| 1417 content::Referrer(), | |
| 1418 CURRENT_TAB, | |
| 1419 content::PAGE_TRANSITION_TYPED, | |
| 1420 false)); | |
| 1421 navigation_observer.WaitForNavigations(1); | |
| 1422 portal_observer.WaitForResults(1); | |
| 1423 EXPECT_FALSE(CheckPending(browser())); | |
| 1424 EXPECT_EQ(1, NumLoadingTabs()); | |
| 1425 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, | |
| 1426 GetStateOfTabReloaderAt(browser(), 0)); | |
| 1427 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1428 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(1))); | |
| 1429 ASSERT_TRUE(IsLoginTab(browser()->GetTabContentsWrapperAt(1))); | |
| 1430 | |
| 1431 // Simulate logging in. | |
| 1432 browser()->ActivateTabAt(1, true); | |
| 1433 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1)); | |
| 1434 Login(browser(), 1, 0); | |
| 1435 | |
| 1436 // Timeout occurs, and page is automatically reloaded. | |
| 1437 FailLoadsAfterLogin(browser(), 1); | |
| 1438 } | |
| 1439 | |
| 1440 // Checks that navigating a timed out tab back clears its state. | |
| 1441 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBack) { | |
| 1442 // Navigate to a working page. | |
| 1443 ui_test_utils::NavigateToURL( | |
| 1444 browser(), | |
| 1445 URLRequestMockHTTPJob::GetMockUrl( | |
| 1446 FilePath(FILE_PATH_LITERAL("title2.html")))); | |
| 1447 | |
| 1448 // Go to the error page. | |
| 1449 SlowLoadBehindCaptivePortal(browser(), true); | |
| 1450 FailLoadsWithoutLogin(browser(), 1); | |
| 1451 | |
| 1452 CaptivePortalObserver portal_observer(browser()->profile()); | |
| 1453 MultiNavigationObserver navigation_observer; | |
| 1454 | |
| 1455 // Activate the error page tab again and go back. | |
| 1456 browser()->ActivateTabAt(0, true); | |
| 1457 browser()->GoBack(CURRENT_TAB); | |
| 1458 navigation_observer.WaitForNavigations(1); | |
| 1459 | |
| 1460 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 1461 browser()->GetWebContentsAt(0))); | |
| 1462 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1463 GetStateOfTabReloaderAt(browser(), 0)); | |
| 1464 EXPECT_EQ(0, portal_observer.num_results_received()); | |
| 1465 } | |
| 1466 | |
| 1467 // Checks that navigating back to a timeout triggers captive portal detection. | |
| 1468 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBackToTimeout) { | |
| 1469 // Disable captive portal detection so the first navigation doesn't open a | |
| 1470 // login tab. | |
| 1471 EnableCaptivePortalDetection(browser()->profile(), false); | |
| 1472 | |
| 1473 SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED); | |
| 1474 | |
| 1475 // Navigate to a working page. | |
| 1476 ui_test_utils::NavigateToURL(browser(), | |
| 1477 URLRequestMockHTTPJob::GetMockUrl( | |
| 1478 FilePath(FILE_PATH_LITERAL("title2.html")))); | |
| 1479 ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1480 GetStateOfTabReloaderAt(browser(), 0)); | |
| 1481 | |
| 1482 EnableCaptivePortalDetection(browser()->profile(), true); | |
| 1483 | |
| 1484 CaptivePortalTabReloader* tab_reloader = | |
| 1485 GetTabReloader(browser()->GetSelectedTabContentsWrapper()); | |
| 1486 ASSERT_TRUE(tab_reloader); | |
| 1487 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta()); | |
| 1488 | |
| 1489 // Go to the error page. | |
| 1490 MultiNavigationObserver navigation_observer; | |
| 1491 CaptivePortalObserver portal_observer(browser()->profile()); | |
| 1492 browser()->GoBack(CURRENT_TAB); | |
| 1493 | |
| 1494 // Wait for both the check triggered by the broken tab and the first load | |
| 1495 // of the login tab, and for the login tab to stop loading. | |
| 1496 portal_observer.WaitForResults(2); | |
| 1497 navigation_observer.WaitForNavigations(1); | |
| 1498 | |
| 1499 EXPECT_EQ(2, portal_observer.num_results_received()); | |
| 1500 ASSERT_FALSE(CheckPending(browser())); | |
| 1501 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL, | |
| 1502 portal_observer.captive_portal_result()); | |
| 1503 | |
| 1504 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, | |
| 1505 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(0))); | |
| 1506 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1507 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(1))); | |
| 1508 ASSERT_TRUE(IsLoginTab(browser()->GetTabContentsWrapperAt(1))); | |
| 1509 | |
| 1510 ASSERT_EQ(2, browser()->tab_count()); | |
| 1511 EXPECT_EQ(1, browser()->active_index()); | |
| 1512 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 1513 browser()->GetWebContentsAt(1))); | |
| 1514 EXPECT_EQ(1, NumLoadingTabs()); | |
| 1515 | |
| 1516 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1)); | |
| 1517 Login(browser(), 1, 0); | |
| 1518 FailLoadsAfterLogin(browser(), 1); | |
| 1519 } | |
| 1520 | |
| 1521 // Checks that reloading a timeout triggers captive portal detection. | |
| 1522 // Much like the last test, though the captive portal is disabled before | |
| 1523 // the inital navigation, rather than captive portal detection. | |
| 1524 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, ReloadTimeout) { | |
| 1525 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false); | |
| 1526 | |
| 1527 // Do the first navigation while not behind a captive portal. | |
| 1528 CaptivePortalObserver portal_observer(browser()->profile()); | |
| 1529 ui_test_utils::NavigateToURL(browser(), GURL(kMockHttpsUrl)); | |
| 1530 ASSERT_EQ(0, portal_observer.num_results_received()); | |
| 1531 ASSERT_EQ(1, browser()->tab_count()); | |
| 1532 | |
| 1533 // A captive portal spontaneously appears. | |
| 1534 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true); | |
| 1535 | |
| 1536 CaptivePortalTabReloader* tab_reloader = | |
| 1537 GetTabReloader(browser()->GetSelectedTabContentsWrapper()); | |
| 1538 ASSERT_TRUE(tab_reloader); | |
| 1539 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta()); | |
| 1540 | |
| 1541 MultiNavigationObserver navigation_observer; | |
| 1542 browser()->GetSelectedWebContents()->GetController().Reload(true); | |
| 1543 | |
| 1544 // Wait for the login tab to open, and the two captive portal results from | |
| 1545 // opening an it. | |
| 1546 portal_observer.WaitForResults(2); | |
| 1547 navigation_observer.WaitForNavigations(1); | |
| 1548 | |
| 1549 ASSERT_EQ(2, portal_observer.num_results_received()); | |
| 1550 ASSERT_FALSE(CheckPending(browser())); | |
| 1551 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL, | |
| 1552 portal_observer.captive_portal_result()); | |
| 1553 | |
| 1554 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, | |
| 1555 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(0))); | |
| 1556 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1557 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(1))); | |
| 1558 ASSERT_TRUE(IsLoginTab(browser()->GetTabContentsWrapperAt(1))); | |
| 1559 | |
| 1560 ASSERT_EQ(2, browser()->tab_count()); | |
| 1561 EXPECT_EQ(1, browser()->active_index()); | |
| 1562 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 1563 browser()->GetWebContentsAt(1))); | |
| 1564 EXPECT_EQ(1, NumLoadingTabs()); | |
| 1565 | |
| 1566 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1)); | |
| 1567 Login(browser(), 1, 0); | |
| 1568 FailLoadsAfterLogin(browser(), 1); | |
| 1569 } | |
| 1570 | |
| 1571 // Checks the case where there are two windows, and there's an SSL timeout in | |
| 1572 // the background one. | |
| 1573 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, TwoWindows) { | |
| 1574 Browser* browser2 = Browser::Create(browser()->profile()); | |
| 1575 // Navigate the new browser window so it'll be shown and we can pick the | |
| 1576 // active window. | |
| 1577 ui_test_utils::NavigateToURL(browser2, GURL(chrome::kAboutBlankURL)); | |
| 1578 | |
| 1579 // Generally, |browser2| will be the active window. However, if the | |
| 1580 // original browser window lost focus before creating the new one, such as | |
| 1581 // when running multiple tests at once, the original browser window may | |
| 1582 // remain the profile's active window. | |
| 1583 Browser* active_browser = | |
| 1584 browser::FindTabbedBrowser(browser()->profile(), true); | |
| 1585 Browser* inactive_browser; | |
| 1586 if (active_browser == browser2) { | |
| 1587 // When only one test is running at a time, the new browser will probably be | |
| 1588 // on top, but when multiple tests are running at once, this is not | |
| 1589 // guaranteed. | |
| 1590 inactive_browser = browser(); | |
| 1591 } else { | |
| 1592 ASSERT_EQ(active_browser, browser()); | |
| 1593 inactive_browser = browser2; | |
| 1594 } | |
| 1595 | |
| 1596 CaptivePortalObserver portal_observer(browser()->profile()); | |
| 1597 MultiNavigationObserver navigation_observer; | |
| 1598 | |
| 1599 // Navigate the tab in the inactive browser to an SSL timeout. Have to use | |
| 1600 // browser::NavigateParams and NEW_BACKGROUND_TAB to avoid activating the | |
| 1601 // window. | |
| 1602 browser::NavigateParams params(inactive_browser, | |
| 1603 GURL(kMockHttpsQuickTimeoutUrl), | |
| 1604 content::PAGE_TRANSITION_TYPED); | |
| 1605 params.disposition = NEW_BACKGROUND_TAB; | |
| 1606 params.window_action = browser::NavigateParams::NO_ACTION; | |
| 1607 ui_test_utils::NavigateToURL(¶ms); | |
| 1608 navigation_observer.WaitForNavigations(2); | |
| 1609 | |
| 1610 // Make sure the active window hasn't changed, and its new tab is | |
| 1611 // active. | |
| 1612 ASSERT_EQ(active_browser, | |
| 1613 browser::FindTabbedBrowser(browser()->profile(), true)); | |
| 1614 ASSERT_EQ(1, active_browser->active_index()); | |
| 1615 | |
| 1616 // Check that the only two navigated tabs were the new error tab in the | |
| 1617 // backround windows, and the login tab in the active window. | |
| 1618 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 1619 inactive_browser->GetWebContentsAt(1))); | |
| 1620 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab( | |
| 1621 active_browser->GetWebContentsAt(1))); | |
| 1622 EXPECT_EQ(0, NumLoadingTabs()); | |
| 1623 | |
| 1624 // Check captive portal test results. | |
| 1625 portal_observer.WaitForResults(2); | |
| 1626 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL, | |
| 1627 portal_observer.captive_portal_result()); | |
| 1628 EXPECT_EQ(2, portal_observer.num_results_received()); | |
| 1629 | |
| 1630 // Check the inactive browser. | |
| 1631 EXPECT_EQ(2, inactive_browser->tab_count()); | |
| 1632 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1633 GetStateOfTabReloaderAt(inactive_browser, 0)); | |
| 1634 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, | |
| 1635 GetStateOfTabReloaderAt(inactive_browser, 1)); | |
| 1636 | |
| 1637 // Check the active browser. | |
| 1638 ASSERT_EQ(2, active_browser->tab_count()); | |
| 1639 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1640 GetStateOfTabReloaderAt(active_browser, 0)); | |
| 1641 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, | |
| 1642 GetStateOfTabReloaderAt(active_browser, 1)); | |
| 1643 EXPECT_TRUE(IsLoginTab(active_browser->GetTabContentsWrapperAt(1))); | |
| 1644 | |
| 1645 // Simulate logging in. | |
| 1646 Login(active_browser, 0, 1); | |
| 1647 } | |
| 1648 | |
| 1649 } // namespace captive_portal | |
| OLD | NEW |