Files
Jyotisha/frontend/tests/mobile-interaction-contract.test.ts
T
Jesse_ChenandClaude Opus 5 111b4a8455
Independent Staging Quality Gate / validate (push) Failing after 9m25s
Independent Staging Quality Gate / publish (push) Skipped
fix(settings): 弹窗高度补 vh 基线,分区菜单去掉强调条(BUG-698)
设置弹窗的固定高度只用 dvh 写、没有回退。不认识该单位的引擎会把整条
height 与 max-height 作废,盒子退回按内容撑开,于是切分区就跳大小——
这正是 BUG-554 现象的复发,而 BUG-554 的防复发「必须同时声明 width 与
height」只检查声明存不存在,挡不住「写了但没生效」。

实测(Chrome 151,真实产物 CSS + 复刻 DOM,1440×900):dvh 正常时四个
分区恒定 866.80×640px,**事故不复现**;摘掉 dvh 后变成 313/313/378/1130,
宽度不动——与用户描述的形状完全一致。因此机制已证实,但用户当时的浏览器
未定位,BUG-698 记为 investigating 而非 resolved。

附带发现:任务书要求照抄的重复声明式回退 `height: 100vh; height: 100dvh;`
在本仓根本发布不出去——Lightning CSS 会合并同名属性的重复声明只留最后一条,
全仓唯一那处回退(sidebar-provider)在线上早就是死的,还有一条测试专门守着
这个从未发布过的写法。改用 @supports (height: 1dvh):vh 作基线,dvh 作升级。
修复后不支持 dvh 的引擎也收敛到恒定 640px,支持的逐像素无变化。

同轮按产品决策去掉设置分区菜单的左侧/下方强调色条,选中与悬停改用面与
墨色等级区分,不用色相、不用字重。左侧会话列表的色条本轮不动。

- 新增 viewport-unit-fallback-contract(3 条,全文件),三次破坏性验证各自打红
- account-dialog-overlay 新增同尺寸契约与分区菜单契约
- 三条钉死旧 dvh 字面量的既有断言按「原值/新值/原因」更新,均未弱化
- tsc 0 错;lint 0 error / 118 warning(持平);npm test 3346/3300/fail 31,
  失败清单与基线逐字相同;/ 仍 ○ Static;样式 gzip +0.38%;
  快速门 pytest 段 792 passed / 1 skipped / 0 failed

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-16 03:50:38 +00:00

29 lines
1.8 KiB
TypeScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
const css = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
const layout = readFileSync(new URL("../src/app/layout.tsx", import.meta.url), "utf8");
test("mobile login can scroll and keeps the form reachable on a short screen", () => {
// BUG-698: the full-viewport height is now a vh base upgraded inside
// @supports (height: 1dvh). Same shipped behaviour on every engine that knows dvh,
// and a real height on the engines that do not.
const mobileAuth = css.indexOf(".auth-page { height: 100vh; overflow-x: hidden; overflow-y: auto;");
assert.ok(mobileAuth >= 0, "the login page must be the mobile scroll container");
assert.match(css, /@supports \(height: 1dvh\)[^}]*\{[\s\S]*?\.auth-page \{ height: 100dvh; \}/);
assert.match(css.slice(mobileAuth, mobileAuth + 900), /\.auth-shell \{ min-height: 100%; overflow: visible;/);
assert.match(css, /@media \(max-width: 767px\) and \(max-height: 640px\) \{\s*\.auth-story \{ display: none; \}/);
assert.match(layout, /interactiveWidget:\s*"resizes-content"/);
});
test("mobile onboarding does not clip the birth place levels or session history", () => {
assert.match(css, /\.session-nav \{ overflow: visible; \}/);
assert.doesNotMatch(css, /\.session-nav \{ overflow: hidden; \}/);
// The birth place levels portal their popup out of the onboarding card, so an
// ancestor can no longer clip it and only the viewport height still constrains it.
const select = readFileSync(new URL("../src/components/ui/select.tsx", import.meta.url), "utf8");
assert.match(select, /<SelectPrimitive\.Portal>/);
assert.match(css, /\.select-list \{ max-height: min\(288px, 48dvh\) !important; \}/);
});