import { createDriver } from '../drivers/factory'; // 从**当前 meter 详情页**调试:齿轮→Settings→Alert Conditions→Calibration,每步 dump+判定。 // 不走首页(用户已手动在详情页;createSession 复用 session+activateApp 不重启)。 const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); async function main() { process.env.PLATFORM = 'ios'; const driver: any = createDriver(); await driver.createSession(); const src = () => driver.getSource().catch(() => ''); const has = async (re: RegExp) => re.test(await src()); const labels = async (tag: string) => { const s = await src(); console.log(`[${tag}] ${[...new Set((s.match(/(?:name|label)="[^"]{1,40}"/g) || []))].slice(0, 25).join(' | ')}`); }; try { console.log('=== 当前页 ==='); await labels('current'); console.log('在详情页?', await has(/Store Data in Cloud|Hr\.|Environmental|Temperature/)); // 1) 齿轮:右上 y<130、x 最大的窄 Button const btns: string[] = await driver.findElementsRaw('predicate string', 'type == "XCUIElementTypeButton"').catch(() => []); let gear: string | null = null, bx = -1; const cand: string[] = []; for (const b of btns) { const r = await driver.getElementRect(b).catch(() => null); const n = await driver.getElementAttribute(b, 'name').catch(() => ''); if (r) { cand.push(`"${n}"@(${Math.round(r.x)},${Math.round(r.y)})w${Math.round(r.width)}`); if (r.y < 130 && r.width < 80 && r.x > bx) { bx = r.x; gear = b; } } } console.log('顶栏候选按钮:', cand.filter((c) => /,(?:[0-9]|1[01][0-9]|12[0-9])\)/.test(c)).join(' | ')); if (!gear) { console.log('!! 没找到齿轮'); return; } await driver.tapElement(gear); await sleep(2500); console.log('点齿轮后 → Settings?', await has(/Alert Conditions|Calibration/)); await labels('齿轮后'); // 2) Alert Conditions const alert = await driver.findElementRaw('predicate string', 'name == "Alert Conditions" OR label == "Alert Conditions"').catch(() => null); if (alert) { await driver.tapElement(alert); await sleep(3500); console.log('进 Alert 页?', await has(/Temperature Alert|VPD Alert/)); // 轮询 Switch(BLE 连上才渲染) let sws: string[] = []; for (let t = 0; t < 8 && !sws.length; t++) { sws = await driver.findElementsRaw('predicate string', 'type == "XCUIElementTypeSwitch"').catch(() => []); if (!sws.length) await sleep(1500); } console.log(`Alert 页 Switch 数=${sws.length}`); if (sws.length) { const v = await driver.getElementAttribute(sws[0], 'value').catch(() => ''); console.log(`首个 Switch(温度报警) value=${v}`); } await driver.tap(33, 69); await sleep(2000); // 返回 Settings } else console.log('!! Settings 页找不到 Alert Conditions'); // 3) Calibration const cal = await driver.findElementRaw('predicate string', 'name == "Calibration" OR label == "Calibration"').catch(() => null); if (cal) { await driver.tapElement(cal); await sleep(3500); console.log('进 Calibration 页?', await has(/Calibrate the (Temperature|Humidity)/)); console.log('Calibration BLE 加载失败?', await has(/Failed to load|try again/)); await labels('Calibration'); // 进温度校准 offset,dump 控件 const t = await driver.findElementRaw('predicate string', 'name CONTAINS "Calibrate the Temperature"').catch(() => null); if (t) { await driver.tapElement(t); await sleep(2500); const nx = await driver.findElementRaw('predicate string', 'name == "Next" OR label == "Next"').catch(() => null); if (nx) { await driver.tapElement(nx); await sleep(2500); } await labels('温度offset页'); const obtns: string[] = await driver.findElementsRaw('predicate string', 'type == "XCUIElementTypeButton"').catch(() => []); const oinfo: string[] = []; for (const b of obtns) { const r = await driver.getElementRect(b).catch(() => null); const n = await driver.getElementAttribute(b, 'name').catch(() => ''); if (r) oinfo.push(`"${n}"@(${Math.round(r.x)},${Math.round(r.y)})w${Math.round(r.width)}`); } console.log('offset 页按钮:', oinfo.join(' | ')); const s = await src(); const m = s.match(/(?:name|label|value)="([+\-]?\d+(?:\.\d+)?\s*(?:°C|℃|%))"/); console.log('offset 值:', m ? m[1] : '(未找到)'); } } else console.log('!! Settings 页找不到 Calibration'); } catch (e: any) { console.log('异常:', e.message); } // 不 destroySession(避免影响你的手动会话) } main();