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

85 lines
2.5 KiB
YAML

# dm/realtime-receive.yaml
#
# Journey: Login → open a DM → wait for an incoming message from the peer →
# assert the message bubble appears WITHOUT manual scroll.
#
# What this covers:
# - Realtime Supabase subscription (useDmRealtime) correctly fires on INSERT
# - Incoming message is appended to the local messages list
# - FlatList auto-scrolls to show the new message (scrollToBottom is called)
# - No "unread / scroll down" lag visible
#
# LIMITATION: This flow requires an EXTERNAL trigger — the test peer must
# send a message while the flow is waiting. This is not automatable with a
# single Maestro device run.
#
# Approaches:
# A) Manual: Run flow, then manually send a message from a second device
# within the 30s wait window. Not suitable for CI.
# B) API-trigger: A helper script sends a message via
# POST /api/dm/send (Service-Role) just before the flow reaches
# the waiting step. Needs coordination outside Maestro.
# C) Two-device Maestro Cloud: Device A runs dm/send-message.yaml,
# Device B runs this flow simultaneously. Phase B / Cloud.
#
# Current status: SCAFFOLD ONLY — assertVisible for incoming message
# will always timeout unless external trigger is set up.
# Leaving this flow as documented intent for Phase B.
#
# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD
# Optional: E2E_TEST_PEER_NICKNAME
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
- assertVisible:
text: "ReBreak"
# --- Navigate to Chat → open DM ---
- tapOn:
text: "Chat"
- waitForAnimationToEnd:
timeout: 3000
- assertVisible:
text: "Direktnachrichten"
- tapOn:
text: ${E2E_TEST_PEER_NICKNAME}
- waitForAnimationToEnd:
timeout: 4000
- assertVisible:
text: "Nachricht schreiben…"
# --- Wait for incoming realtime message ---
# External trigger must fire within this window.
# The [E2E-INCOMING] prefix is used by the helper script to identify
# test messages for cleanup after the run.
- waitForAnimationToEnd:
timeout: 30000
# Assert the incoming message bubble appeared.
# WILL FAIL without external trigger — intentional for Phase B scaffolding.
- assertVisible:
text: "[E2E-INCOMING]"