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.
6 #include "ash/system/tray/system_tray.h"
7 #include "base/command_line.h"
8 #include "base/strings/string_util.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/chromeos/login/login_manager_test.h"
11 #include "chrome/browser/chromeos/login/login_wizard.h"
12 #include "chrome/browser/chromeos/login/startup_utils.h"
13 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
14 #include "chrome/browser/chromeos/login/wizard_controller.h"
15 #include "chrome/browser/chromeos/settings/cros_settings.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/profiles/profiles_state.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/common/chrome_constants.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/test/base/in_process_browser_test.h"
22 #include "chrome/test/base/interactive_test_utils.h"
23 #include "chrome/test/base/tracing.h"
24 #include "chromeos/chromeos_switches.h"
25 #include "chromeos/login/user_names.h"
26 #include "chromeos/settings/cros_settings_names.h"
27 #include "content/public/test/browser_test_utils.h"
28 #include "content/public/test/test_utils.h"
29 #include "extensions/browser/extension_system.h"
30 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gtest/include/gtest/gtest.h"
34 using ::testing::AnyNumber
;
35 using ::testing::Return
;
39 const char kGaiaId
[] = "12345";
40 const char kTestUser
[] = "test-user@gmail.com";
41 const char kPassword
[] = "password";
43 class LoginUserTest
: public InProcessBrowserTest
{
45 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
46 command_line
->AppendSwitchASCII(
47 chromeos::switches::kLoginUser
, "TestUser@gmail.com");
48 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
,
53 class LoginGuestTest
: public InProcessBrowserTest
{
55 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
56 command_line
->AppendSwitch(chromeos::switches::kGuestSession
);
57 command_line
->AppendSwitch(::switches::kIncognito
);
58 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
,
60 command_line
->AppendSwitchASCII(chromeos::switches::kLoginUser
,
61 chromeos::login::kGuestUserName
);
65 class LoginCursorTest
: public InProcessBrowserTest
{
67 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
68 command_line
->AppendSwitch(chromeos::switches::kLoginManager
);
72 class LoginSigninTest
: public InProcessBrowserTest
{
74 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
75 command_line
->AppendSwitch(chromeos::switches::kLoginManager
);
76 command_line
->AppendSwitch(chromeos::switches::kForceLoginManagerInTests
);
79 void SetUpOnMainThread() override
{
80 ASSERT_TRUE(tracing::BeginTracingWithWatch(
81 "ui", "ui", "ShowLoginWebUI", 1));
85 class LoginTest
: public chromeos::LoginManagerTest
{
87 LoginTest() : LoginManagerTest(true) {}
88 ~LoginTest() override
{}
90 void StartGaiaAuthOffline() {
91 content::DOMMessageQueue message_queue
;
92 const std::string js
= "(function() {"
93 "var authenticator = $('gaia-signin').gaiaAuthHost_;"
94 "authenticator.addEventListener('ready',"
96 "authenticator.removeEventListener('ready', f);"
97 "window.domAutomationController.setAutomationId(0);"
98 "window.domAutomationController.send('offlineLoaded');"
100 "$('error-offline-login-link').onclick();"
102 ASSERT_TRUE(content::ExecuteScript(web_contents(), js
));
106 ASSERT_TRUE(message_queue
.WaitForMessage(&message
));
107 } while (message
!= "\"offlineLoaded\"");
110 void SubmitGaiaAuthOfflineForm(const std::string
& user_email
,
111 const std::string
& password
) {
112 const std::string animated_pages
=
113 "document.querySelector('#offline-gaia /deep/ "
115 const std::string email_input
=
116 "document.querySelector('#offline-gaia /deep/ #emailInput')";
117 const std::string email_next_button
=
118 "document.querySelector('#offline-gaia /deep/ #emailSection "
120 const std::string password_input
=
121 "document.querySelector('#offline-gaia /deep/ "
123 const std::string password_next_button
=
124 "document.querySelector('#offline-gaia /deep/ #passwordSection"
127 content::DOMMessageQueue message_queue
;
128 JSExpect("!document.querySelector('#offline-gaia').hidden");
129 JSExpect("document.querySelector('#signin-frame').hidden");
130 const std::string js
=
132 ".addEventListener('neon-animation-finish',"
134 "window.domAutomationController.setAutomationId(0);"
135 "window.domAutomationController.send('switchToPassword');"
137 ASSERT_TRUE(content::ExecuteScript(web_contents(), js
));
138 std::string set_email
= email_input
+ ".value = '$Email'";
139 base::ReplaceSubstringsAfterOffset(&set_email
, 0, "$Email", user_email
);
140 ASSERT_TRUE(content::ExecuteScript(web_contents(), set_email
));
141 ASSERT_TRUE(content::ExecuteScript(web_contents(),
142 email_next_button
+ ".fire('tap')"));
145 ASSERT_TRUE(message_queue
.WaitForMessage(&message
));
146 } while (message
!= "\"switchToPassword\"");
148 std::string set_password
= password_input
+ ".value = '$Password'";
149 base::ReplaceSubstringsAfterOffset(&set_password
, 0, "$Password", password
);
150 ASSERT_TRUE(content::ExecuteScript(web_contents(), set_password
));
151 ASSERT_TRUE(content::ExecuteScript(web_contents(),
152 password_next_button
+ ".fire('tap')"));
155 void PrepareOfflineLogin() {
157 ASSERT_TRUE(chromeos::CrosSettings::Get()->GetBoolean(
158 chromeos::kAccountsPrefShowUserNamesOnSignIn
, &show_user
));
159 ASSERT_FALSE(show_user
);
161 StartGaiaAuthOffline();
163 chromeos::UserContext
user_context(kTestUser
);
164 user_context
.SetGaiaID(kGaiaId
);
165 user_context
.SetKey(chromeos::Key(kPassword
));
166 SetExpectedCredentials(user_context
);
170 // Used to make sure that the system tray is visible and within the screen
171 // bounds after login.
172 void TestSystemTrayIsVisible() {
173 ash::SystemTray
* tray
= ash::Shell::GetInstance()->GetPrimarySystemTray();
174 aura::Window
* primary_win
= ash::Shell::GetPrimaryRootWindow();
175 EXPECT_TRUE(tray
->visible());
176 EXPECT_TRUE(primary_win
->bounds().Contains(tray
->GetBoundsInScreen()));
179 // After a chrome crash, the session manager will restart chrome with
180 // the -login-user flag indicating that the user is already logged in.
181 // This profile should NOT be an OTR profile.
182 IN_PROC_BROWSER_TEST_F(LoginUserTest
, UserPassed
) {
183 Profile
* profile
= browser()->profile();
184 std::string
profile_base_path("hash");
185 profile_base_path
.insert(0, chrome::kProfileDirPrefix
);
186 EXPECT_EQ(profile_base_path
, profile
->GetPath().BaseName().value());
187 EXPECT_FALSE(profile
->IsOffTheRecord());
189 TestSystemTrayIsVisible();
192 // Verifies the cursor is not hidden at startup when user is logged in.
193 IN_PROC_BROWSER_TEST_F(LoginUserTest
, CursorShown
) {
194 EXPECT_TRUE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible());
196 TestSystemTrayIsVisible();
199 // After a guest login, we should get the OTR default profile.
200 IN_PROC_BROWSER_TEST_F(LoginGuestTest
, GuestIsOTR
) {
201 Profile
* profile
= browser()->profile();
202 EXPECT_TRUE(profile
->IsOffTheRecord());
203 // Ensure there's extension service for this profile.
204 EXPECT_TRUE(extensions::ExtensionSystem::Get(profile
)->extension_service());
206 TestSystemTrayIsVisible();
209 // Verifies the cursor is not hidden at startup when running guest session.
210 IN_PROC_BROWSER_TEST_F(LoginGuestTest
, CursorShown
) {
211 EXPECT_TRUE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible());
213 TestSystemTrayIsVisible();
216 // Verifies the cursor is hidden at startup on login screen.
217 IN_PROC_BROWSER_TEST_F(LoginCursorTest
, CursorHidden
) {
218 // Login screen needs to be shown explicitly when running test.
219 chromeos::ShowLoginWizard(chromeos::WizardController::kLoginScreenName
);
221 // Cursor should be hidden at startup
222 EXPECT_FALSE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible());
224 // Cursor should be shown after cursor is moved.
225 EXPECT_TRUE(ui_test_utils::SendMouseMoveSync(gfx::Point()));
226 EXPECT_TRUE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible());
228 base::MessageLoop::current()->DeleteSoon(
229 FROM_HERE
, chromeos::LoginDisplayHostImpl::default_host());
231 TestSystemTrayIsVisible();
234 // Verifies that the webui for login comes up successfully.
235 IN_PROC_BROWSER_TEST_F(LoginSigninTest
, WebUIVisible
) {
236 base::TimeDelta no_timeout
;
237 EXPECT_TRUE(tracing::WaitForWatchEvent(no_timeout
));
238 std::string json_events
;
239 ASSERT_TRUE(tracing::EndTracing(&json_events
));
243 IN_PROC_BROWSER_TEST_F(LoginTest
, PRE_GaiaAuthOffline
) {
244 RegisterUser(kTestUser
);
245 chromeos::StartupUtils::MarkOobeCompleted();
246 chromeos::CrosSettings::Get()->SetBoolean(
247 chromeos::kAccountsPrefShowUserNamesOnSignIn
, false);
250 IN_PROC_BROWSER_TEST_F(LoginTest
, GaiaAuthOffline
) {
251 PrepareOfflineLogin();
252 content::WindowedNotificationObserver
session_start_waiter(
253 chrome::NOTIFICATION_SESSION_STARTED
,
254 content::NotificationService::AllSources());
255 SubmitGaiaAuthOfflineForm(kTestUser
, kPassword
);
256 session_start_waiter
.Wait();
258 TestSystemTrayIsVisible();