release: WRNexusJS 0.8.0
This commit is contained in:
@@ -18,6 +18,7 @@ function install(bodyHtml: string): void {
|
||||
g.location = win.location;
|
||||
g.DOMParser = win.DOMParser;
|
||||
g.CustomEvent = win.CustomEvent;
|
||||
g.Event = win.Event;
|
||||
g.fetch = win.fetch = (url: string, opts: any) => {
|
||||
fetchCalls.push({ url, opts });
|
||||
return Promise.resolve({
|
||||
@@ -44,6 +45,7 @@ beforeEach(() => {
|
||||
"location",
|
||||
"DOMParser",
|
||||
"CustomEvent",
|
||||
"Event",
|
||||
"fetch",
|
||||
]) {
|
||||
delete g[k];
|
||||
@@ -64,6 +66,22 @@ test("intercepts an internal link click and swaps #app in place", async () => {
|
||||
expect(win.document.title).toBe("About");
|
||||
});
|
||||
|
||||
test("prefetches focused routes once and reuses the document during navigation", async () => {
|
||||
install(`<div id="app"><a href="/about" id="prefetch">About</a></div>`);
|
||||
nextHtml =
|
||||
`<!doctype html><html><head><title>About</title></head>` +
|
||||
`<body><div id="app"><h1>Prefetched</h1></div></body></html>`;
|
||||
const link = win.document.getElementById("prefetch");
|
||||
link.dispatchEvent(new win.FocusEvent("focusin", { bubbles: true }));
|
||||
await flush();
|
||||
expect(fetchCalls).toHaveLength(1);
|
||||
expect(fetchCalls[0]?.opts.headers["x-wrnexus-prefetch"]).toBe("1");
|
||||
link.click();
|
||||
await flush();
|
||||
expect(fetchCalls).toHaveLength(1);
|
||||
expect(win.document.querySelector("h1")?.textContent).toBe("Prefetched");
|
||||
});
|
||||
|
||||
test("ignores cross-origin links (full navigation)", async () => {
|
||||
install(`<div id="app"><a href="https://other.test/x" id="lnk">x</a></div>`);
|
||||
win.document.getElementById("lnk").click();
|
||||
@@ -151,3 +169,37 @@ test("synchronizes page styles during client navigation and preserves the curren
|
||||
expect(style.textContent).toContain("color:blue");
|
||||
expect(style.getAttribute("nonce")).toBe("current-nonce");
|
||||
});
|
||||
|
||||
test("restores declared form state but never preserves sensitive fields", async () => {
|
||||
install(
|
||||
`<meta name="wrnexus-preserve" content="forms">` +
|
||||
`<div id="app"><input name="query" value="draft"><input name="password" type="password" value="secret"></div>`,
|
||||
);
|
||||
nextHtml = `<html><head><meta name="wrnexus-preserve" content="forms"></head><body><div id="app">Next</div></body></html>`;
|
||||
win.__wrnexusNavigate("/next");
|
||||
await flush();
|
||||
|
||||
nextHtml =
|
||||
`<html><head><meta name="wrnexus-preserve" content="forms"></head><body><div id="app">` +
|
||||
`<input name="query" value=""><input name="password" type="password" value=""></div></body></html>`;
|
||||
win.__wrnexusNavigate("/");
|
||||
await flush();
|
||||
|
||||
expect(win.document.querySelector('[name="query"]').value).toBe("draft");
|
||||
expect(win.document.querySelector('[name="password"]').value).toBe("");
|
||||
});
|
||||
|
||||
test("KeepAlive preserves the same live DOM instance across routes", async () => {
|
||||
install(
|
||||
`<div id="app"><section data-wrn-keepalive="dashboard"><input value="live"></section></div>`,
|
||||
);
|
||||
const original = win.document.querySelector("[data-wrn-keepalive]");
|
||||
original.runtimeState = { count: 7 };
|
||||
nextHtml = `<html><body><div id="app"><section data-wrn-keepalive="dashboard"><input value="new"></section></div></body></html>`;
|
||||
win.__wrnexusNavigate("/next");
|
||||
await flush();
|
||||
const restored = win.document.querySelector("[data-wrn-keepalive]");
|
||||
expect(restored).toBe(original);
|
||||
expect(restored.runtimeState).toEqual({ count: 7 });
|
||||
expect(restored.querySelector("input").value).toBe("live");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user