1:mod:`mozrunner` --- Manage remote and local gecko processes 2============================================================ 3 4Mozrunner provides an API to manage a gecko-based application with an 5arbitrary configuration profile. It currently supports local desktop 6binaries such as Firefox and Thunderbird, as well as Firefox OS on 7mobile devices and emulators. 8 9 10Basic usage 11----------- 12 13The simplest way to use mozrunner, is to instantiate a runner, start it 14and then wait for it to finish: 15 16.. code-block:: python 17 18 from mozrunner import FirefoxRunner 19 binary = 'path/to/firefox/binary' 20 runner = FirefoxRunner(binary=binary) 21 runner.start() 22 runner.wait() 23 24This automatically creates and uses a default mozprofile object. If you 25wish to use a specialized or pre-existing profile, you can create a 26:doc:`mozprofile <mozprofile>` object and pass it in: 27 28.. code-block:: python 29 30 from mozprofile import FirefoxProfile 31 from mozrunner import FirefoxRunner 32 import os 33 34 binary = 'path/to/firefox/binary' 35 profile_path = 'path/to/profile' 36 if os.path.exists(profile_path): 37 profile = FirefoxProfile.clone(path_from=profile_path) 38 else: 39 profile = FirefoxProfile(profile=profile_path) 40 runner = FirefoxRunner(binary=binary, profile=profile) 41 runner.start() 42 runner.wait() 43 44 45Handling output 46--------------- 47 48By default, mozrunner dumps the output of the gecko process to standard output. 49It is possible to add arbitrary output handlers by passing them in via the 50`process_args` argument. Be careful, passing in a handler overrides the default 51behaviour. So if you want to use a handler in addition to dumping to stdout, you 52need to specify that explicitly. For example: 53 54.. code-block:: python 55 56 from mozrunner import FirefoxRunner 57 58 def handle_output_line(line): 59 do_something(line) 60 61 binary = 'path/to/firefox/binary' 62 process_args = { 'stream': sys.stdout, 63 'processOutputLine': [handle_output_line] } 64 runner = FirefoxRunner(binary=binary, process_args=process_args) 65 66Mozrunner uses :doc:`mozprocess <mozprocess>` to manage the underlying gecko 67process and handle output. See the :doc:`mozprocess documentation <mozprocess>` 68for all available arguments accepted by `process_args`. 69 70 71Handling timeouts 72----------------- 73 74Sometimes gecko can hang, or maybe it is just taking too long. To handle this case you 75may want to set a timeout. Mozrunner has two kinds of timeouts, the 76traditional `timeout`, and the `outputTimeout`. These get passed into the 77`runner.start()` method. Setting `timeout` will cause gecko to be killed after 78the specified number of seconds, no matter what. Setting `outputTimeout` will cause 79gecko to be killed after the specified number of seconds with no output. In both 80cases the process handler's `onTimeout` callbacks will be triggered. 81 82.. code-block:: python 83 84 from mozrunner import FirefoxRunner 85 86 def on_timeout(): 87 print('timed out after 10 seconds with no output!') 88 89 binary = 'path/to/firefox/binary' 90 process_args = { 'onTimeout': on_timeout } 91 runner = FirefoxRunner(binary=binary, process_args=process_args) 92 runner.start(outputTimeout=10) 93 runner.wait() 94 95The `runner.wait()` method also accepts a timeout argument. But unlike the arguments 96to `runner.start()`, this one simply returns from the wait call and does not kill the 97gecko process. 98 99.. code-block:: python 100 101 runner.start(timeout=100) 102 103 waiting = 0 104 while runner.wait(timeout=1) is None: 105 waiting += 1 106 print("Been waiting for %d seconds so far.." % waiting) 107 assert waiting <= 100 108 109 110Using a device runner 111--------------------- 112 113The previous examples used a GeckoRuntimeRunner. If you want to control a 114gecko process on a remote device, you need to use a DeviceRunner. The api is 115nearly identical except you don't pass in a binary, instead you create a device 116object. For example to run Firefox for Android on the emulator, you might do: 117 118.. code-block:: python 119 120 from mozrunner import FennecEmulatorRunner 121 122 avd_home = 'path/to/avd' 123 runner = FennecEmulatorRunner(app='org.mozilla.fennec', avd_home=avd_home) 124 runner.start() 125 runner.wait() 126 127Device runners have a `device` object. Remember that the gecko process runs on 128the device. In the case of the emulator, it is possible to start the 129device independently of the gecko process. 130 131.. code-block:: python 132 133 runner.device.start() # launches the emulator 134 runner.start() # stops the gecko process (if started), installs the profile, (re)starts the gecko process 135 136 137Runner API Documentation 138------------------------ 139 140Application Runners 141~~~~~~~~~~~~~~~~~~~ 142.. automodule:: mozrunner.runners 143 :members: 144 145BaseRunner 146~~~~~~~~~~ 147.. autoclass:: mozrunner.base.BaseRunner 148 :members: 149 150GeckoRuntimeRunner 151~~~~~~~~~~~~~~~~~~ 152.. autoclass:: mozrunner.base.GeckoRuntimeRunner 153 :show-inheritance: 154 :members: 155 156BlinkRuntimeRunner 157~~~~~~~~~~~~~~~~~~ 158.. autoclass:: mozrunner.base.BlinkRuntimeRunner 159 :show-inheritance: 160 :members: 161 162DeviceRunner 163~~~~~~~~~~~~ 164.. autoclass:: mozrunner.base.DeviceRunner 165 :show-inheritance: 166 :members: 167 168Device API Documentation 169------------------------ 170 171Generally using the device classes directly shouldn't be required, but in some 172cases it may be desirable. 173 174Device 175~~~~~~ 176.. autoclass:: mozrunner.devices.Device 177 :members: 178 179EmulatorAVD 180~~~~~~~~~~~ 181.. autoclass:: mozrunner.devices.EmulatorAVD 182 :show-inheritance: 183 :members: 184