test(coding-agent): fixed environment-sensitive and stale-trigger test failures

- Shimmed writable select.value in export-html harness; linkedom's getter-only HTMLSelectElement.value made template.js theme assignment throw under strict mode.
- Bound the oauth-flow port blocker to 127.0.0.1 explicitly; macOS lets a specific-address bind coexist with a wildcard one, so the flow bound the blocked port and never fell back.
- Re-anchored atomic-rewrite race tests on rewriteEntries() after the compaction-supersede rewrite trigger was removed in cb63ebd.
This commit is contained in:
can1357
2026-07-24 03:38:15 +02:00
parent debccaaacb
commit 4e5cb4d400
3 changed files with 24 additions and 5 deletions
@@ -45,6 +45,19 @@ function renderSession(session: MinimalSession) {
value: () => ({ matches: false, addEventListener() {}, removeEventListener() {} }),
configurable: true,
});
// linkedom's HTMLSelectElement.value is getter-only; template.js assigns it
// under 'use strict', which would throw. Shim a writable value like a browser.
const themeSelect = document.getElementById("theme-select");
if (themeSelect) {
let themeValue = "auto";
Object.defineProperty(themeSelect, "value", {
get: () => themeValue,
set: next => {
themeValue = String(next);
},
configurable: true,
});
}
const context = vm.createContext({
window,
@@ -540,7 +540,10 @@ describe("mcp oauth flow", () => {
// Here `clientId` is unset, so `MCPOAuthFlow.#tryRegisterClient` will
// register the actual fallback URI with the provider and the
// authorization request will use that fresh client_id.
const blocker = Bun.serve({ port: 0, fetch: () => new Response("blocker") });
// Occupy 127.0.0.1 explicitly — the interface callback flows bind for
// `localhost` — because macOS lets a specific-address bind coexist with a
// wildcard one, which would let the flow bind the "blocked" port.
const blocker = Bun.serve({ hostname: "127.0.0.1", port: 0, fetch: () => new Response("blocker") });
const blockerPort = blocker.port;
if (typeof blockerPort !== "number") {
blocker.stop(true);
@@ -177,6 +177,8 @@ describe("SessionManager atomic rewrite race", () => {
sessionManager.appendCompaction("older summary", "older", firstKeptEntryId, 100);
await sessionManager.flush();
sessionManager.appendCompaction("newer summary", "newer", firstKeptEntryId, 80);
// Kick off a full-file rewrite that parks inside the fake storage until released.
const rewritePublished = sessionManager.rewriteEntries();
await storage.rewriteStarted.promise;
sessionManager.appendMessage({ role: "user", content: "during rewrite prompt", timestamp: Date.now() });
@@ -185,6 +187,7 @@ describe("SessionManager atomic rewrite race", () => {
const titlePersisted = sessionManager.setSessionName("Post rewrite title", "user", "test");
storage.allowRewrite.resolve();
await rewritePublished;
await titlePersisted;
await sessionManager.flush();
sessionManager.appendMessage({
@@ -288,9 +291,10 @@ describe("SessionManager atomic rewrite race", () => {
if (!firstKeptEntryId) throw new Error("Expected seeded branch entry");
sessionManager.appendCompaction("older summary", "older", firstKeptEntryId, 100);
await sessionManager.flush();
// Second compaction elides the first, scheduling a full-file rewrite that
// parks inside the fake storage until we release it.
sessionManager.appendCompaction("newer summary", "newer", firstKeptEntryId, 80);
// Kick off a full-file rewrite that parks inside the fake storage until we
// release it.
const rewritePublished = sessionManager.rewriteEntries();
await storage.rewriteStarted.promise;
// Simulate a Ctrl+C teardown: append a session_exit custom entry (fenced
@@ -308,8 +312,7 @@ describe("SessionManager atomic rewrite race", () => {
// stale body serialized before flushSync bumped the disk epoch; otherwise
// the async publish would overwrite the durable exit record.
storage.allowRewrite.resolve();
await Promise.resolve();
await Promise.resolve();
await rewritePublished;
const afterRelease = await storage.readText(sessionFile);
expect(afterRelease).toContain('"customType":"session_exit"');