Mobile Firefox (Android emulator) verification — 2026-07-11¶
Goal¶
Per the sequencing directive ("finish desktop first, then the lightest emulator for mobile Firefox"), verify the extension's core behavior on real Firefox for Android, fully headless and automated, on an 8 GB M1. Logged-out only.
Environment (lightest workable path)¶
- Toolchain: Homebrew
openjdk(26) +android-commandlinetools;sdkmanagerinstallsplatform-tools,emulator, and thesystem-images;android-34;aosp_atd;arm64-v8aimage (AOSP Automated-Test-Device — the lightest arm64 image: stripped UI, fast boot, low RAM; native on Apple Silicon, no x86 translation). - AVD:
yta_test, booted headless:-no-window -no-audio -no-boot-anim -gpu swiftshader_indirect -memory 1536. Booted in seconds; host stayed ~21-27% RAM free throughout (workable on 8 GB). - Browser: Firefox Nightly (Fenix
154.0a1,org.mozilla.fenix), official arm64-v8a APK fromarchive.mozilla.org/pub/fenix/nightly/..., sideloaded withadb install.
Headless techniques that made it work (not in doc 18, worth keeping)¶
screencapreturns a blank surface under headless swiftshader → drive the UI by the accessibility tree instead:adb shell uiautomator dumpgives every node's text + bounds, so taps are computed from the XML with no pixels. Helper:tests/e2e/android/ui.py. Used to walk Fenix onboarding and toggle Settings → Advanced → Remote debugging via USB (confirmed by the@org.mozilla.fenix/firefox-debugger-socketunix socket appearing in/proc/net/unix).adb root(the aosp_atd image is userdebug) is required for geckodriver to push its profile: without it the session dies withadb error: fchown failed: Operation not permitted(Fenix Nightly is not debuggable, so geckodriver's app-storagerun-aspath fails; root lets it chown the pushed profile).- geckodriver + Marionette (not web-ext) drives Fenix, so the same
executeScriptDOM-marker assertions as the desktop bench apply.selenium enableMobile('org.mozilla.fenix')with no serial (geckodriver auto-detects the single device; selenium'sdeviceSerialfield is rejected by geckodriver 0.37). Extension loaded viadriver.installAddon(xpi, /*temporary*/ true)— no signing. Defaults already haveaudioOnlyEnabled:true, so no settings seeding is needed.
Result — tests/e2e/probe-mobile-fenix.mjs, 4/4 PASS¶
Extension installs as a temporary add-on (youtube-audio@local); content script injects on m.youtube.com (data-yta-bench=1).
| Video | Branch | Observed |
|---|---|---|
Bu4ztj3R32k (music) | audio-only hijack | status=active, currentSrc→googlevideo, videoWidth=0, readyState=4 |
DaWe9L1iwNw (podcast) | audio-only hijack | status=active, hijacked, videoWidth=0, readyState=4 |
fOdo1GkzZAk (kids) | credentialless UNPLAYABLE fallback | status=fallback, reason=UNPLAYABLE, not hijacked |
X4VbdwhkE10 (live) | live fallback | status=fallback, reason=live, not hijacked |
Conclusions: the MV2 build loads and runs on Firefox for Android; the credentialless ANDROID_VR fetch + <video>.src hijack works on the mobile (m.youtube.com) DOM; and both fallback branches (kids-UNPLAYABLE and the newly-fixed live exclusion) behave correctly on mobile, exactly as on desktop.
Reproduce¶
export JAVA_HOME=/opt/homebrew/opt/openjdk
export ANDROID_SDK_ROOT=/opt/homebrew/share/android-commandlinetools
export PATH="$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$PATH"
emulator @yta_test -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect -memory 1536 &
adb wait-for-device && adb root
# (first time only) sideload Fenix + enable Remote debugging via tests/e2e/android/ui.py
node tests/e2e/probe-mobile-fenix.mjs dist/youtube-audio-bench.xpi
Not covered on mobile (honest carve-out)¶
Background/lock-screen mediaSession controls and the popup/options UI rendering are not asserted here (headless, no compositor). Core playback + protection logic is identical JS to desktop (same Gecko), and is proven on both surfaces.