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