Kaynağa Gözat

test: repair v2 CI failures (#40803)

Co-authored-by: Aiden Cline <rekram1-node@users.noreply.github.com>
opencode-agent[bot] 1 hafta önce
ebeveyn
işleme
a15ec425de

+ 1 - 0
bun.lock

@@ -111,6 +111,7 @@
         "@types/luxon": "catalog:",
         "@types/luxon": "catalog:",
         "@types/node": "catalog:",
         "@types/node": "catalog:",
         "@typescript/native-preview": "catalog:",
         "@typescript/native-preview": "catalog:",
+        "happy-dom": "20.11.1",
         "tw-animate-css": "1.4.0",
         "tw-animate-css": "1.4.0",
         "typescript": "catalog:",
         "typescript": "catalog:",
         "vite": "catalog:",
         "vite": "catalog:",

+ 1 - 0
packages/app/package.json

@@ -40,6 +40,7 @@
     "@types/luxon": "catalog:",
     "@types/luxon": "catalog:",
     "@types/node": "catalog:",
     "@types/node": "catalog:",
     "@typescript/native-preview": "catalog:",
     "@typescript/native-preview": "catalog:",
+    "happy-dom": "20.11.1",
     "tw-animate-css": "1.4.0",
     "tw-animate-css": "1.4.0",
     "typescript": "catalog:",
     "typescript": "catalog:",
     "vite": "catalog:",
     "vite": "catalog:",

+ 24 - 17
packages/app/src/pages/session/timeline/observe-element-offset.test.ts

@@ -1,5 +1,6 @@
 import { expect, test } from "bun:test"
 import { expect, test } from "bun:test"
 import { type Virtualizer } from "@tanstack/solid-virtual"
 import { type Virtualizer } from "@tanstack/solid-virtual"
+import { Window } from "happy-dom"
 import { mutationNodesContainElement, observeElementOffsetReconnectAware } from "./observe-element-offset"
 import { mutationNodesContainElement, observeElementOffsetReconnectAware } from "./observe-element-offset"
 
 
 test("matches only the scroll element or an ancestor containing it", () => {
 test("matches only the scroll element or an ancestor containing it", () => {
@@ -16,14 +17,15 @@ test("matches only the scroll element or an ancestor containing it", () => {
 })
 })
 
 
 test("reports a divergent native offset once and ignores equal offsets and unrelated mutations", async () => {
 test("reports a divergent native offset once and ignores equal offsets and unrelated mutations", async () => {
-  const route = document.createElement("section")
-  const viewport = document.createElement("div")
-  const unrelated = document.createElement("div")
+  const targetWindow = new Window()
+  const route = targetWindow.document.createElement("section")
+  const viewport = targetWindow.document.createElement("div")
+  const unrelated = targetWindow.document.createElement("div")
   route.append(viewport)
   route.append(viewport)
-  document.body.append(route)
+  targetWindow.document.body.append(route)
   const instance = {
   const instance = {
     scrollElement: viewport,
     scrollElement: viewport,
-    targetWindow: window,
+    targetWindow,
     scrollOffset: 79_400,
     scrollOffset: 79_400,
     options: {
     options: {
       horizontal: false,
       horizontal: false,
@@ -38,24 +40,24 @@ test("reports a divergent native offset once and ignores equal offsets and unrel
     instance.scrollOffset = offset
     instance.scrollOffset = offset
   })
   })
 
 
-  document.body.append(unrelated)
+  targetWindow.document.body.append(unrelated)
   unrelated.remove()
   unrelated.remove()
-  await frames(2)
+  await frames(2, targetWindow)
   expect(calls).toEqual([])
   expect(calls).toEqual([])
 
 
   route.remove()
   route.remove()
-  document.body.append(route)
-  await waitFor(() => calls.length === 1)
+  targetWindow.document.body.append(route)
+  await waitFor(() => calls.length === 1, targetWindow)
   expect(calls).toEqual([[0, false]])
   expect(calls).toEqual([[0, false]])
 
 
   route.remove()
   route.remove()
-  document.body.append(route)
+  targetWindow.document.body.append(route)
   await new Promise((resolve) => setTimeout(resolve, 0))
   await new Promise((resolve) => setTimeout(resolve, 0))
-  await frames(3)
+  await frames(3, targetWindow)
   expect(calls).toEqual([[0, false]])
   expect(calls).toEqual([[0, false]])
 
 
   cleanup?.()
   cleanup?.()
-  route.remove()
+  await targetWindow.happyDOM.close()
 })
 })
 
 
 test("keeps checking until stale reset-delay callbacks can no longer win", async () => {
 test("keeps checking until stale reset-delay callbacks can no longer win", async () => {
@@ -191,13 +193,18 @@ test("cleanup cancels reconnect checks and delegated offset observation", async
   route.remove()
   route.remove()
 })
 })
 
 
-async function frames(count: number) {
+type FrameWindow = {
+  requestAnimationFrame(callback: () => void): unknown
+  performance: { now(): number }
+}
+
+async function frames(count: number, targetWindow: FrameWindow = window) {
   for (let index = 0; index < count; index++) {
   for (let index = 0; index < count; index++) {
-    await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
+    await new Promise<void>((resolve) => targetWindow.requestAnimationFrame(() => resolve()))
   }
   }
 }
 }
 
 
-async function waitFor(condition: () => boolean) {
-  const deadline = performance.now() + 1_000
-  while (!condition() && performance.now() < deadline) await frames(1)
+async function waitFor(condition: () => boolean, targetWindow: FrameWindow = window) {
+  const deadline = targetWindow.performance.now() + 1_000
+  while (!condition() && targetWindow.performance.now() < deadline) await frames(1, targetWindow)
 }
 }

+ 1 - 0
packages/core/test/config/reload.test.ts

@@ -53,6 +53,7 @@ describe("config plugin reloads", () => {
       expect(yield* catalog.provider.get(Provider.ID.make("first"))).toBeDefined()
       expect(yield* catalog.provider.get(Provider.ID.make("first"))).toBeDefined()
 
 
       yield* test.setEntries([config("second")])
       yield* test.setEntries([config("second")])
+      yield* Effect.yieldNow
       yield* bus.publish(ConfigSchema.Event.Updated, {})
       yield* bus.publish(ConfigSchema.Event.Updated, {})
       yield* waitUntil(
       yield* waitUntil(
         Effect.gen(function* () {
         Effect.gen(function* () {

+ 3 - 1
packages/core/test/event-logger.test.ts

@@ -35,7 +35,9 @@ describe("EventLogger", () => {
       Effect.runPromise,
       Effect.runPromise,
     )
     )
 
 
-    expect(output.map((entry) => entry.message)).toEqual([
+    expect(
+      output.flatMap((entry) => (Array.isArray(entry.message) && entry.message[0] === "event" ? [entry.message] : [])),
+    ).toEqual([
       ["event", { event: expect.objectContaining({ type: "agent.updated" }) }],
       ["event", { event: expect.objectContaining({ type: "agent.updated" }) }],
       ["event", { event: expect.objectContaining({ type: "catalog.updated" }) }],
       ["event", { event: expect.objectContaining({ type: "catalog.updated" }) }],
       ["event", { event: expect.objectContaining({ type: "command.updated" }) }],
       ["event", { event: expect.objectContaining({ type: "command.updated" }) }],

+ 1 - 3
packages/core/test/session-log.test.ts

@@ -46,9 +46,7 @@ describe("Session.log", () => {
 
 
       const items = Array.from(yield* Stream.runCollect(session.log({ sessionID: created.id })))
       const items = Array.from(yield* Stream.runCollect(session.log({ sessionID: created.id })))
 
 
-      // Session creation commits a non-public durable event, so the marker's
-      // seq covers more of the aggregate than the public events emitted.
-      expect(items.map((item) => item.type)).toEqual(["session.renamed", "log.synced"])
+      expect(items.map((item) => item.type)).toEqual(["session.created", "session.renamed", "log.synced"])
       expect(items.at(-1)).toEqual({ type: "log.synced", aggregateID: created.id, seq: Event.Seq.make(1) })
       expect(items.at(-1)).toEqual({ type: "log.synced", aggregateID: created.id, seq: Event.Seq.make(1) })
     }),
     }),
   )
   )

+ 1 - 1
packages/core/test/session-projector.test.ts

@@ -117,7 +117,7 @@ describe("SessionProjector", () => {
         diff: "legacy patch",
         diff: "legacy patch",
         files: [{ path: "src/old.ts", status: "modified", additions: 1, deletions: 0, patch: "@@" }],
         files: [{ path: "src/old.ts", status: "modified", additions: 1, deletions: 0, patch: "@@" }],
       })
       })
-      yield* db.run(sql`update session set revert = ${legacy} where id = ${sessionID}`)
+      yield* db.run(sql`update session_v2 set revert = ${legacy} where id = ${sessionID}`)
       const stored = yield* db.select().from(SessionTable).where(eq(SessionTable.id, sessionID)).get()
       const stored = yield* db.select().from(SessionTable).where(eq(SessionTable.id, sessionID)).get()
       if (!stored) return yield* Effect.die("Session row missing")
       if (!stored) return yield* Effect.die("Session row missing")
       const storedRevert = fromRow(stored).revert
       const storedRevert = fromRow(stored).revert