Files
spring-ai/chat-ui-htmx/scripts/browser-test.py
T

68 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python3
"""Drives the real page in headless Chromium (Playwright for Python) against the running app + stub.
Prints a transcript to stdout. Needs: pip install playwright && playwright install chromium."""
import sys, time, urllib.request
from playwright.sync_api import sync_playwright
APP = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:38180"
STUB = sys.argv[2] if len(sys.argv) > 2 else "http://localhost:38181"
def stub(path):
return urllib.request.urlopen(STUB + path, data=b"" if "config" in path else None).read().decode().strip()
def ask(page, text):
n = page.locator(".msg.bot").count()
page.fill("input[name=message]", text)
page.click("form button")
page.wait_for_selector(f".msg.bot >> nth={n}")
return int(page.locator(".msg.bot span[id^=out-]").last.get_attribute("id")[4:])
def wait_done(page, n, timeout=20000):
page.wait_for_function(f"!document.querySelector('#stop-{n}')", timeout=timeout)
def bot_text(page, n):
return page.locator(f"#out-{n}").inner_text()
with sync_playwright() as p:
b = p.chromium.launch()
ctx = b.new_context()
page = ctx.new_page()
dialogs = []
page.on("dialog", lambda d: (dialogs.append(d.message), d.dismiss()))
page.goto(APP + "/")
print("== turn 1 (session A)")
n = ask(page, "My name is Asha and I like tea"); wait_done(page, n)
print("A1:", repr(bot_text(page, n)))
print("== turn 2 (session A, same cookie)")
n = ask(page, "What did I just tell you?"); wait_done(page, n)
print("A2:", repr(bot_text(page, n)))
print("cookies:", [c["name"] for c in ctx.cookies()])
print("== turn 1 (session B, fresh browser context, no cookie)")
ctx2 = b.new_context(); page2 = ctx2.new_page(); page2.goto(APP + "/")
n = ask(page2, "What did I just tell you?"); wait_done(page2, n)
print("B1:", repr(bot_text(page2, n)))
print("== New conversation button in session A, then ask again")
page.click("text=New conversation"); time.sleep(0.5)
n = ask(page, "Do you remember me?"); wait_done(page, n)
print("A3:", repr(bot_text(page, n)))
print("== model output containing markup")
n = ask(page, "html please"); wait_done(page, n)
print("rendered text:", repr(bot_text(page, n)))
print("<b> elements created inside the answer:", page.locator(f"#out-{n} b").count())
print("<img> elements created inside the answer:", page.locator(f"#out-{n} img").count())
print("alert dialogs fired:", len(dialogs))
print("== stop button")
stub("/stub/config?delayMs=50")
n = ask(page, "count 200")
page.wait_for_function(f"document.querySelector('#out-{n}').innerText.length > 30")
before = bot_text(page, n)
t0 = time.time(); page.click(f"#stop-{n}")
page.wait_for_function(f"!document.querySelector('#stop-{n}')")
time.sleep(1.5)
after = bot_text(page, n)
print("text at click :", repr(before))
print("text 1.5 s on :", repr(after))
print("grew after stop:", len(after.replace(' [stopped]','')) > len(before.replace(' [stopped]','')) + 6)
stub("/stub/config?delayMs=20")
b.close()