diff options
| author | Kit Langton <[email protected]> | 2026-03-31 21:24:39 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-31 21:24:39 -0400 |
| commit | c8ecd640220331ce7695d72ea8c618dd8909eab1 (patch) | |
| tree | c9b1037d1f1f9c2ecd14bab102144dfb97fb7884 /packages/app/e2e/fixtures.ts | |
| parent | ca376a4cffc47e1fd629c4073d3cdca27eba9adc (diff) | |
| download | opencode-c8ecd640220331ce7695d72ea8c618dd8909eab1.tar.gz opencode-c8ecd640220331ce7695d72ea8c618dd8909eab1.zip | |
test(app): add mock llm e2e fixture (#20375)
Diffstat (limited to 'packages/app/e2e/fixtures.ts')
| -rw-r--r-- | packages/app/e2e/fixtures.ts | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/packages/app/e2e/fixtures.ts b/packages/app/e2e/fixtures.ts index ca06858a4..7fc4cda05 100644 --- a/packages/app/e2e/fixtures.ts +++ b/packages/app/e2e/fixtures.ts @@ -1,5 +1,8 @@ import { test as base, expect, type Page } from "@playwright/test" +import { ManagedRuntime } from "effect" import type { E2EWindow } from "../src/testing/terminal" +import type { Item, Reply, Usage } from "../../opencode/test/lib/llm-server" +import { TestLLMServer } from "../../opencode/test/lib/llm-server" import { healthPhase, cleanupSession, @@ -13,6 +16,24 @@ import { } from "./actions" import { createSdk, dirSlug, getWorktree, sessionPath } from "./utils" +type LLMFixture = { + url: string + push: (...input: (Item | Reply)[]) => Promise<void> + text: (value: string, opts?: { usage?: Usage }) => Promise<void> + tool: (name: string, input: unknown) => Promise<void> + toolHang: (name: string, input: unknown) => Promise<void> + reason: (value: string, opts?: { text?: string; usage?: Usage }) => Promise<void> + fail: (message?: unknown) => Promise<void> + error: (status: number, body: unknown) => Promise<void> + hang: () => Promise<void> + hold: (value: string, wait: PromiseLike<unknown>) => Promise<void> + hits: () => Promise<Array<{ url: URL; body: Record<string, unknown> }>> + calls: () => Promise<number> + wait: (count: number) => Promise<void> + inputs: () => Promise<Record<string, unknown>[]> + pending: () => Promise<number> +} + export const settingsKey = "settings.v3" const seedModel = (() => { @@ -26,6 +47,7 @@ const seedModel = (() => { })() type TestFixtures = { + llm: LLMFixture sdk: ReturnType<typeof createSdk> gotoSession: (sessionID?: string) => Promise<void> withProject: <T>( @@ -36,7 +58,11 @@ type TestFixtures = { trackSession: (sessionID: string, directory?: string) => void trackDirectory: (directory: string) => void }) => Promise<T>, - options?: { extra?: string[] }, + options?: { + extra?: string[] + model?: { providerID: string; modelID: string } + setup?: (directory: string) => Promise<void> + }, ) => Promise<T> } @@ -46,6 +72,31 @@ type WorkerFixtures = { } export const test = base.extend<TestFixtures, WorkerFixtures>({ + llm: async ({}, use) => { + const rt = ManagedRuntime.make(TestLLMServer.layer) + try { + const svc = await rt.runPromise(TestLLMServer.asEffect()) + await use({ + url: svc.url, + push: (...input) => rt.runPromise(svc.push(...input)), + text: (value, opts) => rt.runPromise(svc.text(value, opts)), + tool: (name, input) => rt.runPromise(svc.tool(name, input)), + toolHang: (name, input) => rt.runPromise(svc.toolHang(name, input)), + reason: (value, opts) => rt.runPromise(svc.reason(value, opts)), + fail: (message) => rt.runPromise(svc.fail(message)), + error: (status, body) => rt.runPromise(svc.error(status, body)), + hang: () => rt.runPromise(svc.hang), + hold: (value, wait) => rt.runPromise(svc.hold(value, wait)), + hits: () => rt.runPromise(svc.hits), + calls: () => rt.runPromise(svc.calls), + wait: (count) => rt.runPromise(svc.wait(count)), + inputs: () => rt.runPromise(svc.inputs), + pending: () => rt.runPromise(svc.pending), + }) + } finally { + await rt.dispose() + } + }, page: async ({ page }, use) => { let boundary: string | undefined setHealthPhase(page, "test") @@ -99,7 +150,8 @@ export const test = base.extend<TestFixtures, WorkerFixtures>({ const root = await createTestProject() const sessions = new Map<string, string>() const dirs = new Set<string>() - await seedStorage(page, { directory: root, extra: options?.extra }) + await options?.setup?.(root) + await seedStorage(page, { directory: root, extra: options?.extra, model: options?.model }) const gotoSession = async (sessionID?: string) => { await page.goto(sessionPath(root, sessionID)) @@ -133,7 +185,14 @@ export const test = base.extend<TestFixtures, WorkerFixtures>({ }, }) -async function seedStorage(page: Page, input: { directory: string; extra?: string[] }) { +async function seedStorage( + page: Page, + input: { + directory: string + extra?: string[] + model?: { providerID: string; modelID: string } + }, +) { await seedProjects(page, input) await page.addInitScript((model: { providerID: string; modelID: string }) => { const win = window as E2EWindow @@ -158,7 +217,7 @@ async function seedStorage(page: Page, input: { directory: string; extra?: strin variant: {}, }), ) - }, seedModel) + }, input.model ?? seedModel) } export { expect } |
