diff --git a/static/icon.svg b/static/icon.svg new file mode 100644 index 0000000..cafb840 --- /dev/null +++ b/static/icon.svg @@ -0,0 +1 @@ +a diff --git a/static/manifest.webmanifest b/static/manifest.webmanifest new file mode 100644 index 0000000..e970277 --- /dev/null +++ b/static/manifest.webmanifest @@ -0,0 +1,10 @@ +{ + "name": "ani-web", + "short_name": "ani-web", + "start_url": "./", + "scope": "./", + "display": "standalone", + "background_color": "#0e0f13", + "theme_color": "#0e0f13", + "icons": [{ "src": "icon.svg", "sizes": "any", "type": "image/svg+xml" }] +} diff --git a/tests/test_browser.py b/tests/test_browser.py index 6327a59..354425f 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -239,6 +239,32 @@ async def _recent_searches(): await browser.close() +def test_live_search(): + asyncio.run(_live_search()) + + +async def _live_search(): + # typing (no Enter) renders results in place; Enter still commits to ?q= + # so results stay shareable/reloadable. + 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") + await page.fill("#q", "chainsaw") + # debounced live results must appear WITHOUT pressing Enter + await page.wait_for_selector("main a.card", timeout=30000) + assert "q=chainsaw" not in page.url, page.url + # Enter commits the query to the URL + await page.keyboard.press("Enter") + await page.wait_for_function( + "location.search.includes('q=chainsaw')", timeout=15000, polling=POLL) + assert not errors, errors + await browser.close() + + def test_auto_next_countdown(): asyncio.run(_auto_next_countdown())