Files
danyang-match/tests/public-id-web-live.cjs
T

80 lines
4.8 KiB
JavaScript
Raw Normal View History

const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const { chromium } = require(process.env.PLAYWRIGHT_MODULE || 'C:/Users/13070/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright');
const base = process.env.DEMO_BASE_URL || 'http://localhost:6688';
const uuid = /[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}/i;
const code = /^[A-Z]{2}\d{11}$/;
const output = path.resolve(__dirname, '../.mimosa/public-id-page-evidence');
fs.mkdirSync(output, { recursive: true });
(async () => {
assert(process.env.DEMO_OPERATOR_PASSWORD, '请通过环境变量提供演示账号密码,不写入测试文件');
const browser = await chromium.launch({ channel: 'msedge', headless: true });
try {
const context = await browser.newContext({ viewport: { width: 1366, height: 768 } });
const page = await context.newPage();
const errors = [];
page.on('pageerror', error => errors.push(error.message));
await page.goto(`${base}/admin/login`);
await page.getByPlaceholder('请输入用户名').fill(process.env.DEMO_OPERATOR_USERNAME || 'demo_admin');
await page.locator('input[type=password]').fill(process.env.DEMO_OPERATOR_PASSWORD);
await page.getByRole('button', { name: '登录管理后台' }).click();
await page.waitForURL('**/admin/dashboard');
const endpoints = [
'/operator/users?page=1&pageSize=20', '/operator/operators', '/operator/activities',
'/operator/reviews/pending?page=1&pageSize=20', '/operator/risk/reports/pending',
'/operator/matchmaker/management/services', '/operator/matchmaker/recommendations',
'/service-appointments/operator/list', '/referrals/operator/history',
'/activities/operator/activity-interest-summary',
];
let checked = 0;
const results = [];
for (const endpoint of endpoints) {
const response = await context.request.get(`${base}/api/v1${endpoint}`);
assert(response.ok(), `${endpoint}: HTTP ${response.status()}`);
const body = await response.json();
assert(body.success, `${endpoint}: ${body.message}`);
function inspect(value) {
if (!value || typeof value !== 'object') return;
for (const [key, child] of Object.entries(value)) {
if (/DisplayId$|DisplayNumber$|^displayId$|^displayNumber$/.test(key) && child != null) {
assert(code.test(child), `${endpoint}: ${key} 格式错误`); checked++;
}
if (typeof child === 'object') inspect(child);
}
}
inspect(body.data);
results.push({ endpoint, status: response.status() });
}
assert(checked > 0, '接口没有可验收编号');
const pages = [
['users', '用户管理'], ['operators', '系统设置'], ['activities', '活动管理'],
['review', '资料审核'], ['risk/reports', '举报风控'], ['service-appointment', '服务预约'],
['referral', '公益红娘'], ['activities/interests', '匹配管理'], ['matchmaker', '红娘服务'],
];
for (const [route, label] of pages) {
await page.getByText(label, { exact: true }).first().click();
await page.waitForTimeout(300);
await page.waitForLoadState('networkidle');
assert(!page.url().includes('/login'), `${route}: 被退回登录`);
const text = await page.locator('body').innerText();
assert(!uuid.test(text), `${route}: 可见文本仍有 UUID`);
await page.screenshot({ path: path.join(output, `${route.replaceAll('/', '-')}-1366.png`), fullPage: true });
if (route === 'matchmaker') {
await page.getByRole('tab', { name: '联系授权审批' }).click();
await page.waitForLoadState('networkidle');
assert(!uuid.test(await page.locator('body').innerText()), '联系授权仍有 UUID');
await page.screenshot({ path: path.join(output, 'contact-authorization-1366.png'), fullPage: true });
await page.setViewportSize({ width: 1920, height: 1080 });
await page.screenshot({ path: path.join(output, 'contact-authorization-1920.png'), fullPage: true });
}
}
assert.equal(errors.length, 0, `页面运行错误: ${errors.join('; ')}`);
const anonymous = await browser.newContext();
const denied = await anonymous.request.get(`${base}/api/v1/operator/matchmaker/management/services`);
assert([401, 403].includes(denied.status()), '未登录不应读取管理服务');
fs.writeFileSync(path.join(output, 'results.json'), JSON.stringify({ results, checkedDisplayFields: checked, pages: 10, anonymousStatus: denied.status(), errors }, null, 2));
console.log(`PASS: ${results.length} 类真实接口、${checked} 个展示字段、10 个页面/区域、匿名访问拒绝;截图已保存。`);
} finally { await browser.close(); }
})().catch(error => { console.error(error.message); process.exitCode = 1; });