Files

39 lines
2.8 KiB
JavaScript

/** SHEIN 批量公共库:按 target 直连页面,避免多处 attach(URL) 抢到同一个标签 */
import { CDP } from '/tmp/cdp3.mjs';
export const wait = ms => new Promise(z => setTimeout(z, ms));
export const BASE = process.env.CDP_BASE || 'http://127.0.0.1:9223';
/** 新开一个页面并返回它自己的 CDP 连接(不会被别的同 URL 标签抢走) */
export async function newPage(url = 'about:blank') {
const r = await fetch(`${BASE}/json/new?${encodeURIComponent(url)}`, { method: 'PUT' });
const t = await r.json();
const c = await CDP.connect(t.webSocketDebuggerUrl);
await c.send('Page.enable'); await c.send('Runtime.enable');
c.targetId = t.id; c.pageUrl = url;
return c;
}
export async function closePage(c) { try { await fetch(`${BASE}/json/close/${c.targetId}`); } catch {} try { c.close(); } catch {} }
export async function listPages() { return (await (await fetch(`${BASE}/json/list`)).json()).filter(t => t.type === 'page'); }
/** 关掉所有匹配 url 的旧标签(清理重复 tab,attach(URL) 才不会抢错) */
export async function closePagesByUrl(part) {
const ps = (await listPages()).filter(t => t.url.includes(part));
for (const t of ps) await fetch(`${BASE}/json/close/${t.id}`).catch(() => {});
return ps.length;
}
export const P = `document.querySelector('#app').__vue_app__.config.globalProperties.$pinia`;
export const stub = store => `(()=>{const p=${P};return p._s.get('${store}').$state;})()`;
export async function state(c, store) { return c.evalJS(`(()=>{const p=${P};const s=p._s.get('${store}').$state;return JSON.stringify(s.formState||s);})()`); }
/** 在指定页面上点「保存」并抓 12 秒内的被吞消息 */
export async function installHook(c) {
await c.evalJS(`(()=>{ window.__cap=[];
function wrap(o,n,l){ try{const f=o[n]; o[n]=function(){ try{window.__cap.push(l+': '+[...arguments].map(a=>typeof a==='string'?a:JSON.stringify(a)).join(' ').slice(0,170));}catch(e){} return f.apply(o,arguments);}; }catch(e){} }
try{['error','warning','info','success'].forEach(k=>wrap(MYJ.message,k,'MYJ.'+k));}catch(e){}
try{['error','warning','info','success'].forEach(k=>wrap(antd.message,k,'antd.'+k));}catch(e){} return 1;})()`);
}
export async function readHook(c) { return String(await c.evalJS(`JSON.stringify(window.__cap||[])`)); }
export async function clickByText(c, re, tag = 'button') {
return c.evalJS(`(()=>{const x=[...document.querySelectorAll('${tag}')].filter(e=>e.offsetParent!==null).find(e=>new RegExp(${JSON.stringify(re)}).test((e.innerText||'').trim()));
if(!x) return 'nf'; x.scrollIntoView({block:'center'});
for(const ev of ['mousedown','mouseup','click']) x.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window})); return (x.innerText||'').trim().slice(0,20);})()`);
}