1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import json 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)import logging 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import os 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import unittest 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)from telemetry.core import browser_finder 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)from telemetry.core import exceptions 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)from telemetry.core import extension_to_load 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)from telemetry.core import util 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)from telemetry.core.backends.chrome import cros_interface 14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)from telemetry.unittest import options_for_unittests 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class CrOSAutoTest(unittest.TestCase): 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def setUp(self): 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) options = options_for_unittests.GetCopy() 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self._cri = cros_interface.CrOSInterface(options.cros_remote, 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) options.cros_ssh_identity) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self._is_guest = options.browser_type == 'cros-chrome-guest' 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._username = '' if self._is_guest else options.browser_options.username 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._password = options.browser_options.password 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def _IsCryptohomeMounted(self): 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) """Returns True if cryptohome is mounted""" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cryptohomeJSON, _ = self._cri.RunCmdOnDevice(['/usr/sbin/cryptohome', 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '--action=status']) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cryptohomeStatus = json.loads(cryptohomeJSON) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (cryptohomeStatus['mounts'] and 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cryptohomeStatus['mounts'][0]['mounted']) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _CreateBrowser(self, autotest_ext=False, auto_login=True): 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Finds and creates a browser for tests. if autotest_ext is True, 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) also loads the autotest extension""" 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) options = options_for_unittests.GetCopy() 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if autotest_ext: 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_path = os.path.join(os.path.dirname(__file__), 'autotest_ext') 40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) self._load_extension = extension_to_load.ExtensionToLoad( 41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) path=extension_path, 42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) browser_type=options.browser_type, 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) is_component=True) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) options.extensions_to_load = [self._load_extension] 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser_to_create = browser_finder.FindBrowser(options) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertTrue(browser_to_create) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options.browser_options.create_browser_with_oobe = True 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options.browser_options.auto_login = auto_login 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) b = browser_to_create.Create() 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) b.Start() 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return b 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def _GetAutotestExtension(self, browser): 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) """Returns the autotest extension instance""" 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension = browser.extensions[self._load_extension] 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertTrue(extension) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return extension 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def _GetLoginStatus(self, browser): 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extension = self._GetAutotestExtension(browser) 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self.assertTrue(extension.EvaluateJavaScript( 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "typeof('chrome.autotestPrivate') != 'undefined'")) 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extension.ExecuteJavaScript(''' 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window.__login_status = null; 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chrome.autotestPrivate.loginStatus(function(s) { 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window.__login_status = s; 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }); 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ''') 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return util.WaitFor( 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) lambda: extension.EvaluateJavaScript('window.__login_status'), 10) 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def testCryptohomeMounted(self): 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) """Verifies cryptohome mount status for regular and guest user and when 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) logged out""" 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) with self._CreateBrowser() as b: 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertEquals(1, len(b.tabs)) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertTrue(b.tabs[0].url) 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertTrue(self._IsCryptohomeMounted()) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chronos_fs = self._cri.FilesystemMountedAt('/home/chronos/user') 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertTrue(chronos_fs) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if self._is_guest: 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertEquals(chronos_fs, 'guestfs') 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else: 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) home, _ = self._cri.RunCmdOnDevice(['/usr/sbin/cryptohome-path', 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'user', self._username]) 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertEquals(self._cri.FilesystemMountedAt(home.rstrip()), 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chronos_fs) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertFalse(self._IsCryptohomeMounted()) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertEquals(self._cri.FilesystemMountedAt('/home/chronos/user'), 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '/dev/mapper/encstateful') 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def testLoginStatus(self): 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) """Tests autotestPrivate.loginStatus""" 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) with self._CreateBrowser(autotest_ext=True) as b: 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) login_status = self._GetLoginStatus(b) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertEquals(type(login_status), dict) 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertEquals(not self._is_guest, login_status['isRegularUser']) 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertEquals(self._is_guest, login_status['isGuest']) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.assertEquals(login_status['email'], self._username) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.assertFalse(login_status['isScreenLocked']) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def _IsScreenLocked(self, browser): 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return self._GetLoginStatus(browser)['isScreenLocked'] 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def _LockScreen(self, browser): 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self.assertFalse(self._IsScreenLocked(browser)) 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extension = self._GetAutotestExtension(browser) 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self.assertTrue(extension.EvaluateJavaScript( 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "typeof chrome.autotestPrivate.lockScreen == 'function'")) 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logging.info('Locking screen') 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extension.ExecuteJavaScript('chrome.autotestPrivate.lockScreen();') 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logging.info('Waiting for the lock screen') 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def ScreenLocked(): 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return (browser.oobe and 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser.oobe.EvaluateJavaScript("typeof Oobe == 'function'") and 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser.oobe.EvaluateJavaScript( 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "typeof Oobe.authenticateForTesting == 'function'")) 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.WaitFor(ScreenLocked, 10) 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self.assertTrue(self._IsScreenLocked(browser)) 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def _AttemptUnlockBadPassword(self, browser): 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logging.info('Trying a bad password') 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def ErrorBubbleVisible(): 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return not browser.oobe.EvaluateJavaScript(''' 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) document.getElementById('bubble').hidden 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ''') 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self.assertFalse(ErrorBubbleVisible()) 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser.oobe.ExecuteJavaScript(''' 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Oobe.authenticateForTesting('%s', 'bad'); 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ''' % self._username) 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.WaitFor(ErrorBubbleVisible, 10) 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self.assertTrue(self._IsScreenLocked(browser)) 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def _UnlockScreen(self, browser): 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logging.info('Unlocking') 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser.oobe.ExecuteJavaScript(''' 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Oobe.authenticateForTesting('%s', '%s'); 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ''' % (self._username, self._password)) 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) util.WaitFor(lambda: not browser.oobe, 10) 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self.assertFalse(self._IsScreenLocked(browser)) 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def testScreenLock(self): 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) """Tests autotestPrivate.screenLock""" 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) with self._CreateBrowser(autotest_ext=True) as browser: 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self._LockScreen(browser) 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self._AttemptUnlockBadPassword(browser) 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self._UnlockScreen(browser) 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def testLogout(self): 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) """Tests autotestPrivate.logout""" 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) with self._CreateBrowser(autotest_ext=True) as b: 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension = self._GetAutotestExtension(b) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) try: 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension.ExecuteJavaScript('chrome.autotestPrivate.logout();') 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) except (exceptions.BrowserConnectionGoneException, 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) exceptions.BrowserGoneException): 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pass 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) util.WaitFor(lambda: not self._IsCryptohomeMounted(), 20) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _SwitchRegion(self, region): 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._cri.RunCmdOnDevice(['stop', 'ui']) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Change VPD (requires RW-enabled firmware). 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # To save time, region and initial_timezone are not set. 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) vpd = {'initial_locale': region.language_code, 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'keyboard_layout': region.keyboard} 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (key, value) in vpd.items(): 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._cri.RunCmdOnDevice(['vpd', '-s', '"%s"="%s"' % (key, value)]) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Remove cached files to clear initial locale info and force regeneration. 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._cri.RunCmdOnDevice(['rm', '/home/chronos/Local\ State']) 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._cri.RunCmdOnDevice(['rm', '/home/chronos/.oobe_completed']) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._cri.RunCmdOnDevice(['dump_vpd_log', '--force']) 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._cri.RunCmdOnDevice(['start', 'ui']) 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _OobeHasOption(self, browser, selectId, value): 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hasOptionJs = ''' 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check that the option is present, and selected if it is the default. 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (function hasOption(selectId, value, isDefault) { 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var options = document.getElementById(selectId).options; 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < options.length; i++) { 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (options[i].value == value) { 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The option is present. Make sure it's selected if necessary. 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return !isDefault || options.selectedIndex == i; 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) })("%s", "%s", %s); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ''' 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return browser.oobe.EvaluateJavaScript( 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hasOptionJs % (selectId, value, 'true')) 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _ResolveLanguage(self, locale): 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # If the locale matches a language but not the country, fall back to 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # an existing locale. See ui/base/l10n/l10n_util.cc. 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) lang, _, region = map(str.lower, locale.partition('-')) 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not region: 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return "" 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Map from other countries to a localized country 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if lang == 'es' and region == 'es': 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 'es-419' 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if lang == 'zh': 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if region in ('hk', 'mo'): 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 'zh-TW' 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 'zh-CN' 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if lang == 'en': 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if region in ('au', 'ca', 'nz', 'za'): 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 'en-GB' 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 'en-US' 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # No mapping found 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return "" 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def testOobeLocalization(self): 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Tests different region configurations at OOBE""" 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Save the original device localization settings. 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # To save time, only read initial_locale and keyboard_layout. 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) initial_region = self.Region('', '', '', '', '') 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) initial_region.language_code, _ = self._cri.RunCmdOnDevice( 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ['vpd', '-g', 'initial_locale']) 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) initial_region.keyboard, _ = self._cri.RunCmdOnDevice( 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ['vpd', '-g', 'keyboard_layout']) 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for region in self.REGIONS_LIST: 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._SwitchRegion(region) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) with self._CreateBrowser(auto_login=False) as browser: 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Ensure the dropdown lists have been created. 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util.WaitFor(lambda: browser.oobe.EvaluateJavaScript( 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'document.getElementById("language-select") != null'), 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10) 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Find the language, or an acceptable fallback value. 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) languageFound = self._OobeHasOption(browser, 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'language-select', 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) region.language_code) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not languageFound: 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fallback = self._ResolveLanguage(region.language_code) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.assertTrue(fallback and 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._OobeHasOption(browser, 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'language-select', 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fallback)) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Find the keyboard layout. 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.assertTrue(self._OobeHasOption( 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) browser, 'keyboard-select', region.keyboard)) 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Test is finished. Restore original region settings. 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._SwitchRegion(initial_region) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # The Region class and region list will be available in regions.py. 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class Region(object): 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __init__(self, region_code, keyboard, time_zone, language_code, 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyboard_mechanical_layout, description=None, notes=None): 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.region_code = region_code 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.keyboard = keyboard 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.time_zone = time_zone 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.language_code = language_code 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.keyboard_mechanical_layout = keyboard_mechanical_layout 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.description = description or region_code 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.notes = notes 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) class Enum(frozenset): 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __getattr__(self, name): 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if name in self: 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return name 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise AttributeError 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) KeyboardMechanicalLayout = Enum(['ANSI', 'ISO', 'JIS', 'ABNT2']) 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _KML = KeyboardMechanicalLayout 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) REGIONS_LIST = [ 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('au', 'xkb:us::eng', 'Australia/Sydney', 'en-AU', _KML.ANSI, 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Australia'), 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('ca.ansi', 'xkb:us::eng', 'America/Toronto', 'en-CA', _KML.ANSI, 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Canada (US keyboard)', 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Canada with US (ANSI) keyboard; see http://goto/cros-canada'), 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('ca.fr', 'xkb:ca::fra', 'America/Toronto', 'fr-CA', _KML.ISO, 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Canada (French keyboard)', 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ('Canadian French (ISO) keyboard. The most common configuration for ' 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Canadian French SKUs. See http://goto/cros-canada')), 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('ca.hybrid', 'xkb:ca:eng:eng', 'America/Toronto', 'en-CA', _KML.ISO, 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Canada (hybrid)', 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ('Canada with hybrid xkb:ca:eng:eng + xkb:ca::fra keyboard (ISO), ' 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'defaulting to English language and keyboard. Used only if there ' 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'needs to be a single SKU for all of Canada. See ' 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'http://goto/cros-canada')), 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('ca.multix', 'xkb:ca:multix:fra', 'America/Toronto', 'fr-CA', 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _KML.ISO, 'Canada (multilingual)', 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ("Canadian Multilingual keyboard; you probably don't want this. See " 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "http://goto/cros-canada")), 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('de', 'xkb:de::ger', 'Europe/Berlin', 'de', _KML.ISO, 'Germany'), 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('fi', 'xkb:fi::fin', 'Europe/Helsinki', 'fi', _KML.ISO, 'Finland'), 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('fr', 'xkb:fr::fra', 'Europe/Paris', 'fr', _KML.ISO, 'France'), 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('gb', 'xkb:gb:extd:eng', 'Europe/London', 'en-GB', _KML.ISO, 'UK'), 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('ie', 'xkb:gb:extd:eng', 'Europe/Dublin', 'en-GB', _KML.ISO, 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Ireland'), 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('in', 'xkb:us::eng', 'Asia/Calcutta', 'en-US', _KML.ANSI, 'India'), 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('my', 'xkb:us::eng', 'Asia/Kuala_Lumpur', 'ms', _KML.ANSI, 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Malaysia'), 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('nl', 'xkb:us:intl:eng', 'Europe/Amsterdam', 'nl', _KML.ANSI, 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Netherlands'), 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('nordic', 'xkb:se::swe', 'Europe/Stockholm', 'en-US', _KML.ISO, 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Nordics', 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ('Unified SKU for Sweden, Norway, and Denmark. This defaults ' 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'to Swedish keyboard layout, but starts with US English language ' 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'for neutrality. Use if there is a single combined SKU for Nordic ' 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'countries.')), 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('se', 'xkb:se::swe', 'Europe/Stockholm', 'sv', _KML.ISO, 'Sweden', 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ("Use this if there separate SKUs for Nordic countries (Sweden, " 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Norway, and Denmark), or the device is only shipping to Sweden. " 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "If there is a single unified SKU, use 'nordic' instead.")), 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('sg', 'xkb:us::eng', 'Asia/Singapore', 'en-GB', _KML.ANSI, 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Singapore'), 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Region('us', 'xkb:us::eng', 'America/Los_Angeles', 'en-US', _KML.ANSI, 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'United States'), 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ] 325