diff --git a/GramAddict/core/telepathic_engine.py b/GramAddict/core/telepathic_engine.py
index 4903ee8..a0412ad 100644
--- a/GramAddict/core/telepathic_engine.py
+++ b/GramAddict/core/telepathic_engine.py
@@ -96,7 +96,7 @@ class TelepathicEngine:
device.back()
time.sleep(1.0)
# Re-fetch UI state
- xml_string = device.get_hierarchy()
+ xml_string = device.dump_hierarchy()
if xml_string:
root = self._parser.parse(xml_string)
if root:
diff --git a/tests/e2e/test_keyboard_guard.py b/tests/e2e/test_keyboard_guard.py
index ca57cbd..9191757 100644
--- a/tests/e2e/test_keyboard_guard.py
+++ b/tests/e2e/test_keyboard_guard.py
@@ -195,3 +195,65 @@ class TestKeyboardContaminationGuard:
assert (
"comment_composer" not in (result.resource_id or "").lower()
), "REGRESSION: Resolver picked comment_composer instead of share button!"
+
+
+class TestTelepathicEngineKeyboardGuard:
+ def test_telepathic_engine_auto_dismisses_keyboard(self):
+ """
+ When the keyboard is detected in find_best_node for a non-typing intent,
+ the TelepathicEngine must actively call device.back() and re-fetch the XML
+ via device.dump_hierarchy().
+ """
+ from GramAddict.core.telepathic_engine import TelepathicEngine
+
+ class DummyDeviceForKeyboardTest:
+ def __init__(self):
+ self.back_called = False
+ self.dump_hierarchy_called = False
+ self.xml_without_keyboard = """
+
+
+
+
+
+ """
+
+ def back(self):
+ self.back_called = True
+
+ def dump_hierarchy(self, compressed=False):
+ self.dump_hierarchy_called = True
+ return self.xml_without_keyboard
+
+ mock_device = DummyDeviceForKeyboardTest()
+
+ xml_with_keyboard = """
+
+
+
+
+
+
+
+
+ """
+
+ engine = TelepathicEngine()
+
+ # We pass "tap post username" which is NOT a typing intent.
+ # It should trigger active dismissal.
+ result = engine.find_best_node(
+ xml_string=xml_with_keyboard,
+ intent_description="tap post username",
+ device=mock_device,
+ track=False
+ )
+
+ # Ensure device.back() was called
+ assert mock_device.back_called is True
+ # Ensure device.dump_hierarchy() was called to re-fetch
+ assert mock_device.dump_hierarchy_called is True
+
+ # Result should still resolve to the profile name node
+ assert result is not None
+ assert "row_feed_photo_profile_name" in result.get("id", "")