Deploy to Production / pre-check (push) Successful in 58s
Deploy to Production / build (push) Successful in 4m3s
Deploy to Production / deploy-edgeone (push) Successful in 3m48s
Deploy to Production / finalize (push) Successful in 26s
Deploy to Production / notify-failure (push) Skipped
69 lines
4.0 KiB
JavaScript
69 lines
4.0 KiB
JavaScript
// 在「真实 Artalk 评论区」里逐状态截图:包装页 iframe 里是 /comment.html
|
||
import { spawn } from 'node:child_process';
|
||
import { mkdtempSync, writeFileSync } 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 = 9385;
|
||
const URL_ = process.argv[2] || 'http://127.0.0.1:1313/human-demo.html';
|
||
const OUT = process.argv[3] || 'C:/Users/QunLIn/WorkBuddy/2026-10-02-15-13-24/.workbuddy/artalk-human.png';
|
||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||
const userDir = mkdtempSync(join(tmpdir(), 'cdp-atk-human-'));
|
||
const chrome = spawn(CHROME, ['--headless=new', `--remote-debugging-port=${PORT}`, `--user-data-dir=${userDir}`,
|
||
'--no-first-run', '--disable-gpu', '--window-size=1280,1100', 'about:blank'], { stdio: 'ignore' });
|
||
|
||
const PROBE = "JSON.stringify((()=>{const f=document.getElementById('fr');const d=f&&f.contentDocument;if(!d)return 'no-iframe-doc';const w=d.querySelector('.atk-human-box');const ed=d.querySelector('.atk-main-editor');const r=(e)=>{if(!e)return null;const b=e.getBoundingClientRect();return {x:Math.round(b.x),y:Math.round(b.y),w:Math.round(b.width),h:Math.round(b.height)};};const im=w?w.querySelector('.atk-human-img'):null;return {box:w?{cls:w.className,text:w.textContent.trim(),rect:r(w),imgW:im?im.naturalWidth:0}:null,editor:r(ed),hasHook:typeof f.contentWindow.__humanCheck};})())";
|
||
|
||
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', (e) => { const m = JSON.parse(e.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 = (m, p = {}) => new Promise((res) => { const mid = ++id; pending.set(mid, res); ws.send(JSON.stringify({ id: mid, method: m, params: p })); });
|
||
const ev = async (expr) => {
|
||
const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise: true });
|
||
return r.result?.result?.value ?? r.result?.value ?? null;
|
||
};
|
||
await send('Runtime.enable');
|
||
await send('Page.enable');
|
||
|
||
// 等 iframe 里的评论页 + Artalk 编辑器渲染出来
|
||
for (let i = 0; i < 30; i++) {
|
||
const p = await ev(PROBE);
|
||
if (p && p.indexOf('"editor":{') >= 0) { console.log('— 评论区已就绪(' + (i * 0.5).toFixed(1) + 's)'); break; }
|
||
if (i === 29) console.log('— 评论区未就绪,最后探测:', p);
|
||
await sleep(500);
|
||
}
|
||
await sleep(4500); // 等页面自己的静默验证跑完,避免它的 drop 把我的控件带走
|
||
console.log('— 初始(正常读者):', await ev(PROBE));
|
||
let s = await send('Page.captureScreenshot', { format: 'png' });
|
||
writeFileSync(OUT.replace(/\.png$/, '-none.png'), Buffer.from(s.result.data, 'base64'));
|
||
|
||
await ev("call('click')");
|
||
await sleep(700);
|
||
console.log('— 点一下状态:', await ev(PROBE));
|
||
s = await send('Page.captureScreenshot', { format: 'png' });
|
||
writeFileSync(OUT.replace(/\.png$/, '-click.png'), Buffer.from(s.result.data, 'base64'));
|
||
|
||
await ev("call('captcha')");
|
||
await sleep(2200);
|
||
console.log('— 图形验证码状态:', await ev(PROBE));
|
||
s = await send('Page.captureScreenshot', { format: 'png' });
|
||
writeFileSync(OUT, Buffer.from(s.result.data, 'base64'));
|
||
|
||
await ev("call('run')");
|
||
await sleep(5000);
|
||
console.log('— 真实验证后:', await ev(PROBE));
|
||
s = await send('Page.captureScreenshot', { format: 'png' });
|
||
writeFileSync(OUT.replace(/\.png$/, '-run.png'), Buffer.from(s.result.data, 'base64'));
|
||
|
||
ws.close();
|
||
} catch (e) {
|
||
console.error('ERROR', e.message);
|
||
} finally {
|
||
chrome.kill();
|
||
}
|