Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / login_browsertest.cc
blob5bc2a6ef161ad6fe4604bd9f1fd80d1b2289c5d7
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.
5 #include "ash/shell.h"
6 #include "ash/system/tray/system_tray.h"
7 #include "base/command_line.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/path_service.h"
10 #include "base/strings/string_util.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/chromeos/login/login_manager_test.h"
13 #include "chrome/browser/chromeos/login/login_wizard.h"
14 #include "chrome/browser/chromeos/login/startup_utils.h"
15 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
16 #include "chrome/browser/chromeos/login/wizard_controller.h"
17 #include "chrome/browser/chromeos/settings/cros_settings.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/profiles/profiles_state.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/common/chrome_constants.h"
22 #include "chrome/common/chrome_paths.h"
23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/common/pref_names.h"
25 #include "chrome/test/base/in_process_browser_test.h"
26 #include "chrome/test/base/interactive_test_utils.h"
27 #include "chrome/test/base/tracing.h"
28 #include "chrome/test/base/ui_test_utils.h"
29 #include "chromeos/chromeos_switches.h"
30 #include "chromeos/login/user_names.h"
31 #include "chromeos/settings/cros_settings_names.h"
32 #include "content/public/browser/render_frame_host.h"
33 #include "content/public/test/browser_test_utils.h"
34 #include "content/public/test/test_utils.h"
35 #include "extensions/browser/extension_system.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
39 using ::testing::_;
40 using ::testing::AnyNumber;
41 using ::testing::Return;
43 namespace {
45 const char kGaiaId[] = "12345";
46 const char kTestUser[] = "test-user@gmail.com";
47 const char kPassword[] = "password";
49 void FilterFrameByName(std::set<content::RenderFrameHost*>* frame_set,
50 const std::string& frame_name,
51 content::RenderFrameHost* frame) {
52 if (frame->GetFrameName() == frame_name)
53 frame_set->insert(frame);
56 class LoginUserTest : public InProcessBrowserTest {
57 protected:
58 void SetUpCommandLine(base::CommandLine* command_line) override {
59 command_line->AppendSwitchASCII(
60 chromeos::switches::kLoginUser, "TestUser@gmail.com");
61 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
62 "hash");
66 class LoginGuestTest : public InProcessBrowserTest {
67 protected:
68 void SetUpCommandLine(base::CommandLine* command_line) override {
69 command_line->AppendSwitch(chromeos::switches::kGuestSession);
70 command_line->AppendSwitch(::switches::kIncognito);
71 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
72 "hash");
73 command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
74 chromeos::login::kGuestUserName);
78 class LoginCursorTest : public InProcessBrowserTest {
79 protected:
80 void SetUpCommandLine(base::CommandLine* command_line) override {
81 command_line->AppendSwitch(chromeos::switches::kLoginManager);
85 class LoginSigninTest : public InProcessBrowserTest {
86 protected:
87 void SetUpCommandLine(base::CommandLine* command_line) override {
88 command_line->AppendSwitch(chromeos::switches::kLoginManager);
89 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
92 void SetUpOnMainThread() override {
93 ASSERT_TRUE(tracing::BeginTracingWithWatch(
94 "ui", "ui", "ShowLoginWebUI", 1));
98 class LoginTest : public chromeos::LoginManagerTest {
99 public:
100 LoginTest() : LoginManagerTest(true) {}
101 ~LoginTest() override {}
103 content::RenderFrameHost* GetNamedFrame(const std::string& frame_name) {
104 std::set<content::RenderFrameHost*> frame_set;
105 web_contents()->ForEachFrame(
106 base::Bind(&FilterFrameByName, &frame_set, frame_name));
107 return frame_set.empty() ? NULL : *frame_set.begin();
110 void ExecuteJsInGaiaAuthFrame(const std::string& js) {
111 content::RenderFrameHost* frame = GetNamedFrame("signin-frame");
112 ASSERT_TRUE(frame);
113 ASSERT_TRUE(content::ExecuteScript(frame, js));
116 void StartGaiaAuthOffline() {
117 content::DOMMessageQueue message_queue;
118 const std::string js = "(function() {"
119 "var authenticator = $('gaia-signin').gaiaAuthHost_;"
120 "authenticator.addEventListener('ready',"
121 "function f() {"
122 "authenticator.removeEventListener('ready', f);"
123 "window.domAutomationController.setAutomationId(0);"
124 "window.domAutomationController.send('offlineLoaded');"
125 "});"
126 "$('error-offline-login-link').onclick();"
127 "})();";
128 ASSERT_TRUE(content::ExecuteScript(web_contents(), js));
130 std::string message;
131 do {
132 ASSERT_TRUE(message_queue.WaitForMessage(&message));
133 } while (message != "\"offlineLoaded\"");
136 void SubmitOldGaiaAuthOfflineForm(const std::string& user_email,
137 const std::string& password) {
138 // Note the input elements must match gaia_auth/offline.html.
139 JSExpect("document.querySelector('#offline-gaia').hidden");
140 JSExpect("!document.querySelector('#signin-frame').hidden");
141 std::string js =
142 "(function(){"
143 "document.getElementsByName('email')[0].value = '$Email';"
144 "document.getElementsByName('password')[0].value = '$Password';"
145 "document.getElementById('submit-button').click();"
146 "})();";
147 base::ReplaceSubstringsAfterOffset(&js, 0, "$Email", user_email);
148 base::ReplaceSubstringsAfterOffset(&js, 0, "$Password", password);
149 ExecuteJsInGaiaAuthFrame(js);
152 void SubmitGaiaAuthOfflineForm(const std::string& user_email,
153 const std::string& password) {
154 const std::string animated_pages =
155 "document.querySelector('#offline-gaia /deep/ "
156 "#animatedPages')";
157 const std::string email_input =
158 "document.querySelector('#offline-gaia /deep/ #emailInput')";
159 const std::string email_next_button =
160 "document.querySelector('#offline-gaia /deep/ #emailSection "
161 "/deep/ #button')";
162 const std::string password_input =
163 "document.querySelector('#offline-gaia /deep/ "
164 "#passwordInput')";
165 const std::string password_next_button =
166 "document.querySelector('#offline-gaia /deep/ #passwordSection"
167 " /deep/ #button')";
169 content::DOMMessageQueue message_queue;
170 JSExpect("!document.querySelector('#offline-gaia').hidden");
171 JSExpect("document.querySelector('#signin-frame').hidden");
172 const std::string js =
173 animated_pages +
174 ".addEventListener('neon-animation-finish',"
175 "function() {"
176 "window.domAutomationController.setAutomationId(0);"
177 "window.domAutomationController.send('switchToPassword');"
178 "})";
179 ASSERT_TRUE(content::ExecuteScript(web_contents(), js));
180 std::string set_email = email_input + ".value = '$Email'";
181 base::ReplaceSubstringsAfterOffset(&set_email, 0, "$Email", user_email);
182 ASSERT_TRUE(content::ExecuteScript(web_contents(), set_email));
183 ASSERT_TRUE(content::ExecuteScript(web_contents(),
184 email_next_button + ".fire('tap')"));
185 std::string message;
186 do {
187 ASSERT_TRUE(message_queue.WaitForMessage(&message));
188 } while (message != "\"switchToPassword\"");
190 std::string set_password = password_input + ".value = '$Password'";
191 base::ReplaceSubstringsAfterOffset(&set_password, 0, "$Password", password);
192 ASSERT_TRUE(content::ExecuteScript(web_contents(), set_password));
193 ASSERT_TRUE(content::ExecuteScript(web_contents(),
194 password_next_button + ".fire('tap')"));
197 void PrepareOfflineLogin() {
198 bool show_user;
199 ASSERT_TRUE(chromeos::CrosSettings::Get()->GetBoolean(
200 chromeos::kAccountsPrefShowUserNamesOnSignIn, &show_user));
201 ASSERT_FALSE(show_user);
203 StartGaiaAuthOffline();
205 chromeos::UserContext user_context(kTestUser);
206 user_context.SetGaiaID(kGaiaId);
207 user_context.SetKey(chromeos::Key(kPassword));
208 SetExpectedCredentials(user_context);
212 class LoginOfflineTest : public LoginTest {
213 public:
214 LoginOfflineTest() {}
215 ~LoginOfflineTest() override {}
217 bool SetUpUserDataDirectory() override {
218 base::FilePath user_data_dir;
219 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
220 base::FilePath local_state_path =
221 user_data_dir.Append(chrome::kLocalStateFilename);
222 base::DictionaryValue local_state_dict;
224 // Set webview disabled flag only when local state file does not exist.
225 // Otherwise, we break PRE tests that leave state in it.
226 if (!base::PathExists(local_state_path)) {
227 // TODO(rsorokin): Fix offline test for webview signin.
228 // http://crbug.com/475569
229 local_state_dict.SetBoolean(prefs::kWebviewSigninDisabled, true);
231 CHECK(JSONFileValueSerializer(local_state_path)
232 .Serialize(local_state_dict));
235 return LoginTest::SetUpUserDataDirectory();
239 // Used to make sure that the system tray is visible and within the screen
240 // bounds after login.
241 void TestSystemTrayIsVisible() {
242 ash::SystemTray* tray = ash::Shell::GetInstance()->GetPrimarySystemTray();
243 aura::Window* primary_win = ash::Shell::GetPrimaryRootWindow();
244 EXPECT_TRUE(tray->visible());
245 EXPECT_TRUE(primary_win->bounds().Contains(tray->GetBoundsInScreen()));
248 // After a chrome crash, the session manager will restart chrome with
249 // the -login-user flag indicating that the user is already logged in.
250 // This profile should NOT be an OTR profile.
251 IN_PROC_BROWSER_TEST_F(LoginUserTest, UserPassed) {
252 Profile* profile = browser()->profile();
253 std::string profile_base_path("hash");
254 profile_base_path.insert(0, chrome::kProfileDirPrefix);
255 EXPECT_EQ(profile_base_path, profile->GetPath().BaseName().value());
256 EXPECT_FALSE(profile->IsOffTheRecord());
258 TestSystemTrayIsVisible();
261 // Verifies the cursor is not hidden at startup when user is logged in.
262 IN_PROC_BROWSER_TEST_F(LoginUserTest, CursorShown) {
263 EXPECT_TRUE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible());
265 TestSystemTrayIsVisible();
268 // After a guest login, we should get the OTR default profile.
269 IN_PROC_BROWSER_TEST_F(LoginGuestTest, GuestIsOTR) {
270 Profile* profile = browser()->profile();
271 EXPECT_TRUE(profile->IsOffTheRecord());
272 // Ensure there's extension service for this profile.
273 EXPECT_TRUE(extensions::ExtensionSystem::Get(profile)->extension_service());
275 TestSystemTrayIsVisible();
278 // Verifies the cursor is not hidden at startup when running guest session.
279 IN_PROC_BROWSER_TEST_F(LoginGuestTest, CursorShown) {
280 EXPECT_TRUE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible());
282 TestSystemTrayIsVisible();
285 // Verifies the cursor is hidden at startup on login screen.
286 IN_PROC_BROWSER_TEST_F(LoginCursorTest, CursorHidden) {
287 // Login screen needs to be shown explicitly when running test.
288 chromeos::ShowLoginWizard(chromeos::WizardController::kLoginScreenName);
290 // Cursor should be hidden at startup
291 EXPECT_FALSE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible());
293 // Cursor should be shown after cursor is moved.
294 EXPECT_TRUE(ui_test_utils::SendMouseMoveSync(gfx::Point()));
295 EXPECT_TRUE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible());
297 base::MessageLoop::current()->DeleteSoon(
298 FROM_HERE, chromeos::LoginDisplayHostImpl::default_host());
300 TestSystemTrayIsVisible();
303 // Verifies that the webui for login comes up successfully.
304 IN_PROC_BROWSER_TEST_F(LoginSigninTest, WebUIVisible) {
305 base::TimeDelta no_timeout;
306 EXPECT_TRUE(tracing::WaitForWatchEvent(no_timeout));
307 std::string json_events;
308 ASSERT_TRUE(tracing::EndTracing(&json_events));
311 IN_PROC_BROWSER_TEST_F(LoginOfflineTest, PRE_OldGaiaAuthOffline) {
312 RegisterUser(kTestUser);
313 chromeos::StartupUtils::MarkOobeCompleted();
314 chromeos::CrosSettings::Get()->SetBoolean(
315 chromeos::kAccountsPrefShowUserNamesOnSignIn, false);
318 IN_PROC_BROWSER_TEST_F(LoginOfflineTest, OldGaiaAuthOffline) {
319 PrepareOfflineLogin();
320 content::WindowedNotificationObserver session_start_waiter(
321 chrome::NOTIFICATION_SESSION_STARTED,
322 content::NotificationService::AllSources());
323 SubmitOldGaiaAuthOfflineForm(kTestUser, kPassword);
324 session_start_waiter.Wait();
326 TestSystemTrayIsVisible();
329 IN_PROC_BROWSER_TEST_F(LoginTest, PRE_GaiaAuthOffline) {
330 RegisterUser(kTestUser);
331 chromeos::StartupUtils::MarkOobeCompleted();
332 chromeos::CrosSettings::Get()->SetBoolean(
333 chromeos::kAccountsPrefShowUserNamesOnSignIn, false);
336 IN_PROC_BROWSER_TEST_F(LoginTest, GaiaAuthOffline) {
337 PrepareOfflineLogin();
338 content::WindowedNotificationObserver session_start_waiter(
339 chrome::NOTIFICATION_SESSION_STARTED,
340 content::NotificationService::AllSources());
341 SubmitGaiaAuthOfflineForm(kTestUser, kPassword);
342 session_start_waiter.Wait();
344 TestSystemTrayIsVisible();
347 } // namespace