import { readFileSync } from 'node:fs' import { fileURLToPath } from 'node:url' import { dirname, resolve } from 'node:path' import { JSDOM, VirtualConsole } from 'jsdom' const HERE = dirname(fileURLToPath(import.meta.url)) const dist = resolve(HERE, '../../../release/web') const idx = readFileSync(dist + '/index.html', 'utf8') const jsFile = (idx.match(/src="([^"]+\.js)"/) || [])[1].replace(/^.*\//, '') const cssFile = (idx.match(/href="([^"]+\.css)"/) || [])[1].replace(/^.*\//, '') const code = readFileSync(dist + '/assets/' + jsFile, 'utf8') const css = readFileSync(dist + '/assets/' + cssFile, 'utf8') const fleet = readFileSync(resolve(HERE, '_fleet_fixture.json'), 'utf8') const vib = readFileSync(resolve(HERE, '_vibcms_fixture.json'), 'utf8') const dom = new JSDOM(idx.replace('', ''), { url: 'http://127.0.0.1:28084/detail/v2#tab=vibration:portal_cms', runScripts: 'outside-only', pretendToBeVisual: true, virtualConsole: new VirtualConsole() }) const w = dom.window w.fetch = async (u) => { const s = String(u); const body = /fleet/.test(s) ? fleet : (/vibcms/.test(s) ? vib : '{}') return { ok: true, status: 200, json: async () => JSON.parse(body), text: async () => body } } try { w.eval(code) } catch (e) { console.log('EVAL_ERR ' + String(e).slice(0, 140)) } for (let i = 0; i < 20; i++) { await new Promise((r) => setTimeout(r, 400)); if (/振动与 SCADA/.test(w.document.body.textContent || '')) break } const root = w.document.querySelector('#root') || w.document.body const txt = (root.textContent || '').replace(/\s+/g, ' ') const REQ = [ '状态监测 · 振动诊断 (windcms)', '振动与 SCADA 联合分析', '六层模型:数据完整性 → ISO 标量 → 主轴承 rms → 台内自适应基线 → 谱线八闸 → 六枚举裁决。厂商判据与模型融合,机制未定不命名部件。', 'TCM 六采集窗 · 320 万记录 · 160 万谱', '振动分析 · 方法与证据边界', '比较基准', '异常比较先核实基准', '先确认测点、工况、处理链和频带可比,再结合线能量占比与机群分布识别异常。阈值须注明来源、样本和适用范围;本底接近检测下限时,倍数不宜单独解释,诊断仍需补充证据。', '证据关联', '多种特征不等于独立证据', '频谱、标量和时域特征若来自同一波形,应保留共同来源,避免重复计票。跨测点或跨窗口的一致性也需核查共同工况与采集依赖;结论升级应结合独立检修等证据,不以特征数量替代证据质量。', '结论边界', '结论强度与证据匹配', '使用“持续恶化”“单调”或“唯一”等表述前,应明确观察范围、比较对象、样本依赖和对应检验。端段差异不能代替全程趋势证据;复核发现支持不足时,补充验证或降低结论强度,并保留不确定性。', '在线 · 客户版', 'CMS 振动分析工作台', '左栏"需关注 / 未见异常"按台展开四个测点判级;工作台可选机组、测点、分析类即时出图;交互页可提问。演示只停客户版与一次工作台运行。', '新窗口打开 windcms →', '工作台 →', ] const missing = REQ.filter((s) => !txt.includes(s.replace(/"/g, txt.includes('"') ? '"' : '"'))) console.log('REQ_TOTAL ' + REQ.length + ' MISSING ' + missing.length) if (missing.length) console.log('MISSING_ITEMS ' + JSON.stringify(missing.slice(0, 3).map((s) => s.slice(0, 40)))) console.log('LIVE ' + /当前时间窗 · \d|当前时间窗 · 全程|当前时间窗 · /.test(txt) + ' ' + /需关注 \d+ 台/.test(txt)) console.log('IFRAME ' + (root.querySelector('iframe[src*="/cms/"]') ? 'Y' : 'N') + ' LINKS ' + root.querySelectorAll('a[href*="/cms/"]').length) console.log('ELEMENTS ' + root.querySelectorAll('*').length)