Files
OpenClaw Agent 2329955e32 baseline: 薪酬逻辑收口到 shared/payroll.js 后的当前全量状态
这是第一个包含完整工作区的提交,也是后续「拆 SFC / 上 Vite」的回滚基线。

此前的提交均为 index.html 单文件历史快照,由 .bak 文件重建。

当前状态(提交前已实测):
- index.html 内联薪酬算法已删除,改调 WHTPayroll
- shared/payroll.js 为唯一薪酬实现,浏览器与 Node 共用
- 对外接口未变:aggregateMonth / isCutEdge / payDayKind 等保留同名薄包装

未入库内容见 .gitignore:依赖、Chrome 验证 profile、验证截图、
运行时 sqlite 数据与日志、时间戳备份、.trash。
2026-09-05 14:35:00 +08:00

65 lines
2.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 专门验刷新循环的防线。
//
// 模拟最刁的一种故障:fetch 能拿到完整文件(所以重试判定为"成功"),
// 但 <script src> 始终起不来(插件拦截、CSP、解析失败都可能这样)。
// 这时每次 reload 都会重新触发一次"成功→reload",若没有计数器就是无限刷新,
// 用户连导出备份都点不到。
//
// 用 resourceType 区分:script 全部 abort,fetch 全部放行。
const puppeteer = require('/root/.openclaw/workspace/web_tasks/node_modules/puppeteer');
const fs = require('fs');
const URL = 'http://127.0.0.1:9522/';
const VUE = 'vue.global.prod.js';
const PROFILE = '/tmp/wht-loop-guard';
(async () => {
fs.rmSync(PROFILE, { recursive: true, force: true });
const browser = await puppeteer.launch({
executablePath: '/usr/bin/chromium',
headless: 'new',
userDataDir: PROFILE,
args: ['--no-sandbox', '--disable-gpu', '--disable-dev-shm-usage']
});
const page = await browser.newPage();
await page.setViewport({ width: 390, height: 844, isMobile: true, deviceScaleFactor: 2 });
let scriptBlocked = 0, fetchAllowed = 0, docLoads = 0;
await page.setRequestInterception(true);
page.on('request', r => {
const isVue = r.url().includes(VUE);
if (isVue && r.resourceType() === 'script') { scriptBlocked++; return r.abort('failed'); }
if (isVue) fetchAllowed++;
if (r.resourceType() === 'document') docLoads++;
r.continue();
});
await page.goto(URL, { waitUntil: 'domcontentloaded', timeout: 30000 });
await new Promise(r => setTimeout(r, 12000)); // 留足时间,若会循环这里必然刷很多次
const s = await page.evaluate(() => ({
cardShown: !document.getElementById('boot-fail')?.hidden,
title: document.getElementById('boot-title')?.textContent,
detail: document.getElementById('boot-detail')?.textContent,
btnUsable: document.getElementById('boot-retry')?.hidden === false,
retryCount: sessionStorage.getItem('wht_boot_retry')
}));
// 文档加载次数 = 1 次首访 + 最多 MAX_AUTO(2) 次 reload
const capped = docLoads <= 3;
const settled = s.cardShown && s.btnUsable;
const pass = capped && settled;
console.log(`[${pass ? 'PASS' : 'FAIL'}] 刷新循环防线`);
console.log(` 文档加载 ${docLoads} 次(上限应为 3 = 首访 + 2 次自动 reload)`);
console.log(` script 被拦 ${scriptBlocked} 次 / fetch 放行 ${fetchAllowed} 次`);
console.log(` 重试计数=${s.retryCount} 卡片显示=${s.cardShown} 按钮可点=${s.btnUsable}`);
console.log(` 标题="${s.title}"`);
console.log(` 详情="${s.detail}"`);
await page.screenshot({ path: '/root/.openclaw/workspace/work-hours-tracker/png/retry_loopguard.png' });
await browser.close();
fs.rmSync(PROFILE, { recursive: true, force: true });
process.exit(pass ? 0 : 1);
})().catch(e => { console.error('FAIL', e); process.exit(1); });