update
This commit is contained in:
49
tests/integration/test_navigation_resilience.py
Normal file
49
tests/integration/test_navigation_resilience.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from GramAddict.core.q_nav_graph import QNavGraph
|
||||
|
||||
@pytest.fixture
|
||||
def mock_device():
|
||||
device = MagicMock()
|
||||
device.app_id = "com.instagram.android"
|
||||
device.deviceV2 = MagicMock()
|
||||
# Mock current app to be Instagram
|
||||
device._get_current_app.return_value = "com.instagram.android"
|
||||
return device
|
||||
|
||||
def test_recovery_from_dm_view(mock_device):
|
||||
"""
|
||||
Test Case: Bot starts in a DM thread (UNKNOWN state).
|
||||
It wants to go to ReelsFeed.
|
||||
Global nav bar is missing in DMs, so first 'tap_reels_tab' will fail.
|
||||
Bot should then press 'back' and try again.
|
||||
"""
|
||||
nav = QNavGraph(mock_device)
|
||||
nav.current_state = "UNKNOWN"
|
||||
|
||||
# Sequence of dumps (exactly 1 per failed attempt, 2 per successful attempt):
|
||||
# 1. Attempt 1 (DM): _execute_transition calls dump(1) -> find_best_node returns None -> Returns False
|
||||
# 2. QNavGraph calls press("back")
|
||||
# 3. Attempt 2 (Home): _execute_transition calls dump(2) -> find_best_node returns Node
|
||||
# 4. _execute_transition calls dump(3) -> post-click != pre-click -> Returns True
|
||||
|
||||
mock_device.deviceV2.dump_hierarchy.side_effect = ["<DM />", "<Home />", "<ReelsFeed />"]
|
||||
|
||||
zero_engine = MagicMock()
|
||||
|
||||
with patch('GramAddict.core.telepathic_engine.TelepathicEngine.get_instance') as mock_get:
|
||||
mock_engine = MagicMock()
|
||||
mock_get.return_value = mock_engine
|
||||
|
||||
# 1st call: DM (nothing found)
|
||||
# 2nd call: Home (reels tab found)
|
||||
mock_engine.find_best_node.side_effect = [None, {"x": 50, "y": 50, "score": 0.95, "source": "keyword"}]
|
||||
|
||||
success = nav.navigate_to("ReelsFeed", zero_engine)
|
||||
|
||||
# Verify
|
||||
assert success is True
|
||||
assert nav.current_state == "ReelsFeed"
|
||||
# Verify recovery was triggered
|
||||
mock_device.deviceV2.press.assert_called_with("back")
|
||||
assert mock_device.deviceV2.dump_hierarchy.call_count == 3
|
||||
@@ -41,6 +41,8 @@ class TestNodeExtraction:
|
||||
"""
|
||||
engine = TelepathicEngine()
|
||||
xml = load_fixture("home_feed_with_ad.xml")
|
||||
|
||||
# Test raw extraction (backward compatibility)
|
||||
nodes = engine._extract_semantic_nodes(xml)
|
||||
|
||||
like_nodes = [n for n in nodes if "row feed button like" in n["semantic_string"]]
|
||||
|
||||
Reference in New Issue
Block a user