const targets = await fetch('http://127.0.0.1:9222/json').then(r => r.json());
const target = targets.find(item => item.type === 'page');
if (!target) throw new Error('WebView target not found');
const socket = new WebSocket(target.webSocketDebuggerUrl);
await new Promise((resolve, reject) => {
  socket.addEventListener('open', resolve, {once:true});
  socket.addEventListener('error', reject, {once:true});
});
let id = 0;
const pending = new Map();
socket.addEventListener('message', event => {
  const message = JSON.parse(event.data);
  if (!message.id || !pending.has(message.id)) return;
  const item = pending.get(message.id);
  pending.delete(message.id);
  message.error ? item.reject(new Error(message.error.message)) : item.resolve(message.result);
});
function send(method, params={}) {
  const commandId = ++id;
  socket.send(JSON.stringify({id:commandId, method, params}));
  return new Promise((resolve,reject) => pending.set(commandId,{resolve,reject}));
}
async function evaluate(expression) {
  const response = await send('Runtime.evaluate',{expression,awaitPromise:true,returnByValue:true});
  return response.result.value;
}
await send('Runtime.enable');
await evaluate(`(() => {
  window.__androidTouchEvents = [];
  for (const type of ['pointerdown','touchstart','click']) {
    document.addEventListener(type, event => {
      const target = event.target;
      window.__androidTouchEvents.push({type,tag:target?.tagName||'',cls:target?.className||'',x:event.clientX||0,y:event.clientY||0});
    }, true);
  }
  return true;
})()`);
await new Promise(resolve => setTimeout(resolve, 7000));
const result = await evaluate(`({
  events: window.__androidTouchEvents || [],
  bodyClass: document.body.className,
  menuOpen: !!document.querySelector('.ua-mobile-drawer.is-open,.ua-sidebar.is-open,[data-ua-menu-open="1"]'),
  active: document.activeElement ? {tag:document.activeElement.tagName,cls:document.activeElement.className} : null
})`);
socket.close();
console.log(JSON.stringify(result,null,2));
