bouquin/tests/test_find_bar.py

100 lines
3.6 KiB
Python

from PySide6.QtCore import Qt
from PySide6.QtGui import QKeySequence, QTextCursor
from PySide6.QtTest import QTest
from tests.qt_helpers import trigger_menu_action
def _cursor_info(editor):
"""Return (start, end, selectedText) for the current selection."""
tc: QTextCursor = editor.textCursor()
start = min(tc.anchor(), tc.position())
end = max(tc.anchor(), tc.position())
return start, end, tc.selectedText()
def test_find_actions_and_shortcuts(open_window, qtbot):
win = open_window
# Actions should be present under Navigate and advertise canonical shortcuts
act_find = trigger_menu_action(win, "Find on page")
assert act_find.shortcut().matches(QKeySequence.Find) == QKeySequence.ExactMatch
act_next = trigger_menu_action(win, "Find Next")
assert act_next.shortcut().matches(QKeySequence.FindNext) == QKeySequence.ExactMatch
act_prev = trigger_menu_action(win, "Find Previous")
assert (
act_prev.shortcut().matches(QKeySequence.FindPrevious)
== QKeySequence.ExactMatch
)
# "Find on page" should open the bar and focus the input
act_find.trigger()
qtbot.waitUntil(lambda: win.findBar.isVisible())
qtbot.waitUntil(lambda: win.findBar.edit.hasFocus())
def test_find_navigate_case_sensitive_and_close_focus(open_window, qtbot):
win = open_window
# Mixed-case content with three matches
text = "alpha … ALPHA … alpha"
win.editor.setPlainText(text)
qtbot.waitUntil(lambda: win.editor.toPlainText() == text)
# Open the find bar from the menu
trigger_menu_action(win, "Find on page").trigger()
qtbot.waitUntil(lambda: win.findBar.isVisible())
win.findBar.edit.clear()
QTest.keyClicks(win.findBar.edit, "alpha")
# 1) First hit (case-insensitive default)
QTest.keyClick(win.findBar.edit, Qt.Key_Return)
qtbot.waitUntil(lambda: win.editor.textCursor().hasSelection())
s0, e0, sel0 = _cursor_info(win.editor)
assert sel0.lower() == "alpha"
# 2) Next → uppercase ALPHA (case-insensitive)
trigger_menu_action(win, "Find Next").trigger()
qtbot.waitUntil(lambda: win.editor.textCursor().hasSelection())
s1, e1, sel1 = _cursor_info(win.editor)
assert sel1.upper() == "ALPHA"
# 3) Next → the *other* lowercase "alpha"
trigger_menu_action(win, "Find Next").trigger()
qtbot.waitUntil(lambda: win.editor.textCursor().hasSelection())
s2, e2, sel2 = _cursor_info(win.editor)
assert sel2.lower() == "alpha"
# Ensure we didn't wrap back to the very first "alpha"
assert s2 != s0
# 4) Case-sensitive: skip ALPHA and only hit lowercase
win.findBar.case.setChecked(True)
# Put the caret at start to make the next search deterministic
tc = win.editor.textCursor()
tc.setPosition(0)
win.editor.setTextCursor(tc)
win.findBar.find_next()
qtbot.waitUntil(lambda: win.editor.textCursor().hasSelection())
s_cs1, e_cs1, sel_cs1 = _cursor_info(win.editor)
assert sel_cs1 == "alpha"
win.findBar.find_next()
qtbot.waitUntil(lambda: win.editor.textCursor().hasSelection())
s_cs2, e_cs2, sel_cs2 = _cursor_info(win.editor)
assert sel_cs2 == "alpha"
assert s_cs2 != s_cs1 # it's the other lowercase match
# 5) Previous goes back to the earlier lowercase match
win.findBar.find_prev()
qtbot.waitUntil(lambda: win.editor.textCursor().hasSelection())
s_prev, e_prev, sel_prev = _cursor_info(win.editor)
assert sel_prev == "alpha"
assert s_prev == s_cs1
# 6) Close returns focus to editor
win.findBar.closeBtn.click()
qtbot.waitUntil(lambda: not win.findBar.isVisible())
qtbot.waitUntil(lambda: win.editor.hasFocus())