fix(navigation): enforce HD Map pre-checks and resolve test inconsistencies
This commit is contained in:
@@ -163,17 +163,134 @@ def isolated_screen_memory():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def e2e_device_dump_injector(request):
|
||||
"""Provides a factory to mock device.dump_hierarchy using real XML files."""
|
||||
if request.config.getoption("--live"):
|
||||
return lambda *args, **kwargs: None
|
||||
def make_real_device_with_xml(monkeypatch):
|
||||
"""Provides a factory to create a REAL DeviceFacade but mocked uiautomator2."""
|
||||
|
||||
def _inject_dump(device_mock, xml_filename):
|
||||
real_xml = load_fixture_xml(xml_filename)
|
||||
device_mock.dump_hierarchy.return_value = real_xml
|
||||
return real_xml
|
||||
def _create(xml_content):
|
||||
import GramAddict.core.device_facade as device_facade
|
||||
from GramAddict.core.device_facade import DeviceFacade
|
||||
|
||||
return _inject_dump
|
||||
class MockU2Watcher:
|
||||
def when(self, xpath=None, **kwargs):
|
||||
return self
|
||||
|
||||
def click(self):
|
||||
return self
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
class MockU2Device:
|
||||
def __init__(self, xml):
|
||||
self.xml = xml
|
||||
self.info = {"sdkInt": 30, "displaySizeDpX": 400, "displayWidth": 1080, "screenOn": True}
|
||||
self.settings = {}
|
||||
|
||||
def dump_hierarchy(self, compressed=False):
|
||||
if isinstance(self.xml, list):
|
||||
res = self.xml.pop(0) if self.xml else ""
|
||||
return res
|
||||
return self.xml
|
||||
|
||||
def screenshot(self):
|
||||
from PIL import Image
|
||||
|
||||
return Image.new("RGB", (1080, 1920), color="black")
|
||||
|
||||
def app_current(self):
|
||||
return {"package": "com.instagram.android"}
|
||||
|
||||
def shell(self, cmd):
|
||||
pass
|
||||
|
||||
def press(self, key):
|
||||
pass
|
||||
|
||||
def watcher(self, name):
|
||||
return MockU2Watcher()
|
||||
|
||||
def app_start(self, package_name, use_monkey=False):
|
||||
pass
|
||||
|
||||
def mock_connect(*args, **kwargs):
|
||||
return MockU2Device(xml_content)
|
||||
|
||||
monkeypatch.setattr(device_facade.u2, "connect", mock_connect)
|
||||
|
||||
# Now we instantiate the REAL DeviceFacade!
|
||||
device = DeviceFacade("test_device", "com.instagram.android", None)
|
||||
return device
|
||||
|
||||
return _create
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def make_real_device_with_image(monkeypatch):
|
||||
"""Provides a factory to create a REAL DeviceFacade but mocked uiautomator2 returning a real image."""
|
||||
|
||||
def _create(img_path, xml_content=None):
|
||||
from PIL import Image
|
||||
|
||||
import GramAddict.core.device_facade as device_facade
|
||||
from GramAddict.core.device_facade import DeviceFacade
|
||||
|
||||
if isinstance(img_path, str):
|
||||
img = Image.open(img_path)
|
||||
else:
|
||||
img = img_path
|
||||
|
||||
class MockU2Watcher:
|
||||
def when(self, xpath=None, **kwargs):
|
||||
return self
|
||||
|
||||
def click(self):
|
||||
return self
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
class MockU2Device:
|
||||
def __init__(self, img, xml):
|
||||
self.img = img
|
||||
self.xml = xml
|
||||
self.info = {"sdkInt": 30, "displaySizeDpX": 400, "displayWidth": 1080, "screenOn": True}
|
||||
self.settings = {}
|
||||
|
||||
def dump_hierarchy(self, compressed=False):
|
||||
if self.xml:
|
||||
if isinstance(self.xml, list):
|
||||
res = self.xml.pop(0) if self.xml else ""
|
||||
return res
|
||||
return self.xml
|
||||
return ""
|
||||
|
||||
def screenshot(self):
|
||||
return self.img
|
||||
|
||||
def app_current(self):
|
||||
return {"package": "com.instagram.android"}
|
||||
|
||||
def shell(self, cmd):
|
||||
pass
|
||||
|
||||
def press(self, key):
|
||||
pass
|
||||
|
||||
def watcher(self, name):
|
||||
return MockU2Watcher()
|
||||
|
||||
def app_start(self, package_name, use_monkey=False):
|
||||
pass
|
||||
|
||||
def mock_connect(*args, **kwargs):
|
||||
return MockU2Device(img, xml_content)
|
||||
|
||||
monkeypatch.setattr(device_facade.u2, "connect", mock_connect)
|
||||
|
||||
device = DeviceFacade("test_device", "com.instagram.android", None)
|
||||
return device
|
||||
|
||||
return _create
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════
|
||||
@@ -224,30 +341,6 @@ def mock_all_delays(monkeypatch, request):
|
||||
_patch_module_delays(monkeypatch, "GramAddict.core.device_facade", money_sleep, random_sleep)
|
||||
_patch_module_delays(monkeypatch, "GramAddict.core.darwin_engine", money_sleep, random_sleep)
|
||||
|
||||
# Standardize DarwinEngine 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
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════
|
||||
# Identity & Account Guard
|
||||
# ═══════════════════════════════════════════════════════
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_identity_guard(monkeypatch):
|
||||
import GramAddict.core.bot_flow
|
||||
|
||||
monkeypatch.setattr(
|
||||
GramAddict.core.bot_flow,
|
||||
"verify_and_switch_account",
|
||||
lambda *args, **kwargs: True,
|
||||
)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════
|
||||
# E2E Configs — Standardized Test Configuration
|
||||
@@ -291,33 +384,31 @@ def e2e_configs():
|
||||
visual_vibe_check_percentage=0,
|
||||
)
|
||||
|
||||
class DummyConfig:
|
||||
def __init__(self, args_ns):
|
||||
self.args = args_ns
|
||||
self.username = "testuser"
|
||||
self.plugins = {}
|
||||
from GramAddict.core.config import Config
|
||||
|
||||
def get_plugin_config(self, plugin_name):
|
||||
mapping = {
|
||||
"likes": {"count": self.args.likes_count, "percentage": self.args.likes_percentage},
|
||||
"comment": {
|
||||
"percentage": self.args.comment_percentage,
|
||||
"dry_run": self.args.dry_run_comments,
|
||||
},
|
||||
"follow": {"percentage": self.args.follow_percentage},
|
||||
"stories": {
|
||||
"count": self.args.stories_count,
|
||||
"percentage": self.args.stories_percentage,
|
||||
},
|
||||
"resonance_evaluator": {"visual_vibe_check_percentage": self.args.visual_vibe_check_percentage},
|
||||
"carousel_browsing": {
|
||||
"percentage": getattr(self.args, "carousel_percentage", 0),
|
||||
"count": getattr(self.args, "carousel_count", "1"),
|
||||
},
|
||||
}
|
||||
return mapping.get(plugin_name, {})
|
||||
|
||||
return DummyConfig(args)
|
||||
config = Config(first_run=True)
|
||||
config.args = args
|
||||
config.username = "testuser"
|
||||
config.config = {
|
||||
"plugins": {
|
||||
"likes": {"count": args.likes_count, "percentage": args.likes_percentage},
|
||||
"comment": {
|
||||
"percentage": args.comment_percentage,
|
||||
"dry_run": args.dry_run_comments,
|
||||
},
|
||||
"follow": {"percentage": args.follow_percentage},
|
||||
"stories": {
|
||||
"count": args.stories_count,
|
||||
"percentage": args.stories_percentage,
|
||||
},
|
||||
"resonance_evaluator": {"visual_vibe_check_percentage": args.visual_vibe_check_percentage},
|
||||
"carousel_browsing": {
|
||||
"percentage": getattr(args, "carousel_percentage", 0),
|
||||
"count": getattr(args, "carousel_count", "1"),
|
||||
},
|
||||
}
|
||||
}
|
||||
return config
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user