Files
cmshoppe/tests/test_chrome.py
T

156 lines
5.7 KiB
Python
Raw Normal View History

2026-06-27 09:33:54 +08:00
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)
2026-06-27 10:38:21 +08:00
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)
2026-06-27 09:33:54 +08:00
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()