58 lines
2.9 KiB
JavaScript
58 lines
2.9 KiB
JavaScript
// 打开友链申请弹窗,测量各元素盒子与计算样式,定位错位/溢出原因
|
|||
|
|
import { spawn } from 'node:child_process';
|
||
|
|
import { mkdtempSync } from 'node:fs';
|
||
|
|
import { tmpdir } from 'node:os';
|
||
|
|
import { join } from 'node:path';
|
||
|
|
|
||
|
|
const CHROME = 'C:/Users/QunLIn/.agent-browser/browsers/chrome-154.0.8037.92/chrome.exe';
|
||
|
|
const PORT = 9355;
|
||
|
|
const URL_ = process.argv[2] || 'http://127.0.0.1:1313/comment.html';
|
||
|
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||
|
|
const userDir = mkdtempSync(join(tmpdir(), 'cdp-modal-'));
|
||
|
|
const chrome = spawn(CHROME, ['--headless=new', `--remote-debugging-port=${PORT}`, `--user-data-dir=${userDir}`,
|
||
|
|
'--no-first-run', '--disable-gpu', '--window-size=1280,1000', 'about:blank'], { stdio: 'ignore' });
|
||
|
|
|
||
|
|
const PROBE = `(() => {
|
||
|
|
const info = (sel) => {
|
||
|
|
const el = document.querySelector(sel);
|
||
|
|
if (!el) return { sel, missing: true };
|
||
|
|
const r = el.getBoundingClientRect();
|
||
|
|
const s = getComputedStyle(el);
|
||
|
|
return {
|
||
|
|
sel,
|
||
|
|
x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height),
|
||
|
|
display: s.display, width: s.width, minWidth: s.minWidth, maxWidth: s.maxWidth,
|
||
|
|
margin: s.margin, padding: s.padding, float: s.float, textAlign: s.textAlign,
|
||
|
|
boxSizing: s.boxSizing, position: s.position, overflowX: s.overflowX,
|
||
|
|
scrollW: el.scrollWidth, clientW: el.clientWidth,
|
||
|
|
};
|
||
|
|
};
|
||
|
|
return JSON.stringify([
|
||
|
|
info('#flApplyMask'), info('#flApplyBox'), info('#flName'), info('#flDesc'), info('#flSubmit'),
|
||
|
|
], null, 1);
|
||
|
|
})()`;
|
||
|
|
|
||
|
|
try {
|
||
|
|
for (let i = 0; i < 40; i++) { try { const r = await fetch(`http://127.0.0.1:${PORT}/json/version`); if (r.ok) break; } catch {} await sleep(300); }
|
||
|
|
const tab = await (await fetch(`http://127.0.0.1:${PORT}/json/new?${encodeURIComponent(URL_)}`, { method: 'PUT' })).json();
|
||
|
|
const ws = new WebSocket(tab.webSocketDebuggerUrl);
|
||
|
|
let id = 0; const pending = new Map();
|
||
|
|
ws.addEventListener('message', (ev) => { const m = JSON.parse(ev.data); if (m.id && pending.has(m.id)) { pending.get(m.id)(m); pending.delete(m.id); } });
|
||
|
|
await new Promise((res) => ws.addEventListener('open', res));
|
||
|
|
const send = (method, params = {}) => new Promise((res) => { const mid = ++id; pending.set(mid, res); ws.send(JSON.stringify({ id: mid, method, params })); });
|
||
|
|
await send('Runtime.enable');
|
||
|
|
await send('Page.enable');
|
||
|
|
await sleep(5000);
|
||
|
|
await send('Runtime.evaluate', { expression: `(window.flApplyOpenModal && window.flApplyOpenModal(), 'opened')`, returnByValue: true });
|
||
|
|
await sleep(600);
|
||
|
|
const r = await send('Runtime.evaluate', { expression: PROBE, returnByValue: true });
|
||
|
|
console.log(r.result.result.value);
|
||
|
|
const shot = await send('Page.captureScreenshot', { format: 'png' });
|
||
|
|
const { writeFileSync } = await import('node:fs');
|
||
|
|
writeFileSync(process.argv[3] || 'modal.png', Buffer.from(shot.result.data, 'base64'));
|
||
|
|
ws.close();
|
||
|
|
} catch (e) {
|
||
|
|
console.error('ERROR', e.message);
|
||
|
|
} finally {
|
||
|
|
chrome.kill();
|
||
|
|
}
|