Index: chrome/browser/chromeos/policy/device_local_account_browsertest.cc |
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc |
index 7be43ac3c4aaebbed1416cab07d8bc3dda13e48f..eb2735709b6d8fcb84b76bdf745b31a8e089176e 100644 |
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc |
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc |
@@ -3,7 +3,9 @@ |
// found in the LICENSE file. |
#include <map> |
+#include <set> |
#include <string> |
+#include <vector> |
#include "apps/app_window_registry.h" |
#include "apps/ui/native_app_window.h" |
@@ -34,11 +36,13 @@ |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "base/threading/sequenced_worker_pool.h" |
#include "base/values.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/chrome_notification_types.h" |
#include "chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h" |
#include "chrome/browser/chromeos/extensions/external_cache.h" |
+#include "chrome/browser/chromeos/input_method/input_method_util.h" |
#include "chrome/browser/chromeos/login/existing_user_controller.h" |
#include "chrome/browser/chromeos/login/screens/wizard_screen.h" |
#include "chrome/browser/chromeos/login/ui/login_display_host.h" |
@@ -99,6 +103,7 @@ |
#include "components/signin/core/common/signin_pref_names.h" |
#include "components/user_manager/user.h" |
#include "components/user_manager/user_type.h" |
+#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/notification_details.h" |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/notification_source.h" |
@@ -173,9 +178,25 @@ const char kPackagedAppCRXPath[] = "extensions/platform_apps/app_window_2.crx"; |
const char kExternalData[] = "External data"; |
const char kExternalDataURL[] = "http://localhost/external_data"; |
+const char* kSingleRecommendedLocale[] = { |
+ "el", |
+}; |
+const char* kRecommendedLocales1[] = { |
+ "pl", |
+ "et", |
+ "en-US", |
+}; |
+const char* kRecommendedLocales2[] = { |
+ "fr", |
+ "nl", |
+}; |
const char kPublicSessionLocale[] = "de"; |
const char kPublicSessionInputMethodIDTemplate[] = "_comp_ime_%sxkb:de:neo:ger"; |
+// The sequence token used by GetKeyboardLayoutsForLocale() for its background |
+// tasks. |
+const char kSequenceToken[] = "chromeos_login_l10n_util"; |
+ |
// Helper that serves extension update manifests to Chrome. |
class TestingUpdateManifestProvider { |
public: |
@@ -356,6 +377,23 @@ bool IsSessionStarted() { |
return chromeos::UserManager::Get()->IsSessionStarted(); |
} |
+// GetKeyboardLayoutsForLocale() posts a task to a background task runner. This |
+// method flushes that task runner and the current thread's message loop to |
+// ensure that GetKeyboardLayoutsForLocale() is finished. |
+void WaitForGetKeyboardLayoutsForLocaleToFinish() { |
+ base::SequencedWorkerPool* worker_pool = |
+ content::BrowserThread::GetBlockingPool(); |
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner = |
+ worker_pool->GetSequencedTaskRunner( |
+ worker_pool->GetNamedSequenceToken(kSequenceToken)); |
+ base::RunLoop run_loop; |
+ background_task_runner->PostTaskAndReply(FROM_HERE, |
+ base::Bind(&base::DoNothing), |
+ run_loop.QuitClosure()); |
+ run_loop.Run(); |
+ base::RunLoop().RunUntilIdle(); |
+} |
+ |
} // namespace |
class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
@@ -370,7 +408,8 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), |
public_session_input_method_id_(base::StringPrintf( |
kPublicSessionInputMethodIDTemplate, |
- chromeos::extension_ime_util::kXkbExtensionId)) { |
+ chromeos::extension_ime_util::kXkbExtensionId)), |
+ contents_(NULL) { |
set_exit_when_last_browser_closes(false); |
} |
@@ -418,6 +457,59 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
InitializePolicy(); |
} |
+ virtual void SetUpOnMainThread() OVERRIDE { |
+ DevicePolicyCrosBrowserTest::SetUpOnMainThread(); |
+ |
+ content::WindowedNotificationObserver( |
+ chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, |
+ content::NotificationService::AllSources()).Wait(); |
+ |
+ chromeos::LoginDisplayHostImpl* host = |
+ reinterpret_cast<chromeos::LoginDisplayHostImpl*>( |
+ chromeos::LoginDisplayHostImpl::default_host()); |
+ ASSERT_TRUE(host); |
+ chromeos::WebUILoginView* web_ui_login_view = host->GetWebUILoginView(); |
+ ASSERT_TRUE(web_ui_login_view); |
+ content::WebUI* web_ui = web_ui_login_view->GetWebUI(); |
+ ASSERT_TRUE(web_ui); |
+ contents_ = web_ui->GetWebContents(); |
+ ASSERT_TRUE(contents_); |
+ |
+ // Wait for the login UI to be ready. |
+ chromeos::OobeUI* oobe_ui = host->GetOobeUI(); |
+ ASSERT_TRUE(oobe_ui); |
+ base::RunLoop run_loop; |
+ const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); |
+ if (!oobe_ui_ready) |
+ run_loop.Run(); |
+ |
+ // The network selection screen changes the application locale on load and |
+ // once again on blur. Wait for the screen to load and blur it so that any |
+ // locale changes caused by this screen happen now and do not affect any |
+ // subsequent parts of the test. |
+ bool done = false; |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
+ contents_, |
+ "var languageSelect = document.getElementById('language-select');" |
+ "var blurAndReportSuccess = function() {" |
+ " languageSelect.blur();" |
+ " domAutomationController.send(true);" |
+ "};" |
+ "var screenLoading = document.getElementById('outer-container')" |
+ " .classList.contains('down');" |
+ "if (document.activeElement == languageSelect || !screenLoading)" |
+ " blurAndReportSuccess();" |
+ "else" |
+ " languageSelect.addEventListener('focus', blurAndReportSuccess);", |
+ &done)); |
+ |
+ // Skip to the login screen. |
+ chromeos::WizardController* wizard_controller = |
+ chromeos::WizardController::default_controller(); |
+ ASSERT_TRUE(wizard_controller); |
+ wizard_controller->SkipToLoginForTesting(LoginScreenContext()); |
+ } |
+ |
virtual void TearDownOnMainThread() OVERRIDE { |
BrowserList::RemoveObserver(this); |
@@ -480,6 +572,19 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
kAccountId1, device_local_account_policy_.GetBlob()); |
} |
+ void SetRecommendedLocales(const char* recommended_locales[], |
+ size_t array_size) { |
+ em::StringListPolicyProto* session_locales_proto = |
+ device_local_account_policy_.payload().mutable_sessionlocales(); |
+ session_locales_proto->mutable_policy_options()->set_mode( |
+ em::PolicyOptions_PolicyMode_RECOMMENDED); |
+ session_locales_proto->mutable_value()->Clear(); |
+ for (size_t i = 0; i < array_size; ++i) { |
+ session_locales_proto->mutable_value()->add_entries( |
+ recommended_locales[i]); |
+ } |
+ } |
+ |
void AddPublicSessionToDevicePolicy(const std::string& username) { |
em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); |
em::DeviceLocalAccountInfoProto* account = |
@@ -492,6 +597,17 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
std::string(), proto.SerializeAsString()); |
} |
+ void EnableAutoLogin() { |
+ em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); |
+ em::DeviceLocalAccountsProto* device_local_accounts = |
+ proto.mutable_device_local_accounts(); |
+ device_local_accounts->set_auto_login_id(kAccountId1); |
+ device_local_accounts->set_auto_login_delay(0); |
+ RefreshDevicePolicy(); |
+ test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, |
+ std::string(), proto.SerializeAsString()); |
+ } |
+ |
void CheckPublicSessionPresent(const std::string& id) { |
const user_manager::User* user = chromeos::UserManager::Get()->FindUser(id); |
ASSERT_TRUE(user); |
@@ -537,53 +653,6 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
WaitForDisplayName(user_id_1_, kDisplayName1); |
} |
- void GetWebContents(content::WebContents** contents) { |
- chromeos::LoginDisplayHostImpl* host = |
- reinterpret_cast<chromeos::LoginDisplayHostImpl*>( |
- chromeos::LoginDisplayHostImpl::default_host()); |
- ASSERT_TRUE(host); |
- chromeos::WebUILoginView* web_ui_login_view = host->GetWebUILoginView(); |
- ASSERT_TRUE(web_ui_login_view); |
- content::WebUI* web_ui = web_ui_login_view->GetWebUI(); |
- ASSERT_TRUE(web_ui); |
- *contents = web_ui->GetWebContents(); |
- ASSERT_TRUE(*contents); |
- } |
- |
- void WaitForLoginUI() { |
- // Wait for the login UI to be ready. |
- chromeos::LoginDisplayHostImpl* host = |
- reinterpret_cast<chromeos::LoginDisplayHostImpl*>( |
- chromeos::LoginDisplayHostImpl::default_host()); |
- ASSERT_TRUE(host); |
- chromeos::OobeUI* oobe_ui = host->GetOobeUI(); |
- ASSERT_TRUE(oobe_ui); |
- base::RunLoop run_loop; |
- const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); |
- if (!oobe_ui_ready) |
- run_loop.Run(); |
- |
- // The network selection screen changes the application locale on load and |
- // once again on blur. Wait for the screen to load and blur it so that any |
- // locale changes caused by this screen happen now and do not affect any |
- // subsequent parts of the test. |
- content::WebContents* contents = NULL; |
- ASSERT_NO_FATAL_FAILURE(GetWebContents(&contents)); |
- bool done = false; |
- ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
- contents, |
- "var languageSelect = document.getElementById('language-select');" |
- "var blurAndReportSuccess = function() {" |
- " languageSelect.blur();" |
- " domAutomationController.send(true);" |
- "};" |
- "if (document.activeElement == languageSelect)" |
- " blurAndReportSuccess();" |
- "else" |
- " languageSelect.addEventListener('focus', blurAndReportSuccess);", |
- &done)); |
- } |
- |
void StartLogin(const std::string& locale, |
const std::string& input_method) { |
// Start login into the device-local account. |
@@ -610,6 +679,20 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
base::Bind(IsSessionStarted)).Wait(); |
} |
+ void VerifyKeyboardLayoutMatchesLocale() { |
+ chromeos::input_method::InputMethodManager* input_method_manager = |
+ chromeos::input_method::InputMethodManager::Get(); |
+ std::vector<std::string> layouts_from_locale; |
+ input_method_manager->GetInputMethodUtil()-> |
+ GetInputMethodIdsFromLanguageCode( |
+ g_browser_process->GetApplicationLocale(), |
+ chromeos::input_method::kKeyboardLayoutsOnly, |
+ &layouts_from_locale); |
+ ASSERT_FALSE(layouts_from_locale.empty()); |
+ EXPECT_EQ(layouts_from_locale.front(), |
+ input_method_manager->GetCurrentInputMethod().id()); |
+ } |
+ |
const std::string user_id_1_; |
const std::string user_id_2_; |
const std::string public_session_input_method_id_; |
@@ -619,6 +702,8 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
UserPolicyBuilder device_local_account_policy_; |
LocalPolicyTestServer test_server_; |
+ content::WebContents* contents_; |
+ |
private: |
DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest); |
}; |
@@ -646,25 +731,14 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { |
WaitForPolicy(); |
- // Skip to the login screen. |
- chromeos::WizardController* wizard_controller = |
- chromeos::WizardController::default_controller(); |
- ASSERT_TRUE(wizard_controller); |
- wizard_controller->SkipToLoginForTesting(LoginScreenContext()); |
- content::WindowedNotificationObserver( |
- chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, |
- content::NotificationService::AllSources()).Wait(); |
- |
// Verify that the display name is shown in the UI. |
- content::WebContents* contents = NULL; |
- ASSERT_NO_FATAL_FAILURE(GetWebContents(&contents)); |
const std::string get_compact_pod_display_name = base::StringPrintf( |
"domAutomationController.send(document.getElementById('pod-row')" |
" .getPodWithUsername_('%s').nameElement.textContent);", |
user_id_1_.c_str()); |
std::string display_name; |
ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
- contents, |
+ contents_, |
get_compact_pod_display_name, |
&display_name)); |
EXPECT_EQ(kDisplayName1, display_name); |
@@ -675,14 +749,14 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { |
user_id_1_.c_str()); |
display_name.clear(); |
ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
- contents, |
+ contents_, |
get_expanded_pod_display_name, |
&display_name)); |
EXPECT_EQ(kDisplayName1, display_name); |
// Click on the pod to expand it. |
ASSERT_TRUE(content::ExecuteScript( |
- contents, |
+ contents_, |
base::StringPrintf( |
"document.getElementById('pod-row').getPodWithUsername_('%s')" |
" .click();", |
@@ -704,13 +778,13 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { |
// Verify that the new display name is shown in the UI. |
display_name.clear(); |
ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
- contents, |
+ contents_, |
get_compact_pod_display_name, |
&display_name)); |
EXPECT_EQ(kDisplayName2, display_name); |
display_name.clear(); |
ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
- contents, |
+ contents_, |
get_expanded_pod_display_name, |
&display_name)); |
EXPECT_EQ(kDisplayName2, display_name); |
@@ -719,7 +793,7 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { |
// without reloading and losing state. |
bool expanded = false; |
ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
- contents, |
+ contents_, |
base::StringPrintf( |
"domAutomationController.send(document.getElementById('pod-row')" |
" .getPodWithUsername_('%s').expanded);", |
@@ -775,7 +849,7 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, AccountListChange) { |
.Wait(); |
} |
-IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_StartSession) { |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, StartSession) { |
// Specify startup pages. |
device_local_account_policy_.payload().mutable_restoreonstartup()->set_value( |
SessionStartupPref::kPrefValueURLs); |
@@ -787,7 +861,7 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_StartSession) { |
AddPublicSessionToDevicePolicy(kAccountId1); |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
+ |
ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
WaitForSessionStart(); |
@@ -815,12 +889,12 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_StartSession) { |
prefs::kGoogleServicesUsername)); |
} |
-IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_FullscreenDisallowed) { |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, FullscreenDisallowed) { |
UploadAndInstallDeviceLocalAccountPolicy(); |
AddPublicSessionToDevicePolicy(kAccountId1); |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
+ |
ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
WaitForSessionStart(); |
@@ -838,7 +912,7 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_FullscreenDisallowed) { |
EXPECT_FALSE(browser_window->IsFullscreen()); |
} |
-IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExtensionsUncached) { |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExtensionsUncached) { |
// Make it possible to force-install a hosted app and an extension. |
ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
TestingUpdateManifestProvider testing_update_manifest_provider( |
@@ -871,7 +945,6 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExtensionsUncached) { |
AddPublicSessionToDevicePolicy(kAccountId1); |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
// Start listening for app/extension installation results. |
content::WindowedNotificationObserver hosted_app_observer( |
@@ -918,7 +991,7 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExtensionsUncached) { |
EXPECT_FALSE(cache->GetExtension(kGoodExtensionID, NULL, NULL)); |
} |
-IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExtensionsCached) { |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExtensionsCached) { |
ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
// Pre-populate the device local account's extension cache with a hosted app |
@@ -951,7 +1024,6 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExtensionsCached) { |
AddPublicSessionToDevicePolicy(kAccountId1); |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
// Start listening for app/extension installation results. |
content::WindowedNotificationObserver hosted_app_observer( |
@@ -992,7 +1064,7 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExtensionsCached) { |
EXPECT_FALSE(cache->GetExtension(kGoodExtensionID, NULL, NULL)); |
} |
-IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExternalData) { |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, ExternalData) { |
// chromeos::UserManager requests an external data fetch whenever |
// the key::kUserAvatarImage policy is set. Since this test wants to |
// verify that the underlying policy subsystem will start a fetch |
@@ -1061,7 +1133,6 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_ExternalData) { |
ASSERT_TRUE(fetched_external_data); |
EXPECT_EQ(kExternalData, *fetched_external_data); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
WaitForSessionStart(); |
@@ -1167,13 +1238,12 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, UserAvatarImage) { |
EXPECT_EQ(policy_image->height(), saved_image->height()); |
} |
-IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
- DISABLED_LastWindowClosedLogoutReminder) { |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LastWindowClosedLogoutReminder) { |
UploadAndInstallDeviceLocalAccountPolicy(); |
AddPublicSessionToDevicePolicy(kAccountId1); |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
+ |
ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
WaitForSessionStart(); |
@@ -1322,45 +1392,355 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
app_window_registry->RemoveObserver(this); |
}; |
-IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
- DISABLED_DoNotSelectLanguageAndKeyboard) { |
- chromeos::input_method::InputMethodManager* input_method_manager = |
- chromeos::input_method::InputMethodManager::Get(); |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, NoRecommendedLocaleNoSwitch) { |
const std::string initial_locale = g_browser_process->GetApplicationLocale(); |
- const std::string initial_input_method = |
- input_method_manager->GetCurrentInputMethod().id(); |
UploadAndInstallDeviceLocalAccountPolicy(); |
AddPublicSessionToDevicePolicy(kAccountId1); |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
- ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
+ |
+ // Click on the pod to expand it. Verify that the pod expands to its basic |
+ // form as there are no recommended locales. |
+ bool advanced = false; |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
+ contents_, |
+ base::StringPrintf( |
+ "var pod =" |
+ " document.getElementById('pod-row').getPodWithUsername_('%s');" |
+ "pod.click();" |
+ "domAutomationController.send(pod.classList.contains('advanced'));", |
+ user_id_1_.c_str()), |
+ &advanced)); |
+ EXPECT_FALSE(advanced); |
+ |
+ // Click the enter button to start the session. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "document.getElementById('pod-row').getPodWithUsername_('%s')" |
+ " .querySelector('.enter-button').click();", |
+ user_id_1_.c_str()))); |
+ |
WaitForSessionStart(); |
+ // Verify that the locale has not changed and the first keyboard layout |
+ // applicable to the locale was chosen. |
EXPECT_EQ(initial_locale, g_browser_process->GetApplicationLocale()); |
- EXPECT_EQ(initial_input_method, |
- input_method_manager->GetCurrentInputMethod().id()); |
+ VerifyKeyboardLayoutMatchesLocale(); |
} |
-IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
- DISABLED_SelectLanguageAndKeyboard) { |
- // Specify startup pages. |
- device_local_account_policy_.payload().mutable_restoreonstartup()->set_value( |
- SessionStartupPref::kPrefValueURLs); |
- em::StringListPolicyProto* startup_urls_proto = |
- device_local_account_policy_.payload().mutable_restoreonstartupurls(); |
- for (size_t i = 0; i < arraysize(kStartupURLs); ++i) |
- startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]); |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, NoRecommendedLocaleSwitch) { |
UploadAndInstallDeviceLocalAccountPolicy(); |
AddPublicSessionToDevicePolicy(kAccountId1); |
- // Log in to the device-local account with a specific locale and keyboard |
- // layout. |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
- ASSERT_NO_FATAL_FAILURE( |
- StartLogin(kPublicSessionLocale, public_session_input_method_id_)); |
+ |
+ // Click on the pod to expand it. Verify that the pod expands to its basic |
+ // form as there are no recommended locales. |
+ bool advanced = false; |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
+ contents_, |
+ base::StringPrintf( |
+ "var pod =" |
+ " document.getElementById('pod-row').getPodWithUsername_('%s');" |
+ "pod.click();" |
+ "domAutomationController.send(pod.classList.contains('advanced'));", |
+ user_id_1_.c_str()), |
+ &advanced)); |
+ EXPECT_FALSE(advanced); |
+ |
+ // Click the link that switches the pod to its advanced form. Verify that the |
+ // pod switches from basic to advanced. |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
+ contents_, |
+ base::StringPrintf( |
+ "var pod =" |
+ " document.getElementById('pod-row').getPodWithUsername_('%s');" |
+ "pod.querySelector('.language-and-input').click();" |
+ "domAutomationController.send(pod.classList.contains('advanced'));", |
+ user_id_1_.c_str()), |
+ &advanced)); |
+ EXPECT_FALSE(advanced); |
+ |
+ // Manually select a different locale. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "var languageSelect = document.getElementById('pod-row')" |
+ " .getPodWithUsername_('%s').querySelector('.language-select');" |
+ "languageSelect.value = '%s';" |
+ "var event = document.createEvent('HTMLEvents');" |
+ "event.initEvent('change', false, true);" |
+ "languageSelect.dispatchEvent(event);", |
+ user_id_1_.c_str(), |
+ kPublicSessionLocale))); |
+ |
+ // The UI will have requested an updated list of keyboard layouts at this |
+ // point. Wait for the constructions of this list to finish. |
+ WaitForGetKeyboardLayoutsForLocaleToFinish(); |
+ |
+ // Manually select a different keyboard layout and click the enter button to |
+ // start the session. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "var pod =" |
+ " document.getElementById('pod-row').getPodWithUsername_('%s');" |
+ "pod.querySelector('.keyboard-select').value = '%s';" |
+ "pod.querySelector('.enter-button').click();", |
+ user_id_1_.c_str(), |
+ public_session_input_method_id_.c_str()))); |
+ |
+ WaitForSessionStart(); |
+ |
+ // Verify that the locale and keyboard layout have been applied. |
+ EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale()); |
+ EXPECT_EQ(public_session_input_method_id_, |
+ chromeos::input_method::InputMethodManager::Get()-> |
+ GetCurrentInputMethod().id()); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, OneRecommendedLocale) { |
+ // Specify a recommended locale. |
+ SetRecommendedLocales(kSingleRecommendedLocale, |
+ arraysize(kSingleRecommendedLocale)); |
+ UploadAndInstallDeviceLocalAccountPolicy(); |
+ AddPublicSessionToDevicePolicy(kAccountId1); |
+ |
+ WaitForPolicy(); |
+ |
+ // Click on the pod to expand it. Verify that the pod expands to its basic |
+ // form as there is only one recommended locale. |
+ bool advanced = false; |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
+ contents_, |
+ base::StringPrintf( |
+ "var pod =" |
+ " document.getElementById('pod-row').getPodWithUsername_('%s');" |
+ "pod.click();" |
+ "domAutomationController.send(pod.classList.contains('advanced'));", |
+ user_id_1_.c_str()), |
+ &advanced)); |
+ EXPECT_FALSE(advanced); |
+ |
+ // Click the enter button to start the session. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "document.getElementById('pod-row').getPodWithUsername_('%s')" |
+ " .querySelector('.enter-button').click();", |
+ user_id_1_.c_str()))); |
+ |
+ WaitForSessionStart(); |
+ |
+ // Verify that the recommended locale has been applied and the first keyboard |
+ // layout applicable to the locale was chosen. |
+ EXPECT_EQ(kSingleRecommendedLocale[0], |
+ g_browser_process->GetApplicationLocale()); |
+ VerifyKeyboardLayoutMatchesLocale(); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MultipleRecommendedLocales) { |
+ // Specify recommended locales. |
+ SetRecommendedLocales(kRecommendedLocales1, arraysize(kRecommendedLocales1)); |
+ UploadAndInstallDeviceLocalAccountPolicy(); |
+ AddPublicSessionToDevicePolicy(kAccountId1); |
+ AddPublicSessionToDevicePolicy(kAccountId2); |
+ |
+ WaitForPolicy(); |
+ |
+ // Click on the pod to expand it. Verify that the pod expands to its advanced |
+ // form directly as there are two or more recommended locales. |
+ bool advanced = false; |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
+ contents_, |
+ base::StringPrintf( |
+ "var pod =" |
+ " document.getElementById('pod-row').getPodWithUsername_('%s');" |
+ "pod.click();" |
+ "domAutomationController.send(pod.classList.contains('advanced'));", |
+ user_id_1_.c_str()), |
+ &advanced)); |
+ EXPECT_TRUE(advanced); |
+ |
+ // Verify that the pod shows a list of locales beginning with the recommended |
+ // ones, followed by others. |
+ const std::string get_locale_list = base::StringPrintf( |
+ "var languageSelect = document.getElementById('pod-row')" |
+ " .getPodWithUsername_('%s').querySelector('.language-select');" |
+ "var locales = [];" |
+ "for (var i = 0; i < languageSelect.length; ++i)" |
+ " locales.push(languageSelect.options[i].value);" |
+ "domAutomationController.send(JSON.stringify(locales));", |
+ user_id_1_.c_str()); |
+ std::string json; |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, |
+ get_locale_list, |
+ &json)); |
+ scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json)); |
+ const base::ListValue* locales = NULL; |
+ ASSERT_TRUE(value_ptr); |
+ ASSERT_TRUE(value_ptr->GetAsList(&locales)); |
+ EXPECT_LT(arraysize(kRecommendedLocales1), locales->GetSize()); |
+ |
+ // Verify that the list starts with the recommended locales, in correct order. |
+ for (size_t i = 0; i < arraysize(kRecommendedLocales1); ++i) { |
+ std::string locale; |
+ EXPECT_TRUE(locales->GetString(i, &locale)); |
+ EXPECT_EQ(kRecommendedLocales1[i], locale); |
+ } |
+ |
+ // Verify that the recommended locales do not appear again in the remainder of |
+ // the list. |
+ std::set<std::string> recommended_locales; |
+ for (size_t i = 0; i < arraysize(kRecommendedLocales1); ++i) |
+ recommended_locales.insert(kRecommendedLocales1[i]); |
+ for (size_t i = arraysize(kRecommendedLocales1); i < locales->GetSize(); |
+ ++i) { |
+ std::string locale; |
+ EXPECT_TRUE(locales->GetString(i, &locale)); |
+ EXPECT_EQ(recommended_locales.end(), recommended_locales.find(locale)); |
+ } |
+ |
+ // Verify that the first recommended locale is selected. |
+ const std::string get_selected_locale = |
+ base::StringPrintf( |
+ "domAutomationController.send(document.getElementById('pod-row')" |
+ " .getPodWithUsername_('%s').querySelector('.language-select')" |
+ " .value);", |
+ user_id_1_.c_str()); |
+ std::string selected_locale; |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, |
+ get_selected_locale, |
+ &selected_locale)); |
+ EXPECT_EQ(kRecommendedLocales1[0], selected_locale); |
+ |
+ // Change the list of recommended locales. |
+ SetRecommendedLocales(kRecommendedLocales2, arraysize(kRecommendedLocales2)); |
+ |
+ // Also change the display name as it is easy to ensure that policy has been |
+ // updated by waiting for a display name change. |
+ device_local_account_policy_.payload().mutable_userdisplayname()->set_value( |
+ kDisplayName2); |
+ UploadAndInstallDeviceLocalAccountPolicy(); |
+ policy::BrowserPolicyConnectorChromeOS* connector = |
+ g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
+ DeviceLocalAccountPolicyBroker* broker = |
+ connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser( |
+ user_id_1_); |
+ ASSERT_TRUE(broker); |
+ broker->core()->store()->Load(); |
+ WaitForDisplayName(user_id_1_, kDisplayName2); |
+ |
+ // Verify that the new list of locales is shown in the UI. |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, |
+ get_locale_list, |
+ &json)); |
+ value_ptr.reset(base::JSONReader::Read(json)); |
+ locales = NULL; |
+ ASSERT_TRUE(value_ptr); |
+ ASSERT_TRUE(value_ptr->GetAsList(&locales)); |
+ EXPECT_LT(arraysize(kRecommendedLocales2), locales->GetSize()); |
+ for (size_t i = 0; i < arraysize(kRecommendedLocales2); ++i) { |
+ std::string locale; |
+ EXPECT_TRUE(locales->GetString(i, &locale)); |
+ EXPECT_EQ(kRecommendedLocales2[i], locale); |
+ } |
+ |
+ // Verify that the first new recommended locale is selected. |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, |
+ get_selected_locale, |
+ &selected_locale)); |
+ EXPECT_EQ(kRecommendedLocales2[0], selected_locale); |
+ |
+ // Manually select a different locale. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "var languageSelect = document.getElementById('pod-row')" |
+ " .getPodWithUsername_('%s').querySelector('.language-select');" |
+ "languageSelect.value = '%s';" |
+ "var event = document.createEvent('HTMLEvents');" |
+ "event.initEvent('change', false, true);" |
+ "languageSelect.dispatchEvent(event);", |
+ user_id_1_.c_str(), |
+ kPublicSessionLocale))); |
+ |
+ // Change the list of recommended locales. |
+ SetRecommendedLocales(kRecommendedLocales2, arraysize(kRecommendedLocales2)); |
+ device_local_account_policy_.payload().mutable_userdisplayname()->set_value( |
+ kDisplayName1); |
+ UploadAndInstallDeviceLocalAccountPolicy(); |
+ broker->core()->store()->Load(); |
+ WaitForDisplayName(user_id_1_, kDisplayName1); |
+ |
+ // Verify that the manually selected locale is still selected. |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, |
+ get_selected_locale, |
+ &selected_locale)); |
+ EXPECT_EQ(kPublicSessionLocale, selected_locale); |
+ |
+ // The UI will request an updated list of keyboard layouts at this point. Wait |
+ // for the constructions of this list to finish. |
+ WaitForGetKeyboardLayoutsForLocaleToFinish(); |
+ |
+ // Manually select a different keyboard layout. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "document.getElementById('pod-row').getPodWithUsername_('%s')" |
+ " .querySelector('.keyboard-select').value = '%s';", |
+ user_id_1_.c_str(), |
+ public_session_input_method_id_.c_str()))); |
+ |
+ // Click on a different pod, causing focus to shift away and the pod to |
+ // contract. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "document.getElementById('pod-row').getPodWithUsername_('%s')" |
+ " .click();", |
+ user_id_2_.c_str()))); |
+ |
+ // Click on the pod again, causing it to expand again. Verify that the pod has |
+ // kept all its state (the advanced form is being shown, the manually selected |
+ // locale and keyboard layout are selected). |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
+ contents_, |
+ base::StringPrintf( |
+ "var pod =" |
+ " document.getElementById('pod-row').getPodWithUsername_('%s');" |
+ "pod.click();" |
+ "var state = {};" |
+ "state.advanced = pod.classList.contains('advanced');" |
+ "state.locale = pod.querySelector('.language-select').value;" |
+ "state.keyboardLayout = pod.querySelector('.keyboard-select').value;" |
+ "console.log(JSON.stringify(state));" |
+ "domAutomationController.send(JSON.stringify(state));", |
+ user_id_1_.c_str()), |
+ &json)); |
+ LOG(ERROR) << json; |
+ value_ptr.reset(base::JSONReader::Read(json)); |
+ const base::DictionaryValue* state = NULL; |
+ ASSERT_TRUE(value_ptr); |
+ ASSERT_TRUE(value_ptr->GetAsDictionary(&state)); |
+ EXPECT_TRUE(state->GetBoolean("advanced", &advanced)); |
+ EXPECT_TRUE(advanced); |
+ EXPECT_TRUE(state->GetString("locale", &selected_locale)); |
+ EXPECT_EQ(kPublicSessionLocale, selected_locale); |
+ std::string selected_keyboard_layout; |
+ EXPECT_TRUE(state->GetString("keyboardLayout", &selected_keyboard_layout)); |
+ EXPECT_EQ(public_session_input_method_id_, selected_keyboard_layout); |
+ |
+ // Click the enter button to start the session. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "document.getElementById('pod-row').getPodWithUsername_('%s')" |
+ " .querySelector('.enter-button').click();", |
+ user_id_1_.c_str()))); |
+ |
WaitForSessionStart(); |
// Verify that the locale and keyboard layout have been applied. |
@@ -1371,7 +1751,42 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
} |
IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
- DISABLED_SelectLanguageAndKeyboardWithTermsOfService) { |
+ AutoLoginWithoutRecommendedLocales) { |
+ const std::string initial_locale = g_browser_process->GetApplicationLocale(); |
+ |
+ UploadAndInstallDeviceLocalAccountPolicy(); |
+ AddPublicSessionToDevicePolicy(kAccountId1); |
+ EnableAutoLogin(); |
+ |
+ WaitForPolicy(); |
+ |
+ WaitForSessionStart(); |
+ |
+ // Verify that the locale has not changed and the first keyboard layout |
+ // applicable to the locale was chosen. |
+ EXPECT_EQ(initial_locale, g_browser_process->GetApplicationLocale()); |
+ VerifyKeyboardLayoutMatchesLocale(); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
+ AutoLoginWithRecommendedLocales) { |
+ // Specify recommended locales. |
+ SetRecommendedLocales(kRecommendedLocales1, arraysize(kRecommendedLocales1)); |
+ UploadAndInstallDeviceLocalAccountPolicy(); |
+ AddPublicSessionToDevicePolicy(kAccountId1); |
+ EnableAutoLogin(); |
+ |
+ WaitForPolicy(); |
+ |
+ WaitForSessionStart(); |
+ |
+ // Verify that the first recommended locale has been applied and the first |
+ // keyboard layout applicable to the locale was chosen. |
+ EXPECT_EQ(kRecommendedLocales1[0], g_browser_process->GetApplicationLocale()); |
+ VerifyKeyboardLayoutMatchesLocale(); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, TermsOfServiceWithLocaleSwitch) { |
// Specify Terms of Service URL. |
ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( |
@@ -1380,12 +1795,24 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
UploadAndInstallDeviceLocalAccountPolicy(); |
AddPublicSessionToDevicePolicy(kAccountId1); |
- // Log in to the device-local account with a specific locale and keyboard |
- // layout. |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
- ASSERT_NO_FATAL_FAILURE( |
- StartLogin(kPublicSessionLocale, public_session_input_method_id_)); |
+ |
+ // Select a different locale. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "var languageSelect = document.getElementById('pod-row')" |
+ " .getPodWithUsername_('%s').querySelector('.language-select');" |
+ "languageSelect.value = '%s';" |
+ "var event = document.createEvent('HTMLEvents');" |
+ "event.initEvent('change', false, true);" |
+ "languageSelect.dispatchEvent(event);", |
+ user_id_1_.c_str(), |
+ kPublicSessionLocale))); |
+ |
+ // The UI will have requested an updated list of keyboard layouts at this |
+ // point. Wait for the constructions of this list to finish. |
+ WaitForGetKeyboardLayoutsForLocaleToFinish(); |
// Set up an observer that will quit the message loop when login has succeeded |
// and the first wizard screen, if any, is being shown. |
@@ -1393,12 +1820,25 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
chromeos::MockAuthStatusConsumer login_status_consumer; |
EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce( |
InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit)); |
- |
- // Spin the loop until the observer fires. Then, unregister the observer. |
chromeos::ExistingUserController* controller = |
chromeos::ExistingUserController::current_controller(); |
ASSERT_TRUE(controller); |
controller->set_login_status_consumer(&login_status_consumer); |
+ |
+ // Manually select a different keyboard layout and click the enter button to |
+ // start the session. |
+ ASSERT_TRUE(content::ExecuteScript( |
+ contents_, |
+ base::StringPrintf( |
+ "var pod =" |
+ " document.getElementById('pod-row').getPodWithUsername_('%s');" |
+ "pod.querySelector('.keyboard-select').value = '%s';" |
+ "pod.querySelector('.enter-button').click();", |
+ user_id_1_.c_str(), |
+ public_session_input_method_id_.c_str()))); |
+ |
+ // Spin the loop until the login observer fires. Then, unregister the |
+ // observer. |
login_wait_run_loop.Run(); |
controller->set_login_status_consumer(NULL); |
@@ -1411,10 +1851,8 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
wizard_controller->current_screen()->GetName()); |
// Wait for the Terms of Service to finish downloading. |
- content::WebContents* contents = NULL; |
- ASSERT_NO_FATAL_FAILURE(GetWebContents(&contents)); |
bool done = false; |
- ASSERT_TRUE(content::ExecuteScriptAndExtractBool(contents, |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool(contents_, |
"var screenElement = document.getElementById('terms-of-service');" |
"function SendReplyIfDownloadDone() {" |
" if (screenElement.classList.contains('tos-loading'))" |
@@ -1437,7 +1875,7 @@ IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
GetCurrentInputMethod().id()); |
// Click the accept button. |
- ASSERT_TRUE(content::ExecuteScript(contents, |
+ ASSERT_TRUE(content::ExecuteScript(contents_, |
"$('tos-accept-button').click();")); |
WaitForSessionStart(); |
@@ -1453,8 +1891,7 @@ class TermsOfServiceDownloadTest : public DeviceLocalAccountTest, |
public testing::WithParamInterface<bool> { |
}; |
-IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, |
- DISABLED_TermsOfServiceScreen) { |
+IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, TermsOfServiceScreen) { |
// Specify Terms of Service URL. |
ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( |
@@ -1466,7 +1903,7 @@ IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, |
AddPublicSessionToDevicePolicy(kAccountId1); |
WaitForPolicy(); |
- ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
+ |
ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
// Set up an observer that will quit the message loop when login has succeeded |
@@ -1494,10 +1931,8 @@ IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, |
// Wait for the Terms of Service to finish downloading, then get the status of |
// the screen's UI elements. |
- content::WebContents* contents = NULL; |
- ASSERT_NO_FATAL_FAILURE(GetWebContents(&contents)); |
std::string json; |
- ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents, |
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, |
"var screenElement = document.getElementById('terms-of-service');" |
"function SendReplyIfDownloadDone() {" |
" if (screenElement.classList.contains('tos-loading'))" |
@@ -1525,7 +1960,7 @@ IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, |
&json)); |
scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json)); |
const base::DictionaryValue* status = NULL; |
- ASSERT_TRUE(value_ptr.get()); |
+ ASSERT_TRUE(value_ptr); |
ASSERT_TRUE(value_ptr->GetAsDictionary(&status)); |
std::string heading; |
EXPECT_TRUE(status->GetString("heading", &heading)); |
@@ -1574,7 +2009,7 @@ IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, |
EXPECT_TRUE(accept_enabled); |
// Click the accept button. |
- ASSERT_TRUE(content::ExecuteScript(contents, |
+ ASSERT_TRUE(content::ExecuteScript(contents_, |
"$('tos-accept-button').click();")); |
WaitForSessionStart(); |