• 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/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 
29 using content::WebContents;
30 
31 namespace {
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.
36 class LoginAttemptObserver : public chromeos::AuthStatusConsumer {
37  public:
38   LoginAttemptObserver();
39   virtual ~LoginAttemptObserver();
40 
41   void WaitForAttempt();
42 
43   // Overridden from AuthStatusConsumer:
OnAuthFailure(const chromeos::AuthFailure & error)44   virtual void OnAuthFailure(const chromeos::AuthFailure& error) OVERRIDE {
45     LoginAttempted();
46   }
47 
OnAuthSuccess(const chromeos::UserContext & credentials)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 
LoginAttemptObserver()62 LoginAttemptObserver::LoginAttemptObserver()
63     : chromeos::AuthStatusConsumer(), login_attempted_(false), waiting_(false) {
64   chromeos::ScreenLocker::default_screen_locker()->SetLoginStatusConsumer(this);
65 }
66 
~LoginAttemptObserver()67 LoginAttemptObserver::~LoginAttemptObserver() {
68   chromeos::ScreenLocker* global_locker =
69       chromeos::ScreenLocker::default_screen_locker();
70   if (global_locker)
71     global_locker->SetLoginStatusConsumer(NULL);
72 }
73 
WaitForAttempt()74 void LoginAttemptObserver::WaitForAttempt() {
75   if (!login_attempted_) {
76     waiting_ = true;
77     content::RunMessageLoop();
78     waiting_ = false;
79   }
80   ASSERT_TRUE(login_attempted_);
81 }
82 
LoginAttempted()83 void LoginAttemptObserver::LoginAttempted() {
84   login_attempted_ = true;
85   if (waiting_)
86     base::MessageLoopForUI::current()->Quit();
87 }
88 
89 }  // anyonymous namespace
90 
91 namespace chromeos {
92 
93 namespace test {
94 
95 class 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 
WebUIScreenLockerTester()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 
SetPassword(const std::string & password)121 void 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 
GetPassword()128 std::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 
EnterPassword(const std::string & password)137 void 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 
EmulateWindowManagerReady()165 void WebUIScreenLockerTester::EmulateWindowManagerReady() {
166 }
167 
GetWidget() const168 views::Widget* WebUIScreenLockerTester::GetWidget() const {
169   return webui_screen_locker()->lock_window_;
170 }
171 
GetChildWidget() const172 views::Widget* WebUIScreenLockerTester::GetChildWidget() const {
173   return webui_screen_locker()->lock_window_;
174 }
175 
RenderViewHost() const176 content::RenderViewHost* WebUIScreenLockerTester::RenderViewHost() const {
177   return webui()->GetWebContents()->GetRenderViewHost();
178 }
179 
webui_screen_locker() const180 WebUIScreenLocker* WebUIScreenLockerTester::webui_screen_locker() const {
181   DCHECK(ScreenLocker::screen_locker_);
182   return static_cast<WebUIScreenLocker*>(
183       ScreenLocker::screen_locker_->delegate_.get());
184 }
185 
webui() const186 content::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 
ScreenLockerTester()193 ScreenLockerTester::ScreenLockerTester() {
194 }
195 
~ScreenLockerTester()196 ScreenLockerTester::~ScreenLockerTester() {
197 }
198 
IsLocked()199 bool ScreenLockerTester::IsLocked() {
200   return ScreenLocker::screen_locker_ &&
201       ScreenLocker::screen_locker_->locked_;
202 }
203 
InjectMockAuthenticator(const UserContext & user_context)204 void 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 
GetTester()215 test::ScreenLockerTester* ScreenLocker::GetTester() {
216   return new test::WebUIScreenLockerTester();
217 }
218 
219 }  // namespace chromeos
220