Previous commit's per-test logoutIfAuthenticated() in HomeGuestFlowTests
and ProfileLoggedOutFlowTests ran the guest address-picker navigation
dance (reachProfileTabRegardlessOfAuthState) twice back-to-back per test
- once in the new launch helper, once again inside reachGuestHome/
reachLoggedOutProfile - doubling exposure to that dance's known race
and regressing 5 previously-stable tests ('Login never completed' was
fixed, but new failures appeared in its place).
Moved the forced logout into override class func setUp() so it runs
once per class instead of once per test; test bodies are back to the
plain XCUIApplication()+launch() pattern.
Also fixed OrderDetailsFlowTests: 'Ver Detalhes' now matches multiple
elements once the QA account has more than one real order (previously
masked because login itself was failing first). Switched to a label
predicate + .firstMatch.
See decisions/2026-09-11-ui-test-shared-login-session.md follow-ups.
All 7 authenticated-flow XCTestCase classes logged out for real in
tearDown, forcing a real OTP round trip against the production backend
on the next authenticated test. Under CI's back-to-back suite run this
produced ~9 real logins to the same QA phone number in ~9 minutes -
the first few succeeded (~30-40s each) but every one after that failed
to complete within timeout, cascading into 'Login never completed'
across CartCheckoutFlowTests, HomeFiltersFlowTests,
OrderDetailsFlowTests, SavedCardsFlowTests, UserProfileFlowTests.
Removed the per-test logout so the QA account's Keychain-backed session
persists across the whole suite (ensureLoggedIn already no-ops when
already authenticated). Moved the 'must start logged out' guarantee to
the two classes that actually need it - HomeGuestFlowTests and
ProfileLoggedOutFlowTests now force logout themselves right after
app.launch() via a small launch helper, instead of relying on whichever
authenticated class happened to run last.
See decisions/2026-09-11-ui-test-shared-login-session.md.
- RegistrationView / LoginEmailView / OtpView: pushed with no nav bar, so
they showed the oversized iOS 26 system glass back button. Wrapped each
in LCENavigationView with the standard AppBackButtonIcon, matching
LoginView and every other screen. Dropped the now-dead colorScheme dark
branches and forced .preferredColorScheme(.light) (app has no dark
theme).
- ContentView: root .auth <-> .main switched with no transition. Added
.move transitions on both branches and wrapped enterAuthFlow() /
LoginView's back action in withAnimation, so opening auth from Profile's
'Entrar ou Cadastrar' now slides in and back slides out.
- ProfileLoggedOutFlowTests: new test asserting the pushed auth screens
carry the LCENavigationView back button.
App Review rejected the 2026-08 build: tapping checkout as a guest
switched root to .auth, which replaced the whole UI with LoginView as the
NavigationStack root - no nav bar, no back, no dismiss. User was trapped.
- LoginView: rebuilt as a static screen in LCENavigationView with a back
button that sets root = .main, a 'Criar conta' and an 'Entrar' button,
and 'Termos de Uso' / 'Politica de Privacidade' links. Added #Preview.
- Forced .preferredColorScheme(.light) and fixed DS colors (the app has
no dark theme, so system dark mode was inverting the nav bar / title).
- Removed the entry-reveal animation machinery (heroVisible/textVisible/
buttonVisible/token/prepare flags across LoginView, AuthFlowView,
ContentView) - dead since guest browsing shipped and the root cause of
the 2026-08-06 'content stuck hidden' bug.
- enterAuthFlow() is now just root = .auth.
- UITestSupport.ensureLoggedIn taps 'Entrar' (new label).
- ProfileLoggedOutFlowTests: new test covering the choices and the way
back out of .auth.
- Localizable.xcstrings: catalog caught up to the new/removed strings.