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 "chrome/browser/chromeos/login/screen_locker_tester.h" 6 7 #include <string> 8 9 #include "base/strings/string_util.h" 10 #include "base/strings/stringprintf.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "base/values.h" 13 #include "chrome/browser/chromeos/login/login_status_consumer.h" 14 #include "chrome/browser/chromeos/login/mock_authenticator.h" 15 #include "chrome/browser/chromeos/login/screen_locker.h" 16 #include "chrome/browser/chromeos/login/webui_screen_locker.h" 17 #include "chrome/test/base/ui_test_utils.h" 18 #include "content/public/browser/render_view_host.h" 19 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_ui.h" 21 #include "content/public/test/test_utils.h" 22 #include "ui/views/controls/button/button.h" 23 #include "ui/views/controls/label.h" 24 #include "ui/views/controls/textfield/textfield.h" 25 #include "ui/views/widget/root_view.h" 26 27 using content::WebContents; 28 29 namespace { 30 31 class LoginAttemptObserver : public chromeos::LoginStatusConsumer { 32 public: 33 explicit LoginAttemptObserver(chromeos::ScreenLocker* locker); 34 virtual ~LoginAttemptObserver(); 35 36 void WaitForAttempt(); 37 38 // Overridden from LoginStatusConsumer: 39 virtual void OnLoginFailure(const chromeos::LoginFailure& error) OVERRIDE { 40 LoginAttempted(); 41 } 42 43 virtual void OnLoginSuccess( 44 const chromeos::UserContext& credentials, 45 bool pending_requests, 46 bool using_oauth) OVERRIDE { 47 LoginAttempted(); 48 } 49 50 private: 51 void LoginAttempted(); 52 53 chromeos::ScreenLocker* locker_; 54 bool login_attempted_; 55 bool waiting_; 56 57 DISALLOW_COPY_AND_ASSIGN(LoginAttemptObserver); 58 }; 59 60 LoginAttemptObserver::LoginAttemptObserver(chromeos::ScreenLocker* locker) 61 : chromeos::LoginStatusConsumer(), 62 locker_(locker), 63 login_attempted_(false), 64 waiting_(false) { 65 locker_->SetLoginStatusConsumer(this); 66 } 67 68 LoginAttemptObserver::~LoginAttemptObserver() { 69 locker_->SetLoginStatusConsumer(NULL); 70 } 71 72 void LoginAttemptObserver::WaitForAttempt() { 73 if (!login_attempted_) { 74 waiting_ = true; 75 content::RunMessageLoop(); 76 waiting_ = false; 77 } 78 ASSERT_TRUE(login_attempted_); 79 } 80 81 void LoginAttemptObserver::LoginAttempted() { 82 login_attempted_ = true; 83 if (waiting_) 84 base::MessageLoopForUI::current()->Quit(); 85 } 86 87 } 88 89 namespace chromeos { 90 91 namespace test { 92 93 class WebUIScreenLockerTester : public ScreenLockerTester { 94 public: 95 // ScreenLockerTester overrides: 96 virtual void SetPassword(const std::string& password) OVERRIDE; 97 virtual std::string GetPassword() OVERRIDE; 98 virtual void EnterPassword(const std::string& password) OVERRIDE; 99 virtual void EmulateWindowManagerReady() OVERRIDE; 100 virtual views::Widget* GetWidget() const OVERRIDE; 101 virtual views::Widget* GetChildWidget() const OVERRIDE; 102 103 private: 104 friend class chromeos::ScreenLocker; 105 106 WebUIScreenLockerTester() {} 107 108 content::RenderViewHost* RenderViewHost() const; 109 110 // Returns the ScreenLockerWebUI object. 111 WebUIScreenLocker* webui_screen_locker() const; 112 113 // Returns the WebUI object from the screen locker. 114 content::WebUI* webui() const; 115 116 DISALLOW_COPY_AND_ASSIGN(WebUIScreenLockerTester); 117 }; 118 119 void WebUIScreenLockerTester::SetPassword(const std::string& password) { 120 RenderViewHost()->ExecuteJavascriptInWebFrame( 121 string16(), 122 ASCIIToUTF16(base::StringPrintf( 123 "$('pod-row').pods[0].passwordElement.value = '%s';", 124 password.c_str()))); 125 } 126 127 std::string WebUIScreenLockerTester::GetPassword() { 128 std::string result; 129 scoped_ptr<base::Value> v = content::ExecuteScriptAndGetValue( 130 RenderViewHost(), 131 "$('pod-row').pods[0].passwordElement.value;"); 132 CHECK(v->GetAsString(&result)); 133 return result; 134 } 135 136 void WebUIScreenLockerTester::EnterPassword(const std::string& password) { 137 bool result; 138 SetPassword(password); 139 140 // Verify password is set. 141 ASSERT_EQ(password, GetPassword()); 142 143 // Verify that "signin" button is hidden. 144 scoped_ptr<base::Value> v = content::ExecuteScriptAndGetValue( 145 RenderViewHost(), 146 "$('pod-row').pods[0].signinButtonElement.hidden;"); 147 ASSERT_TRUE(v->GetAsBoolean(&result)); 148 ASSERT_TRUE(result); 149 150 // Attempt to sign in. 151 LoginAttemptObserver login(ScreenLocker::screen_locker_); 152 v = content::ExecuteScriptAndGetValue( 153 RenderViewHost(), 154 "$('pod-row').pods[0].activate();"); 155 ASSERT_TRUE(v->GetAsBoolean(&result)); 156 ASSERT_TRUE(result); 157 158 // Wait for login attempt. 159 login.WaitForAttempt(); 160 } 161 162 void WebUIScreenLockerTester::EmulateWindowManagerReady() { 163 } 164 165 views::Widget* WebUIScreenLockerTester::GetWidget() const { 166 return webui_screen_locker()->lock_window_; 167 } 168 169 views::Widget* WebUIScreenLockerTester::GetChildWidget() const { 170 return webui_screen_locker()->lock_window_; 171 } 172 173 content::RenderViewHost* WebUIScreenLockerTester::RenderViewHost() const { 174 return webui()->GetWebContents()->GetRenderViewHost(); 175 } 176 177 WebUIScreenLocker* WebUIScreenLockerTester::webui_screen_locker() const { 178 DCHECK(ScreenLocker::screen_locker_); 179 return static_cast<WebUIScreenLocker*>( 180 ScreenLocker::screen_locker_->delegate_.get()); 181 } 182 183 content::WebUI* WebUIScreenLockerTester::webui() const { 184 DCHECK(webui_screen_locker()->webui_ready_); 185 content::WebUI* webui = webui_screen_locker()->GetWebUI(); 186 DCHECK(webui); 187 return webui; 188 } 189 190 ScreenLockerTester::ScreenLockerTester() { 191 } 192 193 ScreenLockerTester::~ScreenLockerTester() { 194 } 195 196 bool ScreenLockerTester::IsLocked() { 197 return ScreenLocker::screen_locker_ && 198 ScreenLocker::screen_locker_->locked_; 199 } 200 201 void ScreenLockerTester::InjectMockAuthenticator( 202 const std::string& user, const std::string& password) { 203 DCHECK(ScreenLocker::screen_locker_); 204 ScreenLocker::screen_locker_->SetAuthenticator( 205 new MockAuthenticator(ScreenLocker::screen_locker_, user, password)); 206 } 207 208 } // namespace test 209 210 test::ScreenLockerTester* ScreenLocker::GetTester() { 211 return new test::WebUIScreenLockerTester(); 212 } 213 214 } // namespace chromeos 215