Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / oobe_localization_browsertest.cc
blobba9405236d3c43b642de767fcf7718cba57684fc
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.
5 #include "base/message_loop/message_loop.h"
6 #include "base/prefs/pref_service.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/task_runner.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/chromeos/customization_document.h"
12 #include "chrome/browser/chromeos/input_method/input_method_util.h"
13 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
14 #include "chrome/browser/chromeos/login/login_wizard.h"
15 #include "chrome/browser/chromeos/login/test/js_checker.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "chromeos/ime/extension_ime_util.h"
19 #include "chromeos/ime/input_method_manager.h"
20 #include "chromeos/ime/input_method_whitelist.h"
21 #include "chromeos/system/statistics_provider.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/test/browser_test_utils.h"
25 #include "content/public/test/test_utils.h"
27 namespace base {
28 class TaskRunner;
31 namespace chromeos {
33 namespace {
35 // OOBE constants.
36 const char* kLocaleSelect = "language-select";
37 const char* kKeyboardSelect = "keyboard-select";
39 const char* kUSLayout = "xkb:us::eng";
43 namespace system {
45 // Custom StatisticsProvider that will return each set of region settings.
46 class FakeStatisticsProvider : public StatisticsProvider {
47 public:
48 virtual ~FakeStatisticsProvider() {}
50 void set_locale(const std::string& locale) {
51 initial_locale_ = locale;
54 void set_keyboard_layout(const std::string& keyboard_layout) {
55 keyboard_layout_ = keyboard_layout;
58 private:
59 // StatisticsProvider overrides.
60 virtual void StartLoadingMachineStatistics(
61 const scoped_refptr<base::TaskRunner>& file_task_runner,
62 bool load_oem_manifest) OVERRIDE {
65 // Populates the named machine statistic for initial_locale and
66 // keyboard_layout only.
67 virtual bool GetMachineStatistic(const std::string& name,
68 std::string* result) OVERRIDE {
69 if (name == "initial_locale")
70 *result = initial_locale_;
71 else if (name == "keyboard_layout")
72 *result = keyboard_layout_;
73 else
74 return false;
76 return true;
79 virtual bool GetMachineFlag(const std::string& name, bool* result) OVERRIDE {
80 return false;
83 virtual void Shutdown() OVERRIDE {
86 std::string initial_locale_;
87 std::string keyboard_layout_;
90 } // namespace system
92 class OobeLocalizationTest : public InProcessBrowserTest {
93 public:
94 OobeLocalizationTest();
95 virtual ~OobeLocalizationTest();
97 // Verifies that the comma-separated |values| corresponds with the first
98 // values in |select_id|, optionally checking for an options group label after
99 // the first set of options.
100 bool VerifyInitialOptions(const char* select_id,
101 const char* values,
102 bool check_separator);
104 // Verifies that |value| exists in |select_id|.
105 bool VerifyOptionExists(const char* select_id, const char* value);
107 // Dumps OOBE select control (language or keyboard) to string.
108 std::string DumpOptions(const char* select_id);
110 protected:
111 // Runs the test for the given locale and keyboard layout.
112 void RunLocalizationTest(const std::string& initial_locale,
113 const std::string& keyboard_layout,
114 const std::string& expected_locale,
115 const std::string& expected_keyboard_layout,
116 const std::string& expected_keyboard_select_control);
118 private:
119 scoped_ptr<system::FakeStatisticsProvider> statistics_provider_;
120 test::JSChecker checker;
122 DISALLOW_COPY_AND_ASSIGN(OobeLocalizationTest);
125 OobeLocalizationTest::OobeLocalizationTest() {
126 statistics_provider_.reset(new system::FakeStatisticsProvider());
127 // Set the instance returned by GetInstance() for testing.
128 system::StatisticsProvider::SetTestProvider(statistics_provider_.get());
131 OobeLocalizationTest::~OobeLocalizationTest() {
132 system::StatisticsProvider::SetTestProvider(NULL);
135 bool OobeLocalizationTest::VerifyInitialOptions(const char* select_id,
136 const char* values,
137 bool check_separator) {
138 const std::string expression = base::StringPrintf(
139 "(function () {\n"
140 " var select = document.querySelector('#%s');\n"
141 " if (!select)\n"
142 " return false;\n"
143 " var values = '%s'.split(',');\n"
144 " var correct = select.selectedIndex == 0;\n"
145 " for (var i = 0; i < values.length && correct; i++) {\n"
146 " if (select.options[i].value != values[i])\n"
147 " correct = false;\n"
148 " }\n"
149 " if (%d && correct)\n"
150 " correct = select.children[values.length].tagName === 'OPTGROUP';\n"
151 " return correct;\n"
152 "})()", select_id, values, check_separator);
153 const bool execute_status = checker.GetBool(expression);
154 EXPECT_TRUE(execute_status) << expression;
155 return execute_status;
158 bool OobeLocalizationTest::VerifyOptionExists(const char* select_id,
159 const char* value) {
160 const std::string expression = base::StringPrintf(
161 "(function () {\n"
162 " var select = document.querySelector('#%s');\n"
163 " if (!select)\n"
164 " return false;\n"
165 " for (var i = 0; i < select.options.length; i++) {\n"
166 " if (select.options[i].value == '%s')\n"
167 " return true;\n"
168 " }\n"
169 " return false;\n"
170 "})()", select_id, value);
171 const bool execute_status = checker.GetBool(expression);
172 EXPECT_TRUE(execute_status) << expression;
173 return execute_status;
176 std::string OobeLocalizationTest::DumpOptions(const char* select_id) {
177 const std::string expression = base::StringPrintf(
178 "\n"
179 "(function () {\n"
180 " var selector = '#%s';\n"
181 " var divider = ',';\n"
182 " var select = document.querySelector(selector);\n"
183 " if (!select)\n"
184 " return 'document.querySelector(' + selector + ') failed.';\n"
185 " var dumpOptgroup = function(group) {\n"
186 " var result = '';\n"
187 " for (var i = 0; i < group.children.length; i++) {\n"
188 " if (i > 0) {\n"
189 " result += divider;\n"
190 " }\n"
191 " if (group.children[i].value) {\n"
192 " result += group.children[i].value;\n"
193 " } else {\n"
194 " result += '__NO_VALUE__';\n"
195 " }\n"
196 " }\n"
197 " return result;\n"
198 " };\n"
199 " var result = '';\n"
200 " if (select.selectedIndex != 0) {\n"
201 " result += '(selectedIndex=' + select.selectedIndex + \n"
202 " ', selected \"' + select.options[select.selectedIndex].value +\n"
203 " '\")';\n"
204 " }\n"
205 " var children = select.children;\n"
206 " for (var i = 0; i < children.length; i++) {\n"
207 " if (i > 0) {\n"
208 " result += divider;\n"
209 " }\n"
210 " if (children[i].value) {\n"
211 " result += children[i].value;\n"
212 " } else if (children[i].tagName === 'OPTGROUP') {\n"
213 " result += '[' + dumpOptgroup(children[i]) + ']';\n"
214 " } else {\n"
215 " result += '__NO_VALUE__';\n"
216 " }\n"
217 " }\n"
218 " return result;\n"
219 "})()\n",
220 select_id);
221 return checker.GetString(expression);
224 std::string TranslateXKB2Extension(const std::string& src) {
225 std::string result(src);
226 if (!extension_ime_util::UseWrappedExtensionKeyboardLayouts())
227 return result;
228 // Modifies the expected keyboard select control options for the new
229 // extension based xkb id.
230 size_t pos = 0;
231 std::string repl_old = "xkb:";
232 std::string repl_new =
233 extension_ime_util::GetInputMethodIDByKeyboardLayout("xkb:");
234 while ((pos = result.find(repl_old, pos)) != std::string::npos) {
235 result.replace(pos, repl_old.length(), repl_new);
236 pos += repl_new.length();
238 return result;
241 void OobeLocalizationTest::RunLocalizationTest(
242 const std::string& initial_locale,
243 const std::string& keyboard_layout,
244 const std::string& expected_locale,
245 const std::string& expected_keyboard_layout,
246 const std::string& expected_keyboard_select_control) {
247 statistics_provider_->set_locale(initial_locale);
248 statistics_provider_->set_keyboard_layout(keyboard_layout);
250 // Initialize StartupCustomizationDocument with fake statistics provider.
251 StartupCustomizationDocument::GetInstance()->Init(
252 statistics_provider_.get());
254 g_browser_process->local_state()->SetString(
255 prefs::kHardwareKeyboardLayout, keyboard_layout);
257 input_method::InputMethodManager::Get()
258 ->GetInputMethodUtil()
259 ->InitXkbInputMethodsForTesting();
261 const std::string expected_keyboard_select =
262 TranslateXKB2Extension(expected_keyboard_select_control);
264 // Bring up the OOBE network screen.
265 chromeos::ShowLoginWizard(chromeos::WizardController::kNetworkScreenName);
266 content::WindowedNotificationObserver(
267 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
268 content::NotificationService::AllSources()).Wait();
270 checker.set_web_contents(static_cast<chromeos::LoginDisplayHostImpl*>(
271 chromeos::LoginDisplayHostImpl::default_host())->
272 GetOobeUI()->web_ui()->GetWebContents());
274 if (!VerifyInitialOptions(kLocaleSelect, expected_locale.c_str(), true)) {
275 LOG(ERROR) << "Actual value of " << kLocaleSelect << ":\n"
276 << DumpOptions(kLocaleSelect);
278 if (!VerifyInitialOptions(
279 kKeyboardSelect,
280 TranslateXKB2Extension(expected_keyboard_layout).c_str(),
281 false)) {
282 LOG(ERROR) << "Actual value of " << kKeyboardSelect << ":\n"
283 << DumpOptions(kKeyboardSelect);
286 // Make sure we have a fallback keyboard.
287 if (!VerifyOptionExists(kKeyboardSelect,
288 extension_ime_util::GetInputMethodIDByKeyboardLayout(
289 kUSLayout).c_str())) {
290 LOG(ERROR) << "Actual value of " << kKeyboardSelect << ":\n"
291 << DumpOptions(kKeyboardSelect);
294 // Note, that sort order is locale-specific, but is unlikely to change.
295 // Especially for keyboard layouts.
296 EXPECT_EQ(expected_keyboard_select, DumpOptions(kKeyboardSelect));
298 // Shut down the display host.
299 chromeos::LoginDisplayHostImpl::default_host()->Finalize();
300 base::MessageLoopForUI::current()->RunUntilIdle();
302 // Clear the locale pref so the statistics provider is pinged next time.
303 g_browser_process->local_state()->SetString(prefs::kApplicationLocale,
304 std::string());
307 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenNonLatin) {
308 // For a non-Latin keyboard layout like Russian, we expect to see the US
309 // keyboard.
310 RunLocalizationTest("ru", "xkb:ru::rus",
311 "ru", kUSLayout,
312 "xkb:us::eng");
314 RunLocalizationTest("ru", "xkb:us::eng,xkb:ru::rus",
315 "ru", kUSLayout,
316 "xkb:us::eng");
318 // IMEs do not load at OOBE, so we just expect to see the (Latin) Japanese
319 // keyboard.
320 RunLocalizationTest("ja", "xkb:jp::jpn",
321 "ja", "xkb:jp::jpn",
322 "xkb:jp::jpn,[xkb:us::eng]");
325 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenKeyboardLayout) {
326 // We don't use the Icelandic locale but the Icelandic keyboard layout
327 // should still be selected when specified as the default.
328 RunLocalizationTest("en-US", "xkb:is::ice",
329 "en-US", "xkb:is::ice",
330 "xkb:is::ice,["
331 "xkb:us::eng,xkb:us:intl:eng,xkb:us:altgr-intl:eng,"
332 "xkb:us:dvorak:eng,xkb:us:colemak:eng]");
335 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenFullLatin) {
336 // French Swiss keyboard.
337 RunLocalizationTest("fr", "xkb:ch:fr:fra",
338 "fr", "xkb:ch:fr:fra",
339 "xkb:ch:fr:fra,["
340 "xkb:fr::fra,xkb:be::fra,xkb:ca::fra,"
341 "xkb:ca:multix:fra,xkb:us::eng]");
343 // German Swiss keyboard.
344 RunLocalizationTest("de", "xkb:ch::ger",
345 "de", "xkb:ch::ger",
346 "xkb:ch::ger,["
347 "xkb:de::ger,xkb:de:neo:ger,xkb:be::ger,xkb:us::eng"
348 "]");
351 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenMultipleLocales) {
352 RunLocalizationTest("es,en-US,nl", "xkb:be::nld",
353 "es,en-US,nl", "xkb:be::nld",
354 "xkb:be::nld,[xkb:es::spa,xkb:latam::spa,xkb:us::eng]");
356 RunLocalizationTest("ru,de", "xkb:ru::rus",
357 "ru,de", kUSLayout,
358 "xkb:us::eng");
361 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenRegionalLocales) {
362 // Syntetic example to test correct merging of different locales.
363 RunLocalizationTest("fr-CH,it-CH,de-CH",
364 "xkb:fr::fra,xkb:it::ita,xkb:de::ger",
365 "fr-CH,it-CH,de-CH",
366 "xkb:fr::fra",
367 "xkb:fr::fra,xkb:it::ita,xkb:de::ger,["
368 "xkb:be::fra,xkb:ca::fra,xkb:ch:fr:fra,"
369 "xkb:ca:multix:fra,xkb:us::eng"
370 "]");
371 // Another syntetic example. Check that british keyboard is available.
372 RunLocalizationTest("en-AU",
373 "xkb:us::eng",
374 "en-AU",
375 "xkb:us::eng",
376 "xkb:us::eng,[xkb:gb:extd:eng,xkb:gb:dvorak:eng]");
379 } // namespace chromeos