|
| 1 | +import { env } from "cloudflare:workers"; |
1 | 2 | import { describe, expect, it } from "vitest"; |
2 | | -import { createBrowserRuntime, createBrowserTools } from "../tools/browser"; |
| 3 | +import type { BrowserToolsHost } from "./worker"; |
3 | 4 |
|
4 | | -// Shape-only tests: nothing here executes against the facet, storage, or the |
5 | | -// browser binding — those paths are exercised by the agents browser e2e |
6 | | -// suite. The facet stub satisfies the runtime's eager `ctx.facets.get`, and |
7 | | -// the export mirrors a Worker entry that re-exports CodemodeRuntime. |
8 | | -const fakeCtx = { |
9 | | - storage: {}, |
10 | | - facets: { get: () => ({}) }, |
11 | | - exports: { CodemodeRuntime: class MockCodemodeRuntime {} } |
12 | | -} as unknown as DurableObjectState; |
| 5 | +function host() { |
| 6 | + const id = env.BrowserToolsHost.idFromName("browser-tools"); |
| 7 | + return env.BrowserToolsHost.get(id) as DurableObjectStub<BrowserToolsHost>; |
| 8 | +} |
13 | 9 |
|
14 | 10 | describe("createBrowserTools", () => { |
15 | | - it("returns browser_execute plus the default Quick Action tools when a binding is present", () => { |
16 | | - const tools = createBrowserTools({ |
17 | | - ctx: fakeCtx, |
18 | | - browser: {} as Fetcher, |
19 | | - loader: {} as WorkerLoader |
20 | | - }); |
| 11 | + it("returns browser_execute plus the default Quick Action tools when a binding is present", async () => { |
| 12 | + const tools = await host().toolsWithBinding(); |
21 | 13 |
|
22 | | - expect(Object.keys(tools).sort()).toEqual([ |
| 14 | + expect(tools.keys).toEqual([ |
23 | 15 | "browser_execute", |
24 | 16 | "browser_extract", |
25 | 17 | "browser_links", |
26 | 18 | "browser_markdown", |
27 | 19 | "browser_scrape" |
28 | 20 | ]); |
29 | | - expect(typeof tools.browser_execute.execute).toBe("function"); |
| 21 | + expect(tools.hasExecute).toBe(true); |
30 | 22 | // The runtime tool description lists the cdp connector namespace. |
31 | | - expect(tools.browser_execute.description).toContain("`cdp`"); |
| 23 | + expect(tools.description).toContain("`cdp`"); |
32 | 24 | }); |
33 | 25 |
|
34 | | - it("omits Quick Action tools when quickActions is false", () => { |
35 | | - const tools = createBrowserTools({ |
36 | | - ctx: fakeCtx, |
37 | | - browser: {} as Fetcher, |
38 | | - loader: {} as WorkerLoader, |
39 | | - quickActions: false |
| 26 | + it("omits Quick Action tools when quickActions is false", async () => { |
| 27 | + await expect(host().toolsWithoutQuickActions()).resolves.toMatchObject({ |
| 28 | + keys: ["browser_execute"] |
40 | 29 | }); |
41 | | - |
42 | | - expect(Object.keys(tools)).toEqual(["browser_execute"]); |
43 | 30 | }); |
44 | 31 |
|
45 | | - it("accepts cdpUrl instead of browser binding (Quick Actions skipped without a binding)", () => { |
46 | | - const tools = createBrowserTools({ |
47 | | - ctx: fakeCtx, |
48 | | - cdpUrl: "http://localhost:9222", |
49 | | - loader: {} as WorkerLoader |
| 32 | + it("accepts cdpUrl instead of browser binding (Quick Actions skipped without a binding)", async () => { |
| 33 | + await expect(host().toolsWithCdpUrl()).resolves.toMatchObject({ |
| 34 | + keys: ["browser_execute"] |
50 | 35 | }); |
51 | | - |
52 | | - expect(Object.keys(tools)).toEqual(["browser_execute"]); |
53 | 36 | }); |
54 | 37 |
|
55 | | - it("accepts optional timeout and session mode", () => { |
56 | | - const tools = createBrowserTools({ |
57 | | - ctx: fakeCtx, |
58 | | - browser: {} as Fetcher, |
59 | | - loader: {} as WorkerLoader, |
60 | | - timeout: 60_000, |
61 | | - session: { mode: "dynamic" } |
| 38 | + it("accepts optional timeout and session mode", async () => { |
| 39 | + await expect(host().toolsWithOptions()).resolves.toMatchObject({ |
| 40 | + keys: expect.arrayContaining(["browser_execute"]) |
62 | 41 | }); |
63 | | - |
64 | | - expect(tools).toHaveProperty("browser_execute"); |
65 | 42 | }); |
66 | 43 |
|
67 | | - it("requires a browser binding or cdpUrl", () => { |
68 | | - expect(() => |
69 | | - createBrowserTools({ |
70 | | - ctx: fakeCtx, |
71 | | - loader: {} as WorkerLoader |
72 | | - }) |
73 | | - ).toThrow("must be provided"); |
| 44 | + it("requires a browser binding or cdpUrl", async () => { |
| 45 | + await expect(host().missingBrowserOrCdpUrlError()).resolves.toContain( |
| 46 | + "must be provided" |
| 47 | + ); |
74 | 48 | }); |
75 | 49 |
|
76 | | - it("exposes the runtime handle and connector via createBrowserRuntime", () => { |
77 | | - const { runtime, connector, tools } = createBrowserRuntime({ |
78 | | - ctx: fakeCtx, |
79 | | - browser: {} as Fetcher, |
80 | | - loader: {} as WorkerLoader |
| 50 | + it("exposes the runtime handle and connector via createBrowserRuntime", async () => { |
| 51 | + await expect(host().runtimeShape()).resolves.toEqual({ |
| 52 | + connectorName: "cdp", |
| 53 | + runtimeApprove: "function", |
| 54 | + runtimeExpirePaused: "function", |
| 55 | + connectorSweep: "function", |
| 56 | + hasExecute: true |
81 | 57 | }); |
82 | | - |
83 | | - expect(connector.name()).toBe("cdp"); |
84 | | - expect(typeof runtime.approve).toBe("function"); |
85 | | - expect(typeof runtime.expirePaused).toBe("function"); |
86 | | - expect(typeof connector.sweep).toBe("function"); |
87 | | - expect(tools).toHaveProperty("browser_execute"); |
88 | 58 | }); |
89 | 59 | }); |
0 commit comments