Files
cmshoppe/tests/test_chrome.py
T
chengma 742193607b feat: 完成账号桌面快捷方式
- 新增 chrome.create_shortcut 使用 PowerShell WScript.Shell 生成 .lnk

- 快捷方式参数复用 Chrome 启动参数,包含调试端口、allow-origins 和账号 user-data-dir

- 在账号服务层和 Tab④ 增加快捷方式入口,不包含密码或密钥

- 补充 chrome/accounts/gui 测试并同步任务、API、路由、当前状态和进度文档
2026-06-27 10:38:21 +08:00

156 lines
5.7 KiB
Python

import json
import os
import socket
import sys
import threading
import unittest
from http.server import BaseHTTPRequestHandler, HTTPServer
from types import SimpleNamespace
from unittest import mock
sys.path.insert(0, os.path.dirname(__file__))
from _helpers import TempDirMixin
from app import chrome
from app import config as account_config
class JsonVersionHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path != "/json/version":
self.send_response(404)
self.end_headers()
return
body = json.dumps({"Browser": "Chrome/Test"}).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, format, *args):
return
class ChromeTests(TempDirMixin, unittest.TestCase):
def start_json_version_server(self):
server = HTTPServer(("127.0.0.1", 0), JsonVersionHandler)
thread = threading.Thread(target=server.serve_forever)
thread.daemon = True
thread.start()
self.addCleanup(server.server_close)
self.addCleanup(server.shutdown)
self.addCleanup(thread.join, 2)
return server.server_address[1]
def unused_port(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("127.0.0.1", 0))
port = sock.getsockname()[1]
sock.close()
return port
def test_build_launch_args_includes_required_flags(self):
with self.make_temp_dir() as temp_dir:
cfg = {
"chrome_path": r"C:\Program Files\Google\Chrome\Application\chrome.exe",
"user_data_root": temp_dir,
}
account = {"alias": "alias", "debug_port": "9222"}
args = chrome.build_launch_args(account, config=cfg)
slug = account_config.make_slug("alias")
user_data_dir = os.path.abspath(os.path.join(temp_dir, slug))
self.assertEqual(cfg["chrome_path"], args[0])
self.assertIn("--remote-debugging-port=9222", args)
self.assertIn("--remote-allow-origins=*", args)
self.assertIn(f"--user-data-dir={user_data_dir}", args)
self.assertTrue(os.path.isdir(user_data_dir))
self.assert_removed(temp_dir)
def test_build_launch_args_accepts_account_object_user_data_dir(self):
with self.make_temp_dir() as temp_dir:
user_data_dir = os.path.join(temp_dir, "custom")
account = SimpleNamespace(debug_port=9333, user_data_dir=user_data_dir)
args = chrome.build_launch_args(
account,
config={"chrome_path": "chrome.exe"},
)
self.assertIn("--remote-debugging-port=9333", args)
self.assertIn(f"--user-data-dir={os.path.abspath(user_data_dir)}", args)
self.assertTrue(os.path.isdir(user_data_dir))
self.assert_removed(temp_dir)
def test_build_launch_args_rejects_invalid_account(self):
with self.assertRaises(chrome.ChromeLaunchError):
chrome.build_launch_args(
{"alias": "alias", "debug_port": 0},
config={"chrome_path": "chrome.exe"},
)
def test_launch_chrome_uses_subprocess_popen(self):
with self.make_temp_dir() as temp_dir:
account = {"alias": "alias", "debug_port": 9222}
cfg = {"chrome_path": "chrome.exe", "user_data_root": temp_dir}
process = object()
with mock.patch("app.chrome.subprocess.Popen", return_value=process) as popen:
result = chrome.launch_chrome(account, config=cfg)
self.assertIs(process, result)
popen.assert_called_once()
args = popen.call_args[0][0]
self.assertEqual("chrome.exe", args[0])
self.assertIn("--remote-debugging-port=9222", args)
self.assertIn("--remote-allow-origins=*", args)
self.assert_removed(temp_dir)
def test_create_shortcut_writes_lnk_with_required_chrome_arguments(self):
with self.make_temp_dir() as temp_dir:
chrome_path = os.path.join(temp_dir, "Chrome App", "chrome.exe")
shortcut_path = os.path.join(temp_dir, "Desktop", "主店.lnk")
account = {
"alias": "alias",
"debug_port": 9222,
"user_data_dir": os.path.join(temp_dir, "profile with space"),
}
cfg = {"chrome_path": chrome_path}
with mock.patch("app.chrome.subprocess.run") as run:
result = chrome.create_shortcut(
account,
shortcut_path=shortcut_path,
config=cfg,
)
self.assertEqual(os.path.abspath(shortcut_path), result)
run.assert_called_once()
command = run.call_args[0][0]
self.assertEqual("powershell", command[0])
script = command[-1]
self.assertIn("$shortcut.TargetPath", script)
self.assertIn(chrome_path, script)
self.assertIn("--remote-debugging-port=9222", script)
self.assertIn("--remote-allow-origins=*", script)
self.assertIn("--user-data-dir=", script)
self.assertIn("profile with space", script)
self.assert_removed(temp_dir)
def test_is_running_and_wait_debug_ready(self):
port = self.start_json_version_server()
self.assertTrue(chrome.is_running(port))
self.assertTrue(chrome.wait_debug_ready(port, timeout=1))
self.assertFalse(chrome.is_running(self.unused_port()))
if __name__ == "__main__":
unittest.main()