import base64 import io import json import os import runpy import zipfile from fastapi.testclient import TestClient from docslib import HeaderButton from docslib.components import H1, Image, P from docslib.hooks import Page from docslib.server import create_app def test_all_endpoints_and_self_contained_build(tmp_path): assets = tmp_path / "assets" assets.mkdir() image_bytes = b"not-a-real-png-but-good-enough-for-encoding" (assets / "hero.png").write_bytes(image_bytes) custom_css = tmp_path / "inject.css" custom_css.write_text(".content { --custom-test: yes; }", encoding="utf-8") @Page("1.1", "Child") def child(): return P("Second page") @Page("1.", "Home") def home(): return [H1("Welcome"), Image("hero.png", "Hero")] app = create_app( title="Test docs", assets_dir=assets, custom_css=custom_css, manifest_path="http://127.0.0.1:9000/", header_buttons=[ HeaderButton("Home", home), HeaderButton.local("Child", "Child", section="1"), HeaderButton.external("Source", "https://example.com"), {"label": "Download", "href": "/index.zip"}, ], ) client = TestClient(app) manifest_response = client.get("/manifest.json") assert manifest_response.status_code == 200 manifest = manifest_response.json() assert [page["number"] for page in manifest["pages"]] == ["1", "1.1"] assert manifest["assets"]["hero.png"]["data"] == base64.b64encode(image_bytes).decode() assert len(manifest["revision"]) == 20 assert manifest["ui"]["header_buttons"] == [ {"label": "Home", "page": "1"}, {"label": "Child", "page": "1.1"}, {"label": "Source", "href": "https://example.com", "target": "_blank"}, {"label": "Download", "href": "/index.zip"}, ] assert manifest_response.headers["cache-control"] == "no-store" html_response = client.get("/index.html") html = html_response.text assert html_response.status_code == 200 assert "http://127.0.0.1:9000/manifest.json" in html assert ".content { --custom-test: yes; }" in html assert "indexedDB.open" in html assert "link.dataset.page = button.page" in html assert 'class="brand-mark"' not in html assert ">Knowledge base<" not in html assert ">Search<" not in html assert ">Ctrl K<" not in html assert ">Up to date<" not in html assert "manifestIdentity" in html assert "100dvh" in html assert "100vh" not in html assert "html, body { width: 100%; height: 100dvh" in html assert "overflow-y: auto" in html assert "elements.pageSurface.scrollTo" in html assert "font-family: system-ui; font-size: 16px" in html assert ".glyph-button, .refresh-glyph { font-family: Arial" in html assert ".nav-arrow { font-family: system-ui; }" in html assert "--shell: #000000" in html assert 'id="desktop-search-input"' in html assert '
' in html assert '