You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
5.1 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// company-api-test/index.html 自动化验收测试
const { chromium } = require("playwright");
const path = require("path");
const OUT = (n) => path.join(require("os").tmpdir(), n);
(async () => {
const errors = [];
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
page.on("pageerror", (e) => errors.push(String(e)));
page.on("console", (m) => {
// 故意触发的 405/404 网络日志不算页面错误
if (m.type() === "error" && !/Failed to load resource/.test(m.text())) errors.push(m.text());
});
await page.goto("http://localhost:9527");
await page.waitForLoadState("networkidle");
// 1) 主链路:公网 api-cx 实名查询(真实网络请求)
const idv = await page.inputValue("#idPlain");
if (idv !== "430703198610010059") throw new Error("默认身份证明文不对: " + idv);
const preview = await page.textContent("#cxPreview");
if (!preview.includes("sign=") || !preview.includes("zjhm=J4jfHM")) throw new Error("签名 URL 预览异常: " + preview);
await page.click("#btnSendCx");
await page.waitForTimeout(4000);
const chipCode = await page.textContent("#chipCode");
if (!chipCode.includes("0")) throw new Error("respCode 应为 0: " + chipCode);
const meta = await page.textContent("#metaLine");
if (!meta.includes("430703198610010059")) throw new Error("台账 meta 应含身份证明文");
const emptyMsg = await page.textContent("#ledgerBody");
if (!emptyMsg.includes("暂无企业数据")) throw new Error("应显示空数据提示: " + emptyMsg);
await page.screenshot({ path: OUT("v2_1_cx_query.png"), fullPage: true });
// 2) 校验密文解密(后端解密回显 → 证明 AES 正确)
await page.click("#btnVerifyZjhm");
await page.waitForTimeout(3000);
const ledger = await page.textContent("#ledgerBody");
if (!ledger.includes("430703198610010059")) throw new Error("校验台账应含明文");
if (!ledger.includes("一致")) throw new Error("校验结论应为一致");
await page.screenshot({ path: OUT("v2_2_verify.png"), fullPage: true });
// 3) JSON 标签页
await page.click('.tab[data-tab="json"]');
const j = await page.textContent("#jsonScreen");
if (!j.includes("respCode")) throw new Error("JSON 视图应含 respCode");
// 4) 次链路tax-appoint 离线示例
await page.check("#mockToggle");
await page.click("#btnSend");
await page.waitForTimeout(400);
const rows = await page.locator("#ledgerBody tr").count();
if (rows !== 2) throw new Error("示例模式应渲染 2 行, 实际 " + rows);
if (!(await page.textContent("#ledgerBody")).includes("义乌市万竹贤口腔诊所")) throw new Error("示例台账缺少企业");
const t2 = await page.textContent("#ledgerBody");
if (t2.includes("330725198202084328")) throw new Error("脱敏开启时不应显示完整证件号");
// 5) 关闭脱敏 → 完整证件号
await page.uncheck("#maskToggle");
await page.waitForTimeout(200);
if (!(await page.textContent("#ledgerBody")).includes("330725198202084328")) throw new Error("关闭脱敏后应显示完整证件号");
await page.check("#maskToggle");
// 6) tax-appoint 真实请求(经代理 → 405→ 友好错误面板
await page.uncheck("#mockToggle");
await page.click("#btnSameOrigin");
await page.click("#btnSend");
await page.waitForTimeout(2500);
if (!(await page.locator("#stageError").isVisible())) throw new Error("后端不可用时应展示错误面板");
const chipHttp = await page.textContent("#chipHttp");
if (!/405|502/.test(chipHttp)) throw new Error("状态条应显示 405/502: " + chipHttp);
await page.screenshot({ path: OUT("v2_3_ta_error.png"), fullPage: true });
// 7) 历史
if ((await page.locator(".h-item").count()) < 2) throw new Error("应有 ≥2 条历史记录");
// 8) AES 工具
await page.fill("#aesPlain", "330725198202084328");
await page.click("#btnAesEnc");
const enc = await page.inputValue("#aesCipherOut");
if (enc !== "MoV2Ra2USY/6tc6b9xQXZkuEA+I6X3u90CSNgvFqzlE=") throw new Error("AES 加密与文档示例不一致: " + enc);
await page.fill("#aesCipherIn", enc);
await page.click("#btnAesDec");
if ((await page.inputValue("#aesPlainOut")) !== "330725198202084328") throw new Error("AES 解密不一致");
await page.fill("#aesKey", "shortkey");
await page.click("#btnAesEnc");
if (!/错误/.test(await page.inputValue("#aesCipherOut"))) throw new Error("非法密钥应提示错误");
await page.fill("#aesKey", "Gi4swf3llyafmsuK");
// 9) 密文一键填入 zjhm
await page.click("#btnAesEnc");
await page.click("#btnFillZjhm");
if ((await page.inputValue("#zjhm")) !== "MoV2Ra2USY/6tc6b9xQXZkuEA+I6X3u90CSNgvFqzlE=") throw new Error("填入 zjhm 失败");
await page.screenshot({ path: OUT("v2_4_final.png"), fullPage: true });
await browser.close();
if (errors.length) {
console.log("CONSOLE/PAGE ERRORS:");
errors.forEach((e) => console.log(" -", e.slice(0, 300)));
process.exit(1);
}
console.log("ALL CHECKS PASSED");
})().catch((e) => { console.error("FAIL:", e.message); process.exit(1); });