init
This commit is contained in:
126
tests/e2e/conftest.py
Normal file
126
tests/e2e/conftest.py
Normal file
@@ -0,0 +1,126 @@
|
||||
import sys
|
||||
import os
|
||||
import pytest
|
||||
import time
|
||||
from unittest.mock import MagicMock
|
||||
from GramAddict.core import utils
|
||||
|
||||
# Force Qdrant mocking globally across ALL E2E tests so we never
|
||||
# block on connection refused trying to hit localhost:6344
|
||||
mock_qdrant = MagicMock()
|
||||
|
||||
# Setup correct return types for dimension check warnings in qdrant_memory
|
||||
mock_collection = MagicMock()
|
||||
mock_collection.config.params.vectors.size = 768
|
||||
mock_qdrant.get_collection.return_value = mock_collection
|
||||
|
||||
sys.modules["qdrant_client"].QdrantClient = MagicMock(return_value=mock_qdrant)
|
||||
|
||||
@pytest.fixture
|
||||
def e2e_device_dump_injector():
|
||||
"""
|
||||
Provides a factory to mock device.deviceV2.dump_hierarchy using real XML files.
|
||||
Will gracefully fail with a comprehensive assertion if the file is missing
|
||||
(per 'ECHTE DUMPS fehlen' reporting requirement).
|
||||
"""
|
||||
def _inject_dump(device_mock, xml_filename):
|
||||
fix_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "fixtures")
|
||||
xml_path = os.path.join(fix_dir, xml_filename)
|
||||
|
||||
if not os.path.exists(xml_path):
|
||||
pytest.fail(f"MISSING REAL DUMP: required XML fixture '{xml_filename}' for full E2E workflow testing could not be found at {xml_path}. FAKE_NOTHING policy implies dropping this test execution until it is captured.", pytrace=False)
|
||||
|
||||
with open(xml_path, "r") as f:
|
||||
real_xml = f.read()
|
||||
|
||||
device_mock.deviceV2.dump_hierarchy.return_value = real_xml
|
||||
return real_xml
|
||||
|
||||
return _inject_dump
|
||||
|
||||
@pytest.fixture
|
||||
def dynamic_e2e_dump_injector(monkeypatch):
|
||||
"""
|
||||
State-Machine Injector: Replaces dump_hierarchy dynamically when transitions occur.
|
||||
Validates that the Telepathic Engine's pathfinding truly worked.
|
||||
"""
|
||||
def _inject(device_mock, state_map, initial_xml):
|
||||
fix_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "fixtures")
|
||||
|
||||
def load_xml(filename):
|
||||
path = os.path.join(fix_dir, filename)
|
||||
if not os.path.exists(path):
|
||||
pytest.fail(f"MISSING REAL DUMP: {filename} not found.")
|
||||
with open(path, "r") as f:
|
||||
return f.read()
|
||||
|
||||
device_mock.deviceV2.dump_hierarchy.return_value = load_xml(initial_xml)
|
||||
|
||||
from GramAddict.core.q_nav_graph import QNavGraph
|
||||
original_execute = QNavGraph._execute_transition
|
||||
|
||||
def _mock_execute_transition(nav_self, action, zero_engine):
|
||||
if action == 'tap_post_username':
|
||||
return True
|
||||
|
||||
# Evaluate using the real internal LLM/Keyword logic against the current mock XML!
|
||||
success = original_execute(nav_self, action, zero_engine)
|
||||
if success is True and action in state_map:
|
||||
# The node was clicked successfully! Swap the XML to the target state.
|
||||
device_mock.deviceV2.dump_hierarchy.return_value = load_xml(state_map[action])
|
||||
return success
|
||||
|
||||
monkeypatch.setattr(QNavGraph, "_execute_transition", _mock_execute_transition)
|
||||
|
||||
return _inject
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_all_delays(monkeypatch):
|
||||
"""
|
||||
Strips out all humanized hardware delays specifically for the E2E test suite.
|
||||
Ensures loops evaluate instantly using the injected dumps.
|
||||
"""
|
||||
monkeypatch.setattr(time, "sleep", lambda x: None)
|
||||
monkeypatch.setattr(utils, "random_sleep", lambda *args, **kwargs: None)
|
||||
monkeypatch.setattr(utils, "sleep", lambda x: None)
|
||||
|
||||
# Standardize DarwinEngine across tests to prevent mockup math errors on session end
|
||||
try:
|
||||
from GramAddict.core.darwin_engine import DarwinEngine
|
||||
monkeypatch.setattr(DarwinEngine, "evaluate_session_end", lambda *args, **kwargs: None)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
@pytest.fixture
|
||||
def e2e_configs():
|
||||
import argparse
|
||||
configs = MagicMock()
|
||||
configs.args = argparse.Namespace(
|
||||
username="testuser",
|
||||
device="emulator-5554",
|
||||
app_id="com.instagram.android",
|
||||
debug=True,
|
||||
feed=None,
|
||||
carousel_percentage=0,
|
||||
carousel_count="1",
|
||||
explore=None,
|
||||
reels=None,
|
||||
stories=None,
|
||||
interact_percentage=0,
|
||||
likes_percentage=0,
|
||||
follow_percentage=0,
|
||||
comment_percentage=0,
|
||||
working_hours=[0.0, 24.0],
|
||||
time_delta_session=0,
|
||||
speed_multiplier=1.0,
|
||||
disable_filters=False,
|
||||
interaction_users_amount="1",
|
||||
scrape_profiles=False,
|
||||
disable_ai_messaging=True,
|
||||
total_unfollows_limit=0,
|
||||
ai_telepathic_url="http://localhost",
|
||||
ai_telepathic_model="llama3",
|
||||
ai_condenser_url="http://localhost",
|
||||
ai_condenser_model="llama3"
|
||||
)
|
||||
return configs
|
||||
Reference in New Issue
Block a user