chahinebrini 63fae25531 fix(android-protection): explicit specialUse FGS type — Samsung/Android 16 crash loop
RebreakVpnService.onStartCommand crashed with SecurityException because Android 16's validateForegroundServiceType rejects the implicit 2-arg startForeground(). Now passes FOREGROUND_SERVICE_TYPE_SPECIAL_USE explicitly (Google's documented best practice) and guards the call so a failed foreground promotion stops the service cleanly instead of crashing the app. Verified vs reported Galaxy A54 / Android 16 signature (97% of crash events, 1-user crash loop).

Bundles pending working-tree work across native/marketing/locales/mac + graphify-out rebuild. gitignore: google-services.json + /screenshots/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 22:33:28 +02:00

93 lines
3.8 KiB
YAML

# onboarding/new-user-streak-guard.yaml
#
# REGRESSION GUARD for the current bug:
# current_days=0 for all users because the streak calculation never runs.
#
# Journey: Launch → Welcome → Privacy → Nickname (skip via DiGA-No path) →
# Plan (Pro, Dev-Trial-CTA) → Payment (Dev-Skip) → Protection (skip
# via CTABar if dialog appears) → Done → App Home → Home screen
# must show streak day > 0 (NOT "0 Tage clean" or "Starte deinen ersten Tag"
# when the test user already has a streak).
#
# Strategy: The test user (claude-android-test) has an existing account with
# onboardingStep='done' so onboarding will NOT replay — _layout.tsx
# routes directly to /(app). We assert the streak widget shows a
# positive day count as the regression guard.
# For a brand new user test, a separate dedicated account is needed
# (see BLOCKER in notes at bottom). This flow covers the post-onboarding
# regression scenario.
#
# Pre-requisite:
# - App installed (Dev-Build OR TestFlight).
# - E2E_TEST_USER account on staging with onboardingStep='done' and streak_start set.
# - Staging backend running.
# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD
#
# Expected outcome: After login, the home screen streak widget shows a day count
# that is NOT "0 Tage" (i.e. current_days is being calculated).
# If it shows "0 Tage clean" or "Starte deinen ersten Tag" when
# the account has a real streak — the regression is present.
#
# IMPORTANT: Text selectors use hardcoded de.json values. If device locale ≠ 'de',
# run with a German locale device or force-set language to 'de' before test.
appId: org.rebreak.app
---
- launchApp:
clearState: true
- waitForAnimationToEnd:
timeout: 5000
# --- Auth ---
- assertVisible:
text: "E-Mail"
- tapOn:
text: "E-Mail"
- inputText: ${E2E_TEST_USER}@rebreak.internal
- tapOn:
text: "Passwort"
- inputText: ${E2E_TEST_PASSWORD}
- tapOn:
text: "Anmelden"
- waitForAnimationToEnd:
timeout: 10000
# --- Home screen reached ---
- assertVisible:
text: "ReBreak"
# The streak widget is in the Home screen (app/index.tsx or a HomeStreakCard).
# home.streak_days_one = "Tag clean"
# home.streak_days_other = "Tage clean"
# home.streak_start = "Starte deinen ersten Tag"
#
# REGRESSION CHECK: if current_days is never calculated, the widget always shows
# "0 Tage clean". We assert "Tage clean" is visible (which is true for any count
# including 0) and additionally assert "Starte deinen ersten Tag" is NOT visible
# (which would only appear for day=0 / null streak start).
#
# This catches the "always 0" bug: when current_days=0 the UI renders
# "0 Tage clean" or "Starte deinen ersten Tag" even for users with real streaks.
- assertVisible:
text: "clean"
# The key assertion: "Starte deinen ersten Tag" must NOT be visible for an
# established test-user. If this fires — the streak calculation bug is present.
- assertNotVisible:
text: "Starte deinen ersten Tag"
# Secondary guard: assert that "0 Tage" is not the streak count.
# "0 Tage clean" is the de.json rendering for 0 days via streak_days_other.
# NOTE: Maestro assertNotVisible matches substring — "0 Tage" catches both
# "0 Tage clean" (streak_days_other) and any "0 Tag clean" variant.
- assertNotVisible:
text: "0 Tage"
# NOTE FOR FULL ONBOARDING TEST (new account flow):
# A completely fresh account (onboardingStep='welcome') is needed to exercise
# the Welcome → Privacy → Nickname → Plan → Payment → Protection → Done flow.
# That requires a separate test account that is reset to onboardingStep='welcome'
# before each run (via Service-Role PATCH). This is not automated here yet.
# See TODO in SETUP.md Phase B.