test(e2e): mobile 视口测试 (375x812) + 扩展登录态路由

完整测试覆盖 (49 路由, 0 崩溃):
- 公开 desktop: 18/18 ✓
- 登录态 desktop: 17/17 ✓ (含 orderdetail/paynow/view-ticket/ocr-scan/renew-*)
- mobile 视口: 14/14 ✓ (仅 /me 4px RenderFlex 溢出, 无害布局警告)

修复汇总 (本轮自动化发现+修复):
1. download Scrollbar 缺 ScrollPosition -> primary:true
2. contact-stores initState dispose 后 setState -> mounted 保护
3. buy-service onGenerateRoute pathElements 越界 RangeError -> 长度检查
4. add_remove_button/shopping_cart_* cartInfo 误加 ! (nullfix 脚本)
5. checkout table_token(tableNumber!) 无判空
This commit is contained in:
2026-08-03 02:01:17 +08:00
parent 33b54fe454
commit 94138ba7f4
3 changed files with 100 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: true });
const ctx = await browser.newContext({ viewport: { width: 375, height: 812 } });
await ctx.addInitScript(([u,p]) => { localStorage['_test_token'] = u+'|'+p; }, ['6477108200','8818']);
const page = await ctx.newPage();
const logs = [];
page.on('console', m => logs.push(m.text()));
await page.goto('http://127.0.0.1:8099/', { waitUntil: 'load' });
await page.waitForSelector('canvas', { timeout: 90000 });
await page.reload({ waitUntil: 'load' });
await page.waitForTimeout(8000);
await page.goto('http://127.0.0.1:8099/me', { waitUntil: 'load' });
await page.waitForTimeout(6000);
const stacks = logs.filter(l => l.startsWith('CK_STACK:'));
for (const s of stacks) {
const proj = s.match(/flutter_wisetronic\/[^\s]+:\d+/g);
if (proj) console.log('RenderFlex 项目位置:', [...new Set(proj)].slice(0,3));
}
await browser.close();
})();

View File

@@ -16,6 +16,14 @@ const AUTH_ROUTES = [
'/new-ticket/310',
'/change-password',
'/checkout/310',
// 带动态 id无效 id 也应优雅处理不崩)
'/orderdetail/1',
'/paynow/1',
'/view-ticket/1',
'/new-comment/1',
'/ocr-scan',
'/renew-license',
'/renew-minioffice/1',
];
(async () => {

71
tools/e2e/run_mobile.js Normal file
View File

@@ -0,0 +1,71 @@
// Mobile 视口测试width 375触发 ScreenTypeLayout mobile 分支)
const { chromium } = require('playwright');
const BASE = 'http://127.0.0.1:8099';
const ROUTES = [
'/',
'/shop',
'/shop/310',
'/me',
'/orders',
'/checkout/310',
'/blog/310',
'/view-blog/52',
'/download',
'/about-us',
'/contact-us',
'/user-profile',
'/my-addresses/310',
'/new-user',
];
(async () => {
const browser = await chromium.launch({ headless: true });
const ctx = await browser.newContext({ viewport: { width: 375, height: 812 } }); // iPhone 尺寸
await ctx.addInitScript(([u, p]) => { localStorage['_test_token'] = u + '|' + p; }, ['6477108200', '8818']);
const page = await ctx.newPage();
// 先 autologin
page.on('console', () => {});
await page.goto(BASE + '/', { waitUntil: 'load', timeout: 60000 });
await page.waitForSelector('canvas', { timeout: 90000 });
await page.reload({ waitUntil: 'load' });
await page.waitForTimeout(8000);
console.log('Mobile 视口 (375x812) 测试:\n');
const results = [];
for (const route of ROUTES) {
const errors = [];
const stacks = [];
const pageErrs = [];
page.removeAllListeners('console');
page.removeAllListeners('pageerror');
page.on('console', m => {
const t = m.text();
if (t.startsWith('CK_ERROR:')) errors.push(t.slice(0, 100));
if (t.startsWith('CK_STACK:')) {
const proj = t.match(/flutter_wisetronic\/[^\s]+:\d+/g);
if (proj) stacks.push([...new Set(proj)].slice(0, 2));
}
});
page.on('pageerror', e => pageErrs.push(e.message.slice(0, 100)));
try {
await page.goto(BASE + route, { waitUntil: 'load', timeout: 30000 });
await page.waitForTimeout(5000);
} catch (e) { errors.push('GOTO: ' + e.message.slice(0, 70)); }
const allErr = [...errors, ...pageErrs];
const status = allErr.length === 0 ? '✓ OK' : `${allErr.length}`;
console.log(`${status.padEnd(10)} ${route}`);
if (allErr.length) {
console.log(` ${allErr[0].slice(0, 100)}`);
if (stacks.length) console.log(` 位置: ${JSON.stringify(stacks[0])}`);
}
results.push({ route, errors: allErr, stacks });
}
const failed = results.filter(r => r.errors.length > 0);
console.log(`\n========== 汇总 ==========`);
console.log(`${results.length} 路由 (mobile)${failed.length} 个有错误`);
await browser.close();
})();