Files
agr-assistent/tests/test_chat_window.py
T
mrleo1nidandClaude Opus 5 85f4210480 Исправлена автопрокрутка журнала
Журнал перерисовывается целиком, и очистка документа сбрасывала прокрутку в начало:
следующая перерисовка принимала это за прокрутку пользователем и оставляла журнал наверху.

- Режим «следовать за низом» меняется только прокруткой пользователя
- Позиция восстанавливается по rangeChanged, когда раскладка документа действительно обновилась
- Новый запрос всегда прокручивает вниз
- Тесты автопрокрутки и сохранения позиции при прокрутке вверх

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 04:50:29 +03:00

73 lines
2.3 KiB
Python

import time
import pytest
from PySide6.QtCore import QCoreApplication
from PySide6.QtWidgets import QApplication
from agr_assistent.core.memory import MemoryStore
from agr_assistent.ui.chat_window import ChatWindow
from tests.fake_llm import FakeLLMServer
from tests.test_assistant_flow import _assistant
def _pump(seconds: float = 0.1) -> None:
deadline = time.monotonic() + seconds
while time.monotonic() < deadline:
QCoreApplication.processEvents()
time.sleep(0.005)
@pytest.fixture
def window(qapp: QApplication, fake_llm: FakeLLMServer, tmp_path) -> ChatWindow: # type: ignore[no-untyped-def]
memory = MemoryStore(tmp_path / "memory.sqlite3")
chat = ChatWindow(_assistant(fake_llm, memory))
chat.resize(500, 300)
chat.show()
yield chat
chat.hide()
memory.close()
def _scrollbar(window: ChatWindow): # type: ignore[no-untyped-def]
return window._transcript.verticalScrollBar()
def _stream_reply(window: ChatWindow, request: str, chunks: int) -> None:
assistant = window._assistant
assistant.request_added.emit(request, False)
assistant.reply_started.emit()
for index in range(chunks):
assistant.reply_chunk.emit(f"Строка ответа номер {index}.\n\n")
_pump(0.01)
assistant.reply_finished.emit("")
_pump(0.2)
def test_journal_follows_new_content(window: ChatWindow) -> None:
for request in range(3):
_stream_reply(window, f"Вопрос {request}", chunks=15)
scrollbar = _scrollbar(window)
assert scrollbar.maximum() > 0
assert scrollbar.value() == scrollbar.maximum()
def test_journal_keeps_position_when_user_scrolled_up(window: ChatWindow) -> None:
_stream_reply(window, "Длинный вопрос", chunks=30)
scrollbar = _scrollbar(window)
scrollbar.setValue(10)
_pump()
assistant = window._assistant
assistant.reply_started.emit()
for index in range(10):
assistant.reply_chunk.emit(f"Ещё строка {index}.\n\n")
_pump(0.01)
_pump(0.2)
assert scrollbar.value() == 10
# Новый запрос пользователя снова прокручивает вниз
assistant.request_added.emit("Новый вопрос", False)
_pump(0.2)
assert scrollbar.value() == scrollbar.maximum()