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