Real phones¶
Emulators and simulators are convenient; a real phone is the real thing. jevtest drives both the same way: only device: changes.
Android phone¶
- On the phone: Settings > About phone, tap Build number seven times, then Settings > System > Developer options > USB debugging on.
- Plug it in and tap Allow on the phone.
- Find its name:
adb deviceslists the serial; its model name (Pixel 4a) works too. device: { android: Pixel 4a }, and keep the phone unlocked while tests run.
A locked or sleeping phone fails the test with a message to unlock it.
iPhone¶
Apple only runs code on an iPhone when it is signed by a developer account the phone trusts, so each person does this once:
- Xcode > Settings > Accounts > + > Apple Account. A free Apple ID works; a paid developer account avoids profiles that expire after 7 days.
- On the iPhone: Settings > Privacy & Security > Developer Mode on (the phone restarts), then Settings > Developer > Enable UI Automation.
- Plug it in, tap Trust, and keep it unlocked while tests run.
- Build your app for the device, signed with your team. An
.appor an.ipacontaining one. Use Release, or any build that runs without a debugger attached. - In the test file:
app:
ios: build/Release-iphoneos/MyApp.app
device:
ios: My iPhone # Settings > General > About > Name, or its UDID
jevtest signs its own agent with the same team that signed your app, read from the app's provisioning profile, so there's nothing to configure. That team must be signed into Xcode; if it isn't, the error says which team to add.
First run: jevtest builds its agent, signs it with your team and registers the phone with that team (about a minute). Later runs reuse it. jevtest reaches the phone through the USB connection Xcode already keeps to it, so nothing else needs installing.
The phone may ask for its passcode. When jevtest's agent starts, iOS can show an XCTest prompt asking for the passcode to allow UI automation. Enter it on the phone; the run waits while the prompt is up. If nobody enters it, iOS cancels the prompt and the run fails saying the phone asked for its passcode and it wasn't given. Apple doesn't let this be skipped, so be near the phone when a run starts. A run killed outright can't stop its agent on the phone; the next run on that phone stops it first.
A touch on a permission prompt takes a minute? Restart the iPhone. The agent log in ~/.cache/jevtest/ shows App animations complete notification not received when this happens.
What's different on an iPhone: everything works except grant: (iOS can't pre-grant permissions: have the test tap the prompt, e.g. do: Allow camera access) and network:.
Leaving the phone as it was¶
jevtest never changes a device's settings to make testing easier: animations stay on, nothing is disabled. The only changes are the ones a step asks for, and those go back at the end of the run:
| Step | Put back at the end |
|---|---|
rotate: |
Android: auto-rotate and orientation. iOS: orientation; a simulator never turned reports none, so it's put back the way its screen showed, upright. |
dark_mode: |
Android and iOS: the appearance it had. |
network: |
Android: Wi-Fi and mobile data as they were. |
autofill: |
Android: the autofill service it had (Google's, say), or none. |
location: |
iOS simulator and iPhone: the simulated location is cleared, so the device uses its actual location again. The Android emulator keeps the last one set: it can't report where it was, so there's nothing to put back. |