diff --git a/GramAddict/core/behaviors/story_view.py b/GramAddict/core/behaviors/story_view.py index 3c08655..5c896e5 100644 --- a/GramAddict/core/behaviors/story_view.py +++ b/GramAddict/core/behaviors/story_view.py @@ -96,7 +96,8 @@ class StoryViewPlugin(BehaviorPlugin): for i in range(count): sleep(random.uniform(2.0, 5.0) * ctx.sleep_mod) if i < count - 1: - humanized_click(ctx.device, int(w * 0.9), int(h * 0.5), sleep_mod=ctx.sleep_mod) + # Click top-right to avoid 'reply' input fields and most stickers + humanized_click(ctx.device, int(w * 0.85), int(h * 0.25), sleep_mod=ctx.sleep_mod) # Atomic state validation after click xml_dump = ctx.device.dump_hierarchy() if not xml_dump: diff --git a/GramAddict/core/telepathic_engine.py b/GramAddict/core/telepathic_engine.py index c0a722a..180a3bb 100644 --- a/GramAddict/core/telepathic_engine.py +++ b/GramAddict/core/telepathic_engine.py @@ -249,20 +249,18 @@ class TelepathicEngine: if "type" not in intent and "reply" not in intent and "message" not in intent and "search" not in intent: return False - # 0.5 LIKE BUTTON GUARD: Never pick structural traps (audio/trending/share) when trying to like. ZERO-TRUST: NO LOCALIZED STRINGS. - if "like" in intent: - res_id = (node.resource_id or "").lower() - if any(forbidden in res_id for forbidden in [ - "album_art", - "use_in_camera", - "share", - "options", - "menu", - "trending", - "audio", - "add", - "save" - ]): + # 0.5 GLOBAL STRUCTURAL TRAP GUARD: Prevent accidental clicks on dangerous/irrelevant UI traps + # ZERO-TRUST: NO LOCALIZED STRINGS. + res_id = (node.resource_id or "").lower() + + # Avoid clicking on audio/trending/camera elements unless explicitly requested + if any(trap in res_id for trap in ["album_art", "use_in_camera", "trending", "audio"]): + if not any(word in intent for word in ["audio", "trending", "camera"]): + return False + + # Avoid clicking share, save, menu, options unless explicitly requested + if any(trap in res_id for trap in ["share", "save", "options", "menu", "add"]): + if not any(word in intent for word in ["share", "save", "options", "menu", "add"]): return False # 1. Post Username Guard diff --git a/tests/unit/test_telepathic_trap_guard.py b/tests/unit/test_telepathic_trap_guard.py new file mode 100644 index 0000000..11dcc5e --- /dev/null +++ b/tests/unit/test_telepathic_trap_guard.py @@ -0,0 +1,55 @@ +from GramAddict.core.perception.spatial_parser import SpatialNode +from GramAddict.core.telepathic_engine import TelepathicEngine + + +def test_telepathic_engine_global_trap_guard(): + """ + TDD Test: Proves that the TelepathicEngine structurally blocks dangerous UI + elements (like 'audio', 'trending', 'save') regardless of the intent, + unless explicitly requested. + """ + engine = TelepathicEngine() + screen_height = 2400 + + # 1. Setup mock nodes for traps + node_audio = SpatialNode( + bounds=(0, 0, 100, 100), + resource_id="com.instagram.android:id/audio_icon", + class_name="android.widget.ImageView", + ) + + node_save = SpatialNode( + bounds=(0, 100, 100, 200), + resource_id="com.instagram.android:id/save_button", + class_name="android.widget.ImageView", + ) + + node_normal = SpatialNode( + bounds=(0, 200, 100, 300), + resource_id="com.instagram.android:id/zoomable_view_container", + class_name="android.widget.FrameLayout", + ) + + # 2. Test Intents that SHOULD NOT trigger the traps + intent_media = "post media content" + + assert ( + engine._structural_sanity_check(node_audio, intent_media, screen_height) is False + ), "Guard failed: Audio icon allowed for 'post media content'." + assert ( + engine._structural_sanity_check(node_save, intent_media, screen_height) is False + ), "Guard failed: Save button allowed for 'post media content'." + assert ( + engine._structural_sanity_check(node_normal, intent_media, screen_height) is True + ), "Guard failed: Normal node was blocked incorrectly." + + # 3. Test Intents that SHOULD trigger the traps + intent_audio = "trending audio" + intent_save = "save button" + + assert ( + engine._structural_sanity_check(node_audio, intent_audio, screen_height) is True + ), "Guard failed: Audio icon blocked for 'trending audio'." + assert ( + engine._structural_sanity_check(node_save, intent_save, screen_height) is True + ), "Guard failed: Save button blocked for 'save button'."