import os import sys import unittest from pathlib import Path from unittest import mock import gi os.environ.setdefault("GSETTINGS_BACKEND", "memory") gi.require_version("Gdk", "3.0") gi.require_version("Gtk", "3.0") sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) soundGeneratorModule = sys.modules.get("cthulhu.sound_generator") if soundGeneratorModule is not None and not hasattr(soundGeneratorModule, "SoundGenerator"): class _StubSoundGenerator: pass soundGeneratorModule.SoundGenerator = _StubSoundGenerator from cthulhu.scripts.web import script as web_script class WebKeyGrabRegressionTests(unittest.TestCase): def _make_partial_script(self): testScript = web_script.Script.__new__(web_script.Script) testScript._lastCommandWasCaretNav = True testScript._lastCommandWasStructNav = True testScript._lastCommandWasMouseButton = True testScript._lastMouseButtonContext = ("old", 7) testScript._madeFindAnnouncement = True testScript._inFocusMode = True testScript._navSuspended = False testScript.removeKeyGrabs = mock.Mock() testScript.refreshKeyGrabs = mock.Mock() testScript._setNavigationSuspended = mock.Mock() testScript.utilities = mock.Mock() testScript.utilities.isZombie.return_value = False testScript.utilities.isDocument.return_value = False testScript.utilities.getTopLevelDocumentForObject.return_value = None return testScript def test_window_deactivate_does_not_drop_key_grabs(self): testScript = self._make_partial_script() result = web_script.Script.onWindowDeactivated(testScript, mock.Mock()) self.assertFalse(result) self.assertFalse(testScript._lastCommandWasCaretNav) self.assertFalse(testScript._lastCommandWasStructNav) self.assertFalse(testScript._lastCommandWasMouseButton) self.assertEqual(testScript._lastMouseButtonContext, (None, -1)) testScript.removeKeyGrabs.assert_not_called() def test_non_document_focus_change_without_prior_document_does_not_refresh_grabs(self): testScript = self._make_partial_script() oldFocus = object() newFocus = object() with mock.patch("cthulhu.scripts.web.script.AXObject.is_dead", return_value=False): result = web_script.Script.locus_of_focus_changed(testScript, None, oldFocus, newFocus) self.assertFalse(result) self.assertFalse(testScript._madeFindAnnouncement) self.assertFalse(testScript._inFocusMode) testScript._setNavigationSuspended.assert_called_once_with( True, "focus left document content", ) testScript.refreshKeyGrabs.assert_not_called() def test_non_document_focus_change_refreshes_grabs_after_leaving_document(self): testScript = self._make_partial_script() oldFocus = object() newFocus = object() oldDocument = object() testScript.utilities.getTopLevelDocumentForObject.side_effect = ( lambda obj: oldDocument if obj is oldFocus else None ) with mock.patch("cthulhu.scripts.web.script.AXObject.is_dead", return_value=False): result = web_script.Script.locus_of_focus_changed(testScript, None, oldFocus, newFocus) self.assertFalse(result) testScript.refreshKeyGrabs.assert_called_once_with() def test_non_document_focus_change_refreshes_grabs_when_old_focus_missing(self): testScript = self._make_partial_script() newFocus = object() with mock.patch("cthulhu.scripts.web.script.AXObject.is_dead", return_value=False): result = web_script.Script.locus_of_focus_changed(testScript, None, None, newFocus) self.assertFalse(result) testScript.refreshKeyGrabs.assert_called_once_with() if __name__ == "__main__": unittest.main()