fix(desktop): 开启 pywebview 文件下载 — 备份导出等 <a download> 点击无反应

pywebview 5.0 起默认取消所有文件下载 (Edge WebView2 args.Cancel / WKWebView 不放行 download 策略), 桌面版里配置备份导出、分析菜单导出、回测/台账 CSV 等 <a download> 直链点击后无声无息。在 webview.start() 前显式设置 ALLOW_DOWNLOADS=True; 必须在 start() 前设置否则部分后端不生效, 回归测试以伪造 webview 模块锁定该顺序。浏览器/Docker 部署不受影响。
This commit is contained in:
shy3130
2026-10-28 09:39:50 +08:00
parent 1cb9c7c69c
commit c2c4e41463
2 changed files with 31 additions and 0 deletions
+3
View File
@@ -339,6 +339,9 @@ def _open_window(url: str) -> None:
"""主线程: 用 pywebview 打开桌面窗口。"""
import webview # type: ignore[import-not-found]
# pywebview 5.0 起默认取消所有文件下载 (Edge WebView2 / WKWebView 一致):
# 配置备份导出、回测 CSV 等 <a download> 直链会点击无反应, 必须在 start() 前显式开启。
webview.settings["ALLOW_DOWNLOADS"] = True
window = webview.create_window(
_APP_NAME,
url,
+28
View File
@@ -134,3 +134,31 @@ def test_main_proceeds_when_mining_lock_precheck_conflicts(
assert opened and opened[0].startswith("http://127.0.0.1:")
assert "启动预检" in caplog.text
assert not (tmp_path / ".desktop.lock").exists()
# ---------- _open_window: pywebview 下载启用 ----------
def test_open_window_enables_downloads_before_start(monkeypatch):
"""pywebview 5.0+ 默认取消所有文件下载 (Edge WebView2 / WKWebView 一致) —
必须在 webview.start() 前显式开启 ALLOW_DOWNLOADS, 否则配置备份导出、
回测 CSV 等 <a download> 直链在桌面版点击无反应 (2026-10-27 用户反馈)。"""
import sys
import types
calls: list[str] = []
class _RecordingSettings(dict):
def __setitem__(self, key, value):
calls.append(f"set:{key}={value}")
super().__setitem__(key, value)
fake = types.ModuleType("webview")
fake.settings = _RecordingSettings()
fake.create_window = lambda *a, **k: calls.append("create_window") or object()
fake.start = lambda *a, **k: calls.append("start")
monkeypatch.setitem(sys.modules, "webview", fake)
desktop._open_window("http://127.0.0.1:1")
assert fake.settings.get("ALLOW_DOWNLOADS") is True
assert calls == ["set:ALLOW_DOWNLOADS=True", "create_window", "start"]