experiments in a post-browser web
at main 243 lines 7.5 kB view raw
1#!/bin/bash 2# iOS Simulator E2E Sync Test Setup 3# 4# Usage: ./scripts/ios-sync-test.sh 5# 6# This script: 7# 1. Starts a local server with fresh temp data 8# 2. Creates a server profile (gets UUID for folder-based routing) 9# 3. Seeds test items on the server 10# 4. Finds the iOS simulator app container 11# 5. Pre-configures profiles.json with server URL, API key, server_profile_id 12# 6. Clears last_sync timestamps for a fresh pull 13# 7. Opens Xcode (build & run from there) 14# 15# The server keeps running until you press Ctrl+C. 16 17set -e 18 19SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" 20PROJECT_DIR="$(dirname "$SCRIPT_DIR")" 21SERVER_DIR="$PROJECT_DIR/backend/server" 22TAURI_DIR="$PROJECT_DIR/backend/tauri-mobile" 23XCODE_PROJECT="$TAURI_DIR/src-tauri/gen/apple/peek-save.xcodeproj" 24 25# --- Configuration --- 26 27PORT="${PORT:-3459}" 28API_KEY="ios-e2e-key-$(date +%s)" 29SERVER_TEMP_DIR="$(mktemp -d /tmp/e2e-peek-ios-XXXXXX)" 30 31LOCAL_IP=$(ipconfig getifaddr en0 2>/dev/null || echo "localhost") 32SERVER_URL="http://$LOCAL_IP:$PORT" 33 34echo "==========================================" 35echo " iOS E2E Sync Test Setup" 36echo "==========================================" 37echo "" 38echo " Server URL: $SERVER_URL" 39echo " API Key: $API_KEY" 40echo " Data dir: $SERVER_TEMP_DIR" 41echo "" 42 43# --- Cleanup trap --- 44 45SERVER_PID="" 46cleanup() { 47 echo "" 48 echo "Cleaning up..." 49 if [ -n "$SERVER_PID" ]; then 50 kill "$SERVER_PID" 2>/dev/null || true 51 wait "$SERVER_PID" 2>/dev/null || true 52 echo " Stopped server (PID $SERVER_PID)" 53 fi 54 rm -rf "$SERVER_TEMP_DIR" 55 echo " Removed $SERVER_TEMP_DIR" 56} 57trap cleanup EXIT 58 59# --- Step 1: Start server --- 60 61echo "Step 1: Starting server..." 62DATA_DIR="$SERVER_TEMP_DIR" PORT="$PORT" API_KEY="$API_KEY" node "$SERVER_DIR/index.js" & 63SERVER_PID=$! 64 65for i in {1..30}; do 66 if curl -sf "http://localhost:$PORT/" > /dev/null 2>&1; then 67 echo " Server ready on port $PORT (PID $SERVER_PID)" 68 break 69 fi 70 if [ "$i" -eq 30 ]; then 71 echo " ERROR: Server failed to start" 72 exit 1 73 fi 74 sleep 0.5 75done 76 77# --- Step 2: Create server profile --- 78 79echo "" 80echo "Step 2: Creating server profile..." 81PROFILE_RESP=$(curl -sf -X POST "http://localhost:$PORT/profiles" \ 82 -H "Authorization: Bearer $API_KEY" \ 83 -H "Content-Type: application/json" \ 84 -d '{"name":"Default"}') 85 86SERVER_PROFILE_ID=$(echo "$PROFILE_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['profile']['id'])") 87echo " Server profile ID: $SERVER_PROFILE_ID" 88 89# --- Step 3: Seed test data --- 90 91echo "" 92echo "Step 3: Seeding test data..." 93 94PROFILE_PARAM="profile=$SERVER_PROFILE_ID" 95VER_HEADERS='-H "X-Peek-Datastore-Version: 1" -H "X-Peek-Protocol-Version: 1"' 96 97curl -sf -X POST "http://localhost:$PORT/items?$PROFILE_PARAM" \ 98 -H "Authorization: Bearer $API_KEY" \ 99 -H "Content-Type: application/json" \ 100 -H "X-Peek-Datastore-Version: 1" \ 101 -H "X-Peek-Protocol-Version: 1" \ 102 -d '{"type":"url","content":"https://example.com/from-server","tags":["server","test"]}' > /dev/null 103 104curl -sf -X POST "http://localhost:$PORT/items?$PROFILE_PARAM" \ 105 -H "Authorization: Bearer $API_KEY" \ 106 -H "Content-Type: application/json" \ 107 -H "X-Peek-Datastore-Version: 1" \ 108 -H "X-Peek-Protocol-Version: 1" \ 109 -d '{"type":"url","content":"https://github.com/anthropics/claude-code","tags":["github","ai"]}' > /dev/null 110 111curl -sf -X POST "http://localhost:$PORT/items?$PROFILE_PARAM" \ 112 -H "Authorization: Bearer $API_KEY" \ 113 -H "Content-Type: application/json" \ 114 -H "X-Peek-Datastore-Version: 1" \ 115 -H "X-Peek-Protocol-Version: 1" \ 116 -d '{"type":"text","content":"Server test note for e2e sync","tags":["note","test"]}' > /dev/null 117 118curl -sf -X POST "http://localhost:$PORT/items?$PROFILE_PARAM" \ 119 -H "Authorization: Bearer $API_KEY" \ 120 -H "Content-Type: application/json" \ 121 -H "X-Peek-Datastore-Version: 1" \ 122 -H "X-Peek-Protocol-Version: 1" \ 123 -d '{"type":"url","content":"https://news.ycombinator.com","tags":["news","tech"]}' > /dev/null 124 125echo " Seeded 4 items on server" 126 127# Verify 128ITEM_COUNT=$(curl -sf "http://localhost:$PORT/items?$PROFILE_PARAM" \ 129 -H "Authorization: Bearer $API_KEY" \ 130 -H "X-Peek-Datastore-Version: 1" \ 131 -H "X-Peek-Protocol-Version: 1" | python3 -c "import sys,json; print(len(json.load(sys.stdin)['items']))") 132echo " Verified: $ITEM_COUNT items on server" 133 134# --- Step 4: Find iOS simulator app container --- 135 136echo "" 137echo "Step 4: Configuring iOS simulator..." 138 139APP_GROUP=$(xcrun simctl get_app_container booted com.dietrich.peek-mobile groups 2>/dev/null | grep "group.com.dietrich.peek-mobile" | awk '{print $2}') 140 141if [ -z "$APP_GROUP" ]; then 142 echo " WARNING: iOS app not installed in simulator." 143 echo " Build and run the app once from Xcode, then re-run this script." 144 echo "" 145 echo " Opening Xcode anyway so you can build..." 146 open "$XCODE_PROJECT" 147 echo "" 148 echo " Server is running. Press Ctrl+C to stop." 149 wait "$SERVER_PID" 150 exit 0 151fi 152 153PROFILES_JSON="$APP_GROUP/profiles.json" 154echo " App container: $APP_GROUP" 155 156# --- Step 5: Update profiles.json --- 157 158echo "" 159echo "Step 5: Updating profiles.json..." 160 161python3 << PYEOF 162import json, os 163 164path = "$PROFILES_JSON" 165 166# Read existing config or create minimal one 167config = {"profiles": [], "currentProfileId": ""} 168if os.path.exists(path): 169 try: 170 with open(path) as f: 171 config = json.load(f) 172 except Exception: 173 pass 174 175# Update every profile entry with our test server settings 176for p in config.get("profiles", []): 177 p["server_url"] = "$SERVER_URL" 178 p["api_key"] = "$API_KEY" 179 p["server_profile_id"] = "$SERVER_PROFILE_ID" 180 181# Update global sync settings 182config["sync"] = { 183 "server_url": "$SERVER_URL", 184 "api_key": "$API_KEY", 185 "auto_sync": False 186} 187 188with open(path, "w") as f: 189 json.dump(config, f, indent=2) 190 191n_profiles = len(config.get("profiles", [])) 192current = config.get("currentProfileId", "?") 193print(f" Updated {n_profiles} profile(s)") 194print(f" Current profile: {current}") 195print(f" Server profile ID: $SERVER_PROFILE_ID") 196PYEOF 197 198# --- Step 6: Clear last_sync --- 199 200echo "" 201echo "Step 6: Clearing last_sync timestamps..." 202 203for dbfile in "$APP_GROUP"/peek-*.db; do 204 if [ -f "$dbfile" ]; then 205 sqlite3 "$dbfile" "DELETE FROM settings WHERE key = 'last_sync';" 2>/dev/null || true 206 echo " Cleared last_sync in $(basename "$dbfile")" 207 fi 208done 209 210# --- Step 7: Open Xcode --- 211 212echo "" 213echo "Step 7: Opening Xcode..." 214open "$XCODE_PROJECT" 215 216# --- Summary --- 217 218echo "" 219echo "==========================================" 220echo " Ready for E2E Sync Testing" 221echo "==========================================" 222echo "" 223echo " Server: $SERVER_URL" 224echo " API Key: $API_KEY" 225echo " Server Profile ID: $SERVER_PROFILE_ID" 226echo " Items on server: $ITEM_COUNT" 227echo "" 228echo " Test steps:" 229echo " 1. Build & run in Xcode (Debug, iPhone simulator)" 230echo " 2. Force-quit and relaunch app (to pick up profiles.json)" 231echo " 3. Go to Settings → verify server URL" 232echo " 4. Tap 'Sync All' → should pull $ITEM_COUNT items" 233echo " 5. Add a local item, tap Push → verify on server" 234echo "" 235echo " Verify server items:" 236echo " curl -s 'http://localhost:$PORT/items?profile=$SERVER_PROFILE_ID' \\" 237echo " -H 'Authorization: Bearer $API_KEY' | python3 -m json.tool" 238echo "" 239echo " Server is running. Press Ctrl+C to stop." 240echo "==========================================" 241echo "" 242 243wait "$SERVER_PID"