oobe_browsertest.cc revision a3f7b4e666c476898878fa745f637129375cd889
1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/command_line.h" 6#include "base/path_service.h" 7#include "chrome/browser/chrome_browser_main.h" 8#include "chrome/browser/chrome_browser_main_extra_parts.h" 9#include "chrome/browser/chrome_content_browser_client.h" 10#include "chrome/browser/chrome_notification_types.h" 11#include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h" 12#include "chrome/browser/chromeos/login/existing_user_controller.h" 13#include "chrome/browser/chromeos/login/webui_login_display.h" 14#include "chrome/browser/chromeos/login/wizard_controller.h" 15#include "chrome/browser/ui/browser.h" 16#include "chrome/common/chrome_paths.h" 17#include "chrome/common/chrome_switches.h" 18#include "chrome/test/base/in_process_browser_test.h" 19#include "chrome/test/base/interactive_test_utils.h" 20#include "chrome/test/base/ui_test_utils.h" 21#include "chromeos/chromeos_switches.h" 22#include "content/public/browser/notification_observer.h" 23#include "content/public/browser/notification_registrar.h" 24#include "content/public/browser/notification_service.h" 25#include "content/public/test/test_utils.h" 26#include "google_apis/gaia/gaia_switches.h" 27#include "net/test/embedded_test_server/embedded_test_server.h" 28#include "net/test/embedded_test_server/http_request.h" 29#include "net/test/embedded_test_server/http_response.h" 30#include "testing/gmock/include/gmock/gmock.h" 31#include "testing/gtest/include/gtest/gtest.h" 32 33using namespace net::test_server; 34 35namespace { 36 37// Used to add an observer to NotificationService after it's created. 38class TestBrowserMainExtraParts 39 : public ChromeBrowserMainExtraParts, 40 public content::NotificationObserver { 41 public: 42 TestBrowserMainExtraParts() 43 : webui_visible_(false), 44 browsing_data_removed_(false), 45 signin_screen_shown_(false) {} 46 virtual ~TestBrowserMainExtraParts() {} 47 48 // ChromeBrowserMainExtraParts implementation. 49 virtual void PreEarlyInitialization() OVERRIDE { 50 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 51 content::NotificationService::AllSources()); 52 registrar_.Add(this, chrome::NOTIFICATION_SESSION_STARTED, 53 content::NotificationService::AllSources()); 54 registrar_.Add(this, chrome::NOTIFICATION_BROWSING_DATA_REMOVED, 55 content::NotificationService::AllSources()); 56 } 57 58 void set_quit_task(const base::Closure& quit_task) { quit_task_ = quit_task; } 59 60 private: 61 // Overridden from content::NotificationObserver: 62 virtual void Observe(int type, 63 const content::NotificationSource& source, 64 const content::NotificationDetails& details) OVERRIDE { 65 if (type == chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE) { 66 LOG(INFO) << "NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE"; 67 webui_visible_ = true; 68 if (browsing_data_removed_ && !signin_screen_shown_) { 69 signin_screen_shown_ = true; 70 ShowSigninScreen(); 71 } 72 } else if (type == chrome::NOTIFICATION_BROWSING_DATA_REMOVED) { 73 LOG(INFO) << "chrome::NOTIFICATION_BROWSING_DATA_REMOVED"; 74 browsing_data_removed_ = true; 75 if (webui_visible_ && !signin_screen_shown_) { 76 signin_screen_shown_ = true; 77 ShowSigninScreen(); 78 } 79 } else if (type == chrome::NOTIFICATION_SESSION_STARTED) { 80 LOG(INFO) << "chrome::NOTIFICATION_SESSION_STARTED"; 81 quit_task_.Run(); 82 } else { 83 NOTREACHED(); 84 } 85 } 86 87 void ShowSigninScreen() { 88 chromeos::ExistingUserController* controller = 89 chromeos::ExistingUserController::current_controller(); 90 CHECK(controller); 91 chromeos::WebUILoginDisplay* webui_login_display = 92 static_cast<chromeos::WebUILoginDisplay*>( 93 controller->login_display()); 94 CHECK(webui_login_display); 95 webui_login_display->ShowSigninScreenForCreds("username", "password"); 96 // TODO(glotov): mock GAIA server (test_server_) should support 97 // username/password configuration. 98 } 99 100 bool webui_visible_, browsing_data_removed_, signin_screen_shown_; 101 content::NotificationRegistrar registrar_; 102 base::Closure quit_task_; 103 GURL gaia_url_; 104 105 DISALLOW_COPY_AND_ASSIGN(TestBrowserMainExtraParts); 106}; 107 108class TestContentBrowserClient : public chrome::ChromeContentBrowserClient { 109 public: 110 TestContentBrowserClient() {} 111 virtual ~TestContentBrowserClient() {} 112 113 virtual content::BrowserMainParts* CreateBrowserMainParts( 114 const content::MainFunctionParams& parameters) OVERRIDE { 115 ChromeBrowserMainParts* main_parts = static_cast<ChromeBrowserMainParts*>( 116 ChromeContentBrowserClient::CreateBrowserMainParts(parameters)); 117 118 browser_main_extra_parts_ = new TestBrowserMainExtraParts(); 119 main_parts->AddParts(browser_main_extra_parts_); 120 return main_parts; 121 } 122 123 TestBrowserMainExtraParts* browser_main_extra_parts_; 124 125 private: 126 DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient); 127}; 128 129const base::FilePath kServiceLogin("chromeos/service_login.html"); 130 131class OobeTest : public chromeos::CrosInProcessBrowserTest { 132 protected: 133 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 134 command_line->AppendSwitch(chromeos::switches::kLoginManager); 135 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); 136 command_line->AppendSwitch( 137 chromeos::switches::kDisableChromeCaptivePortalDetector); 138 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); 139 command_line->AppendSwitchASCII( 140 chromeos::switches::kAuthExtensionPath, "gaia_auth"); 141 } 142 143 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 144 content_browser_client_.reset(new TestContentBrowserClient()); 145 original_content_browser_client_ = content::SetBrowserClientForTesting( 146 content_browser_client_.get()); 147 base::FilePath test_data_dir; 148 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); 149 CHECK(file_util::ReadFileToString(test_data_dir.Append(kServiceLogin), 150 &service_login_response_)); 151 } 152 153 virtual void SetUpOnMainThread() OVERRIDE { 154 test_server_ = new EmbeddedTestServer( 155 content::BrowserThread::GetMessageLoopProxyForThread( 156 content::BrowserThread::IO)); 157 CHECK(test_server_->InitializeAndWaitUntilReady()); 158 test_server_->RegisterRequestHandler( 159 base::Bind(&OobeTest::HandleRequest, base::Unretained(this))); 160 LOG(INFO) << "Set up http server at " << test_server_->base_url(); 161 162 const GURL gaia_url("http://localhost:" + test_server_->base_url().port()); 163 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 164 ::switches::kGaiaUrl, gaia_url.spec()); 165 } 166 167 virtual void CleanUpOnMainThread() OVERRIDE { 168 LOG(INFO) << "Stopping the http server."; 169 EXPECT_TRUE(test_server_->ShutdownAndWaitUntilComplete()); 170 delete test_server_; // Destructor wants UI thread. 171 } 172 173 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { 174 GURL url = test_server_->GetURL(request.relative_url); 175 LOG(INFO) << "Http request: " << url.spec(); 176 177 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse()); 178 if (url.path() == "/ServiceLogin") { 179 http_response->set_code(net::HTTP_OK); 180 http_response->set_content(service_login_response_); 181 http_response->set_content_type("text/html"); 182 } else if (url.path() == "/ServiceLoginAuth") { 183 LOG(INFO) << "Params: " << request.content; 184 static const char kContinueParam[] = "continue="; 185 int continue_arg_begin = request.content.find(kContinueParam) + 186 arraysize(kContinueParam) - 1; 187 int continue_arg_end = request.content.find("&", continue_arg_begin); 188 const std::string continue_url = request.content.substr( 189 continue_arg_begin, continue_arg_end - continue_arg_begin); 190 http_response->set_code(net::HTTP_OK); 191 const std::string redirect_js = 192 "document.location.href = unescape('" + continue_url + "');"; 193 http_response->set_content( 194 "<HTML><HEAD><SCRIPT>\n" + redirect_js + "\n</SCRIPT></HEAD></HTML>"); 195 http_response->set_content_type("text/html"); 196 } else { 197 NOTREACHED() << url.path(); 198 } 199 return http_response.PassAs<HttpResponse>(); 200 } 201 202 scoped_ptr<TestContentBrowserClient> content_browser_client_; 203 content::ContentBrowserClient* original_content_browser_client_; 204 std::string service_login_response_; 205 EmbeddedTestServer* test_server_; // cant use scoped_ptr because destructor 206 // needs UI thread. 207}; 208 209IN_PROC_BROWSER_TEST_F(OobeTest, NewUser) { 210 chromeos::WizardController::SkipPostLoginScreensForTesting(); 211 chromeos::WizardController* wizard_controller = 212 chromeos::WizardController::default_controller(); 213 CHECK(wizard_controller); 214 wizard_controller->SkipToLoginForTesting(); 215 216 scoped_refptr<content::MessageLoopRunner> runner = 217 new content::MessageLoopRunner; 218 content_browser_client_->browser_main_extra_parts_->set_quit_task( 219 runner->QuitClosure()); 220 runner->Run(); 221} 222 223} // namespace 224