One sign-up helper, because five copies had the same bug
Seven of 52 UI tests failed in one run with "sign-up did not complete". The
app was right and the tests were wrong, and the failure dump said so:
signup.password value: • ← one character
signup.confirm value: ••••••••••••••••• ← all seventeen
signup.submit Disabled
iOS puts "Use Strong Password?" over the first `.newPassword` field, and from
the first keystroke on it swallows what follows. Every sign-up helper in this
target called `dismissPasswordSuggestionIfPresent()` — at the end, after both
passwords had been typed, by which point there is nothing left to save. The app
then correctly refused a form whose two passwords disagreed, and the report
blamed sign-up for it.
It is non-deterministic, which is why it reads as flake: a fifth suite running
identical keystrokes passed in the same run. It is not flake and it is not
machine load.
There were five hand-rolled copies of that helper — four here, plus one I wrote
for the new two-simulator suite, which reproduced the bug immediately and is
what makes the point. Now there is one, `XCUIApplication.completeSignUp`, and it
dismisses the panel when the field takes focus, reads both fields back, repairs a
short one, and fails naming the cause instead of the app.
Two new suites:
TwoSimulatorUITests — two simulators, two accounts, one relay. Both sides run
the same test with the handles swapped, so neither has to start first; the
peer lookup retries, which is the rendezvous. A direct message crosses in both
directions and a group created on one device arrives on the other. This is
weaker evidence than CrossPlatformUITests and says so in its own header: both
halves are the same binary and will agree when both are wrong. What it proves
that nothing else does is that a message crosses two devices, two Keychains
and two ratchets and lands in the app's own UI.
AppSurfaceUITests — the screens nothing was opening. Reactions, unsend,
in-chat search, mute, the voice-note recorder, the stories strip, the groups
section, the safety number and five of the seven settings screens had no test
at all. Deliberately shallow and it says so: this catches a screen that
crashes or fails to push, not one that is wrong.
Also here, each found while running the above:
- DEVELOPMENT_TEAM was "2W7DA3A8W2", the free personal team on the build Mac,
while the App Store provisioning profile that already exists for
net.flamenet.messenger belongs to M5923Y84P5 — the team that ships hittfitness
and shepherdgiving, valid to 2027-06-04. A personal team cannot produce a
distribution build, so every archive for TestFlight would have failed naming
the certificate rather than the team ID that put it out of reach.
- Scripts/generate.sh, because .gitignore excludes the whole .xcodeproj and
SwiftPM keeps Package.resolved inside it. Since the WebRTC dependency landed a
fresh checkout had no pins at all: resolve against the network and get a
different build tomorrow, or disable resolution and fail outright. Both
unacceptable for something going to testers. The pins live in Scripts/ now.
- rounds.sh ran an iOS *build* and called it a round. The 45 XCUITest cases
never ran. It runs them now — and refuses to score a run that executed zero
tests as a pass, which xcodebuild will happily report after a runner crashes
and relaunches:
Test Suite 'TwoSimulatorUITests' passed
Executed 0 tests, with 0 failures
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a213ad8d5d
commit
a9ec8e98bb
@@ -17,7 +17,7 @@ screen renders.
|
||||
| Protocol engine | `Sources/E2E`, 15 files | `engine`, 10 files |
|
||||
| App layer | ~9,700 lines, 45 files | accounts, contacts, chat, photos |
|
||||
| Tests | XCUITest + JS interop | 114 unit + 37 cross-engine + 15 on-device + live round trips |
|
||||
| Ships to | nobody (no signing team) | a debug APK that installs and runs |
|
||||
| Ships to | TestFlight, once a distribution cert is minted (see below) | a debug APK that installs and runs; the release keystore is configured |
|
||||
|
||||
Android's engine is **verified against the web engine in both directions**
|
||||
(`engine/test/interop-kotlin.mjs`), which is a stronger claim than the iOS app
|
||||
@@ -334,3 +334,26 @@ for the app to settle before deciding anything.
|
||||
first takes the message and the other reports zero, which reads as "nothing was
|
||||
sent". Run a single `autoreply` at a time.
|
||||
|
||||
## Signing, on both sides (2026-08-25)
|
||||
|
||||
**iOS was pinned to the wrong Apple team, and that — not a missing membership —
|
||||
is what made TestFlight unreachable.** `project.yml` carried
|
||||
`DEVELOPMENT_TEAM: "2W7DA3A8W2"`, the free personal team attached to the iCloud
|
||||
address on the build Mac. Meanwhile an **App Store provisioning profile for
|
||||
`net.flamenet.messenger` already exists**, issued to team `M5923Y84P5` — the
|
||||
team that ships hittfitness and shepherdgiving — and valid until 2027-06-04. A
|
||||
personal team cannot produce a distribution build at all, so every archive would
|
||||
have failed at signing while naming the certificate rather than the team ID that
|
||||
put it out of reach. The team is now `M5923Y84P5`.
|
||||
|
||||
⚠️ **Still outstanding: no distribution certificate in the build Mac's
|
||||
keychain.** `security find-identity -v -p codesigning` returns exactly one
|
||||
identity, the personal-team *development* one. Signing in to Xcode with the App
|
||||
Store Connect account mints the distribution certificate and the matching
|
||||
profile; nothing in this repository can do it, and nothing here should try.
|
||||
|
||||
**Android needs none of that.** The release `signingConfig` reads
|
||||
`~/.flamenet-android-signing.properties` — present on the build Mac since
|
||||
2026-08-23 — so `:app:assembleRelease` produces a signed APK that can go
|
||||
straight to a tester. That asymmetry is why Android reaches testers first, and
|
||||
it has nothing to do with which app is more finished.
|
||||
|
||||
Reference in New Issue
Block a user