Files
my-botty/test/conftest.py
T
alexpolo1andClaude Opus 5 b0d8fdf028 test: block real mouse/keyboard input and window moves during pytest
Many tests run real bot code paths with only the screen faked; those paths end in
win_input's SendInput/SetCursorPos, which act on the focused window. Running the
suite while the bot played on 2026-09-15 sent test clicks and keys into D2R (a
game started with no bot input, the inventory opened, the character got
stranded), and the bot was blamed for getting stuck.

conftest now wraps win_input.user32 so SendInput/SetCursorPos/keybd_event/
mouse_event report success and do nothing, and no-ops utils.misc window
SetWindowPos/SetForegroundWindow/ShowWindow. Verified: a test calling
win_input.mouse_move leaves the real cursor in place; with
BOTTY_TESTS_ALLOW_REAL_INPUT=1 the same test moves it.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-15 18:00:58 +02:00

62 lines
2.5 KiB
Python

# Apply the same SSL cert-store workaround the bot entry points use, so the
# test suite can be collected on Windows machines whose cert store is corrupted.
# Importing the bot code pulls in discord/aiohttp, which calls
# ssl.create_default_context() at import time; a malformed Windows cert raises
# ssl.SSLError: [ASN1: NOT_ENOUGH_DATA]. No-op on a healthy cert store (incl. CI).
import sys
if sys.platform == "win32":
import ssl
_orig_load_default_certs = ssl.SSLContext.load_default_certs
def _safe_load_default_certs(self, purpose=ssl.Purpose.CLIENT_AUTH):
try:
_orig_load_default_certs(self, purpose)
except ssl.SSLError:
try:
import certifi
self.load_verify_locations(certifi.where())
except Exception:
pass
ssl.SSLContext.load_default_certs = _safe_load_default_certs
# Never let a test drive the real desktop.
#
# Many tests run real bot code paths (town maintenance, waypoints, NPC clicks, game
# creation) with only the screen faked. Those paths end in win_input's SendInput /
# SetCursorPos, which act on whatever window has focus. On 2026-09-15 the suite was
# run repeatedly while the bot was playing: D2R received test keystrokes and clicks -
# a game started with no bot input, the inventory opened, and the character ended up
# stranded - and the bot was blamed for "getting stuck".
#
# Block it at the lowest layer so no test can reach the OS, whatever it forgets to
# mock. Set BOTTY_TESTS_ALLOW_REAL_INPUT=1 to opt out for a deliberate live test.
if sys.platform == "win32":
import os
if not os.environ.get("BOTTY_TESTS_ALLOW_REAL_INPUT"):
class _NoRealInputUser32:
"""user32 proxy: input and cursor calls report success and do nothing."""
def __init__(self, real):
self._real = real
def __getattr__(self, name):
if name == "SendInput":
return lambda count, *args: count # "all events inserted"
if name in ("SetCursorPos", "keybd_event", "mouse_event"):
return lambda *args: 1
return getattr(self._real, name)
from input_layer import win_input as _win_input
from utils import misc as _misc
_win_input.user32 = _NoRealInputUser32(_win_input.user32)
# Window moves / focus steals: tests must not reposition or front D2R either.
for _name in ("SetWindowPos", "SetForegroundWindow", "ShowWindow"):
setattr(_misc, _name, lambda *args, **kwargs: None)