| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- #!/usr/bin/env node
- /**
- * 成员管理全链路验证(2026-11-10)
- *
- * 云函数已部署,这里验证真实数据流:
- * ① 列表加载出真实成员
- * ② 搜索能过滤
- * ③ 分页条工作
- * ④ 编辑弹窗能打开并回填
- * ⑤ 删除确认弹窗能打开(**不实际执行删除**)
- */
- import { chromium } from 'playwright';
- import { mkdir } from 'node:fs/promises';
- import { dirname, resolve } from 'node:path';
- import { fileURLToPath } from 'node:url';
- const here = dirname(fileURLToPath(import.meta.url));
- const outDir = resolve(here, '..', 'test-results', 'admin-users-e2e');
- const BASE = process.env.BASE_URL || 'http://127.0.0.1:4300';
- await mkdir(outDir, { recursive: true });
- const browser = await chromium.launch({ channel: 'chrome' });
- const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
- const errors = [];
- page.on('pageerror', (e) => errors.push(String(e)));
- const results = [];
- await page.goto(`${BASE}/desktop/admin/users`, { waitUntil: 'domcontentloaded' });
- await page.waitForTimeout(7000);
- await page.screenshot({ path: `${outDir}/1-list.png` });
- // ① 真实数据
- const rows = await page.locator('.tbody .tr').count();
- const isEmpty = await page.locator('ui-empty', { hasText: '加载失败' }).count();
- results.push(['列表加载出真实成员', rows > 0 && isEmpty === 0, `rows=${rows} error=${isEmpty}`]);
- const totalText = await page.locator('.total').innerText().catch(() => '');
- results.push(['显示总人数', /共\s*\d+\s*人/.test(totalText), totalText]);
- // ② 搜索
- const firstMobile = await page.locator('.tbody .tr .mono').first().innerText().catch(() => '');
- if (firstMobile && firstMobile !== '—') {
- await page.locator('input.search').fill(firstMobile);
- await page.locator('ui-button', { hasText: '搜索' }).first().click();
- await page.waitForTimeout(2500);
- const afterSearch = await page.locator('.tbody .tr').count();
- await page.screenshot({ path: `${outDir}/2-search.png` });
- results.push(['搜索能过滤', afterSearch >= 1 && afterSearch <= rows, `before=${rows} after=${afterSearch}`]);
- // 还原
- await page.locator('input.search').fill('');
- await page.locator('ui-button', { hasText: '搜索' }).first().click();
- await page.waitForTimeout(2000);
- } else {
- results.push(['搜索能过滤', false, '取不到手机号列']);
- }
- // ③ 分页
- const pagerCount = await page.locator('.pager ui-pagination').count();
- results.push(['有分页条', pagerCount > 0, `pager=${pagerCount}`]);
- // ④ 编辑弹窗
- const editBtn = page.locator('ui-button', { hasText: '编辑' }).first();
- if (await editBtn.count()) {
- await editBtn.click();
- await page.waitForTimeout(900);
- const dialogTitle = await page.locator('ui-modal', { hasText: '编辑成员' }).count();
- const nickInput = await page.locator('ui-modal input').first().inputValue().catch(() => '');
- await page.screenshot({ path: `${outDir}/3-edit-modal.png` });
- results.push(['编辑弹窗打开并回填', dialogTitle > 0, `title=${dialogTitle} nick=${nickInput}`]);
- // 关闭
- await page.locator('ui-modal ui-button', { hasText: '取消' }).first().click().catch(() => {});
- await page.waitForTimeout(600);
- } else {
- results.push(['编辑弹窗打开并回填', false, '没有编辑按钮']);
- }
- // ⑤ 删除二次确认(只打开,不确认)
- const delBtn = page.locator('ui-button', { hasText: '移除' }).first();
- if (await delBtn.count()) {
- await delBtn.click();
- await page.waitForTimeout(900);
- const confirm = await page.locator('ui-modal', { hasText: '确认移除' }).count();
- await page.screenshot({ path: `${outDir}/4-remove-confirm.png` });
- results.push(['移除走二次确认', confirm > 0, `confirm=${confirm}`]);
- await page.locator('ui-modal ui-button', { hasText: '取消' }).first().click().catch(() => {});
- } else {
- results.push(['移除走二次确认', false, '没有移除按钮']);
- }
- // 汇总
- let pass = true;
- console.log('\n=== 结果 ===');
- for (const [name, ok, detail] of results) {
- if (!ok) pass = false;
- console.log(`${ok ? '✓' : '✗'} ${name} (${detail})`);
- }
- if (errors.length) {
- pass = false;
- console.log('页面错误:', errors.slice(0, 3).join(' | '));
- }
- console.log(`\n${pass ? '✓ 全部通过' : '✗ 存在失败项'}`);
- await browser.close();
- process.exit(pass ? 0 : 1);
|