screen_locker_tester.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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/mock_authenticator.h"
14#include "chrome/browser/chromeos/login/lock/screen_locker.h"
15#include "chrome/browser/chromeos/login/lock/webui_screen_locker.h"
16#include "chrome/test/base/ui_test_utils.h"
17#include "chromeos/login/auth/auth_status_consumer.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
28using content::WebContents;
29
30namespace {
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.
35class LoginAttemptObserver : public chromeos::AuthStatusConsumer {
36 public:
37  LoginAttemptObserver();
38  virtual ~LoginAttemptObserver();
39
40  void WaitForAttempt();
41
42  // Overridden from AuthStatusConsumer:
43  virtual void OnAuthFailure(const chromeos::AuthFailure& error) OVERRIDE {
44    LoginAttempted();
45  }
46
47  virtual void OnAuthSuccess(
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
61LoginAttemptObserver::LoginAttemptObserver()
62    : chromeos::AuthStatusConsumer(), login_attempted_(false), waiting_(false) {
63  chromeos::ScreenLocker::default_screen_locker()->SetLoginStatusConsumer(this);
64}
65
66LoginAttemptObserver::~LoginAttemptObserver() {
67  chromeos::ScreenLocker* global_locker =
68      chromeos::ScreenLocker::default_screen_locker();
69  if (global_locker)
70    global_locker->SetLoginStatusConsumer(NULL);
71}
72
73void LoginAttemptObserver::WaitForAttempt() {
74  if (!login_attempted_) {
75    waiting_ = true;
76    content::RunMessageLoop();
77    waiting_ = false;
78  }
79  ASSERT_TRUE(login_attempted_);
80}
81
82void LoginAttemptObserver::LoginAttempted() {
83  login_attempted_ = true;
84  if (waiting_)
85    base::MessageLoopForUI::current()->Quit();
86}
87
88}  // anyonymous namespace
89
90namespace chromeos {
91
92namespace test {
93
94class WebUIScreenLockerTester : public ScreenLockerTester {
95 public:
96  // ScreenLockerTester overrides:
97  virtual void SetPassword(const std::string& password) OVERRIDE;
98  virtual std::string GetPassword() OVERRIDE;
99  virtual void EnterPassword(const std::string& password) OVERRIDE;
100  virtual void EmulateWindowManagerReady() OVERRIDE;
101  virtual views::Widget* GetWidget() const OVERRIDE;
102  virtual views::Widget* GetChildWidget() const OVERRIDE;
103
104 private:
105  friend class chromeos::ScreenLocker;
106
107  WebUIScreenLockerTester() {}
108
109  content::RenderViewHost* RenderViewHost() const;
110
111  // Returns the ScreenLockerWebUI object.
112  WebUIScreenLocker* webui_screen_locker() const;
113
114  // Returns the WebUI object from the screen locker.
115  content::WebUI* webui() const;
116
117  DISALLOW_COPY_AND_ASSIGN(WebUIScreenLockerTester);
118};
119
120void WebUIScreenLockerTester::SetPassword(const std::string& password) {
121  webui()->GetWebContents()->GetMainFrame()->ExecuteJavaScript(
122      base::ASCIIToUTF16(base::StringPrintf(
123          "$('pod-row').pods[0].passwordElement.value = '%s';",
124          password.c_str())));
125}
126
127std::string WebUIScreenLockerTester::GetPassword() {
128  std::string result;
129  scoped_ptr<base::Value> v = content::ExecuteScriptAndGetValue(
130      RenderViewHost()->GetMainFrame(),
131      "$('pod-row').pods[0].passwordElement.value;");
132  CHECK(v->GetAsString(&result));
133  return result;
134}
135
136void 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()->GetMainFrame(),
146      "window.getComputedStyle("
147      "    $('pod-row').pods[0].querySelector('.signin-button-container'))"
148      "        .display == 'none'");
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
164void WebUIScreenLockerTester::EmulateWindowManagerReady() {
165}
166
167views::Widget* WebUIScreenLockerTester::GetWidget() const {
168  return webui_screen_locker()->lock_window_;
169}
170
171views::Widget* WebUIScreenLockerTester::GetChildWidget() const {
172  return webui_screen_locker()->lock_window_;
173}
174
175content::RenderViewHost* WebUIScreenLockerTester::RenderViewHost() const {
176  return webui()->GetWebContents()->GetRenderViewHost();
177}
178
179WebUIScreenLocker* WebUIScreenLockerTester::webui_screen_locker() const {
180  DCHECK(ScreenLocker::screen_locker_);
181  return static_cast<WebUIScreenLocker*>(
182      ScreenLocker::screen_locker_->delegate_.get());
183}
184
185content::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
192ScreenLockerTester::ScreenLockerTester() {
193}
194
195ScreenLockerTester::~ScreenLockerTester() {
196}
197
198bool ScreenLockerTester::IsLocked() {
199  return ScreenLocker::screen_locker_ &&
200      ScreenLocker::screen_locker_->locked_;
201}
202
203void 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
212test::ScreenLockerTester* ScreenLocker::GetTester() {
213  return new test::WebUIScreenLockerTester();
214}
215
216}  // namespace chromeos
217