Index: chrome/test/telemetry/chromeos/login_unittest.py |
diff --git a/chrome/test/telemetry/chromeos/login_unittest.py b/chrome/test/telemetry/chromeos/login_unittest.py |
index 7675e95dbf72118c523e0b0e885f9239fd1dd535..86b8aba13af33d7534f429cc7d5eda4e95f58299 100644 |
--- a/chrome/test/telemetry/chromeos/login_unittest.py |
+++ b/chrome/test/telemetry/chromeos/login_unittest.py |
@@ -152,7 +152,6 @@ class CrOSAutoTest(unittest.TestCase): |
self._AttemptUnlockBadPassword(browser) |
self._UnlockScreen(browser) |
- |
def testLogout(self): |
"""Tests autotestPrivate.logout""" |
with self._CreateBrowser(autotest_ext=True) as b: |
@@ -163,3 +162,163 @@ class CrOSAutoTest(unittest.TestCase): |
exceptions.BrowserGoneException): |
pass |
util.WaitFor(lambda: not self._IsCryptohomeMounted(), 20) |
+ |
+ def _SwitchRegion(self, region): |
+ self._cri.RunCmdOnDevice(['stop', 'ui']) |
+ |
+ # Change VPD (requires RW-enabled firmware). |
+ # To save time, region and initial_timezone are not set. |
+ vpd = {'initial_locale': region.language_code, |
+ 'keyboard_layout': region.keyboard} |
+ |
+ for (key, value) in vpd.items(): |
+ self._cri.RunCmdOnDevice(['vpd', '-s', '"%s"="%s"' % (key, value)]) |
+ |
+ # Remove cached files to clear initial locale info and force regeneration. |
+ self._cri.RunCmdOnDevice(['rm', '/home/chronos/Local\ State']) |
+ self._cri.RunCmdOnDevice(['rm', '/home/chronos/.oobe_completed']) |
+ self._cri.RunCmdOnDevice(['dump_vpd_log', '--force']) |
+ |
+ self._cri.RunCmdOnDevice(['start', 'ui']) |
+ |
+ def _OobeHasOption(self, browser, selectId, value): |
+ hasOptionJs = ''' |
+ // Check that the option is present, and selected if it is the default. |
+ (function hasOption(selectId, value, isDefault) { |
+ var options = document.getElementById(selectId).options; |
+ for (var i = 0; i < options.length; i++) { |
+ if (options[i].value == value) { |
+ // The option is present. Make sure it's selected if necessary. |
+ return !isDefault || options.selectedIndex == i; |
+ } |
+ } |
+ return false; |
+ })("%s", "%s", %s); |
+ ''' |
+ return browser.oobe.EvaluateJavaScript( |
+ hasOptionJs % (selectId, value, 'true')) |
+ |
+ def _ResolveLanguage(self, locale): |
+ # If the locale matches a language but not the country, fall back to |
+ # an existing locale. See ui/base/l10n/l10n_util.cc. |
+ lang, _, region = map(str.lower, locale.partition('-')) |
+ if not region: |
+ return "" |
+ |
+ # Map from other countries to a localized country |
+ if lang == 'es' and region == 'es': |
+ return 'es-419' |
+ if lang == 'zh': |
+ if region in ('hk', 'mo'): |
+ return 'zh-TW' |
+ return 'zh-CN' |
+ if lang == 'en': |
+ if region in ('au', 'ca', 'nz', 'za'): |
+ return 'en-GB' |
+ return 'en-US' |
+ |
+ # No mapping found |
+ return "" |
+ |
+ def testOobeLocalization(self): |
+ """Tests different region configurations at OOBE""" |
+ # Save the original device localization settings. |
+ # To save time, only read initial_locale and keyboard_layout. |
+ initial_region = self.Region('', '', '', '', '') |
+ initial_region.language_code, _ = self._cri.RunCmdOnDevice( |
+ ['vpd', '-g', 'initial_locale']) |
+ initial_region.keyboard, _ = self._cri.RunCmdOnDevice( |
+ ['vpd', '-g', 'keyboard_layout']) |
+ |
+ for region in self.REGIONS_LIST: |
+ self._SwitchRegion(region) |
+ with self._CreateBrowser(auto_login=False) as browser: |
+ # Ensure the dropdown lists have been created. |
+ util.WaitFor(lambda: browser.oobe.EvaluateJavaScript( |
+ 'document.getElementById("language-select") != null'), |
+ 10) |
+ |
+ # Find the language, or an acceptable fallback value. |
+ languageFound = self._OobeHasOption(browser, |
+ 'language-select', |
+ region.language_code) |
+ if not languageFound: |
+ fallback = self._ResolveLanguage(region.language_code) |
+ self.assertTrue(fallback and |
+ self._OobeHasOption(browser, |
+ 'language-select', |
+ fallback)) |
+ |
+ # Find the keyboard layout. |
+ self.assertTrue(self._OobeHasOption( |
+ browser, 'keyboard-select', region.keyboard)) |
+ |
+ # Test is finished. Restore original region settings. |
+ self._SwitchRegion(initial_region) |
+ |
+ # The Region class and region list will be available in regions.py. |
+ class Region(object): |
+ def __init__(self, region_code, keyboard, time_zone, language_code, |
+ keyboard_mechanical_layout, description=None, notes=None): |
+ self.region_code = region_code |
+ self.keyboard = keyboard |
+ self.time_zone = time_zone |
+ self.language_code = language_code |
+ self.keyboard_mechanical_layout = keyboard_mechanical_layout |
+ self.description = description or region_code |
+ self.notes = notes |
+ |
+ class Enum(frozenset): |
+ def __getattr__(self, name): |
+ if name in self: |
+ return name |
+ raise AttributeError |
+ |
+ KeyboardMechanicalLayout = Enum(['ANSI', 'ISO', 'JIS', 'ABNT2']) |
+ _KML = KeyboardMechanicalLayout |
+ REGIONS_LIST = [ |
+ Region('au', 'xkb:us::eng', 'Australia/Sydney', 'en-AU', _KML.ANSI, |
+ 'Australia'), |
+ Region('ca.ansi', 'xkb:us::eng', 'America/Toronto', 'en-CA', _KML.ANSI, |
+ 'Canada (US keyboard)', |
+ 'Canada with US (ANSI) keyboard; see http://goto/cros-canada'), |
+ Region('ca.fr', 'xkb:ca::fra', 'America/Toronto', 'fr-CA', _KML.ISO, |
+ 'Canada (French keyboard)', |
+ ('Canadian French (ISO) keyboard. The most common configuration for ' |
+ 'Canadian French SKUs. See http://goto/cros-canada')), |
+ Region('ca.hybrid', 'xkb:ca:eng:eng', 'America/Toronto', 'en-CA', _KML.ISO, |
+ 'Canada (hybrid)', |
+ ('Canada with hybrid xkb:ca:eng:eng + xkb:ca::fra keyboard (ISO), ' |
+ 'defaulting to English language and keyboard. Used only if there ' |
+ 'needs to be a single SKU for all of Canada. See ' |
+ 'http://goto/cros-canada')), |
+ Region('ca.multix', 'xkb:ca:multix:fra', 'America/Toronto', 'fr-CA', |
+ _KML.ISO, 'Canada (multilingual)', |
+ ("Canadian Multilingual keyboard; you probably don't want this. See " |
+ "http://goto/cros-canada")), |
+ Region('de', 'xkb:de::ger', 'Europe/Berlin', 'de', _KML.ISO, 'Germany'), |
+ Region('fi', 'xkb:fi::fin', 'Europe/Helsinki', 'fi', _KML.ISO, 'Finland'), |
+ Region('fr', 'xkb:fr::fra', 'Europe/Paris', 'fr', _KML.ISO, 'France'), |
+ Region('gb', 'xkb:gb:extd:eng', 'Europe/London', 'en-GB', _KML.ISO, 'UK'), |
+ Region('ie', 'xkb:gb:extd:eng', 'Europe/Dublin', 'en-GB', _KML.ISO, |
+ 'Ireland'), |
+ Region('in', 'xkb:us::eng', 'Asia/Calcutta', 'en-US', _KML.ANSI, 'India'), |
+ Region('my', 'xkb:us::eng', 'Asia/Kuala_Lumpur', 'ms', _KML.ANSI, |
+ 'Malaysia'), |
+ Region('nl', 'xkb:us:intl:eng', 'Europe/Amsterdam', 'nl', _KML.ANSI, |
+ 'Netherlands'), |
+ Region('nordic', 'xkb:se::swe', 'Europe/Stockholm', 'en-US', _KML.ISO, |
+ 'Nordics', |
+ ('Unified SKU for Sweden, Norway, and Denmark. This defaults ' |
+ 'to Swedish keyboard layout, but starts with US English language ' |
+ 'for neutrality. Use if there is a single combined SKU for Nordic ' |
+ 'countries.')), |
+ Region('se', 'xkb:se::swe', 'Europe/Stockholm', 'sv', _KML.ISO, 'Sweden', |
+ ("Use this if there separate SKUs for Nordic countries (Sweden, " |
+ "Norway, and Denmark), or the device is only shipping to Sweden. " |
+ "If there is a single unified SKU, use 'nordic' instead.")), |
+ Region('sg', 'xkb:us::eng', 'Asia/Singapore', 'en-GB', _KML.ANSI, |
+ 'Singapore'), |
+ Region('us', 'xkb:us::eng', 'America/Los_Angeles', 'en-US', _KML.ANSI, |
+ 'United States'), |
+ ] |