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>
85 lines
2.5 KiB
YAML
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]"
|