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