Updated speech handling specifically for web.

This commit is contained in:
Storm Dragon
2026-07-24 20:05:54 -04:00
parent f8107f0759
commit 65c0e57aa8
5 changed files with 126 additions and 3 deletions
@@ -17,6 +17,25 @@ from cthulhu import structural_navigation
class StructuralNavigationTableRegressionTests(unittest.TestCase):
def test_object_presentation_marks_keyboard_interruption_as_already_handled(self):
navigator = structural_navigation.StructuralNavigation.__new__(
structural_navigation.StructuralNavigation
)
navigator._script = mock.Mock()
navigator._presentWithSayAll = mock.Mock(return_value=False)
target = object()
with mock.patch.object(structural_navigation.AXEventSynthesizer, "scroll_to_top_edge"):
navigator._presentObject(target, 3, "prior")
navigator._script.presentObject.assert_called_once_with(
target,
offset=3,
priorObj="prior",
interrupt=True,
interrupt_already_handled=True,
)
def test_table_cell_coordinates_do_not_interrupt_cell_contents(self):
navigator = structural_navigation.StructuralNavigation.__new__(
structural_navigation.StructuralNavigation
+72
View File
@@ -278,6 +278,78 @@ class WebPresentationModeSpeechRegressionTests(unittest.TestCase):
testScript.presentMessage.assert_called_once_with(messages.MODE_FOCUS, interrupt=True)
class WebObjectPresentationInterruptionRegressionTests(unittest.TestCase):
@staticmethod
def _make_script():
testScript = web_script.Script.__new__(web_script.Script)
testScript._lastCommandWasCaretNav = False
testScript._loadingDocumentContent = False
testScript.utilities = mock.Mock()
testScript.utilities.inDocumentContent.return_value = True
testScript.utilities.getTable.return_value = None
testScript.utilities.get_objectContentsAtOffset.return_value = ["target"]
testScript.displayContents = mock.Mock()
testScript.speakContents = mock.Mock()
return testScript
def test_keyboard_owned_object_presentation_does_not_interrupt_again(self):
testScript = self._make_script()
target = object()
with (
mock.patch.object(web_script.AXUtilities, "is_document", return_value=False),
mock.patch.object(web_script.AXUtilities, "is_status_bar", return_value=False),
mock.patch.object(web_script.AXUtilities, "is_entry", return_value=False),
):
web_script.Script.presentObject(
testScript,
target,
interrupt=True,
interrupt_already_handled=True,
)
testScript.speakContents.assert_called_once_with(["target"], interrupt=False)
def test_non_keyboard_object_presentation_still_interrupts(self):
testScript = self._make_script()
target = object()
with (
mock.patch.object(web_script.AXUtilities, "is_document", return_value=False),
mock.patch.object(web_script.AXUtilities, "is_status_bar", return_value=False),
mock.patch.object(web_script.AXUtilities, "is_entry", return_value=False),
):
web_script.Script.presentObject(testScript, target, interrupt=True)
testScript.speakContents.assert_called_once_with(["target"], interrupt=True)
def test_web_alert_keeps_non_keyboard_interrupt_request(self):
testScript = self._make_script()
testScript._lastCommandWasStructNav = False
testScript._lastMouseButtonContext = (None, -1)
testScript.lastMouseRoutingTime = 0
testScript.utilities.eventIsBrowserUINoise.return_value = False
testScript.utilities.isLiveRegion.return_value = False
testScript.utilities.getTopLevelDocumentForObject.return_value = "document"
testScript.utilities.isZombie.return_value = False
testScript.utilities.handleEventFromContextReplicant.return_value = False
testScript.utilities.lastQueuedLiveRegion.return_value = None
testScript.presentObject = mock.Mock()
alert = object()
event = mock.Mock(source=object(), any_data=alert)
with (
mock.patch.object(web_script.AXObject, "clear_cache_now"),
mock.patch.object(web_script.AXUtilities, "is_busy", return_value=False),
mock.patch.object(web_script.AXUtilities, "is_alert", return_value=True),
mock.patch.object(web_script.AXUtilities, "get_focused_object", return_value=None),
):
result = web_script.Script.onChildrenAdded(testScript, event)
self.assertTrue(result)
testScript.presentObject.assert_called_once_with(alert, interrupt=True)
class WebFocusSpeechInterruptionRegressionTests(unittest.TestCase):
def _make_script(self):
testScript = web_script.Script.__new__(web_script.Script)