This commit is contained in:
parent
33c68c2f44
commit
749f525f83
44 changed files with 5380 additions and 3532 deletions
70
tests/ShouldBootWasmAtDepth/main.cpp
Normal file
70
tests/ShouldBootWasmAtDepth/main.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
catcrafts.net
|
||||
Copyright (C) 2026 Catcrafts
|
||||
|
||||
The source code of this website is made available for viewing purposes only.
|
||||
No permission is granted to copy, modify, distribute, or create derivative works.
|
||||
*/
|
||||
|
||||
// The bug this suite exists for: /demos/raytracer is two segments deep, and
|
||||
// every asset the runtime needs was referenced RELATIVE to the document —
|
||||
// src="runtime.js", fetch("files.json"), fetch("variants.json"), and the
|
||||
// .wasm named by variants.json. So the browser asked for /demos/runtime.js,
|
||||
// Caddy's try_files handed back index.html, and the module was blocked for
|
||||
// being text/html. Four NS_ERROR_CORRUPTED_CONTENT failures and a blank demo.
|
||||
//
|
||||
// The server emits <base href="/"> on any page that boots wasm, which fixes
|
||||
// all of them at once. These checks pin that, and pin the precondition that
|
||||
// makes it safe: nothing else on the page may use a relative URL.
|
||||
//
|
||||
// Skips (exit 77) when no wasm bundle sits under bin/ — build the web product
|
||||
// first. CI re-runs exactly this suite after the wasm build for that reason.
|
||||
|
||||
import std;
|
||||
import Catcrafts.E2eHarness;
|
||||
|
||||
using namespace Catcrafts::E2e;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
TestServer srv(argv[1], 8213);
|
||||
|
||||
const std::string page = srv.Body("/demos/raytracer");
|
||||
if (page.find("<script src=") == std::string::npos) {
|
||||
std::println("no bundle under bin/, so no boot scripts were emitted — "
|
||||
"build the wasm product first");
|
||||
return 77;
|
||||
}
|
||||
|
||||
Check(page.find("<base href=\"/\">") != std::string::npos,
|
||||
"wasm page sets <base href=\"/\">");
|
||||
|
||||
// Absolute script srcs regardless of the <base>, so the tags stay correct
|
||||
// even if the base is ever removed.
|
||||
{
|
||||
const std::regex relativeSrc(R"(<script\s[^>]*src="[^"/:])");
|
||||
Check(!std::regex_search(page, relativeSrc),
|
||||
"every boot script src is absolute");
|
||||
}
|
||||
|
||||
// A <base> rewrites every relative URL in the document, so it is only
|
||||
// safe while there are none. If a view ever emits href="x" or a bare
|
||||
// "#frag", the base silently retargets it — assert the precondition
|
||||
// rather than trusting it.
|
||||
{
|
||||
const std::regex urlAttr(R"lit((href|src|action)="([^"]*)")lit");
|
||||
std::size_t relative = 0;
|
||||
for (auto it = std::sregex_iterator(page.begin(), page.end(), urlAttr);
|
||||
it != std::sregex_iterator(); ++it) {
|
||||
const std::string url = (*it)[2].str();
|
||||
const bool absolute = url.starts_with("/")
|
||||
|| url.starts_with("http://")
|
||||
|| url.starts_with("https://")
|
||||
|| url.starts_with("mailto:");
|
||||
if (!absolute) ++relative;
|
||||
}
|
||||
Check(relative == 0, "wasm page has no relative URL for <base> to retarget",
|
||||
std::format("{} URL(s) would be retargeted by the base tag", relative));
|
||||
}
|
||||
|
||||
return Finish();
|
||||
}
|
||||
Loading…
Reference in a new issue