Runs every activated plugin's Mob.Plugin.SelfTest on a device.
A plugin declares selftest: Module in its manifest; run_all/3 calls
Module.run/1 on the device's node, one plugin at a time, and returns one
entry per activated plugin. mix mob.selftest prints those as a table;
mob_ci records them per nightly cell (invariant P12).
The entry's :result is always one of the contract's three shapes:
:pass{:fail, reason}— also what a self-test that raised, exited, threw, timed out, is not on the device or returned something outside the contract gets, and what a plugin whose manifest failed signature verification gets. The reason says which.{:skip, :needs_hardware | :needs_user | reason}— including plugins with noselftest:in their manifest (module: nil), so a plugin without one is visible, not silently absent.
Permissions are not granted here: the node is already running, and on an
iOS simulator a privacy change can terminate the app. Callers grant
before launching the app with grant_permissions/4, as
mix mob.selftest does.
Summary
Types
What a self-test is told about where it runs (Mob.Plugin.SelfTest.ctx/0).
One plugin's outcome. :ms is the wall time of the call on the host.
A granted (or attempted) permission.
An activated plugin as MobDev.Plugin.activated_with_verify/0 (3-tuple) or
activated/0 (2-tuple) lists them; the first element is the plugin's name
or its dependency directory.
Functions
The entries whose result is {:fail, _}.
Grants the permissions the plugins' manifests declare to bundle_id on
device, so self-tests do not hit a system prompt. Call it before
launching the app: a simulator may terminate a running app whose privacy
settings change.
Runs the self-test of every activated plugin on node and returns an entry per plugin.
One line: N passed, N failed, N skipped.
The table mix mob.selftest prints for one device: a header plus one
line per entry, plugin outcome ms detail.
Types
@type ctx() :: %{
platform: :ios | :android,
device: :simulator | :emulator | :physical
}
What a self-test is told about where it runs (Mob.Plugin.SelfTest.ctx/0).
@type entry() :: %{ plugin: atom(), module: module() | nil, result: term(), ms: non_neg_integer() }
One plugin's outcome. :ms is the wall time of the call on the host.
A granted (or attempted) permission.
An activated plugin as MobDev.Plugin.activated_with_verify/0 (3-tuple) or
activated/0 (2-tuple) lists them; the first element is the plugin's name
or its dependency directory.
Functions
The entries whose result is {:fail, _}.
@spec grant_permissions(MobDev.Device.t(), [plugin()], String.t(), (String.t(), [String.t()] -> {String.t(), integer()})) :: [ grant() ]
Grants the permissions the plugins' manifests declare to bundle_id on
device, so self-tests do not hit a system prompt. Call it before
launching the app: a simulator may terminate a running app whose privacy
settings change.
- Android emulator: each
android.permissionsentry viaadb -s <serial> shell pm grant. Only runtime permissions are grantable; a normal or signature permission answers with an error, which is recorded, not raised. - iOS simulator: each
permissions: [%{capability: cap}]whose capability maps to asimctl privacyservice. - Physical devices: nothing is granted (returns
[]); a self-test that needs a permission the user has not given skips with:needs_user.
Returns one grant/0 per attempt. cmd is fn exe, argv -> {output, status} end.
Runs the self-test of every activated plugin on node and returns an entry per plugin.
Options:
:plugins—plugin/0list (default:MobDev.Plugin.activated_with_verify/0, read from the host project'smob.exsand deps). A plugin whose manifest failed verification is a{:fail, _}entry; one with no manifest (tier 0) is a skip.:timeout_ms— per self-test (default 30000). A test still running at the deadline is killed on the device, so the next plugin's test never runs beside it.:boot_timeout_ms— how long to wait for the plugins' OTP applications to be started on the node before the first test (default 15000). mob starts them after the node is up, so a run right after a relaunch would otherwise test a plugin whose supervisor is not there yet. A plugin whose application never starts is tested anyway and reports it.
One line: N passed, N failed, N skipped.
The table mix mob.selftest prints for one device: a header plus one
line per entry, plugin outcome ms detail.