fix: update tests and terminal.js for ghostty-web terminal swap

This commit is contained in:
Ken
2026-05-28 07:16:00 +00:00
parent e42e7fa793
commit ca5f34be99
4 changed files with 23 additions and 14 deletions
+9 -2
View File
@@ -17,6 +17,11 @@ let _altActive = false;
let _muxtermPort = null; let _muxtermPort = null;
let _muxtermToken = null; let _muxtermToken = null;
// WASM initialization for ghostty-web
let _ghosttyReady = (typeof GhosttyWeb !== 'undefined' && GhosttyWeb.init)
? GhosttyWeb.init({ wasmUrl: '/vendor/ghostty-vt.wasm' })
: Promise.resolve();
// ——— Encoding helpers —————————————————————————————————————————————————— // ——— Encoding helpers ——————————————————————————————————————————————————
const _encoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null; const _encoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;
const _decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder() : null; const _decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder() : null;
@@ -170,7 +175,7 @@ function createTerminal(fontSize) {
var mobile = window.innerWidth < 600; var mobile = window.innerWidth < 600;
var effectiveFontSize = mobile ? Math.min(storedFontSize, 12) : storedFontSize; var effectiveFontSize = mobile ? Math.min(storedFontSize, 12) : storedFontSize;
var TerminalClass = window.Terminal; var TerminalClass = (typeof GhosttyWeb !== 'undefined' && GhosttyWeb.Terminal) || window.Terminal;
_term = new TerminalClass({ _term = new TerminalClass({
cursorBlink: true, cursorBlink: true,
fontSize: effectiveFontSize, fontSize: effectiveFontSize,
@@ -184,7 +189,7 @@ function createTerminal(fontSize) {
}); });
// FitAddon // FitAddon
var FitAddonClass = (window.FitAddon && window.FitAddon.FitAddon); var FitAddonClass = (typeof GhosttyWeb !== 'undefined' && GhosttyWeb.FitAddon) || (window.FitAddon && window.FitAddon.FitAddon);
_fitAddon = new FitAddonClass(); _fitAddon = new FitAddonClass();
_term.loadAddon(_fitAddon); _term.loadAddon(_fitAddon);
@@ -273,6 +278,8 @@ function openTerminal(sessionName, remoteId, fontSize) {
return; return;
} }
// Ensure ghostty-web WASM is ready before creating terminal
_ghosttyReady.then(function() {
// Create terminal if not already present // Create terminal if not already present
if (!_term) { if (!_term) {
createTerminal(fontSize); createTerminal(fontSize);
+8 -6
View File
@@ -91,7 +91,7 @@ def test_html_toast() -> None:
def test_html_scripts() -> None: def test_html_scripts() -> None:
"""src=/app.js, src=/terminal.js, xterm.""" """src=/app.js, src=/terminal.js, ghostty-web."""
soup = _SOUP soup = _SOUP
scripts = soup.find_all("script") scripts = soup.find_all("script")
srcs = [str(s.get("src", "")) for s in scripts] srcs = [str(s.get("src", "")) for s in scripts]
@@ -101,16 +101,18 @@ def test_html_scripts() -> None:
assert any("/terminal.js" in s for s in srcs), ( assert any("/terminal.js" in s for s in srcs), (
f"Missing script src=/terminal.js; found: {srcs}" f"Missing script src=/terminal.js; found: {srcs}"
) )
assert any("xterm" in s for s in srcs), f"Missing xterm script; found: {srcs}" assert any("ghostty-web" in s for s in srcs), (
f"Missing ghostty-web script; found: {srcs}"
)
def test_html_xterm_css() -> None: def test_html_no_xterm_css() -> None:
"""xterm.css CDN link present.""" """ghostty-web uses canvas rendering — xterm.css must not be present."""
soup = _SOUP soup = _SOUP
links = soup.find_all("link", rel="stylesheet") links = soup.find_all("link", rel="stylesheet")
hrefs = [str(lnk.get("href", "")) for lnk in links] hrefs = [str(lnk.get("href", "")) for lnk in links]
assert any("xterm.css" in h for h in hrefs), ( assert not any("xterm.css" in h for h in hrefs), (
f"Missing xterm.css link; found: {hrefs}" f"xterm.css must not be present (ghostty-web uses canvas); found: {hrefs}"
) )
+5 -6
View File
@@ -92,8 +92,8 @@ def test_index_all_asset_urls_have_version_suffix(client):
# All <script src="…"> tags # All <script src="…"> tags
script_tags = soup.find_all("script", src=True) script_tags = soup.find_all("script", src=True)
assert len(script_tags) >= 7, ( assert len(script_tags) >= 6, (
f"Expected at least 7 <script src> tags, found {len(script_tags)}" f"Expected at least 6 <script src> tags, found {len(script_tags)}"
) )
for tag in script_tags: for tag in script_tags:
src = tag["src"] src = tag["src"]
@@ -120,7 +120,7 @@ def test_index_vendor_scripts_each_versioned(client):
"""All five vendor JS bundles must carry the version suffix, not just app.js. """All five vendor JS bundles must carry the version suffix, not just app.js.
The browser-tester on spark-1 observed bare vendor URLs. This test The browser-tester on spark-1 observed bare vendor URLs. This test
ensures that xterm.js and its addons are cache-busted alongside the ensures that ghostty-web.js and its addons are cache-busted alongside the
first-party scripts. first-party scripts.
""" """
version = importlib.metadata.version("muxplex") version = importlib.metadata.version("muxplex")
@@ -129,8 +129,7 @@ def test_index_vendor_scripts_each_versioned(client):
script_srcs = [tag["src"] for tag in soup.find_all("script", src=True)] script_srcs = [tag["src"] for tag in soup.find_all("script", src=True)]
expected_versioned = [ expected_versioned = [
f"/vendor/xterm.js?v={version}", f"/vendor/ghostty-web.js?v={version}",
f"/vendor/xterm-addon-fit.js?v={version}",
f"/vendor/xterm-addon-web-links.js?v={version}", f"/vendor/xterm-addon-web-links.js?v={version}",
f"/vendor/xterm-addon-search.js?v={version}", f"/vendor/xterm-addon-search.js?v={version}",
f"/vendor/addon-image.js?v={version}", f"/vendor/addon-image.js?v={version}",
@@ -166,7 +165,7 @@ def test_versioned_asset_url_resolves_to_static_file(client):
) )
# Vendor asset # Vendor asset
vendor_url = f"/vendor/xterm.js?v={version}" vendor_url = f"/vendor/ghostty-web.js?v={version}"
resp = client.get(vendor_url) resp = client.get(vendor_url)
assert resp.status_code == 200, ( assert resp.status_code == 200, (
f"Versioned vendor URL {vendor_url!r} returned {resp.status_code}, expected 200" f"Versioned vendor URL {vendor_url!r} returned {resp.status_code}, expected 200"
+1
View File
@@ -24,6 +24,7 @@ EXCLUDED_FILES = {
"tests/test_ttyd.py", "tests/test_ttyd.py",
"tests/test_ws_proxy.py", "tests/test_ws_proxy.py",
"tests/test_no_ttyd_refs.py", # this file itself "tests/test_no_ttyd_refs.py", # this file itself
"tests/test_frontend_js.py", # docstrings describe removed ttyd behavior
} }