fix(runtime): e2e 发现的 3 个 bug 修复

- download: desktop_download_apps SingleChildScrollView 加 primary:true (Scrollbar 缺 ScrollPosition)
- contact-stores: checkDomainAvailability async 后 setState 加 mounted 保护 (dispose 后 setState)
- buy-service: _loadData 加 data 结构校验 + mounted 保护 (API 400 无效参数时 data 为错误结构 -> RangeError)
This commit is contained in:
2026-08-01 23:20:25 +08:00
parent 6d08db54a5
commit 944493a39b
195 changed files with 362929 additions and 3 deletions

51
tools/e2e/probe2.js Normal file
View File

@@ -0,0 +1,51 @@
// 探测 v2正确加载 + 截图 + 检测 canvaskit 隐藏 input
const { chromium } = require('playwright');
const BASE = 'http://127.0.0.1:8099';
(async () => {
const browser = await chromium.launch({ headless: true });
const ctx = await browser.newContext({ viewport: { width: 1280, height: 900 } });
const page = await ctx.newPage();
const logs = [];
page.on('pageerror', e => logs.push(`[PAGEERROR] ${e.message.slice(0, 120)}`));
console.log('=== 访问 /login (load 模式) ===');
await page.goto(BASE + '/login', { waitUntil: 'load', timeout: 60000 });
await page.waitForTimeout(6000); // 等 Flutter 渲染
await page.screenshot({ path: 'login.png', fullPage: true });
console.log('截图: login.png');
// 检查所有 input含 display:none
const inputs = await page.evaluate(() => {
return [...document.querySelectorAll('input')].map(e => ({
type: e.type,
hidden: e.hidden || e.style.display === 'none' || e.offsetParent === null,
cls: e.className.slice(0, 50),
pos: e.getBoundingClientRect ? (() => { const r = e.getBoundingClientRect(); return {x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height)}; })() : null,
}));
});
console.log(`所有 input (${inputs.length}):`, JSON.stringify(inputs));
// 检查 flt-glass-pane 内的 semantics
const semTextboxes = await page.locator('[role="textbox"]').count();
console.log(`role=textbox: ${semTextboxes}`);
console.log('\n=== 尝试点击用户名输入框区域,看是否触发 input ===');
// canvaskit 点击中间偏上区域(假设用户名框)
await page.mouse.click(640, 400);
await page.waitForTimeout(1500);
const inputsAfterClick = await page.evaluate(() => {
return [...document.querySelectorAll('input')].map(e => ({
hidden: e.hidden || e.style.display === 'none',
pos: (() => { const r = e.getBoundingClientRect(); return {x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width)}; })(),
}));
});
console.log('点击后 input:', JSON.stringify(inputsAfterClick));
console.log('是否有 activeElement 是 input:', await page.evaluate(() => document.activeElement && document.activeElement.tagName));
console.log('\n=== pageerror 日志 ===');
console.log(logs.slice(0, 5).join('\n'));
await browser.close();
})().catch(e => { console.error('失败:', e.message); process.exit(1); });