After a fierce battle, Firefox support should be better, not perfect, but better.
This commit is contained in:
@@ -10,6 +10,9 @@ os.environ.setdefault("GSETTINGS_BACKEND", "memory")
|
||||
|
||||
gi.require_version("Gdk", "3.0")
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version("Atspi", "2.0")
|
||||
|
||||
from gi.repository import Atspi
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
||||
|
||||
@@ -23,6 +26,7 @@ if soundGeneratorModule is not None and not hasattr(soundGeneratorModule, "Sound
|
||||
from cthulhu import messages
|
||||
from cthulhu.scripts.web import script as web_script
|
||||
from cthulhu.scripts.web import script_utilities as web_script_utilities
|
||||
from cthulhu.scripts.toolkits.Gecko import script_utilities as gecko_script_utilities
|
||||
|
||||
|
||||
class WebKeyGrabRegressionTests(unittest.TestCase):
|
||||
@@ -716,6 +720,124 @@ class WebContentCacheRegressionTests(unittest.TestCase):
|
||||
utilities._cleanupContexts.assert_called_once_with()
|
||||
|
||||
|
||||
class WebSkipSpaceCaretNavigationRegressionTests(unittest.TestCase):
|
||||
def _make_utilities(self):
|
||||
utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities)
|
||||
utilities.getCaretContext = mock.Mock(return_value=(None, -1))
|
||||
utilities.treatAsTextObject = mock.Mock(return_value=True)
|
||||
return utilities
|
||||
|
||||
def test_next_context_does_not_skip_named_whole_object_as_space(self):
|
||||
utilities = self._make_utilities()
|
||||
start = object()
|
||||
wholeObject = object()
|
||||
after = object()
|
||||
utilities.treatAsTextObject.return_value = False
|
||||
utilities.findNextCaretInOrder = mock.Mock(
|
||||
side_effect=[(wholeObject, 0), (after, 0)]
|
||||
)
|
||||
|
||||
with mock.patch.object(
|
||||
web_script_utilities.AXText,
|
||||
"get_character_at_offset",
|
||||
return_value=(" ", 0, 1),
|
||||
) as getCharacter:
|
||||
result = web_script_utilities.Utilities.nextContext(
|
||||
utilities,
|
||||
start,
|
||||
0,
|
||||
skipSpace=True,
|
||||
)
|
||||
|
||||
self.assertEqual(result, (wholeObject, 0))
|
||||
utilities.treatAsTextObject.assert_called_once_with(wholeObject)
|
||||
getCharacter.assert_not_called()
|
||||
utilities.findNextCaretInOrder.assert_called_once_with(start, 0)
|
||||
|
||||
def test_previous_context_does_not_skip_named_whole_object_as_space(self):
|
||||
utilities = self._make_utilities()
|
||||
start = object()
|
||||
wholeObject = object()
|
||||
before = object()
|
||||
utilities.treatAsTextObject.return_value = False
|
||||
utilities.findPreviousCaretInOrder = mock.Mock(
|
||||
side_effect=[(wholeObject, 0), (before, 0)]
|
||||
)
|
||||
|
||||
with mock.patch.object(
|
||||
web_script_utilities.AXText,
|
||||
"get_character_at_offset",
|
||||
return_value=(" ", 0, 1),
|
||||
) as getCharacter:
|
||||
result = web_script_utilities.Utilities.previousContext(
|
||||
utilities,
|
||||
start,
|
||||
0,
|
||||
skipSpace=True,
|
||||
)
|
||||
|
||||
self.assertEqual(result, (wholeObject, 0))
|
||||
utilities.treatAsTextObject.assert_called_once_with(wholeObject)
|
||||
getCharacter.assert_not_called()
|
||||
utilities.findPreviousCaretInOrder.assert_called_once_with(start, 0)
|
||||
|
||||
def test_next_context_breaks_skip_space_cycles(self):
|
||||
utilities = self._make_utilities()
|
||||
start = object()
|
||||
first = object()
|
||||
second = object()
|
||||
utilities.findNextCaretInOrder = mock.Mock(
|
||||
side_effect=[(first, 0), (second, 0), (first, 0)]
|
||||
)
|
||||
|
||||
with mock.patch.object(
|
||||
web_script_utilities.AXText,
|
||||
"get_character_at_offset",
|
||||
return_value=(" ", 0, 1),
|
||||
):
|
||||
result = web_script_utilities.Utilities.nextContext(
|
||||
utilities,
|
||||
start,
|
||||
0,
|
||||
skipSpace=True,
|
||||
)
|
||||
|
||||
self.assertEqual(result, (first, 0))
|
||||
self.assertEqual(utilities.findNextCaretInOrder.call_args_list, [
|
||||
mock.call(start, 0),
|
||||
mock.call(first, 0),
|
||||
mock.call(second, 0),
|
||||
])
|
||||
|
||||
def test_previous_context_breaks_skip_space_cycles(self):
|
||||
utilities = self._make_utilities()
|
||||
start = object()
|
||||
first = object()
|
||||
second = object()
|
||||
utilities.findPreviousCaretInOrder = mock.Mock(
|
||||
side_effect=[(first, 0), (second, 0), (first, 0)]
|
||||
)
|
||||
|
||||
with mock.patch.object(
|
||||
web_script_utilities.AXText,
|
||||
"get_character_at_offset",
|
||||
return_value=(" ", 0, 1),
|
||||
):
|
||||
result = web_script_utilities.Utilities.previousContext(
|
||||
utilities,
|
||||
start,
|
||||
0,
|
||||
skipSpace=True,
|
||||
)
|
||||
|
||||
self.assertEqual(result, (first, 0))
|
||||
self.assertEqual(utilities.findPreviousCaretInOrder.call_args_list, [
|
||||
mock.call(start, 0),
|
||||
mock.call(first, 0),
|
||||
mock.call(second, 0),
|
||||
])
|
||||
|
||||
|
||||
class WebSplitLinkLineNavigationRegressionTests(unittest.TestCase):
|
||||
def _make_utilities(self, link):
|
||||
utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities)
|
||||
@@ -867,3 +989,32 @@ class WebSplitLinkLineNavigationRegressionTests(unittest.TestCase):
|
||||
mock.call(paragraph, 96, layoutMode=False, useCache=False),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class WebGeckoBrokenTextRecoveryRegressionTests(unittest.TestCase):
|
||||
def test_gecko_limits_broken_text_recovery_to_sentences(self):
|
||||
utilities = gecko_script_utilities.Utilities.__new__(gecko_script_utilities.Utilities)
|
||||
utilities.isContentEditableWithEmbeddedObjects = mock.Mock(return_value=True)
|
||||
obj = object()
|
||||
|
||||
self.assertTrue(
|
||||
gecko_script_utilities.Utilities._attemptBrokenTextRecovery(
|
||||
utilities,
|
||||
obj,
|
||||
boundary=Atspi.TextBoundaryType.SENTENCE_START,
|
||||
)
|
||||
)
|
||||
self.assertFalse(
|
||||
gecko_script_utilities.Utilities._attemptBrokenTextRecovery(
|
||||
utilities,
|
||||
obj,
|
||||
boundary=Atspi.TextBoundaryType.LINE_START,
|
||||
)
|
||||
)
|
||||
self.assertFalse(
|
||||
gecko_script_utilities.Utilities._attemptBrokenTextRecovery(
|
||||
utilities,
|
||||
obj,
|
||||
boundary=Atspi.TextBoundaryType.WORD_START,
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user