Import the pre-repair source tree as the history baseline. Runtime data (data/), virtualenvs, bytecode caches and logs are gitignored so local secrets and user state stay out of the repo.
116 lines
5.4 KiB
Python
116 lines
5.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
离屏验证:思考/压缩气泡内代码朴素渲染(去"紫+边框")+ 正文代码块不受影响
|
|
背景:压缩摘要充满代码,finishTimelineMessage 对全部 pre code 做 hljs 高亮后,
|
|
.code-block-wrapper 的浅色语法色(#a626a4 紫)+ 1px 边框 + 语言栏让定格后的
|
|
压缩气泡观感"紫色带边框"。修复:.think-content 作用域内代码统一朴素灰、
|
|
无边框、无头部、无 min-width;正文气泡代码块保持原样。
|
|
"""
|
|
import os, sys, json
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
os.environ["QT_QPA_PLATFORM"] = "offscreen"
|
|
os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--disable-gpu"
|
|
os.environ.setdefault("HAOCODE_RENDER", "software")
|
|
|
|
from PyQt6.QtWidgets import QApplication # noqa: E402 铁律:WebEngine 先于 QApplication 创建导入
|
|
from PyQt6.QtCore import QTimer, QUrl # noqa: E402
|
|
from PyQt6.QtWebEngineWidgets import QWebEngineView # noqa: E402
|
|
|
|
RESULTS = []
|
|
def check(name, cond, extra=""):
|
|
RESULTS.append((name, bool(cond)))
|
|
print(f"{'PASS' if cond else 'FAIL'} {name} {extra if not cond else ''}", flush=True)
|
|
|
|
GRAY = "rgb(119, 119, 119)" # #777
|
|
PURPLE = "rgb(166, 38, 164)" # #a626a4(正文代码块关键字色,保持)
|
|
|
|
SUMMARY = ("## 摘要\n说明文字。\n```python\nimport os\ndef run():\n return \"x\"\n```\n"
|
|
"另外 `flowkit` 与 `read_file` 是工具名。")
|
|
|
|
TEST_JS = r"""
|
|
(function(){
|
|
try {
|
|
var out = {};
|
|
var SUM = __SUMMARY__;
|
|
|
|
// ---------- 压缩气泡:定格 + finish(触发全量 hljs 兜底)后探测 ----------
|
|
createMessage('m1','assistant','','Assistant');
|
|
compactionStarted('m1','pre_prompt');
|
|
compactionFinished('m1',{summary:SUM,before:100,after:50,duration_ms:10,path:'pre_prompt'});
|
|
finishMessage('m1');
|
|
(function(){
|
|
var block = document.querySelector('#m1 .compaction-think');
|
|
if (!block) { out.m1 = 'NO-BLOCK'; return; }
|
|
var wrap = block.querySelector('.code-block-wrapper');
|
|
if (!wrap) { out.m1 = 'NO-WRAP'; return; }
|
|
var cs = getComputedStyle(wrap);
|
|
out.m1_border = cs.borderTopWidth;
|
|
out.m1_minw = cs.minWidth;
|
|
var hdr = wrap.querySelector('.code-header');
|
|
out.m1_header_display = hdr ? getComputedStyle(hdr).display : 'NO-HDR';
|
|
var kw = wrap.querySelector('.hljs-keyword');
|
|
out.m1_kw_color = kw ? getComputedStyle(kw).color : 'NO-KW-SPAN';
|
|
var pre = wrap.querySelector('pre code');
|
|
out.m1_pre_color = pre ? getComputedStyle(pre).color : 'NO-PRE';
|
|
var ic = block.querySelector('p code');
|
|
out.m1_inline_color = ic ? getComputedStyle(ic).color : 'NO-INLINE';
|
|
})();
|
|
|
|
// ---------- 对照组:正文消息的代码块保持原样(边框+语法色) ----------
|
|
createMessage('m2','assistant','','Assistant');
|
|
appendToken('m2','前文。\n```python\nimport os\ndef run():\n return "x"\n```\n后文。');
|
|
finishMessage('m2');
|
|
(function(){
|
|
var w = document.querySelector('#m2 .code-block-wrapper');
|
|
if (!w) { out.m2 = 'NO-WRAP'; return; }
|
|
var cs = getComputedStyle(w);
|
|
out.m2_border = cs.borderTopWidth;
|
|
var hdr = w.querySelector('.code-header');
|
|
out.m2_header_display = hdr ? getComputedStyle(hdr).display : 'NO-HDR';
|
|
var kw = w.querySelector('.hljs-keyword');
|
|
out.m2_kw_color = kw ? getComputedStyle(kw).color : 'NO-KW-SPAN';
|
|
})();
|
|
|
|
return JSON.stringify(out);
|
|
} catch(e) { return 'JSERR:' + e.message + ' @' + ((e.stack||'').split('\n')[1]||''); }
|
|
})()
|
|
""".replace("__SUMMARY__", json.dumps(SUMMARY, ensure_ascii=False))
|
|
|
|
app = QApplication(sys.argv)
|
|
_js = {"v": None}
|
|
view = QWebEngineView(); view.resize(1000, 700)
|
|
_index = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
|
"..", "ui", "web", "index.html"))
|
|
def _run():
|
|
view.page().runJavaScript(TEST_JS, lambda v: _js.update(v=v))
|
|
view.loadFinished.connect(lambda ok: QTimer.singleShot(1500, _run))
|
|
QTimer.singleShot(9000, app.quit)
|
|
view.load(QUrl.fromLocalFile(_index))
|
|
app.exec()
|
|
|
|
try:
|
|
r = json.loads(_js["v"])
|
|
except Exception:
|
|
r = None
|
|
print(f"DOM 结果解析失败: {_js['v']!r}", flush=True)
|
|
|
|
check("T.DOM 返回", isinstance(r, dict), repr(_js["v"])[:300])
|
|
if isinstance(r, dict):
|
|
# 压缩气泡内:朴素化
|
|
check("T.压缩气泡代码块边框=0", r.get("m1_border") == "0px", r)
|
|
check("T.压缩气泡代码块min-width=0", r.get("m1_minw") == "0px", r)
|
|
check("T.压缩气泡代码头部=隐藏", r.get("m1_header_display") == "none", r)
|
|
check("T.压缩气泡关键字色=#777(去紫)", r.get("m1_kw_color") == GRAY, r.get("m1_kw_color"))
|
|
check("T.压缩气泡pre代码色=#777", r.get("m1_pre_color") == GRAY, r.get("m1_pre_color"))
|
|
check("T.压缩气泡内联代码色=#777(去粉)", r.get("m1_inline_color") == GRAY, r.get("m1_inline_color"))
|
|
# 正文对照:保持原样
|
|
check("T.正文代码块边框=1px(不变)", r.get("m2_border") == "1px", r)
|
|
check("T.正文代码头部=可见(不变)", r.get("m2_header_display") not in ("none", "NO-HDR"), r)
|
|
check("T.正文关键字色=#a626a4(不变)", r.get("m2_kw_color") == PURPLE, r.get("m2_kw_color"))
|
|
|
|
failed = [n for n, ok in RESULTS if not ok]
|
|
print(f"\n===== {len(RESULTS) - len(failed)}/{len(RESULTS)} PASS =====", flush=True)
|
|
print("ALL PASS" if not failed else f"FAILED: {failed}", flush=True)
|
|
sys.exit(0 if not failed else 1)
|