diff --git a/apps/web/tests/clickable-links-gallery.e2e.ts b/apps/web/tests/clickable-links-gallery.e2e.ts index 081d183c5b..48285d1c65 100644 --- a/apps/web/tests/clickable-links-gallery.e2e.ts +++ b/apps/web/tests/clickable-links-gallery.e2e.ts @@ -45,6 +45,8 @@ const OVERLAY = fileURLToPath(new URL('./produced-files.overlay.yml', import.met const MODE = webSnapshotMode() const SEED_ID = 'clickable-links-gallery-web-e2e' const DONE = 'LINK_GALLERY_DONE' +// Seeded events and browser time share a day independently of host timezones. +const GALLERY_TIME = Date.UTC(2026, 0, 15, 12) const GUIDE_URL = 'https://docs.example.test/guide' const API_URL = 'https://docs.example.test/api' @@ -192,7 +194,6 @@ const CALLS: GalleryCall[] = [ */ function galleryFixture(imageUrl: string): string { const session = Session.create(SessionId('clickable-links-gallery-source')) - const eventTimeOrigin = new Date().setHours(12, 0, 0, 0) session.append('turn/start', { turn: 1 }) const user = session.append('user/message', createUserMessage({ content: text('Assemble the link gallery: write the report and styles, inspect the sources, and summarize.'), @@ -289,7 +290,7 @@ function galleryFixture(imageUrl: string): string { }), ...session.snapshotEvents().map(event => JSON.stringify({ ...event, - time: eventTimeOrigin + event.seq * 1_000, + time: GALLERY_TIME + event.seq * 1_000, })), '', ].join('\n') @@ -305,9 +306,10 @@ describe('web e2e: clickable links gallery', () => { beforeAll(async () => { scaffold = await launchWebScaffold({ extraOverlayPath: OVERLAY }) imageUrl = new URL('/favicon.svg', scaffold.baseUrl).toString() - await seedSession(scaffold, galleryFixture(imageUrl), SEED_ID) + await seedSession(scaffold, galleryFixture(imageUrl), SEED_ID, undefined, { createdAt: GALLERY_TIME }) browser = await chromium.launch() page = await newEnglishPage(browser) + await page.clock.setFixedTime(GALLERY_TIME + 60_000) tripwire = watchConsole(page) await page.goto(scaffold.authenticatedUrl, { waitUntil: 'load' }) await page.waitForSelector('[class*="frame"]', { timeout: 30_000 }) diff --git a/packages/fs/fs-local/tests/fsio.spec.ts b/packages/fs/fs-local/tests/fsio.spec.ts index be3bef5b5b..40ed836309 100644 --- a/packages/fs/fs-local/tests/fsio.spec.ts +++ b/packages/fs/fs-local/tests/fsio.spec.ts @@ -110,7 +110,8 @@ describe('resolveLocalTarget', () => { await mkdir(join(dir, 'nested')) await writeFile(join(dir, 'created.txt'), 'native') const drive = parse(dir).root.slice(0, 2) - const driveCwd = `${drive}${relative(process.cwd(), dir)}` + // Resolve the temp drive independently when the checkout lives on another volume. + const driveCwd = `${drive}${relative(resolve(drive), dir)}` for (const cwd of [dir, driveCwd]) { for (const requested of ['created.txt', `${drive}nested/../created.txt`]) { const target = await resolveLocalTarget(cwd, requested) diff --git a/packages/subagent/subagent/tests/list-children.spec.ts b/packages/subagent/subagent/tests/list-children.spec.ts index 6d83648d23..2794f825bd 100644 --- a/packages/subagent/subagent/tests/list-children.spec.ts +++ b/packages/subagent/subagent/tests/list-children.spec.ts @@ -35,10 +35,12 @@ import { seedStoredSession } from './persistence-helpers.ts' type Script = ConstructorParameters[0] const roots: string[] = [] +const projectionCacheDisposers: Array<() => Promise> = [] const persistenceDisposers: Array<() => Promise> = [] const projCacheRoots: string[] = [] afterEach(async () => { + await Promise.all(projectionCacheDisposers.splice(0).map(dispose => dispose())) await Promise.all(persistenceDisposers.splice(0).map(dispose => dispose())) for (const root of projCacheRoots.splice(0)) rmSync(root, { recursive: true, force: true }) for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }) @@ -64,7 +66,8 @@ async function setup( await ctx.plugin(Storage) await ctx.plugin({ name: storageJsonName, inject: storageJsonInject, apply: storageJsonApply, Config: storageJsonConfig }, { root }) await ctx.plugin({ name: storageDomainName, inject: storageDomainInject, apply: storageDomainApply, Config: storageDomainConfig }, { backend: 'json' }) - await ctx.plugin(SessionProjectionCache, { writeEveryEvents: 100, writeIntervalMs: 60_000 }) + const cache = await ctx.plugin(SessionProjectionCache, { writeEveryEvents: 100, writeIntervalMs: 60_000 }) + projectionCacheDisposers.push(() => cache.dispose()) } await ctx.plugin(TestSessionQuery) await ctx.plugin(SubagentRuntime) diff --git a/packages/subprocess/subprocess-local/tests/linux-scope.spec.ts b/packages/subprocess/subprocess-local/tests/linux-scope.spec.ts index 99a2890ae1..8aea04d9f8 100644 --- a/packages/subprocess/subprocess-local/tests/linux-scope.spec.ts +++ b/packages/subprocess/subprocess-local/tests/linux-scope.spec.ts @@ -288,10 +288,14 @@ describe('Linux scope establishment and quiescence', () => { result.owner.cleanup?.() }) - it('accepts request consumption followed by rapid --collect unload as stopped', async () => { + it.each([undefined, 'pipe'] as const)('accepts request consumption and rapid --collect unload with control %s', async (control) => { const states = [activeUnit(), unloadedUnit()] - const { child, result, requestPath } = launch(async () => states.shift() ?? missingUnit()) - expect(consumeLinuxLaunchRequest(requestPath)).toEqual({ cwd: '/target', env: { TARGET: 'yes' } }) + const controlOptions = control === undefined ? {} : { control } + const { child, result, requestPath } = launch(async () => states.shift() ?? missingUnit(), {}, { + ...spec(), stdio: { ...spec().stdio, ...controlOptions }, + }) + expect(consumeLinuxLaunchRequest(requestPath)).toEqual({ cwd: '/target', env: { TARGET: 'yes' }, ...controlOptions }) + expect(result.control).toBe(control === undefined ? undefined : child.control) const waiting = result.owner.waitForExit() child.exit(0, null) await expect(result.direct).resolves.toEqual({ exitCode: 0, signal: null })