Files
cthulhu/tests/test_event_manager_relevance_gate_regressions.py

194 lines
9.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import sys
import types
import unittest
from pathlib import Path
from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from cthulhu import cthulhu_state
stubCthulhu = types.ModuleType("cthulhu.cthulhu")
stubCthulhu.cthulhuApp = mock.Mock()
sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu)
from cthulhu import event_manager
class FakeEvent:
def __init__(self, event_type, source="same", detail1=0, detail2=0, any_data=None):
self.type = event_type
self.source = source
self.detail1 = detail1
self.detail2 = detail2
self.any_data = any_data
class EventManagerRelevanceGateRegressionTests(unittest.TestCase):
def setUp(self) -> None:
self.listener = mock.Mock()
self.listenerPatch = mock.patch.object(
event_manager.Atspi.EventListener,
"new",
return_value=self.listener,
)
self.listenerPatch.start()
self.addCleanup(self.listenerPatch.stop)
self.steamAppPatch = mock.patch.object(event_manager.EventManager, "_isSteamApp", return_value=False)
self.steamNotificationPatch = mock.patch.object(
event_manager.EventManager,
"_isSteamNotificationEvent",
return_value=False,
)
self.steamAppPatch.start()
self.steamNotificationPatch.start()
self.addCleanup(self.steamAppPatch.stop)
self.addCleanup(self.steamNotificationPatch.stop)
self.originalActiveScript = cthulhu_state.activeScript
self.originalLocusOfFocus = cthulhu_state.locusOfFocus
self.addCleanup(self._restore_state)
self.manager = event_manager.EventManager(mock.Mock(), asyncMode=False)
self.manager._active = True
cthulhu_state.activeScript = None
cthulhu_state.locusOfFocus = None
def _restore_state(self) -> None:
cthulhu_state.activeScript = self.originalActiveScript
cthulhu_state.locusOfFocus = self.originalLocusOfFocus
def test_unfocused_web_link_name_change_is_dropped_when_focus_is_stable_elsewhere(self) -> None:
app = object()
focus = object()
source = object()
event = FakeEvent(
"object:property-change:accessible-name",
source=source,
any_data="Diablo II: Resurrected Infernal Edition $39.99",
)
cthulhu_state.activeScript = mock.Mock(app=app)
cthulhu_state.locusOfFocus = focus
with (
mock.patch.object(event_manager.debug, "printMessage"),
mock.patch.object(event_manager.debug, "printTokens"),
mock.patch.object(event_manager.debug, "print_log"),
mock.patch.object(event_manager.AXObject, "get_application", return_value=app),
mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"),
mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.LINK),
mock.patch.object(event_manager.AXObject, "is_dead", return_value=False),
mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_focused", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False),
):
self.assertTrue(self.manager._ignore(event))
def test_focused_web_link_name_change_is_kept(self) -> None:
app = object()
source = object()
event = FakeEvent("object:property-change:accessible-name", source=source, any_data="Cookie Clicker")
cthulhu_state.activeScript = mock.Mock(app=app)
cthulhu_state.locusOfFocus = source
with (
mock.patch.object(event_manager.debug, "printMessage"),
mock.patch.object(event_manager.debug, "printTokens"),
mock.patch.object(event_manager.debug, "print_log"),
mock.patch.object(event_manager.AXObject, "get_application", return_value=app),
mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"),
mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.LINK),
mock.patch.object(event_manager.AXObject, "is_dead", return_value=False),
mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_focused", return_value=True),
mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False),
):
self.assertFalse(self.manager._ignore(event))
def test_live_region_name_change_is_kept_even_when_unfocused(self) -> None:
app = object()
focus = object()
source = object()
event = FakeEvent("object:property-change:accessible-name", source=source, any_data="sale updated")
cthulhu_state.activeScript = mock.Mock(app=app)
cthulhu_state.locusOfFocus = focus
def get_attribute(obj, name):
if name == "live":
return "polite"
return ""
with (
mock.patch.object(event_manager.debug, "printMessage"),
mock.patch.object(event_manager.debug, "printTokens"),
mock.patch.object(event_manager.debug, "print_log"),
mock.patch.object(event_manager.AXObject, "get_application", return_value=app),
mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"),
mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.LINK),
mock.patch.object(event_manager.AXObject, "get_attribute", side_effect=get_attribute),
mock.patch.object(event_manager.AXObject, "is_dead", return_value=False),
mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_focused", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False),
):
self.assertFalse(self.manager._ignore(event))
def test_unfocused_focus_loss_is_dropped_when_focus_is_stable_elsewhere(self) -> None:
app = object()
focus = object()
source = object()
event = FakeEvent("object:state-changed:focused", source=source, detail1=0)
cthulhu_state.activeScript = mock.Mock(app=app)
cthulhu_state.locusOfFocus = focus
with (
mock.patch.object(event_manager.debug, "printMessage"),
mock.patch.object(event_manager.debug, "printTokens"),
mock.patch.object(event_manager.debug, "print_log"),
mock.patch.object(event_manager.AXObject, "get_application", return_value=app),
mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"),
mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.LINK),
mock.patch.object(event_manager.AXObject, "is_dead", return_value=False),
mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False),
):
self.assertTrue(self.manager._ignore(event))
def test_repeated_web_children_changed_burst_is_collapsed(self) -> None:
app = object()
focus = object()
source = object()
firstEvent = FakeEvent("object:children-changed:add", source=source, any_data=object())
secondEvent = FakeEvent("object:children-changed:add", source=source, any_data=object())
cthulhu_state.activeScript = mock.Mock(app=app)
cthulhu_state.locusOfFocus = focus
with (
mock.patch.object(event_manager.time, "monotonic", side_effect=[100.0, 100.05]),
mock.patch.object(event_manager.debug, "printMessage"),
mock.patch.object(event_manager.debug, "printTokens"),
mock.patch.object(event_manager.debug, "print_log"),
mock.patch.object(event_manager.AXObject, "get_application", return_value=app),
mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"),
mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.SECTION),
mock.patch.object(event_manager.AXObject, "is_dead", return_value=False),
mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False),
mock.patch.object(event_manager.AXUtilities, "manages_descendants", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_image", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_menu_item", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False),
mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False),
):
self.assertFalse(self.manager._ignore(firstEvent))
self.assertTrue(self.manager._ignore(secondEvent))