import WebSocket from 'ws' const C = JSON.parse((await (await fetch('http://127.0.0.1:9223/json/version')).text())) const ws = new WebSocket(C.webSocketDebuggerUrl, { perMessageDeflate: false }) let id = 0; const pending = new Map() const send = (m, p = {}, s) => new Promise((r) => { const i = ++id; pending.set(i, r); ws.send(JSON.stringify({ id: i, method: m, params: p, sessionId: s })) }) ws.on('message', (d) => { const m = JSON.parse(d); if (m.id && pending.has(m.id)) { pending.get(m.id)(m.result); pending.delete(m.id) } }) await new Promise((r) => ws.on('open', r)) const targets = await send('Target.getTargets') const t = targets.targetInfos.find((x) => x.url.includes('dragtest')) const { sessionId } = await send('Target.attachToTarget', { targetId: t.targetId, flatten: true }) const S = (m, p) => send(m, p, sessionId) const sleep = (ms) => new Promise((r) => setTimeout(r, ms)) const ev = async (e) => (await S('Runtime.evaluate', { expression: e, returnByValue: true })).result.value // 长按 habit-2 主体, 分别在 450ms 后检查激活态, 再拖动 const r = JSON.parse(await ev(`JSON.stringify(document.querySelector('[data-habit-id="2"]').getBoundingClientRect())`)) const x = r.left + r.width / 2, y = r.top + r.height / 2 await S('Input.dispatchTouchEvent', { type: 'touchStart', touchPoints: [{ x, y, id: 1 }] }) await sleep(460) console.log('after 460ms class:', await ev(`document.querySelector('[data-habit-id="2"]').className`)) const r3 = JSON.parse(await ev(`JSON.stringify(document.querySelector('[data-habit-id="3"]').getBoundingClientRect())`)) await S('Input.dispatchTouchEvent', { type: 'touchMove', touchPoints: [{ x: r3.left + r3.width / 2, y: r3.top + r3.height - 8, id: 1 }] }) await sleep(80) console.log('class of 3 after move:', await ev(`document.querySelector('[data-habit-id="3"]').className`)) await S('Input.dispatchTouchEvent', { type: 'touchEnd', touchPoints: [] }) await sleep(300) console.log('events:', await ev('window.__ev.join(" | ")')) ws.close()