feat(chat): stop an in-flight answer — Send becomes Stop, the partial is kept and persisted, the model stream is torn down

This commit is contained in:
2026-08-29 17:27:04 -04:00
parent 6bf7f456d4
commit 1a60ecbd8b
186 changed files with 1738 additions and 7796 deletions
+9 -4
View File
@@ -176,10 +176,13 @@ def send_and_wait(page: Page, question: str) -> None:
page.evaluate("() => document.querySelector('#composer').requestSubmit()")
expect(page.locator(".msg.user .bubble").last).to_contain_text(question)
# The mock streams at 0.02s/chunk, so thinking + answer land in a few
# seconds — 30s is generous on headless Chromium.
# seconds — 30s is generous on headless Chromium. Phase 48: the label
# assertion carries the settle wait with an explicit timeout — the
# in-flight button is the enabled Stop control (never disabled), so
# to_be_enabled no longer blocks until the turn settles.
expect(page.locator(".msg.brain .bubble").last).not_to_have_text("", timeout=30_000)
expect(page.locator("#send-btn")).to_be_enabled(timeout=30_000)
expect(page.locator("#send-label")).to_have_text("Send")
expect(page.locator("#send-label")).to_have_text("Send", timeout=30_000)
def submit(page: Page, question: str) -> None:
@@ -787,8 +790,10 @@ def test_thinking_window_follows_across_paragraph_breaks(
)
# The turn settles; the scratchpad text past the break is intact and
# the answer landed.
# the answer landed. Phase 48: the label assertion carries the settle
# wait (explicit timeout — the in-flight Stop button is never
# disabled, so to_be_enabled no longer blocks until the turn ends).
expect(page.locator("#send-btn")).to_be_enabled(timeout=30_000)
expect(page.locator("#send-label")).to_have_text("Send")
expect(page.locator("#send-label")).to_have_text("Send", timeout=30_000)
expect(details.locator(".thinking-text")).to_contain_text("Step 3")
expect(page.locator(".msg.brain .bubble").last).to_contain_text(MOCK_ANSWER_MARKER)