v0.315.0: close the log tab's <script> — the live poller was dead, and a test now says so
gates / gates (push) Failing after 49s
gates / gates (push) Failing after 49s
FOUND IN A BROWSER. The log tab's body was lifted out of the old logs.html by line range and the
range stopped one line short, so the closing </script> never came with it. Everything downstream
agreed the page was fine:
- html/template parsed it,
- the page rendered and looked right,
- TestAppPage_EachTabRendersItsOwnContent found `setInterval(window.fetchLogs` exactly where it
expected it, because the TEXT was there.
Chrome refused the whole block with "SyntaxError: Unexpected token '<'" at the `</div>` that
followed, so the live log never refreshed. A marker proves a string is present; it does not prove
the browser will execute it.
TestAppPage_ScriptTagsAreBalanced now counts <script> against </script> on all seven app-page URLs
and checks the last block is closed. Red-proved by removing the tag again: it fails naming the logs
tab, 3 opened and 2 closed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
This commit is contained in:
@@ -583,3 +583,39 @@ func TestAppPage_EachTabRendersItsOwnContent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAppPage_ScriptTagsAreBalanced — every tab's rendered HTML closes every <script> it opens.
|
||||||
|
//
|
||||||
|
// THIS TEST EXISTS BECAUSE THE SUITE MISSED A DEAD PAGE. The log tab's body was lifted out of the
|
||||||
|
// old logs.html by line range and the range stopped one line short, dropping `</script>`. 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 `</script>` 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, "<script")
|
||||||
|
closed := strings.Count(body, "</script>")
|
||||||
|
if open != closed {
|
||||||
|
t.Errorf("%s: %d <script> opened, %d closed — an unclosed block swallows the markup after it "+
|
||||||
|
"and the browser refuses the whole thing", p, open, closed)
|
||||||
|
}
|
||||||
|
// An unclosed block shows up as page markup INSIDE the script: the first thing after the
|
||||||
|
// last statement would be a tag rather than </script>.
|
||||||
|
if i := strings.LastIndex(body, "<script"); i >= 0 {
|
||||||
|
rest := body[i:]
|
||||||
|
if j := strings.Index(rest, "</script>"); j < 0 {
|
||||||
|
t.Errorf("%s: the last <script> is never closed", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
container.scrollTop = container.scrollHeight;
|
container.scrollTop = container.scrollHeight;
|
||||||
startPolling();
|
startPolling();
|
||||||
})();
|
})();
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{template "layout_end" .}}
|
{{template "layout_end" .}}
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ line two</pre>
|
|||||||
container.scrollTop = container.scrollHeight;
|
container.scrollTop = container.scrollHeight;
|
||||||
startPolling();
|
startPolling();
|
||||||
})();
|
})();
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user