This source file includes following definitions.
- Start
- WaitForJobs
- FailJobs
- AbandonJobs
- next_job_
- RemoveFromList
- WaitForJobsOnIOThread
- MaybeStopWaitingForJobsOnIOThread
- FailOrAbandonJobsOnIOThread
- AddUrlHandlers
- SetBehindCaptivePortal
- AddUrlHandlersOnIOThread
- SetBehindCaptivePortalOnIOThread
- CreateServerRedirect
- NumLoadingTabs
- IsLoginTab
- num_navigations
- waiting_for_navigation_
- WaitForNavigations
- NumNavigationsForTab
- WaitForNavigations
- num_results_received
- captive_portal_result
- captive_portal_result_
- WaitForResults
- AddHstsHost
- SetUpOnMainThread
- CleanUpOnMainThread
- EnableCaptivePortalDetection
- SetUpCaptivePortalService
- CheckPending
- GetStateOfTabReloader
- GetStateOfTabReloaderAt
- NumTabsWithState
- NumBrokenTabs
- NumNeedReloadTabs
- NavigateToPageExpectNoTest
- SlowLoadNoCaptivePortal
- FastTimeoutNoCaptivePortal
- SlowLoadBehindCaptivePortal
- SlowLoadBehindCaptivePortal
- FastTimeoutBehindCaptivePortal
- FastErrorBehindCaptivePortal
- NavigateLoginTab
- Login
- FailLoadsAfterLogin
- FailLoadsWithoutLogin
- RunNavigateLoadingTabToTimeoutTest
- SetSlowSSLLoadTime
- GetTabReloader
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
#include <map>
#include <set>
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/captive_portal/captive_portal_service.h"
#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
#include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
#include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "content/test/net/url_request_failed_job.h"
#include "content/test/net/url_request_mock_http_job.h"
#include "net/base/net_errors.h"
#include "net/http/transport_security_state.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_status.h"
#include "testing/gtest/include/gtest/gtest.h"
using content::BrowserThread;
using content::URLRequestFailedJob;
using content::URLRequestMockHTTPJob;
using content::WebContents;
namespace captive_portal {
namespace {
const char* const kTestServerLoginPath = "files/captive_portal/login.html";
const char* const kTestServerIframeTimeoutPath =
"files/captive_portal/iframe_timeout.html";
const char* const kMockCaptivePortalTestUrl =
"http://mock.captive.portal.test/login.html";
const char* const kMockCaptivePortal511Url =
"http://mock.captive.portal.511/page511.html";
const char* const kMockHttpsUrl =
"https://mock.captive.portal.long.timeout/title2.html";
const char* const kMockHttpsUrl2 =
"https://mock.captive.portal.long.timeout2/title2.html";
const char* const kMockHttpsQuickTimeoutUrl =
"https://mock.captive.portal.quick.timeout/title2.html";
const char* const kInternetConnectedTitle = "Title Of Awesomeness";
class URLRequestTimeoutOnDemandJob : public net::URLRequestJob,
public base::NonThreadSafe {
public:
virtual void Start() OVERRIDE;
static void WaitForJobs(int num_jobs);
static void FailJobs(int expected_num_jobs);
static void AbandonJobs(int expected_num_jobs);
private:
friend class URLRequestMockCaptivePortalJobFactory;
enum EndJobOperation {
FAIL_JOBS,
ABANDON_JOBS,
};
URLRequestTimeoutOnDemandJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate);
virtual ~URLRequestTimeoutOnDemandJob();
bool RemoveFromList();
static void WaitForJobsOnIOThread(int num_jobs);
static void FailOrAbandonJobsOnIOThread(
int expected_num_jobs,
EndJobOperation end_job_operation);
static void MaybeStopWaitingForJobsOnIOThread();
static int num_jobs_to_wait_for_;
static int last_num_jobs_to_wait_for_;
static int num_jobs_started_;
static URLRequestTimeoutOnDemandJob* job_list_;
URLRequestTimeoutOnDemandJob* next_job_;
DISALLOW_COPY_AND_ASSIGN(URLRequestTimeoutOnDemandJob);
};
int URLRequestTimeoutOnDemandJob::num_jobs_to_wait_for_ = 0;
int URLRequestTimeoutOnDemandJob::last_num_jobs_to_wait_for_ = 0;
int URLRequestTimeoutOnDemandJob::num_jobs_started_ = 0;
URLRequestTimeoutOnDemandJob* URLRequestTimeoutOnDemandJob::job_list_ = NULL;
void URLRequestTimeoutOnDemandJob::Start() {
EXPECT_TRUE(CalledOnValidThread());
next_job_ = job_list_;
job_list_ = this;
++num_jobs_started_;
MaybeStopWaitingForJobsOnIOThread();
}
void URLRequestTimeoutOnDemandJob::WaitForJobs(int num_jobs) {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread,
num_jobs));
content::RunMessageLoop();
}
void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs) {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
expected_num_jobs,
FAIL_JOBS));
}
void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs) {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
expected_num_jobs,
ABANDON_JOBS));
}
URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob(
net::URLRequest* request, net::NetworkDelegate* network_delegate)
: net::URLRequestJob(request, network_delegate),
next_job_(NULL) {
}
URLRequestTimeoutOnDemandJob::~URLRequestTimeoutOnDemandJob() {
EXPECT_FALSE(RemoveFromList());
}
bool URLRequestTimeoutOnDemandJob::RemoveFromList() {
URLRequestTimeoutOnDemandJob** job = &job_list_;
while (*job) {
if (*job == this) {
*job = next_job_;
next_job_ = NULL;
return true;
}
job = &next_job_;
}
EXPECT_FALSE(next_job_);
return false;
}
void URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread(int num_jobs) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
ASSERT_EQ(0, num_jobs_to_wait_for_);
ASSERT_LT(0, num_jobs);
ASSERT_LE(last_num_jobs_to_wait_for_, num_jobs);
num_jobs_to_wait_for_ = num_jobs;
MaybeStopWaitingForJobsOnIOThread();
}
void URLRequestTimeoutOnDemandJob::MaybeStopWaitingForJobsOnIOThread() {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (num_jobs_to_wait_for_ == 0)
return;
EXPECT_LE(num_jobs_started_, num_jobs_to_wait_for_);
if (num_jobs_started_ >= num_jobs_to_wait_for_) {
last_num_jobs_to_wait_for_ = num_jobs_to_wait_for_;
num_jobs_to_wait_for_ = 0;
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::MessageLoop::QuitClosure());
}
}
void URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread(
int expected_num_jobs,
EndJobOperation end_job_operation) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
ASSERT_LT(0, expected_num_jobs);
EXPECT_EQ(last_num_jobs_to_wait_for_, expected_num_jobs);
last_num_jobs_to_wait_for_ = 0;
int num_jobs = 0;
while (job_list_) {
++num_jobs;
URLRequestTimeoutOnDemandJob* job = job_list_;
EXPECT_TRUE(job->RemoveFromList());
if (end_job_operation == FAIL_JOBS) {
job->NotifyStartError(net::URLRequestStatus(
net::URLRequestStatus::FAILED,
net::ERR_CONNECTION_TIMED_OUT));
}
}
EXPECT_EQ(expected_num_jobs, num_jobs_started_);
EXPECT_EQ(expected_num_jobs, num_jobs);
num_jobs_started_ -= expected_num_jobs;
}
class URLRequestMockCaptivePortalJobFactory {
public:
static void AddUrlHandlers();
static void SetBehindCaptivePortal(bool behind_captive_portal);
private:
static void AddUrlHandlersOnIOThread();
static void SetBehindCaptivePortalOnIOThread(bool behind_captive_portal);
static net::URLRequestJob* Factory(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme);
static bool behind_captive_portal_;
DISALLOW_IMPLICIT_CONSTRUCTORS(URLRequestMockCaptivePortalJobFactory);
};
bool URLRequestMockCaptivePortalJobFactory::behind_captive_portal_ = true;
void URLRequestMockCaptivePortalJobFactory::AddUrlHandlers() {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(
&URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread));
}
void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(
bool behind_captive_portal) {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(
&URLRequestMockCaptivePortalJobFactory::
SetBehindCaptivePortalOnIOThread,
behind_captive_portal));
}
void URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread() {
EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
filter->AddUrlHandler(GURL(kMockCaptivePortalTestUrl),
URLRequestMockCaptivePortalJobFactory::Factory);
filter->AddUrlHandler(GURL(kMockCaptivePortal511Url),
URLRequestMockCaptivePortalJobFactory::Factory);
filter->AddUrlHandler(GURL(kMockHttpsUrl),
URLRequestMockCaptivePortalJobFactory::Factory);
filter->AddUrlHandler(GURL(kMockHttpsUrl2),
URLRequestMockCaptivePortalJobFactory::Factory);
filter->AddUrlHandler(GURL(kMockHttpsQuickTimeoutUrl),
URLRequestMockCaptivePortalJobFactory::Factory);
}
void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread(
bool behind_captive_portal) {
EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
behind_captive_portal_ = behind_captive_portal;
}
net::URLRequestJob* URLRequestMockCaptivePortalJobFactory::Factory(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const std::string& scheme) {
EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
base::FilePath root_http;
PathService::Get(chrome::DIR_TEST_DATA, &root_http);
if (request->url() == GURL(kMockHttpsUrl) ||
request->url() == GURL(kMockHttpsUrl2)) {
if (behind_captive_portal_)
return new URLRequestTimeoutOnDemandJob(request, network_delegate);
return new URLRequestMockHTTPJob(
request,
network_delegate,
root_http.Append(FILE_PATH_LITERAL("title2.html")));
} else if (request->url() == GURL(kMockHttpsQuickTimeoutUrl)) {
if (behind_captive_portal_)
return new URLRequestFailedJob(
request, network_delegate, net::ERR_CONNECTION_TIMED_OUT);
return new URLRequestMockHTTPJob(
request,
network_delegate,
root_http.Append(FILE_PATH_LITERAL("title2.html")));
} else {
EXPECT_TRUE(GURL(kMockCaptivePortalTestUrl) == request->url() ||
GURL(kMockCaptivePortal511Url) == request->url());
if (behind_captive_portal_) {
if (GURL(kMockCaptivePortal511Url) == request->url()) {
return new URLRequestMockHTTPJob(
request,
network_delegate,
root_http.Append(FILE_PATH_LITERAL("captive_portal/page511.html")));
}
return new URLRequestMockHTTPJob(
request,
network_delegate,
root_http.Append(FILE_PATH_LITERAL("captive_portal/login.html")));
}
return new URLRequestMockHTTPJob(
request,
network_delegate,
root_http.Append(FILE_PATH_LITERAL("captive_portal/page204.html")));
}
}
std::string CreateServerRedirect(const std::string& dest_url) {
const char* const kServerRedirectBase = "server-redirect?";
return kServerRedirectBase + dest_url;
}
int NumLoadingTabs() {
int num_loading_tabs = 0;
for (TabContentsIterator it; !it.done(); it.Next()) {
if (it->IsLoading())
++num_loading_tabs;
}
return num_loading_tabs;
}
bool IsLoginTab(WebContents* web_contents) {
return CaptivePortalTabHelper::FromWebContents(web_contents)->IsLoginTab();
}
class MultiNavigationObserver : public content::NotificationObserver {
public:
MultiNavigationObserver();
virtual ~MultiNavigationObserver();
void WaitForNavigations(int num_navigations_to_wait_for);
int NumNavigationsForTab(WebContents* web_contents) const;
int num_navigations() const { return num_navigations_; }
private:
typedef std::map<const WebContents*, int> TabNavigationMap;
virtual void Observe(int type, const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
int num_navigations_;
TabNavigationMap tab_navigation_map_;
int num_navigations_to_wait_for_;
bool waiting_for_navigation_;
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(MultiNavigationObserver);
};
MultiNavigationObserver::MultiNavigationObserver()
: num_navigations_(0),
num_navigations_to_wait_for_(0),
waiting_for_navigation_(false) {
registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
content::NotificationService::AllSources());
}
MultiNavigationObserver::~MultiNavigationObserver() {
}
void MultiNavigationObserver::WaitForNavigations(
int num_navigations_to_wait_for) {
EXPECT_FALSE(waiting_for_navigation_);
EXPECT_LT(0, num_navigations_to_wait_for);
if (num_navigations_ < num_navigations_to_wait_for) {
num_navigations_to_wait_for_ = num_navigations_to_wait_for;
waiting_for_navigation_ = true;
content::RunMessageLoop();
EXPECT_FALSE(waiting_for_navigation_);
}
EXPECT_EQ(num_navigations_, num_navigations_to_wait_for);
}
int MultiNavigationObserver::NumNavigationsForTab(
WebContents* web_contents) const {
TabNavigationMap::const_iterator tab_navigations =
tab_navigation_map_.find(web_contents);
if (tab_navigations == tab_navigation_map_.end())
return 0;
return tab_navigations->second;
}
void MultiNavigationObserver::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
ASSERT_EQ(type, content::NOTIFICATION_LOAD_STOP);
content::NavigationController* controller =
content::Source<content::NavigationController>(source).ptr();
++num_navigations_;
++tab_navigation_map_[controller->GetWebContents()];
if (waiting_for_navigation_ &&
num_navigations_to_wait_for_ == num_navigations_) {
waiting_for_navigation_ = false;
base::MessageLoopForUI::current()->Quit();
}
}
class FailLoadsAfterLoginObserver : public content::NotificationObserver {
public:
FailLoadsAfterLoginObserver();
virtual ~FailLoadsAfterLoginObserver();
void WaitForNavigations();
private:
typedef std::set<const WebContents*> TabSet;
virtual void Observe(int type, const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
TabSet tabs_needing_navigation_;
TabSet tabs_navigated_to_final_destination_;
bool waiting_for_navigation_;
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(FailLoadsAfterLoginObserver);
};
FailLoadsAfterLoginObserver::FailLoadsAfterLoginObserver()
: waiting_for_navigation_(false) {
registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
content::NotificationService::AllSources());
for (TabContentsIterator it; !it.done(); it.Next()) {
if (it->IsLoading())
tabs_needing_navigation_.insert(*it);
}
}
FailLoadsAfterLoginObserver::~FailLoadsAfterLoginObserver() {
}
void FailLoadsAfterLoginObserver::WaitForNavigations() {
EXPECT_FALSE(waiting_for_navigation_);
if (tabs_needing_navigation_.size() !=
tabs_navigated_to_final_destination_.size()) {
waiting_for_navigation_ = true;
content::RunMessageLoop();
EXPECT_FALSE(waiting_for_navigation_);
}
EXPECT_EQ(tabs_needing_navigation_.size(),
tabs_navigated_to_final_destination_.size());
}
void FailLoadsAfterLoginObserver::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
ASSERT_EQ(type, content::NOTIFICATION_LOAD_STOP);
content::NavigationController* controller =
content::Source<content::NavigationController>(source).ptr();
WebContents* contents = controller->GetWebContents();
ASSERT_EQ(1u, tabs_needing_navigation_.count(contents));
ASSERT_EQ(0u, tabs_navigated_to_final_destination_.count(contents));
if (contents->GetTitle() != base::ASCIIToUTF16(kInternetConnectedTitle))
return;
tabs_navigated_to_final_destination_.insert(contents);
if (waiting_for_navigation_ &&
tabs_needing_navigation_.size() ==
tabs_navigated_to_final_destination_.size()) {
waiting_for_navigation_ = false;
base::MessageLoopForUI::current()->Quit();
}
}
class CaptivePortalObserver : public content::NotificationObserver {
public:
explicit CaptivePortalObserver(Profile* profile);
void WaitForResults(int num_results_to_wait_for);
int num_results_received() const { return num_results_received_; }
Result captive_portal_result() const {
return captive_portal_result_;
}
private:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
int num_results_received_;
int num_results_to_wait_for_;
bool waiting_for_result_;
Profile* profile_;
CaptivePortalService* captive_portal_service_;
Result captive_portal_result_;
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(CaptivePortalObserver);
};
CaptivePortalObserver::CaptivePortalObserver(Profile* profile)
: num_results_received_(0),
num_results_to_wait_for_(0),
waiting_for_result_(false),
profile_(profile),
captive_portal_service_(
CaptivePortalServiceFactory::GetForProfile(profile)),
captive_portal_result_(
captive_portal_service_->last_detection_result()) {
registrar_.Add(this,
chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
content::Source<Profile>(profile_));
}
void CaptivePortalObserver::WaitForResults(int num_results_to_wait_for) {
EXPECT_LT(0, num_results_to_wait_for);
EXPECT_FALSE(waiting_for_result_);
if (num_results_received_ < num_results_to_wait_for) {
num_results_to_wait_for_ = num_results_to_wait_for;
waiting_for_result_ = true;
content::RunMessageLoop();
EXPECT_FALSE(waiting_for_result_);
}
EXPECT_EQ(num_results_to_wait_for, num_results_received_);
}
void CaptivePortalObserver::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
ASSERT_EQ(type, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT);
ASSERT_EQ(profile_, content::Source<Profile>(source).ptr());
CaptivePortalService::Results* results =
content::Details<CaptivePortalService::Results>(details).ptr();
EXPECT_EQ(captive_portal_result_, results->previous_result);
EXPECT_EQ(captive_portal_service_->last_detection_result(),
results->result);
captive_portal_result_ = results->result;
++num_results_received_;
if (waiting_for_result_ &&
num_results_to_wait_for_ == num_results_received_) {
waiting_for_result_ = false;
base::MessageLoop::current()->Quit();
}
}
void AddHstsHost(net::URLRequestContextGetter* context_getter,
const std::string& host) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
net::TransportSecurityState* transport_security_state =
context_getter->GetURLRequestContext()->transport_security_state();
if (!transport_security_state) {
FAIL();
return;
}
base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
bool include_subdomains = false;
transport_security_state->AddHSTS(host, expiry, include_subdomains);
}
}
class CaptivePortalBrowserTest : public InProcessBrowserTest {
public:
CaptivePortalBrowserTest();
virtual void SetUpOnMainThread() OVERRIDE;
virtual void CleanUpOnMainThread() OVERRIDE;
void EnableCaptivePortalDetection(Profile* profile, bool enabled);
void SetUpCaptivePortalService(Profile* profile, const GURL& test_url);
bool CheckPending(Browser* browser);
CaptivePortalTabReloader::State GetStateOfTabReloader(
WebContents* web_contents) const;
CaptivePortalTabReloader::State GetStateOfTabReloaderAt(Browser* browser,
int index) const;
int NumTabsWithState(CaptivePortalTabReloader::State state) const;
int NumBrokenTabs() const;
int NumNeedReloadTabs() const;
void NavigateToPageExpectNoTest(Browser* browser,
const GURL& url,
int expected_navigations);
void SlowLoadNoCaptivePortal(Browser* browser, Result expected_result);
void FastTimeoutNoCaptivePortal(Browser* browser, Result expected_result);
void SlowLoadBehindCaptivePortal(Browser* browser, bool expect_login_tab);
void SlowLoadBehindCaptivePortal(Browser* browser,
bool expect_open_login_tab,
const GURL& hanging_url,
int expected_portal_checks,
int expected_login_tab_navigations);
void FastTimeoutBehindCaptivePortal(Browser* browser,
bool expect_open_login_tab);
void FastErrorBehindCaptivePortal(Browser* browser,
bool expect_open_login_tab,
const GURL& error_url);
void NavigateLoginTab(Browser* browser,
int num_loading_tabs,
int num_timed_out_tabs);
void Login(Browser* browser, int num_loading_tabs, int num_timed_out_tabs);
void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs);
void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs);
void RunNavigateLoadingTabToTimeoutTest(Browser* browser,
const GURL& starting_url,
const GURL& interrupted_url,
const GURL& timeout_url);
void SetSlowSSLLoadTime(CaptivePortalTabReloader* tab_reloader,
base::TimeDelta slow_ssl_load_time);
CaptivePortalTabReloader* GetTabReloader(WebContents* web_contents) const;
private:
DISALLOW_COPY_AND_ASSIGN(CaptivePortalBrowserTest);
};
CaptivePortalBrowserTest::CaptivePortalBrowserTest() {
}
void CaptivePortalBrowserTest::SetUpOnMainThread() {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
URLRequestMockCaptivePortalJobFactory::AddUrlHandlers();
EXPECT_EQ(CaptivePortalService::DISABLED_FOR_TESTING,
CaptivePortalService::get_state_for_testing());
CaptivePortalService::set_state_for_testing(
CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING);
EnableCaptivePortalDetection(browser()->profile(), true);
SetUpCaptivePortalService(browser()->profile(),
GURL(kMockCaptivePortalTestUrl));
}
void CaptivePortalBrowserTest::CleanUpOnMainThread() {
EXPECT_FALSE(CheckPending(browser()));
}
void CaptivePortalBrowserTest::EnableCaptivePortalDetection(
Profile* profile, bool enabled) {
profile->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled);
}
void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile,
const GURL& test_url) {
CaptivePortalService* captive_portal_service =
CaptivePortalServiceFactory::GetForProfile(profile);
captive_portal_service->set_test_url(test_url);
CaptivePortalService::RecheckPolicy* recheck_policy =
&captive_portal_service->recheck_policy();
recheck_policy->initial_backoff_no_portal_ms = 0;
recheck_policy->initial_backoff_portal_ms = 0;
recheck_policy->backoff_policy.maximum_backoff_ms = 0;
}
bool CaptivePortalBrowserTest::CheckPending(Browser* browser) {
CaptivePortalService* captive_portal_service =
CaptivePortalServiceFactory::GetForProfile(browser->profile());
return captive_portal_service->DetectionInProgress() ||
captive_portal_service->TimerRunning();
}
CaptivePortalTabReloader::State CaptivePortalBrowserTest::GetStateOfTabReloader(
WebContents* web_contents) const {
return GetTabReloader(web_contents)->state();
}
CaptivePortalTabReloader::State
CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser* browser,
int index) const {
return GetStateOfTabReloader(
browser->tab_strip_model()->GetWebContentsAt(index));
}
int CaptivePortalBrowserTest::NumTabsWithState(
CaptivePortalTabReloader::State state) const {
int num_tabs = 0;
for (TabContentsIterator it; !it.done(); it.Next()) {
if (GetStateOfTabReloader(*it) == state)
++num_tabs;
}
return num_tabs;
}
int CaptivePortalBrowserTest::NumBrokenTabs() const {
return NumTabsWithState(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL);
}
int CaptivePortalBrowserTest::NumNeedReloadTabs() const {
return NumTabsWithState(CaptivePortalTabReloader::STATE_NEEDS_RELOAD);
}
void CaptivePortalBrowserTest::NavigateToPageExpectNoTest(
Browser* browser,
const GURL& url,
int expected_navigations) {
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser->profile());
ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
browser, url, expected_navigations);
EXPECT_EQ(0, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(1, browser->tab_strip_model()->count());
EXPECT_EQ(expected_navigations, navigation_observer.num_navigations());
EXPECT_EQ(0, NumLoadingTabs());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser, 0));
}
void CaptivePortalBrowserTest::SlowLoadNoCaptivePortal(
Browser* browser, Result expected_result) {
CaptivePortalTabReloader* tab_reloader =
GetTabReloader(browser->tab_strip_model()->GetActiveWebContents());
ASSERT_TRUE(tab_reloader);
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser->profile());
ui_test_utils::NavigateToURLWithDisposition(browser,
GURL(kMockHttpsUrl),
CURRENT_TAB,
ui_test_utils::BROWSER_TEST_NONE);
portal_observer.WaitForResults(1);
ASSERT_EQ(1, browser->tab_strip_model()->count());
EXPECT_EQ(expected_result, portal_observer.captive_portal_result());
EXPECT_EQ(1, portal_observer.num_results_received());
EXPECT_EQ(0, navigation_observer.num_navigations());
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(1, NumLoadingTabs());
URLRequestTimeoutOnDemandJob::WaitForJobs(1);
URLRequestTimeoutOnDemandJob::FailJobs(1);
navigation_observer.WaitForNavigations(1);
ASSERT_EQ(1, browser->tab_strip_model()->count());
EXPECT_EQ(1, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(0, NumLoadingTabs());
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
}
void CaptivePortalBrowserTest::FastTimeoutNoCaptivePortal(
Browser* browser, Result expected_result) {
ASSERT_NE(expected_result, RESULT_BEHIND_CAPTIVE_PORTAL);
CaptivePortalTabReloader* tab_reloader =
GetTabReloader(browser->tab_strip_model()->GetActiveWebContents());
ASSERT_TRUE(tab_reloader);
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser->profile());
int active_index = browser->tab_strip_model()->active_index();
int expected_tab_count = browser->tab_strip_model()->count();
ui_test_utils::NavigateToURL(
browser,
URLRequestFailedJob::GetMockHttpsUrl(net::ERR_CONNECTION_TIMED_OUT));
ASSERT_TRUE(portal_observer.num_results_received() > 0 ||
CheckPending(browser));
portal_observer.WaitForResults(1);
navigation_observer.WaitForNavigations(1);
EXPECT_EQ(1, portal_observer.num_results_received());
EXPECT_EQ(expected_result, portal_observer.captive_portal_result());
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
browser->tab_strip_model()->GetWebContentsAt(active_index)));
EXPECT_EQ(0, NumLoadingTabs());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser, 0));
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(expected_tab_count, browser->tab_strip_model()->count());
}
void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
Browser* browser,
bool expect_open_login_tab) {
SlowLoadBehindCaptivePortal(browser,
expect_open_login_tab,
GURL(kMockHttpsUrl),
1,
1);
}
void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
Browser* browser,
bool expect_open_login_tab,
const GURL& hanging_url,
int expected_portal_checks,
int expected_login_tab_navigations) {
ASSERT_GE(expected_portal_checks, 1);
TabStripModel* tab_strip_model = browser->tab_strip_model();
ASSERT_FALSE(tab_strip_model->GetActiveWebContents()->IsLoading());
CaptivePortalTabReloader* tab_reloader =
GetTabReloader(tab_strip_model->GetActiveWebContents());
ASSERT_TRUE(tab_reloader);
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
int initial_tab_count = tab_strip_model->count();
int initial_active_index = tab_strip_model->active_index();
int initial_loading_tabs = NumLoadingTabs();
int expected_broken_tabs = NumBrokenTabs();
if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL !=
GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())) {
++expected_broken_tabs;
}
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser->profile());
ui_test_utils::NavigateToURLWithDisposition(browser,
hanging_url,
CURRENT_TAB,
ui_test_utils::BROWSER_TEST_NONE);
portal_observer.WaitForResults(expected_portal_checks);
if (expect_open_login_tab) {
ASSERT_GE(expected_login_tab_navigations, 1);
navigation_observer.WaitForNavigations(expected_login_tab_navigations);
ASSERT_EQ(initial_tab_count + 1, tab_strip_model->count());
EXPECT_EQ(initial_tab_count, tab_strip_model->active_index());
EXPECT_EQ(expected_login_tab_navigations,
navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(initial_tab_count)));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser, 1));
EXPECT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
} else {
EXPECT_EQ(0, navigation_observer.num_navigations());
EXPECT_EQ(initial_active_index, tab_strip_model->active_index());
ASSERT_EQ(initial_tab_count, tab_strip_model->count());
EXPECT_EQ(initial_active_index, tab_strip_model->active_index());
}
URLRequestTimeoutOnDemandJob::WaitForJobs(initial_loading_tabs + 1);
EXPECT_EQ(initial_loading_tabs + 1, NumLoadingTabs());
EXPECT_EQ(expected_broken_tabs, NumBrokenTabs());
EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
portal_observer.captive_portal_result());
EXPECT_EQ(expected_portal_checks, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
GetStateOfTabReloaderAt(browser, initial_active_index));
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
}
void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal(
Browser* browser,
bool expect_open_login_tab) {
FastErrorBehindCaptivePortal(browser,
expect_open_login_tab,
GURL(kMockHttpsQuickTimeoutUrl));
}
void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal(
Browser* browser,
bool expect_open_login_tab,
const GURL& error_url) {
TabStripModel* tab_strip_model = browser->tab_strip_model();
ASSERT_FALSE(tab_strip_model->GetActiveWebContents()->IsLoading());
CaptivePortalTabReloader* tab_reloader =
GetTabReloader(tab_strip_model->GetActiveWebContents());
ASSERT_TRUE(tab_reloader);
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
int initial_tab_count = tab_strip_model->count();
int initial_active_index = tab_strip_model->active_index();
int initial_loading_tabs = NumLoadingTabs();
int expected_broken_tabs = NumBrokenTabs();
if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL !=
GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())) {
++expected_broken_tabs;
}
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser->profile());
ui_test_utils::NavigateToURLWithDisposition(browser,
error_url,
CURRENT_TAB,
ui_test_utils::BROWSER_TEST_NONE);
portal_observer.WaitForResults(1);
if (expect_open_login_tab) {
navigation_observer.WaitForNavigations(2);
ASSERT_EQ(initial_tab_count + 1, tab_strip_model->count());
EXPECT_EQ(initial_tab_count, tab_strip_model->active_index());
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(initial_active_index)));
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(initial_tab_count)));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser, 1));
EXPECT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
} else {
navigation_observer.WaitForNavigations(1);
EXPECT_EQ(initial_active_index, tab_strip_model->active_index());
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(initial_active_index)));
ASSERT_EQ(initial_tab_count, tab_strip_model->count());
EXPECT_EQ(initial_active_index, tab_strip_model->active_index());
}
EXPECT_EQ(initial_loading_tabs, NumLoadingTabs());
EXPECT_EQ(expected_broken_tabs, NumBrokenTabs());
EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
portal_observer.captive_portal_result());
EXPECT_EQ(1, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
GetStateOfTabReloaderAt(browser, initial_active_index));
}
void CaptivePortalBrowserTest::NavigateLoginTab(Browser* browser,
int num_loading_tabs,
int num_timed_out_tabs) {
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser->profile());
TabStripModel* tab_strip_model = browser->tab_strip_model();
int initial_tab_count = tab_strip_model->count();
EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs());
int login_tab_index = tab_strip_model->active_index();
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloader(tab_strip_model->GetActiveWebContents()));
ASSERT_TRUE(IsLoginTab(browser->tab_strip_model()->GetActiveWebContents()));
content::RenderFrameHost* render_frame_host =
tab_strip_model->GetActiveWebContents()->GetMainFrame();
render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
portal_observer.WaitForResults(1);
navigation_observer.WaitForNavigations(1);
EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
portal_observer.captive_portal_result());
EXPECT_EQ(1, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(initial_tab_count, tab_strip_model->count());
EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
EXPECT_EQ(num_loading_tabs + num_timed_out_tabs, NumBrokenTabs());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser, login_tab_index));
EXPECT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(login_tab_index)));
}
void CaptivePortalBrowserTest::Login(Browser* browser,
int num_loading_tabs,
int num_timed_out_tabs) {
URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser->profile());
TabStripModel* tab_strip_model = browser->tab_strip_model();
int initial_tab_count = tab_strip_model->count();
ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs());
int login_tab_index = tab_strip_model->active_index();
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser, login_tab_index));
ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
content::RenderFrameHost* render_frame_host =
tab_strip_model->GetActiveWebContents()->GetMainFrame();
render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
portal_observer.WaitForResults(1);
navigation_observer.WaitForNavigations(1 + num_timed_out_tabs);
EXPECT_EQ(1, portal_observer.num_results_received());
EXPECT_EQ(0, NumBrokenTabs());
EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
EXPECT_EQ(num_loading_tabs, NumNeedReloadTabs());
EXPECT_EQ(initial_tab_count, tab_strip_model->count());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser, login_tab_index));
EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(login_tab_index)));
}
void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser,
int num_loading_tabs) {
ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
ASSERT_EQ(num_loading_tabs, NumNeedReloadTabs());
EXPECT_EQ(0, NumBrokenTabs());
TabStripModel* tab_strip_model = browser->tab_strip_model();
int initial_num_tabs = tab_strip_model->count();
int initial_active_tab = tab_strip_model->active_index();
CaptivePortalObserver portal_observer(browser->profile());
FailLoadsAfterLoginObserver fail_loads_observer;
URLRequestTimeoutOnDemandJob::WaitForJobs(num_loading_tabs);
URLRequestTimeoutOnDemandJob::FailJobs(num_loading_tabs);
fail_loads_observer.WaitForNavigations();
EXPECT_EQ(0, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(initial_num_tabs, tab_strip_model->count());
EXPECT_EQ(initial_active_tab, tab_strip_model->active_index());
EXPECT_EQ(0, NumNeedReloadTabs());
EXPECT_EQ(0, NumLoadingTabs());
}
void CaptivePortalBrowserTest::FailLoadsWithoutLogin(Browser* browser,
int num_loading_tabs) {
ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
ASSERT_EQ(0, NumNeedReloadTabs());
EXPECT_EQ(num_loading_tabs, NumBrokenTabs());
TabStripModel* tab_strip_model = browser->tab_strip_model();
int initial_num_tabs = tab_strip_model->count();
int login_tab = tab_strip_model->active_index();
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloader(tab_strip_model->GetActiveWebContents()));
ASSERT_TRUE(IsLoginTab(tab_strip_model->GetActiveWebContents()));
CaptivePortalObserver portal_observer(browser->profile());
MultiNavigationObserver navigation_observer;
URLRequestTimeoutOnDemandJob::FailJobs(num_loading_tabs);
navigation_observer.WaitForNavigations(num_loading_tabs);
EXPECT_EQ(0, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(initial_num_tabs, tab_strip_model->count());
EXPECT_EQ(0, NumNeedReloadTabs());
EXPECT_EQ(0, NumLoadingTabs());
EXPECT_EQ(num_loading_tabs, NumBrokenTabs());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloader(tab_strip_model->GetActiveWebContents()));
EXPECT_TRUE(IsLoginTab(tab_strip_model->GetActiveWebContents()));
EXPECT_EQ(login_tab, tab_strip_model->active_index());
EXPECT_EQ(0, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(login_tab)));
}
void CaptivePortalBrowserTest::RunNavigateLoadingTabToTimeoutTest(
Browser* browser,
const GURL& starting_url,
const GURL& hanging_url,
const GURL& timeout_url) {
URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
NavigateToPageExpectNoTest(browser, starting_url, 1);
URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
SlowLoadBehindCaptivePortal(browser, true, hanging_url, 1, 1);
URLRequestTimeoutOnDemandJob::WaitForJobs(1);
URLRequestTimeoutOnDemandJob::AbandonJobs(1);
TabStripModel* tab_strip_model = browser->tab_strip_model();
CaptivePortalTabReloader* tab_reloader =
GetTabReloader(tab_strip_model->GetWebContentsAt(0));
ASSERT_TRUE(tab_reloader);
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromSeconds(2));
CaptivePortalObserver portal_observer(browser->profile());
tab_strip_model->ActivateTabAt(0, true);
browser->OpenURL(content::OpenURLParams(timeout_url,
content::Referrer(),
CURRENT_TAB,
content::PAGE_TRANSITION_TYPED,
false));
portal_observer.WaitForResults(1);
EXPECT_FALSE(CheckPending(browser));
EXPECT_EQ(1, NumLoadingTabs());
EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
GetStateOfTabReloaderAt(browser, 0));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser, 1));
ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
URLRequestTimeoutOnDemandJob::WaitForJobs(1);
tab_strip_model->ActivateTabAt(1, true);
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
Login(browser, 1, 0);
FailLoadsAfterLogin(browser, 1);
}
void CaptivePortalBrowserTest::SetSlowSSLLoadTime(
CaptivePortalTabReloader* tab_reloader,
base::TimeDelta slow_ssl_load_time) {
tab_reloader->set_slow_ssl_load_time(slow_ssl_load_time);
}
CaptivePortalTabReloader* CaptivePortalBrowserTest::GetTabReloader(
WebContents* web_contents) const {
return CaptivePortalTabHelper::FromWebContents(web_contents)->
GetTabReloaderForTest();
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpTimeout) {
GURL url = URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT);
NavigateToPageExpectNoTest(browser(), url, 2);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsNonTimeoutError) {
GURL url = URLRequestFailedJob::GetMockHttpsUrl(net::ERR_UNEXPECTED);
NavigateToPageExpectNoTest(browser(), url, 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsIframeTimeout) {
net::SpawnedTestServer https_server(
net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
ASSERT_TRUE(https_server.Start());
GURL url = https_server.GetURL(kTestServerIframeTimeoutPath);
NavigateToPageExpectNoTest(browser(), url, 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFails) {
SetUpCaptivePortalService(
browser()->profile(),
URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED));
SlowLoadNoCaptivePortal(browser(), RESULT_NO_RESPONSE);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFailsFastTimout) {
SetUpCaptivePortalService(
browser()->profile(),
URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED));
FastTimeoutNoCaptivePortal(browser(), RESULT_NO_RESPONSE);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Disabled) {
EnableCaptivePortalDetection(browser()->profile(), false);
SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, InternetConnected) {
ASSERT_TRUE(test_server()->Start());
SetUpCaptivePortalService(browser()->profile(),
test_server()->GetURL("nocontent"));
SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RedirectSSLCertError) {
ASSERT_TRUE(test_server()->Start());
net::SpawnedTestServer::SSLOptions ssl_options;
ssl_options.server_certificate =
net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
net::SpawnedTestServer https_server(
net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
ASSERT_TRUE(https_server.Start());
GURL ssl_login_url = https_server.GetURL(kTestServerLoginPath);
CaptivePortalService* captive_portal_service =
CaptivePortalServiceFactory::GetForProfile(browser()->profile());
ASSERT_TRUE(captive_portal_service);
SetUpCaptivePortalService(
browser()->profile(),
test_server()->GetURL(CreateServerRedirect(ssl_login_url.spec())));
SlowLoadNoCaptivePortal(browser(), RESULT_NO_RESPONSE);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Login) {
SlowLoadBehindCaptivePortal(browser(), true);
Login(browser(), 1, 0);
FailLoadsAfterLogin(browser(), 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginIncognito) {
MultiNavigationObserver navigation_observer;
CaptivePortalObserver non_incognito_portal_observer(browser()->profile());
Browser* incognito_browser = CreateIncognitoBrowser();
EnableCaptivePortalDetection(incognito_browser->profile(), true);
SetUpCaptivePortalService(incognito_browser->profile(),
GURL(kMockCaptivePortalTestUrl));
SlowLoadBehindCaptivePortal(incognito_browser, true);
TabStripModel* tab_strip_model = browser()->tab_strip_model();
EXPECT_EQ(1, tab_strip_model->count());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 0));
Login(incognito_browser, 1, 0);
FailLoadsAfterLogin(incognito_browser, 1);
EXPECT_EQ(1, tab_strip_model->count());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 0));
EXPECT_EQ(0, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(0)));
EXPECT_EQ(0, non_incognito_portal_observer.num_results_received());
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginSlow) {
SlowLoadBehindCaptivePortal(browser(), true);
FailLoadsWithoutLogin(browser(), 1);
Login(browser(), 0, 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) {
FastTimeoutBehindCaptivePortal(browser(), true);
Login(browser(), 0, 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, SSLCertErrorLogin) {
ASSERT_TRUE(test_server()->Start());
net::SpawnedTestServer::SSLOptions https_options;
https_options.server_certificate =
net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
net::SpawnedTestServer https_server(
net::SpawnedTestServer::TYPE_HTTPS, https_options,
base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
ASSERT_TRUE(https_server.Start());
GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
FastErrorBehindCaptivePortal(browser(), true, cert_error_url);
URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser()->profile());
TabStripModel* tab_strip_model = browser()->tab_strip_model();
content::RenderFrameHost* render_frame_host =
tab_strip_model->GetActiveWebContents()->GetMainFrame();
render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
portal_observer.WaitForResults(2);
navigation_observer.WaitForNavigations(2);
EXPECT_EQ(2, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser()));
EXPECT_EQ(captive_portal::RESULT_INTERNET_CONNECTED,
portal_observer.captive_portal_result());
ASSERT_EQ(2, tab_strip_model->count());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 0));
EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 1));
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(1)));
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) {
FastTimeoutBehindCaptivePortal(browser(), true);
TabStripModel* tab_strip_model = browser()->tab_strip_model();
tab_strip_model->ActivateTabAt(0, true);
FastTimeoutBehindCaptivePortal(browser(), false);
tab_strip_model->ActivateTabAt(1, true);
NavigateLoginTab(browser(), 0, 1);
Login(browser(), 0, 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, CloseLoginTab) {
SlowLoadBehindCaptivePortal(browser(), true);
FailLoadsWithoutLogin(browser(), 1);
chrome::CloseTab(browser());
SlowLoadBehindCaptivePortal(browser(), true);
Login(browser(), 1, 0);
FailLoadsAfterLogin(browser(), 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, TwoBrokenTabs) {
SlowLoadBehindCaptivePortal(browser(), true);
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser()->profile());
ui_test_utils::NavigateToURLWithDisposition(
browser(),
URLRequestMockHTTPJob::GetMockUrl(
base::FilePath(FILE_PATH_LITERAL("title2.html"))),
NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
TabStripModel* tab_strip_model = browser()->tab_strip_model();
ASSERT_EQ(3, tab_strip_model->count());
EXPECT_FALSE(CheckPending(browser()));
EXPECT_EQ(0, portal_observer.num_results_received());
EXPECT_EQ(1, NumLoadingTabs());
EXPECT_EQ(1, navigation_observer.num_navigations());
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(2)));
ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
GetStateOfTabReloaderAt(browser(), 0));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 1));
ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 2));
ASSERT_EQ(2, tab_strip_model->active_index());
SlowLoadBehindCaptivePortal(browser(), false);
tab_strip_model->ActivateTabAt(1, true);
Login(browser(), 2, 0);
FailLoadsAfterLogin(browser(), 2);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, AbortLoad) {
SlowLoadBehindCaptivePortal(browser(), true);
URLRequestTimeoutOnDemandJob::WaitForJobs(1);
URLRequestTimeoutOnDemandJob::AbandonJobs(1);
CaptivePortalObserver portal_observer(browser()->profile());
MultiNavigationObserver navigation_observer;
TabStripModel* tab_strip_model = browser()->tab_strip_model();
tab_strip_model->ActivateTabAt(0, true);
chrome::Stop(browser());
navigation_observer.WaitForNavigations(1);
EXPECT_EQ(0, NumBrokenTabs());
EXPECT_EQ(0, portal_observer.num_results_received());
EXPECT_FALSE(CheckPending(browser()));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 0));
tab_strip_model->ActivateTabAt(1, true);
Login(browser(), 0, 0);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, NavigateBrokenTab) {
SlowLoadBehindCaptivePortal(browser(), true);
FailLoadsWithoutLogin(browser(), 1);
TabStripModel* tab_strip_model = browser()->tab_strip_model();
tab_strip_model->ActivateTabAt(0, true);
ui_test_utils::NavigateToURL(
browser(), URLRequestMockHTTPJob::GetMockUrl(
base::FilePath(FILE_PATH_LITERAL("title2.html"))));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 0));
tab_strip_model->ActivateTabAt(1, true);
Login(browser(), 0, 0);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
NavigateLoadingTabToTimeoutSingleSite) {
RunNavigateLoadingTabToTimeoutTest(
browser(),
GURL(kMockHttpsUrl),
GURL(kMockHttpsUrl),
GURL(kMockHttpsUrl));
}
#if defined(OS_WIN)
#define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
DISABLED_NavigateLoadingTabToTimeoutTwoSites
#else
#define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
NavigateLoadingTabToTimeoutTwoSites
#endif
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
MAYBE_NavigateLoadingTabToTimeoutTwoSites) {
RunNavigateLoadingTabToTimeoutTest(
browser(),
GURL(kMockHttpsUrl),
GURL(kMockHttpsUrl),
GURL(kMockHttpsUrl2));
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
NavigateLoadingTabToTimeoutThreeSites) {
RunNavigateLoadingTabToTimeoutTest(
browser(),
URLRequestMockHTTPJob::GetMockUrl(
base::FilePath(FILE_PATH_LITERAL("title.html"))),
GURL(kMockHttpsUrl),
GURL(kMockHttpsUrl2));
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBack) {
ui_test_utils::NavigateToURL(
browser(),
URLRequestMockHTTPJob::GetMockUrl(
base::FilePath(FILE_PATH_LITERAL("title2.html"))));
SlowLoadBehindCaptivePortal(browser(), true);
FailLoadsWithoutLogin(browser(), 1);
CaptivePortalObserver portal_observer(browser()->profile());
MultiNavigationObserver navigation_observer;
TabStripModel* tab_strip_model = browser()->tab_strip_model();
tab_strip_model->ActivateTabAt(0, true);
chrome::GoBack(browser(), CURRENT_TAB);
navigation_observer.WaitForNavigations(1);
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(0)));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 0));
EXPECT_EQ(0, portal_observer.num_results_received());
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBackToTimeout) {
EnableCaptivePortalDetection(browser()->profile(), false);
SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED);
ui_test_utils::NavigateToURL(
browser(), URLRequestMockHTTPJob::GetMockUrl(
base::FilePath(FILE_PATH_LITERAL("title2.html"))));
ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 0));
EnableCaptivePortalDetection(browser()->profile(), true);
TabStripModel* tab_strip_model = browser()->tab_strip_model();
CaptivePortalTabReloader* tab_reloader =
GetTabReloader(tab_strip_model->GetActiveWebContents());
ASSERT_TRUE(tab_reloader);
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
MultiNavigationObserver navigation_observer;
CaptivePortalObserver portal_observer(browser()->profile());
chrome::GoBack(browser(), CURRENT_TAB);
portal_observer.WaitForResults(1);
navigation_observer.WaitForNavigations(1);
URLRequestTimeoutOnDemandJob::WaitForJobs(1);
EXPECT_EQ(1, portal_observer.num_results_received());
ASSERT_FALSE(CheckPending(browser()));
ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
portal_observer.captive_portal_result());
ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
GetStateOfTabReloaderAt(browser(), 0));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 1));
ASSERT_TRUE(IsLoginTab(browser()->tab_strip_model()->GetWebContentsAt(1)));
ASSERT_EQ(2, tab_strip_model->count());
EXPECT_EQ(1, tab_strip_model->active_index());
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(1)));
EXPECT_EQ(1, NumLoadingTabs());
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
Login(browser(), 1, 0);
FailLoadsAfterLogin(browser(), 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, ReloadTimeout) {
URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
TabStripModel* tab_strip_model = browser()->tab_strip_model();
CaptivePortalObserver portal_observer(browser()->profile());
ui_test_utils::NavigateToURL(browser(), GURL(kMockHttpsUrl));
ASSERT_EQ(0, portal_observer.num_results_received());
ASSERT_EQ(1, tab_strip_model->count());
URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
CaptivePortalTabReloader* tab_reloader =
GetTabReloader(tab_strip_model->GetActiveWebContents());
ASSERT_TRUE(tab_reloader);
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
MultiNavigationObserver navigation_observer;
tab_strip_model->GetActiveWebContents()->GetController().Reload(true);
portal_observer.WaitForResults(1);
navigation_observer.WaitForNavigations(1);
URLRequestTimeoutOnDemandJob::WaitForJobs(1);
ASSERT_EQ(1, portal_observer.num_results_received());
ASSERT_FALSE(CheckPending(browser()));
ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
portal_observer.captive_portal_result());
ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
GetStateOfTabReloaderAt(browser(), 0));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(browser(), 1));
ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
ASSERT_EQ(2, tab_strip_model->count());
EXPECT_EQ(1, tab_strip_model->active_index());
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
tab_strip_model->GetWebContentsAt(1)));
EXPECT_EQ(1, NumLoadingTabs());
SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
Login(browser(), 1, 0);
FailLoadsAfterLogin(browser(), 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, DISABLED_TwoWindows) {
Browser* browser2 =
new Browser(Browser::CreateParams(browser()->profile(),
browser()->host_desktop_type()));
ui_test_utils::NavigateToURL(browser2, GURL(content::kAboutBlankURL));
Browser* active_browser =
chrome::FindTabbedBrowser(browser()->profile(), true,
browser()->host_desktop_type());
Browser* inactive_browser;
if (active_browser == browser2) {
inactive_browser = browser();
} else {
ASSERT_EQ(active_browser, browser());
inactive_browser = browser2;
}
CaptivePortalObserver portal_observer(browser()->profile());
MultiNavigationObserver navigation_observer;
chrome::NavigateParams params(inactive_browser,
GURL(kMockHttpsQuickTimeoutUrl),
content::PAGE_TRANSITION_TYPED);
params.disposition = NEW_BACKGROUND_TAB;
params.window_action = chrome::NavigateParams::NO_ACTION;
ui_test_utils::NavigateToURL(¶ms);
navigation_observer.WaitForNavigations(2);
ASSERT_EQ(active_browser,
chrome::FindTabbedBrowser(browser()->profile(), true,
browser()->host_desktop_type()));
ASSERT_EQ(1, active_browser->tab_strip_model()->active_index());
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
inactive_browser->tab_strip_model()->GetWebContentsAt(1)));
EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
active_browser->tab_strip_model()->GetWebContentsAt(1)));
EXPECT_EQ(0, NumLoadingTabs());
portal_observer.WaitForResults(1);
ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
portal_observer.captive_portal_result());
EXPECT_EQ(1, portal_observer.num_results_received());
EXPECT_EQ(2, inactive_browser->tab_strip_model()->count());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(inactive_browser, 0));
EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
GetStateOfTabReloaderAt(inactive_browser, 1));
ASSERT_EQ(2, active_browser->tab_strip_model()->count());
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(active_browser, 0));
EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
GetStateOfTabReloaderAt(active_browser, 1));
EXPECT_TRUE(
IsLoginTab(active_browser->tab_strip_model()->GetWebContentsAt(1)));
Login(active_browser, 0, 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpToHttpsRedirectLogin) {
ASSERT_TRUE(test_server()->Start());
SlowLoadBehindCaptivePortal(
browser(),
true,
test_server()->GetURL(CreateServerRedirect(kMockHttpsUrl)),
1,
1);
Login(browser(), 1, 0);
FailLoadsAfterLogin(browser(), 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsToHttpRedirect) {
net::SpawnedTestServer https_server(
net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
ASSERT_TRUE(https_server.Start());
GURL http_timeout_url =
URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT);
NavigateToPageExpectNoTest(
browser(),
https_server.GetURL(CreateServerRedirect(http_timeout_url.spec())),
2);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Status511) {
SetUpCaptivePortalService(browser()->profile(),
GURL(kMockCaptivePortal511Url));
SlowLoadBehindCaptivePortal(browser(), true, GURL(kMockHttpsUrl), 2, 2);
Login(browser(), 1, 0);
FailLoadsAfterLogin(browser(), 1);
}
IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HstsLogin) {
GURL::Replacements replacements;
std::string scheme = "http";
replacements.SetSchemeStr(scheme);
GURL http_timeout_url = GURL(kMockHttpsUrl).ReplaceComponents(replacements);
URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT);
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&AddHstsHost,
make_scoped_refptr(browser()->profile()->GetRequestContext()),
http_timeout_url.host()));
SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url, 1, 1);
Login(browser(), 1, 0);
FailLoadsAfterLogin(browser(), 1);
}
}