Mobly CrOS controller module for using Python code to operate CrOS devices in Mobly tests.
Project description
Mobly ChromeOS Controller
Mobly ChromeOS controller module for using Python code to operate ChromeOS (CrOS) devices in Mobly tests.
This is not an officially supported Google product. This project is not eligible for the Google Open Source Software Vulnerability Rewards Program.
Requirements
- Python 3.11+
- Mobly 1.12.4+
Hardware Requirements
- One or more ChromeOS devices (that are being tested).
- A Linux workstation (host machine) to run Mobly test script.
Set Up ChromeOS Devices
To control the ChromeOS device, users need to do some one-time settings on the ChromeOS device.
Pre-setting requirements:
- Flash a test image to ChromeOS device (prefer to use latest build).
- Connect the ChromeOS device to the same local network as the host machine (your workstation).
Use ChromeOS Devices in a test
This section introduces how to develop a basic Mobly ChromeOS controller test which runs one shell command on the ChromeOS device.
Define a Testbed
Define the ChromeOS device in a testbed with CrosDevice type. Save the config in a local Mobly config yaml file. Example Testbed config:
sample_config.yaml
TestBeds:
- Name: SampleCrosTestbed
Controllers:
CrosDevice:
- hostname: "DEVICE_IP"
Write Test Script
We use the "Hello World" test script as a simple example using ChromeOS device. In this example, we will connect to a ChromeOS device and execute a shell command on this ChromeOS device. Mobly test script:
hello_world_test.py
"""A sample test demonstrating using Mobly Cros controller."""
from mobly import base_test
from mobly import test_runner
from mobly.controllers.cros import cros_device
class HelloWorldTest(base_test.BaseTestClass):
"""A sample test demonstrating using Mobly ChromeOS controller."""
def setup_class(self):
super().setup_class()
# Registers cros_device controller module. By default, we expect at
# least one ChromeOS device.
self._crosd = self.register_controller(cros_device)[0]
def test_ssh_execute_command(self):
# Executes console command 'ls' on the ChromeOS device and gets the result.
result = self._crosd.ssh.execute_command('ls')
self._crosd.log.info('ls result: %s', result)
if __name__ == '__main__':
test_runner.main()
Run Test
python hello_world_test.py -c sample_config.yaml
ChromeOS Device Login
Mobly ChromeOS controller provides the TastSessionService for tests to start a new Chrome user session with the given account and password. You should register it on CrosDevice objects:
from mobly import base_test
from mobly.controllers.cros import cros_device
from mobly.controllers.cros.lib.tast_services import tast_session_service
class MoblyTastExampleTest(base_test.BaseTestClass):
_crosd: cros_device.CrosDevice
def setup_class(self):
super().setup_class()
self._crosd = self.register_controller(cros_device)[0]
login_config = tast_session_service.Config(
# Note that keep_state=False will delete user data on the ChromeOS device.
# We recommend this setting as it helps us avoid test flakiness due to
# device state.
keep_state=False,
)
self._crosd.services.register('tast_session_service',
tast_session_service.TastSessionService,
login_config)
Regarding the login config,
- If your test doesn't require any account information, use the above config and the ChromeOS device will log in with a default test account. If your test requires logging in with specific account, e.g. pairing a ChromeOS device and an Android device logged in with the same account, you need to log in with an OTA account and following login config:
login_config = tast_session_service.Config(
# GAIA login mode uses a GAIA backend to verify the login credential,
# which could be slow and sometimes flaky, use this mode only when you
# really need it.
login_mode=tast_session_service.LOGIN_MODE_GAIA_LOGIN,
username="xxxx",
password="xxxxxxx",
keep_state=False,
)
Set logging levels
TastSessionService supports passing extra command line flags to Chrome. This is mostly used for setting logging levels. Here's an example usage:
login_config = tast_session_service.Config(
...,
extra_args=[
'--enable-logging',
# "ble_*=3" sets the VLOG level of files prefixed with "ble_" to 3
'--vmodule=ble_*=3,*blue*=3,device_event_log*=3',
# Sets the VLOG level of other files to be 1
'--v=1',
]
)
You can check that the flags are properly passed by checking chrome://version tab on the ChromeOS device. See doc for more details about ChromeOS logging.
Change ChromeOS feature flags
TastSessionService supports enabling/disabling ChromeOS features. Instead of modifying feature flags via the chrome://flags page and then restarting Chrome, you only need to modify the login config, the features will be enabled/disabled. Here's an example:
login_config = tast_session_service.Config(
...,
enable_features=['EcheSWA', 'FastPair'],
disable_features=['EcheSWADebugMode'],
...
)
Device Language Setting
Some automation tools requires English as the system language. In the login config, we have set region='US' which asks the ChromeOS device to use English.
Device Log Collection
This section describes using DeviceLogService to get logs on ChromeOS devices, which are critical for debugging tests. Here's an example which collects the chrome log /var/log/chrome/chrome and bluetooth monitor log from ChromeOS devices.
from mobly.controllers.cros.lib.tast_services import device_log_service
def setup_class(self):
super().setup_class()
self._crosd = self.register_controller(cros_device)[0]
log_service_config = device_log_service.Config(
log_types={
device_log_service.LogType.CHROME_LOG,
device_log_service.LogType.BLUETOOTH_MONITOR,
})
self._crosd.services.register('device_log_service',
device_log_service.DeviceLogService,
log_service_config)
Currently ChromeOS logs are scattered in different places, and different logs need to be obtained in different ways. So we need to increase the supported log types one by one. The supported log types can be found in LogType.
Screen Recording
Screen recording can be critical for debugging tests that involve UI.
Mobly ChromeOS controller provides the ScreenRecorderService to record the screen on ChromeOS devices. You should register it on CrosDevice objects:
from mobly.controllers.cros.lib.tast_services import screen_recorder_service
...
def setup_class(self):
...
self._crosd.services.register('tast_session_service',
tast_session_service.TastSessionService,
login_config)
# ScreenRecorderService can only be registered after TastSessionService
self._crosd.services.register('screen_recorder_service',
screen_recorder_service.ScreenRecorderService)
Keyboard Input Control
The CrosDevice provides two interfaces to control keyboard input:
- input_text: Inputs text on the test device by simulating typing on the keyboard.
- input_hotkey: Inputs the hotkey by simulating key events on the keyboard.
Here's an example:
def test_keyboard_input_example(self):
# Input hotkey "Ctrl"+"t" to open the Chrome browser on ChromeOS device
self._crosd.input_hotkey('Ctrl+t')
# Input the given hotkey to get the cursor to the address bar of the browser
self._crosd.input_hotkey('Alt+d')
# Input the given text in the address bar
self._crosd.input_text('Test Type Successfully.')
Webdriver
Webdriver is an open-source control mechanism that enables remote control of web browsers.
Mobly ChromeOS controller creates a helper module for setting up and tearing down a remote Webdriver object, so users can use this object to operate the Chrome browser on ChromeOS devices, like navigating pages and calling JavaScript APIs to access the underlying HTML UI elements.
Here is an example:
def test_webdriver_example(self):
# Open the Chrome browser
self._crosd.input_hotkey('Ctrl+t')
# Navigate to the setting page
self._crosd.webdriver.get('chrome://os-settings')
# Execute a JS script to click on the button "About ChromeOS"
self._crosd.webdriver.execute_script(
'return document'
'.querySelector("os-settings-ui").shadowRoot'
'.querySelector("os-settings-menu").shadowRoot'
'.querySelector("#aboutItem")').click()
Tast services
Tast folder contain all generated files with services required for CrOS controller.
To update or regenerate services follow scripts/README
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mobly_cros-1.0.0.tar.gz.
File metadata
- Download URL: mobly_cros-1.0.0.tar.gz
- Upload date:
- Size: 181.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e134e51d739c52372cf87aeeb9abb58840c372a56af074c88ec01a15d71d18cf
|
|
| MD5 |
449ab936447ef603992c9323fa6aa6f6
|
|
| BLAKE2b-256 |
163b946daf38fa893500957fdc337f600a1e63f3454b19e2fbd1b9f6d6e664a2
|
File details
Details for the file mobly_cros-1.0.0-py3-none-any.whl.
File metadata
- Download URL: mobly_cros-1.0.0-py3-none-any.whl
- Upload date:
- Size: 261.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef8da59aeede9cc9d9e30bd89c187154b01575d4e4440b2e1511b2bf994aee9f
|
|
| MD5 |
116016a82e5326517466d7b30a707504
|
|
| BLAKE2b-256 |
6d6f2d10cb51853d82ce748e44aee8301363bd13d7be421267a6a46f7483ff33
|