features: auto-next w/ 5s countdown, prev/next, playback speed, hide fillers, recent searches

This commit is contained in:
jozamudi committed 2026-08-19 18:41:13 +00:00
1 parent 9fdf3944fc
commit 98fb4e5461
6 files changed
+269 -25

No files matched your search

+68
View File
@@ -159,6 +159,72 @@ async def test_stream_failure_retry():
print("ok test_stream_failure_retry")
async def test_recent_searches():
# UI: focus the (empty) search box -> dropdown of saved searches;
# typing filters; clicking one runs the search.
jar = http.cookiejar.CookieJar()
op = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
op.open(urllib.request.Request(BASE + "/login",
data=json.dumps({"username": "alice", "password": "alicepw12345"}).encode(),
headers={"Content-Type": "application/json"}, method="POST"))
op.open(urllib.request.Request(BASE + "/api/searches",
data=json.dumps({"q": "chainsaw"}).encode(),
headers={"Content-Type": "application/json"}, method="POST"))
async with async_playwright() as p:
browser = await p.chromium.launch(args=LAUNCH_ARGS)
page = await (await browser.new_context()).new_page()
errors = []
page.on("pageerror", lambda e: errors.append(str(e)))
await _login(page, "alice", "alicepw12345")
await page.focus("#q")
await page.wait_for_selector(".recent.open", timeout=10000)
assert "chainsaw" in await page.inner_text(".recent")
# typing narrows the list to the matching entry
await page.fill("#q", "cha")
await page.wait_for_function(
"document.querySelectorAll('.recent button').length === 1",
timeout=5000, polling=POLL)
await page.click(".recent button", force=True)
await page.wait_for_selector("a.card", timeout=30000)
assert "q=chainsaw" in page.url, page.url
assert not errors, errors
await browser.close()
print("ok test_recent_searches")
async def test_auto_next_countdown():
# playing a full episode to its natural end is too slow; simulate the
# `ended` event and verify the countdown overlay + cancel path.
async with async_playwright() as p:
browser = await p.chromium.launch(args=LAUNCH_ARGS)
page = await (await browser.new_context()).new_page()
errors = []
page.on("pageerror", lambda e: errors.append(str(e)))
await _login(page, "admin", "adminpw12345")
# straight to the 12-ep series (the first search card is the 1-ep
# movie — no next episode there)
await page.goto(BASE + "/?anime=chainsaw-man-922")
await page.wait_for_selector("video", timeout=30000)
await page.wait_for_function(
"document.querySelector('video').readyState >= 4",
timeout=120000, polling=250) # cold CDN/upstream starts can be slow
await page.evaluate(
"document.querySelector('video').dispatchEvent(new Event('ended'))")
await page.wait_for_selector(".pl-overlay .btn", timeout=10000)
assert "Next: E2" in await page.inner_text(".pl-overlay")
# cancel (x): overlay gone, still on the same episode
await page.click(".pl-overlay .cnt-x", force=True)
await page.wait_for_function(
"!document.querySelector('.pl-overlay')", timeout=5000, polling=POLL)
assert "E1" in await page.inner_text(".ep.active")
assert not errors, errors
await browser.close()
print("ok test_auto_next_countdown")
if __name__ == "__main__":
if len(sys.argv) > 1:
BASE = sys.argv[1]
@@ -166,3 +232,5 @@ if __name__ == "__main__":
asyncio.run(test_video_plays_behind_auth())
asyncio.run(test_history_page_and_delete())
asyncio.run(test_stream_failure_retry())
asyncio.run(test_recent_searches())
asyncio.run(test_auto_next_countdown())