fix(island): 失焦收起加 500ms 宽限期 + 冒烟不再改写班级码(打包产物验证稳定)

- 灵动岛窗口 blur 处理增加 BLUR_GRACE_MS = 500:激活后 500ms 内的失焦一律忽略。
  实机/打包产物上偶发"刚展开就被系统换前台造成的 blur 立刻收起",
  表现为"下课后自动弹出通知详情"变成 pill(截图比例也随之异常);
  宽限期后该用例稳定,且"点击屏幕任意位置收起"用例(展开后等 700ms 再触发 blur)仍正常。
- 桌面冒烟准备班级账号时**永不修改班级码**(只按需重置密码):
  班级码是给学生用的凭据,不应被测试工具改写;实测产物验证不再依赖固定班级码。

验证: verify:desktop 53/53(首轮)与 47/47(二次启动)全绿
This commit is contained in:
LoveChengke committed 2026-09-12 17:48:32 +08:00
1 parent a5c717e33e
commit 93447922dc
2 files changed
+21 -8

No files matched your search

+6 -6
View File
@@ -83,17 +83,17 @@ async function provisionClassAccount() {
const target = classes[0]; const target = classes[0];
if (!target) return null; if (!target) return null;
const code = target.code || `SMOKE${Math.floor(Math.random() * 9000 + 1000)}`; // 冒烟**永不修改班级码**(班级码是给学生用的,不应被测试工具改写):
// 只有"现有班级码 + 目标密码登录失败"时才重置密码,班级码原样保留。
const code = target.code;
if (!code) return null;
// 若现有班级码 + 目标密码已经能登录,就直接复用,避免每次冒烟都改密码
if (target.code) {
const probe = await fetch(`${base}/auth/class-login`, { const probe = await fetch(`${base}/auth/class-login`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code: target.code, password }), body: JSON.stringify({ code, password }),
}); });
if (probe.ok) return { code: target.code, password, className: target.name }; if (probe.ok) return { code, password, className: target.name };
}
const patchResponse = await fetch(`${base}/classes/${target.id}/class-account`, { const patchResponse = await fetch(`${base}/classes/${target.id}/class-account`, {
method: 'PATCH', method: 'PATCH',
+15 -2
View File
@@ -204,12 +204,20 @@ class IslandController {
/** /**
* 点击屏幕任意位置收起:展开态临时允许窗口获得焦点, * 点击屏幕任意位置收起:展开态临时允许窗口获得焦点,
* 用户点到别处(桌面、浏览器、其他应用)时窗口失焦 → 回缩为胶囊。 * 用户点到别处(桌面、浏览器、其他应用)时窗口失焦 → 回缩为胶囊。
*
* 加一个宽限期(`BLUR_GRACE_MS`):刚弹出/刚激活的瞬间,系统可能因为换前台窗口、
* 抢焦点或截图等操作立刻产生一次 blur,此时收起会让"刚弹出的通知一闪就没了"。
* 只在激活满 500ms 后才把 blur 当作"用户点击了别处"。
*/ */
win.on('blur', () => { win.on('blur', () => {
if (this.state.mode === 'expanded' && !this.state.inClass) { if (this.state.mode !== 'expanded' || this.state.inClass) return;
const sinceActivated = Date.now() - this.state.updatedAt;
if (sinceActivated < BLUR_GRACE_MS) {
logger.info(`灵动岛:忽略激活后 ${sinceActivated}ms 内的失焦(宽限期内不收起)`);
return;
}
logger.info('灵动岛:点击屏幕其他位置,回缩为胶囊'); logger.info('灵动岛:点击屏幕其他位置,回缩为胶囊');
this.handleAction({ action: 'collapse' }); this.handleAction({ action: 'collapse' });
}
}); });
this.win = win; this.win = win;
@@ -922,6 +930,11 @@ const ISLAND_MARGIN = 8;
* 空闲细缝等"极小形态"必须以此作为高度下限,否则断言与真实窗口会不一致。 * 空闲细缝等"极小形态"必须以此作为高度下限,否则断言与真实窗口会不一致。
*/ */
const MIN_WINDOW_HEIGHT = 36; const MIN_WINDOW_HEIGHT = 36;
/**
* 失焦收起的宽限期:刚展开的 500ms 内忽略 blur(避免"刚弹出就被抢焦点导致瞬间收起")。
* 冒烟里"点击屏幕任意位置收起"的用例会在展开后等待约 700ms 再触发 blur,仍能正常验证收起。
*/
const BLUR_GRACE_MS = 500;
interface Bounds { interface Bounds {
x: number; x: number;