diff --git a/controller/internal/web/app_page_test.go b/controller/internal/web/app_page_test.go
index cb26ecb..991164d 100644
--- a/controller/internal/web/app_page_test.go
+++ b/controller/internal/web/app_page_test.go
@@ -583,3 +583,39 @@ func TestAppPage_EachTabRendersItsOwnContent(t *testing.T) {
}
}
}
+
+// TestAppPage_ScriptTagsAreBalanced — every tab's rendered HTML closes every `. Go's
+// html/template parsed it, the page rendered, and TestAppPage_EachTabRendersItsOwnContent found
+// `setInterval(window.fetchLogs` exactly where it expected it — because the TEXT was there. The
+// browser then refused the block with „SyntaxError: Unexpected token '<'" and the live log poller
+// never ran. A marker proves a string is present; it does not prove the browser will execute it.
+//
+// RED-PROOF (REPORT.md): delete the `` from app_logs.html again → this fails naming the
+// logs tab. Reverted.
+func TestAppPage_ScriptTagsAreBalanced(t *testing.T) {
+ s := appPageHarness(t)
+ for _, p := range []string{
+ "/apps/adventurelog", "/apps/adventurelog/settings", "/apps/adventurelog/data",
+ "/apps/adventurelog/guide", "/apps/adventurelog/logs",
+ "/apps/grocy", "/apps/grocy/install",
+ } {
+ body := appGet(t, s, p).Body.String()
+ open := strings.Count(body, ".
+ if i := strings.LastIndex(body, ""); j < 0 {
+ t.Errorf("%s: the last
{{template "layout_end" .}}
diff --git a/controller/internal/web/testdata/i18n_parity/app_logs.html b/controller/internal/web/testdata/i18n_parity/app_logs.html
index 08f1293..50a7093 100644
--- a/controller/internal/web/testdata/i18n_parity/app_logs.html
+++ b/controller/internal/web/testdata/i18n_parity/app_logs.html
@@ -289,6 +289,7 @@ line two
container.scrollTop = container.scrollHeight;
startPolling();
})();
+