The Android jump from 3 failures (7f75e5c) to 23 (6a269a9) is not a product
regression. 6a269a9 changes three lines of app code — an awaited
updateLocalCustomStatus in the account row — and 22 of the 27 failures in that
run's merged report are "[launchAndVerify] Neither server.screen nor
channel_list.screen appeared within 90s", i.e. the app never launched at all.
Shard 13 of run 32184155037 is the whole story. Its job log:
Test Suites: 1 failed, 6 passed, 7 total
Tests: 2 failed, 20 passed, 22 total
==> Attempt 1 failed with exit 1
==> Cleaning up before retry
...
Test Suites: 7 failed, 7 total
Tests: 22 failed, 22 total
==> Attempt 2 failed with exit 1
Attempt 1 was a normal run with the two known custom-status flakes. Because jest
exits 1 on any test failure, the retry wrapper treated that as an infra failure,
wiped detox/artifacts, killed the emulator and re-ran all seven specs. Every
launch on the re-booted emulator then failed inside Espresso with "Waited for the
root of the view hierarchy to have window focus and not request layout for 10
seconds ... has-window-focus=false", so the shard's final report — the only one
that survives — read 22 failed. That single retry is 20 of the 23 failures.
Changes:
* e2e-android-template.yml: retry only when the attempt produced no usable
verdict. A report covering every assigned spec with at least one passing test
means the emulator worked and the failures are test failures, so it is kept.
A missing report (killed by the 60m timeout, bootstrap failure) or a report
with nothing passing still retries.
* create_android_emulator.sh: keep the display awake and unlocked
(svc power stayon, screen_off_timeout, KEYCODE_WAKEUP, dismiss-keyguard,
CLOSE_SYSTEM_DIALOGS), force-stop Chrome after priming its command-line file
instead of relying on one BACK that lands on its splash, and gate the run on
the emulator actually having a focused window.
* setup.ts: recover the device between launch attempts rather than only
relaunching the app, and log mCurrentFocus/mFocusedApp so a repeat is
diagnosable from the job log.
* save_report.js: stop deleting the whole {platform}-results-* folders before the
S3 upload. That removed every device.log and testFnFailure.png Detox wrote, so
the S3 report only ever carried the HTML summary — path_builder.js names each
folder after the Jest fullName so TSIO can link screenshots, but the files never
arrived. Only the parts already merged into the top-level report (per-shard
jest-stare, junit XML, jest-results.json) are dropped now. Video is off and
screenshots are failure-only, so the upload stays small.
* Maestro MM-T5611: the flow failed on "Assertion is false: id: tab_bar.home.tab
is visible". bookmark-browser-opened.png shows Safari in the foreground on
mattermost.com with the back-to-app pill present, so the hand-off worked; the
`when: notVisible` guard after the breadcrumb tap sampled the hierarchy while
iOS was still resuming the suspended app, dropped into the cold-restart
recovery, and that sub-flow's 30s wait for the tab bar expired. Give the resume
its own optional wait before the guard, and let a cold start have 60s.
Co-Authored-By: Claude <noreply@anthropic.com>