AI_UIAutomation/scripts/run-ios-adds.sh

155 lines
10 KiB
Bash

#!/bin/bash
# iOS 添加用例批量调试:每个用例前用 WDA terminate/launch 复位到首页,跑完记录结果。
# WDA 须已在 localhost:8100。失败不阻塞,继续下一个。
set -u
cd "$(dirname "$0")/.."
export PLATFORM=ios SOAK_MODE=1
# ★ 对齐 Android:添加阶段**不做首页预检**(Android 从不设 ADD_PRECHECK)。预检会在 iOS 用固定大甩动扫首页、
# 扫不中冲到底,把首页停在底部 → 加后校验从底部向下找不到顶部新设备而假失败。这里强制关闭,不受启动环境影响。
unset ADD_PRECHECK
BUNDLE=com.wohand.wohand
LOG=reports/ios-adds.log
: > "$LOG"
# iOS 阶段起点:清空 .results.json,使 iOS 合并报告(iOSAdds/iOSAll)只含 iOS 结果。
# 否则会 append 到 Android 阶段(run-p0-all 跑完未清)的记录后 → iOSAll 把 Android 的 ble/wifi 记录一并计入(总数虚高,如 267)。
# 仅在此清(iOS 阶段开头);run-ios-controls 不清,以便 iOSAll 含「添加+控制」全程 iOS 结果。
rm -f reports/.results.json
# WDA 健康检查 + 恢复:/status 不通则重启 iproxy 端口转发(覆盖过夜端口转发断开;设备上 WDA 进程仍在即恢复)。
ensure_wda(){
for t in 1 2 3; do
curl -s --max-time 5 http://localhost:8100/status 2>/dev/null | grep -q '"ready"' && return 0
echo "[wda] /status 不通,重启 iproxy(第 $t 次)..." | tee -a "$LOG"
pkill -f "iproxy 8100" 2>/dev/null; sleep 1
local udid; udid=$(idevice_id -l 2>/dev/null | head -1)
nohup iproxy 8100 8100 -u "$udid" >/dev/null 2>&1 &
sleep 5
done
curl -s --max-time 5 http://localhost:8100/status 2>/dev/null | grep -q '"ready"' && return 0
echo "[wda] !! WDA 仍不可达(设备上 WDA 进程可能已退出,需手动重启 WDA)" | tee -a "$LOG"; return 1
}
reset_home(){
ensure_wda || return 1
local sid
sid=$(curl -s --max-time 5 http://localhost:8100/status 2>/dev/null | grep -oE '"sessionId" *: *"[^"]*"' | sed 's/.*"\([^"]*\)"$/\1/')
[ -z "$sid" ] && { echo "[reset] 无 WDA session(WDA 掉了?)" | tee -a "$LOG"; return 1; }
curl -s -X POST "http://localhost:8100/session/$sid/wda/apps/terminate" -H 'Content-Type: application/json' -d "{\"bundleId\":\"$BUNDLE\"}" >/dev/null 2>&1
sleep 1
curl -s -X POST "http://localhost:8100/session/$sid/wda/apps/launch" -H 'Content-Type: application/json' -d "{\"bundleId\":\"$BUNDLE\"}" >/dev/null 2>&1
sleep 3
}
# iOS 全量添加清单(对齐 Android run-p0-all.sh 的 ADD,补 iOS 专属差异):
# - plug 三区域加 PLUG_OTHER_PAIRING=1(iOS 配对后弹 "Add to HomeKit",需点 Other Pairing → Yes 才进配网)
# - WiFi 已统一用 Android 配置(ASUS_30),由 PLATFORM=ios + wifi.config 回落自动生效
# - 锁/摄像头(含 doorbell 视频门铃)添加跳过:iOS 需扫码/校准无方案(控制类已另覆盖)
ADDS=(
# —— BLE(物理接继电器口,不配网) ——
"bot|npx vitest run tests/bot/bot_connect.test.ts"
"meter|npx vitest run tests/meter/meter_connect.test.ts"
"meter_plus|npx vitest run tests/meter/meter_plus_connect.test.ts"
"outdoor_meter|npx vitest run tests/meter/outdoor_meter_connect.test.ts"
"meter_pro|npx vitest run tests/meter/meter_pro_connect.test.ts"
"motion_sensor|npx vitest run tests/sensor/motion_sensor_connect.test.ts"
"presence_sensor|npx vitest run tests/sensor/presence_sensor_connect.test.ts"
"contact_sensor|npx vitest run tests/sensor/contact_sensor_connect.test.ts"
"remote|npx vitest run tests/remote/remote_connect.test.ts"
"find_card|npx vitest run tests/find_card/find_card_connect.test.ts"
"safety_alarm|npx vitest run tests/safety_alarm/safety_alarm_connect.test.ts"
"water_detector|npx vitest run tests/water_detector/water_detector_connect.test.ts"
"weather_station|npx vitest run tests/weather_station/weather_station_connect.test.ts"
"curtain|npx vitest run tests/curtain/curtain_connect.test.ts"
"curtain3_2b|CURTAIN_DEVICE='Curtain3 2B' CURTAIN_CALIBRATE=1 npx vitest run tests/curtain/curtain_connect.test.ts"
"curtain3_2025|CURTAIN_CALIBRATE=1 npx vitest run tests/curtain/curtain3_2025_connect.test.ts"
"keypad_vision|npx vitest run tests/keypad/keypad_vision_connect.test.ts"
"keypad_touch|npx vitest run tests/keypad/keypad_touch_connect.test.ts"
# —— WiFi Hub 类 ——
"hub_mini|npx vitest run tests/hub/hub_connect.test.ts"
"hub_matter|npx vitest run tests/hub/hub_matter_connect.test.ts"
"hub3|npx vitest run tests/hub/hub3_connect.test.ts"
"hub_plus|npx vitest run tests/hub/hub_plus_connect.test.ts"
"relay_switch|npx vitest run tests/switch/relay_switch_connect.test.ts"
"relay_switch_1pm|RELAY_SWITCH_SUBMODEL='Relay Switch 1PM' RELAY_SWITCH_RELAY=relay_switch_1pm RELAY_SWITCH_DEVICE='Relay Switch 1PM' RELAY_SWITCH_PATTERN='Relay Switch 1PM\\s*[0-9A-Za-z]{0,4}' npx vitest run tests/switch/relay_switch_connect.test.ts"
"relay_switch_2pm|RELAY_SWITCH_SUBMODEL='Relay Switch 2PM' RELAY_SWITCH_RELAY=relay_switch_2pm RELAY_SWITCH_DEVICE='Relay Switch 2PM' RELAY_SWITCH_PATTERN='Relay Switch 2PM\\s*[0-9A-Za-z]{0,4}' npx vitest run tests/switch/relay_switch_connect.test.ts"
"aihub|npx vitest run tests/aihub/aihub_connect.test.ts -t '通过BLE添加'"
"ai_art_frame|npx vitest run tests/aihub/ai_art_frame_connect.test.ts"
# —— 插座(iOS 需 Other Pairing → Yes) ——
"plug_jp|PLUG_OTHER_PAIRING=1 PLUG_MINI_CATEGORY='Plug Mini (JP)' PLUG_MINI_RELAY=plug_mini npx vitest run tests/plug/plug_mini_connect.test.ts"
"plug_us|PLUG_OTHER_PAIRING=1 PLUG_MINI_CATEGORY='Plug Mini (US)' PLUG_MINI_RELAY=plug_mini_us npx vitest run tests/plug/plug_mini_connect.test.ts"
"plug_eu|PLUG_OTHER_PAIRING=1 PLUG_MINI_CATEGORY='Plug Mini (EU)' PLUG_MINI_RELAY=plug_mini_eu PLUG_MINI_ONES=332918 npx vitest run tests/plug/plug_mini_connect.test.ts"
# —— 环境类 ——
"humidifier2|npx vitest run tests/humidifier/humidifier2_connect.test.ts"
"air_purifier|npx vitest run tests/air_purifier/air_purifier_connect.test.ts"
# —— 灯类(WiFi 配网 + 浮层) ——
"color_bulb|npx vitest run tests/color_bulb/color_bulb_connect.test.ts"
"ceiling_pro|npx vitest run tests/ceiling_light/ceiling_light_pro_connect.test.ts"
"strip_light|npx vitest run tests/strip_light/strip_light_connect.test.ts"
"floor_lamp|npx vitest run tests/ceiling_light/floor_lamp_connect.test.ts"
"color_floor_lamp|npx vitest run tests/ceiling_light/color_floor_lamp_connect.test.ts"
"neon|npx vitest run tests/strip_light/neon_light_connect.test.ts"
"strip_light_3|npx vitest run tests/strip_light/strip_light_3_connect.test.ts"
"eave_light|npx vitest run tests/ceiling_light/eave_light_connect.test.ts"
"urc|npx vitest run tests/urc/urc_connect.test.ts"
# —— 扫地机 ——
"robot_s1p|npx vitest run tests/robot/robot_s1p_connect.test.ts"
"robot_s10|npx vitest run tests/robot/robot_s10_connect.test.ts"
# —— 摄像头/门铃添加(iOS 需扫码/校准无方案;账号已保留这两设备 → 多为已存在 SKIP,纳入为对齐 Android P0 口径)——
"doorbell|npx vitest run tests/camera/doorbell_connect.test.ts"
"outdoor_ptc|npx vitest run tests/camera/outdoor_ptc_connect.test.ts"
)
echo "===== $(date '+%F %T') iOS 添加批量开始 =====" | tee -a "$LOG"
# ★ 对齐 Android:加之前**先 reset 清空可重加设备**(Android run-p0-all 每轮都清),让首页干净、
# 新设备加完就是顶部那张卡,加后校验首轮即命中(不再依赖在 40+ 设备首页滚动找卡)。默认开;RESET_FIRST=0 可临时关。
if [ "${RESET_FIRST:-1}" = "1" ]; then
echo "[reset-except] 清空可重加设备(白名单与 Android 一致:Lock 6D/Lock Pro DE/Blind Tilt 42 + Cam/Doorbell/Lock Lite)..." | tee -a "$LOG"
reset_home
# 白名单与 Android 完全一致(KEEP_DEVICES + KEEP_KEYWORDS)。keypad 系列**不再入白名单**——
# reset-except 已支持 keypad 单独"进设置页解绑门锁再删(未绑定直接删)",故删非白名单时会连 keypad 一并清掉。
RESET_EXCEPT=1 KEEP_DEVICES="Lock 6D,Lock Pro DE,Blind Tilt 42" KEEP_KEYWORDS="Cam,Doorbell,Lock Lite" PLATFORM=ios npx ts-node scripts/reset-except.ts >> "$LOG" 2>&1 \
&& echo "[reset-except] 完成" | tee -a "$LOG" \
|| echo "[reset-except] 异常(继续跑添加)" | tee -a "$LOG"
fi
# 跑单条添加:复位→执行→打印;含 "✗ [FAIL]" 返回 1(SKIP/已存在不算失败,不重试)。
run_add_one() {
local name="$1" cmd="$2"
echo "----- $(date +%T) [$name] -----" | tee -a "$LOG"
reset_home
eval "$cmd" > /tmp/ios-add-one.log 2>&1
grep -E '✓ \[PASS\]|✗ \[FAIL\]|○ \[SKIP\]|结果:|relay:|未触发|not found|cannot|品类' /tmp/ios-add-one.log | grep -ivE "deprecat" | tail -6 | tee -a "$LOG"
grep -q '✗ \[FAIL\]' /tmp/ios-add-one.log && return 1 || return 0
}
# 添加前置:**确保蓝牙为开**(确定性,非盲翻转)。根因——上一轮控制的盲翻转「设定蓝牙」可能把蓝牙留在关闭态,
# 导致整个添加阶段所有 BLE 设备 "not found in BLE scan" 批量假失败(06-28 即此症)。
echo "[前置] 确保 iOS 蓝牙为开(防 BLE 全扫不到)..." | tee -a "$LOG"
npx ts-node scripts/ios-ensure-bt-on.ts 2>&1 | grep -iE "iOS-BT|蓝牙|ERR" | tee -a "$LOG" || echo "[前置] 确保蓝牙异常(继续)" | tee -a "$LOG"
FAILED=()
for entry in "${ADDS[@]}"; do
name="${entry%%|*}"; cmd="${entry#*|}"
run_add_one "$name" "$cmd" || FAILED+=("$entry")
done
# 添加失败重试(对齐 Android run-p0-all:每个最多重试 2 次;WiFi 抖动/BLE 扫描漏常一次过)
if [ ${#FAILED[@]} -gt 0 ]; then
echo "===== iOS 添加失败 ${#FAILED[@]} 个,重试(每个最多2次)=====" | tee -a "$LOG"
for entry in "${FAILED[@]}"; do
name="${entry%%|*}"; cmd="${entry#*|}"; ok=0
for att in 1 2; do
echo "--- 重试 $att/2: [$name] ---" | tee -a "$LOG"
if run_add_one "${name}-retry${att}" "$cmd"; then ok=1; echo "[ADD-RETRY-OK] $name" | tee -a "$LOG"; break; fi
done
[ $ok -eq 0 ] && echo "[ADD-RETRY-GIVEUP] $name" | tee -a "$LOG"
done
fi
echo "===== $(date '+%F %T') 完成 =====" | tee -a "$LOG"
# 汇总逐用例 HTML 报告(SOAK_MODE 已累计到 reports/.results.json)
TS=$(date +%Y%m%d-%H%M%S)
npx ts-node scripts/gen-combined.ts "iOSAdds_$TS" >> "$LOG" 2>&1 \
&& echo "逐用例报告: reports/iOSAdds_${TS}_*.html" | tee -a "$LOG" \
|| echo "报告生成失败(见 $LOG)" | tee -a "$LOG"