1import * as AWS from "@/AWS";
2import { BrowserCustom } from "@/AWS/BedrockAgentCore";
3import * as Test from "@/Test/Alchemy";
4import * as control from "@distilled.cloud/aws/bedrock-agentcore-control";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import * as Schedule from "effect/Schedule";
8
9const { test } = Test.make({ providers: AWS.providers() });
10
11// Ungated typed-error probe.
12test.provider(
13 "getBrowser on a nonexistent id fails with ResourceNotFoundException",
14 () =>
15 Effect.gen(function* () {
16 const error = yield* Effect.flip(
17 control.getBrowser({
18 browserId: "alchemy_nonexistent_probe-0000000000",
19 }),
20 );
21 expect(error._tag).toBe("ResourceNotFoundException");
22 }),
23 { tags: ["provider:aws", "provider:aws:bedrockagentcore", "live"] },
24);
25
26const assertBrowserGone = (browserId: string) =>
27 Effect.gen(function* () {
28 const status = yield* control.getBrowser({ browserId }).pipe(
29 Effect.map((r) => r.status as string),
30 Effect.catchTag("ResourceNotFoundException", () =>
31 Effect.succeed("DELETED" as string),
32 ),
33 );
34 if (status !== "DELETED") {
35 return yield* Effect.fail(
36 new Error(`browser still live (status: ${status})`),
37 );
38 }
39 }).pipe(
40 Effect.retry({
41 schedule: Schedule.max([
42 Schedule.fixed("3 seconds"),
43 Schedule.recurs(10),
44 ]),
45 }),
46 );
47
48test.provider(
49 "create custom browser, verify out-of-band, destroy",
50 (stack) =>
51 Effect.gen(function* () {
52 yield* stack.destroy();
53
54 const { browser } = yield* stack.deploy(
55 Effect.gen(function* () {
56 const browser = yield* BrowserCustom("AgentBrowser", {
57 description: "alchemy agentcore browser test",
58 tags: { fixture: "agentcore-browser" },
59 });
60 return { browser };
61 }),
62 );
63
64 expect(browser.browserId).toBeTruthy();
65 expect(browser.browserArn).toContain(":browser");
66 expect(browser.status).toBe("READY");
67
68 const observed = yield* control.getBrowser({
69 browserId: browser.browserId,
70 });
71 expect(observed.status).toBe("READY");
72 expect(observed.networkConfiguration.networkMode).toBe("PUBLIC");
73
74 // tags observed on the resource
75 const tags = yield* control.listTagsForResource({
76 resourceArn: browser.browserArn,
77 });
78 expect(tags.tags?.fixture).toBe("agentcore-browser");
79 expect(tags.tags?.["alchemy::id"]).toBe("AgentBrowser");
80
81 yield* stack.destroy();
82 yield* assertBrowserGone(browser.browserId);
83 }),
84 {
85 tags: ["provider:aws", "provider:aws:bedrockagentcore", "live"],
86 timeout: 120_000,
87 },
88);