#!/usr/bin/env node /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import { readFile } from 'node:fs/promises' import path from 'node:path' import { fileURLToPath } from 'node:url' const scriptPath = fileURLToPath(import.meta.url) const appRoot = path.resolve(path.dirname(scriptPath), '..') const parityScript = path.join(appRoot, 'scripts/verify-parity.mjs') const browserScript = path.join(appRoot, 'scripts/verify-browser-runtime.mjs') const adminProductScript = path.join(appRoot, 'scripts/verify-admin-product.mjs') const adminSiteScript = path.join(appRoot, 'scripts/verify-admin-site.mjs') const rendererCopyScript = path.join(appRoot, 'scripts/verify-erp-renderer-production-copy.mjs') const packageFile = path.join(appRoot, 'package.json') const source = await readFile(parityScript, 'utf8') const browserSource = await readFile(browserScript, 'utf8') const adminProductSource = await readFile(adminProductScript, 'utf8') const adminSiteSource = await readFile(adminSiteScript, 'utf8') const rendererCopySource = await readFile(rendererCopyScript, 'utf8') const packageJson = JSON.parse(await readFile(packageFile, 'utf8')) function functionBody(name) { const marker = `async function ${name}` const start = source.indexOf(marker) if (start < 0) return '' const braceStart = source.indexOf('{', start) if (braceStart < 0) return '' let depth = 0 for (let index = braceStart; index < source.length; index += 1) { const char = source[index] if (char === '{') depth += 1 if (char === '}') depth -= 1 if (depth === 0) return source.slice(braceStart + 1, index) } return '' } const smokeBody = functionBody('verifyRuntimeSmoke') const pageBody = functionBody('verifyModernUiRuntime') const runtimeBody = functionBody('openModernUiRuntime') function includesAll(content, tokens) { return tokens.every((token) => content.includes(token)) } const checks = [ { id: 'single-browser-runtime', passed: runtimeBody.includes('launchChrome(') && smokeBody.includes('openModernUiRuntime(chrome)') && smokeBody.includes('closeModernUiRuntime(modernRuntime)') }, { id: 'no-per-page-chrome-launch', passed: !pageBody.includes('launchChrome(') && !pageBody.includes('closeChrome(') }, { id: 'cdp-fallback-labelled', passed: source.includes("renderMode: 'chrome-cdp'") }, { id: 'browser-runtime-script', passed: packageJson.scripts?.['verify:browser-runtime'] === 'node scripts/verify-browser-runtime.mjs' && browserSource.includes('launchChrome(chrome') && browserSource.includes('Page.captureScreenshot') && browserSource.includes('browser-runtime-report.json') }, { id: 'browser-runtime-product-anchors', passed: browserSource.includes('document.body.innerText') && includesAll(browserSource, ['ERP 管理员工作台', '今日运营', '待办队列', '最近记录', '快捷动作']) && !browserSource.includes("text.includes('