@browserbasehq/orca 3.2.0-preview.3 → 3.2.0-preview.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/dist/cjs/lib/utils.d.ts +1 -0
  2. package/dist/cjs/lib/utils.js +4 -0
  3. package/dist/cjs/lib/utils.js.map +1 -1
  4. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +5 -7
  5. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  6. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +5 -7
  7. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  8. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +5 -7
  9. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  10. package/dist/cjs/lib/v3/agent/tools/act.js +1 -10
  11. package/dist/cjs/lib/v3/agent/tools/act.js.map +1 -1
  12. package/dist/cjs/lib/v3/agent/tools/ariaTree.js +1 -12
  13. package/dist/cjs/lib/v3/agent/tools/ariaTree.js.map +1 -1
  14. package/dist/cjs/lib/v3/agent/tools/braveSearch.js.map +1 -1
  15. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.js.map +1 -1
  16. package/dist/cjs/lib/v3/agent/tools/click.js.map +1 -1
  17. package/dist/cjs/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  18. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  19. package/dist/cjs/lib/v3/agent/tools/extract.js +1 -10
  20. package/dist/cjs/lib/v3/agent/tools/extract.js.map +1 -1
  21. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  22. package/dist/cjs/lib/v3/agent/tools/fillform.js +1 -10
  23. package/dist/cjs/lib/v3/agent/tools/fillform.js.map +1 -1
  24. package/dist/cjs/lib/v3/agent/tools/index.d.ts +2 -2
  25. package/dist/cjs/lib/v3/agent/tools/index.js +53 -5
  26. package/dist/cjs/lib/v3/agent/tools/index.js.map +1 -1
  27. package/dist/cjs/lib/v3/agent/tools/keys.d.ts +1 -1
  28. package/dist/cjs/lib/v3/agent/tools/keys.js.map +1 -1
  29. package/dist/cjs/lib/v3/agent/tools/type.js.map +1 -1
  30. package/dist/cjs/lib/v3/api.js +9 -2
  31. package/dist/cjs/lib/v3/api.js.map +1 -1
  32. package/dist/cjs/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  33. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js +30 -0
  34. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  35. package/dist/cjs/lib/v3/flowlogger/EventSink.d.ts +44 -0
  36. package/dist/cjs/lib/v3/flowlogger/EventSink.js +217 -0
  37. package/dist/cjs/lib/v3/flowlogger/EventSink.js.map +1 -0
  38. package/dist/cjs/lib/v3/flowlogger/EventStore.d.ts +26 -0
  39. package/dist/cjs/lib/v3/flowlogger/EventStore.js +135 -0
  40. package/dist/cjs/lib/v3/flowlogger/EventStore.js.map +1 -0
  41. package/dist/cjs/lib/v3/flowlogger/FlowLogger.d.ts +99 -0
  42. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js +591 -0
  43. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  44. package/dist/cjs/lib/v3/flowlogger/prettify.d.ts +6 -0
  45. package/dist/cjs/lib/v3/flowlogger/prettify.js +395 -0
  46. package/dist/cjs/lib/v3/flowlogger/prettify.js.map +1 -0
  47. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js +43 -57
  48. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  49. package/dist/cjs/lib/v3/handlers/v3AgentHandler.d.ts +0 -4
  50. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +2 -32
  51. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  52. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +9 -13
  53. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  54. package/dist/cjs/lib/v3/llm/aisdk.js +11 -17
  55. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  56. package/dist/cjs/lib/v3/types/public/options.d.ts +7 -0
  57. package/dist/cjs/lib/v3/types/public/options.js.map +1 -1
  58. package/dist/cjs/lib/v3/understudy/cdp.d.ts +3 -12
  59. package/dist/cjs/lib/v3/understudy/cdp.js +134 -21
  60. package/dist/cjs/lib/v3/understudy/cdp.js.map +1 -1
  61. package/dist/cjs/lib/v3/understudy/page.js +28 -18
  62. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  63. package/dist/cjs/lib/v3/v3.d.ts +7 -2
  64. package/dist/cjs/lib/v3/v3.js +178 -159
  65. package/dist/cjs/lib/v3/v3.js.map +1 -1
  66. package/dist/cjs/tests/integration/flowLogger.spec.d.ts +1 -0
  67. package/dist/cjs/tests/integration/flowLogger.spec.js +714 -0
  68. package/dist/cjs/tests/integration/flowLogger.spec.js.map +1 -0
  69. package/dist/cjs/tests/integration/testUtils.d.ts +33 -0
  70. package/dist/cjs/tests/integration/testUtils.js +144 -0
  71. package/dist/cjs/tests/integration/testUtils.js.map +1 -1
  72. package/dist/cjs/tests/integration/timeouts.spec.js +112 -2
  73. package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
  74. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  75. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js +95 -0
  76. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  77. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  78. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js +43 -0
  79. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  80. package/dist/cjs/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  81. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js +250 -0
  82. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  83. package/dist/esm/lib/utils.d.ts +1 -0
  84. package/dist/esm/lib/utils.js +3 -0
  85. package/dist/esm/lib/utils.js.map +1 -1
  86. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +5 -7
  87. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  88. package/dist/esm/lib/v3/agent/GoogleCUAClient.js +5 -7
  89. package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  90. package/dist/esm/lib/v3/agent/OpenAICUAClient.js +5 -7
  91. package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  92. package/dist/esm/lib/v3/agent/tools/act.js +1 -10
  93. package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
  94. package/dist/esm/lib/v3/agent/tools/ariaTree.js +1 -12
  95. package/dist/esm/lib/v3/agent/tools/ariaTree.js.map +1 -1
  96. package/dist/esm/lib/v3/agent/tools/braveSearch.js.map +1 -1
  97. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.js.map +1 -1
  98. package/dist/esm/lib/v3/agent/tools/click.js.map +1 -1
  99. package/dist/esm/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  100. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  101. package/dist/esm/lib/v3/agent/tools/extract.js +1 -10
  102. package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
  103. package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  104. package/dist/esm/lib/v3/agent/tools/fillform.js +1 -10
  105. package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
  106. package/dist/esm/lib/v3/agent/tools/index.d.ts +2 -2
  107. package/dist/esm/lib/v3/agent/tools/index.js +53 -5
  108. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  109. package/dist/esm/lib/v3/agent/tools/keys.d.ts +1 -1
  110. package/dist/esm/lib/v3/agent/tools/keys.js.map +1 -1
  111. package/dist/esm/lib/v3/agent/tools/type.js.map +1 -1
  112. package/dist/esm/lib/v3/api.js +9 -2
  113. package/dist/esm/lib/v3/api.js.map +1 -1
  114. package/dist/esm/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  115. package/dist/esm/lib/v3/flowlogger/EventEmitter.js +26 -0
  116. package/dist/esm/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  117. package/dist/esm/lib/v3/flowlogger/EventSink.d.ts +44 -0
  118. package/dist/esm/lib/v3/flowlogger/EventSink.js +206 -0
  119. package/dist/esm/lib/v3/flowlogger/EventSink.js.map +1 -0
  120. package/dist/esm/lib/v3/flowlogger/EventStore.d.ts +26 -0
  121. package/dist/esm/lib/v3/flowlogger/EventStore.js +127 -0
  122. package/dist/esm/lib/v3/flowlogger/EventStore.js.map +1 -0
  123. package/dist/esm/lib/v3/flowlogger/FlowLogger.d.ts +99 -0
  124. package/dist/esm/lib/v3/flowlogger/FlowLogger.js +583 -0
  125. package/dist/esm/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  126. package/dist/esm/lib/v3/flowlogger/prettify.d.ts +6 -0
  127. package/dist/esm/lib/v3/flowlogger/prettify.js +389 -0
  128. package/dist/esm/lib/v3/flowlogger/prettify.js.map +1 -0
  129. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js +43 -57
  130. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  131. package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +0 -4
  132. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +2 -32
  133. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  134. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +9 -13
  135. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  136. package/dist/esm/lib/v3/llm/aisdk.js +11 -17
  137. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  138. package/dist/esm/lib/v3/types/public/options.d.ts +7 -0
  139. package/dist/esm/lib/v3/types/public/options.js.map +1 -1
  140. package/dist/esm/lib/v3/understudy/cdp.d.ts +3 -12
  141. package/dist/esm/lib/v3/understudy/cdp.js +134 -21
  142. package/dist/esm/lib/v3/understudy/cdp.js.map +1 -1
  143. package/dist/esm/lib/v3/understudy/page.js +28 -18
  144. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  145. package/dist/esm/lib/v3/v3.d.ts +7 -2
  146. package/dist/esm/lib/v3/v3.js +178 -159
  147. package/dist/esm/lib/v3/v3.js.map +1 -1
  148. package/dist/esm/tests/integration/flowLogger.spec.d.ts +1 -0
  149. package/dist/esm/tests/integration/flowLogger.spec.js +712 -0
  150. package/dist/esm/tests/integration/flowLogger.spec.js.map +1 -0
  151. package/dist/esm/tests/integration/testUtils.d.ts +33 -0
  152. package/dist/esm/tests/integration/testUtils.js +138 -0
  153. package/dist/esm/tests/integration/testUtils.js.map +1 -1
  154. package/dist/esm/tests/integration/timeouts.spec.js +112 -2
  155. package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
  156. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  157. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js +93 -0
  158. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  159. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  160. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js +41 -0
  161. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  162. package/dist/esm/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  163. package/dist/esm/tests/unit/flowlogger-eventstore.test.js +248 -0
  164. package/dist/esm/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  165. package/package.json +3 -1
  166. package/dist/cjs/lib/v3/flowLogger.d.ts +0 -139
  167. package/dist/cjs/lib/v3/flowLogger.js +0 -881
  168. package/dist/cjs/lib/v3/flowLogger.js.map +0 -1
  169. package/dist/esm/lib/v3/flowLogger.d.ts +0 -139
  170. package/dist/esm/lib/v3/flowLogger.js +0 -868
  171. package/dist/esm/lib/v3/flowLogger.js.map +0 -1
@@ -0,0 +1,714 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const test_1 = require("@playwright/test");
4
+ const zod_1 = require("zod");
5
+ const EventSink_js_1 = require("../../lib/v3/flowlogger/EventSink.js");
6
+ const FlowLogger_js_1 = require("../../lib/v3/flowlogger/FlowLogger.js");
7
+ const actHandlerUtils_js_1 = require("../../lib/v3/handlers/handlerUtils/actHandlerUtils.js");
8
+ const v3_js_1 = require("../../lib/v3/v3.js");
9
+ const testUtils_js_1 = require("./testUtils.js");
10
+ const v3_config_js_1 = require("./v3.config.js");
11
+ function encodeHtml(html) {
12
+ return `data:text/html,${encodeURIComponent(html)}`;
13
+ }
14
+ function createRecordedFlowLoggerV3(overrides = {}) {
15
+ const v3 = new v3_js_1.V3((0, v3_config_js_1.getV3TestConfig)(overrides));
16
+ const sink = new EventSink_js_1.InMemoryEventSink();
17
+ v3.bus.on("*", (event) => {
18
+ if (event instanceof FlowLogger_js_1.FlowEvent) {
19
+ void sink.emit(event);
20
+ }
21
+ });
22
+ v3.eventStore.query = (query) => sink.query({ ...query, sessionId: v3.eventStore.sessionId });
23
+ return v3;
24
+ }
25
+ async function listRecordedFlowEvents(v3) {
26
+ return v3.eventStore.query({});
27
+ }
28
+ async function captureFlowEventBaseline(v3) {
29
+ const events = await listRecordedFlowEvents(v3);
30
+ return new Set(events.map((event) => event.eventId));
31
+ }
32
+ async function listRecordedFlowEventsSince(v3, baseline) {
33
+ const events = await listRecordedFlowEvents(v3);
34
+ return events.filter((event) => !baseline.has(event.eventId));
35
+ }
36
+ function eventsOfType(events, eventType) {
37
+ return events.filter((event) => event.eventType === eventType);
38
+ }
39
+ function requireSingleEvent(events, eventType) {
40
+ const matches = eventsOfType(events, eventType);
41
+ (0, test_1.expect)(matches, `expected a single ${eventType}`).toHaveLength(1);
42
+ return matches[0];
43
+ }
44
+ function expectRootEvent(event) {
45
+ (0, test_1.expect)(event.eventParentIds).toEqual([]);
46
+ }
47
+ function expectDirectParent(child, parent) {
48
+ (0, test_1.expect)(child.eventParentIds).toEqual([
49
+ ...parent.eventParentIds,
50
+ parent.eventId,
51
+ ]);
52
+ }
53
+ function assertAllParentIdsResolve(events) {
54
+ const eventIds = new Set(events.map((event) => event.eventId));
55
+ for (const event of events) {
56
+ for (const parentId of event.eventParentIds) {
57
+ (0, test_1.expect)(eventIds.has(parentId), `${event.eventType} references missing parent ${parentId}`).toBe(true);
58
+ }
59
+ }
60
+ }
61
+ function assertSessionIds(events, sessionId) {
62
+ for (const event of events) {
63
+ (0, test_1.expect)(event.sessionId).toBe(sessionId);
64
+ }
65
+ }
66
+ function directChildrenOfType(events, parent, eventType) {
67
+ const expectedParentIds = [...parent.eventParentIds, parent.eventId];
68
+ return events.filter((event) => event.eventType === eventType &&
69
+ JSON.stringify(event.eventParentIds) ===
70
+ JSON.stringify(expectedParentIds));
71
+ }
72
+ function assertCompletedEnvelope(events, eventType, completedEventType = `${eventType.replace(/Event$/, "")}CompletedEvent`) {
73
+ const root = requireSingleEvent(events, eventType);
74
+ const completed = requireSingleEvent(events, completedEventType);
75
+ expectDirectParent(completed, root);
76
+ return root;
77
+ }
78
+ function assertNoFloatingLlmEvents(events) {
79
+ const llmEvents = events.filter((event) => event.eventType === "LlmRequestEvent" ||
80
+ event.eventType === "LlmResponseEvent");
81
+ const byId = new Map(events.map((event) => [event.eventId, event]));
82
+ (0, test_1.expect)(llmEvents.length).toBeGreaterThan(0);
83
+ for (const event of llmEvents) {
84
+ (0, test_1.expect)(event.eventParentIds.length, `${event.eventType} is floating`).toBeGreaterThan(0);
85
+ const lastParentId = event.eventParentIds.at(-1);
86
+ const lastParent = lastParentId ? byId.get(lastParentId) : undefined;
87
+ (0, test_1.expect)(lastParent, `${event.eventType} has no resolved parent`).toBeDefined();
88
+ (0, test_1.expect)(lastParent?.eventType.startsWith("Llm")).toBe(false);
89
+ }
90
+ }
91
+ function assertNoFloatingCdpEvents(events) {
92
+ const cdpEvents = events.filter((event) => event.eventType.startsWith("Cdp"));
93
+ const byId = new Map(events.map((event) => [event.eventId, event]));
94
+ (0, test_1.expect)(cdpEvents.length).toBeGreaterThan(0);
95
+ for (const event of cdpEvents) {
96
+ (0, test_1.expect)(event.eventParentIds.length, `${event.eventType} is floating`).toBeGreaterThan(0);
97
+ const lastParentId = event.eventParentIds.at(-1);
98
+ const lastParent = lastParentId ? byId.get(lastParentId) : undefined;
99
+ (0, test_1.expect)(lastParent, `${event.eventType} has no resolved parent`).toBeDefined();
100
+ if (event.eventType === "CdpCallEvent") {
101
+ (0, test_1.expect)(lastParent?.eventType.startsWith("Cdp")).toBe(false);
102
+ }
103
+ else {
104
+ (0, test_1.expect)(lastParent?.eventType).toBe("CdpCallEvent");
105
+ }
106
+ }
107
+ }
108
+ function assertDirectRootCdpEvents(events, sessionId) {
109
+ const call = requireSingleEvent(events, "CdpCallEvent");
110
+ const responseTypes = ["CdpResponseEvent", "CdpResponseErrorEvent"];
111
+ const response = events.find((event) => responseTypes.includes(event.eventType));
112
+ (0, test_1.expect)(response, "expected a direct CDP response event").toBeDefined();
113
+ assertSessionIds(events, sessionId);
114
+ expectRootEvent(call);
115
+ (0, test_1.expect)(response?.eventParentIds).toEqual([call.eventId]);
116
+ }
117
+ function sortCountRecord(input) {
118
+ return Object.fromEntries(Object.entries(input).sort(([left], [right]) => left.localeCompare(right)));
119
+ }
120
+ function assertNonCdpEventCounts(events, expected) {
121
+ const actual = events.reduce((counts, event) => {
122
+ if (event.eventType.startsWith("Cdp")) {
123
+ return counts;
124
+ }
125
+ counts[event.eventType] = (counts[event.eventType] ?? 0) + 1;
126
+ return counts;
127
+ }, {});
128
+ (0, test_1.expect)(sortCountRecord(actual)).toEqual(sortCountRecord(expected));
129
+ }
130
+ test_1.test.describe("flow logger integration", () => {
131
+ test_1.test.describe.configure({ mode: "serial" });
132
+ (0, test_1.test)("act emits a rooted tree with nested understudy, llm, and cdp events", async () => {
133
+ const buttonText = "Flow Logger Act Button";
134
+ const llmClient = (0, testUtils_js_1.createScriptedAisdkTestLlmClient)({
135
+ jsonResponses: {
136
+ act: (options) => ({
137
+ elementId: (0, testUtils_js_1.findLastEncodedId)(options),
138
+ description: `click ${buttonText}`,
139
+ method: "click",
140
+ arguments: [],
141
+ twoStep: false,
142
+ }),
143
+ },
144
+ });
145
+ const v3 = createRecordedFlowLoggerV3({
146
+ llmClient,
147
+ });
148
+ await v3.init();
149
+ try {
150
+ const page = v3.context.pages()[0];
151
+ await page.goto(encodeHtml(`
152
+ <!doctype html>
153
+ <html>
154
+ <body>
155
+ <button
156
+ id="act-target"
157
+ onclick="document.body.dataset.clicked='true'"
158
+ >
159
+ ${buttonText}
160
+ </button>
161
+ </body>
162
+ </html>
163
+ `));
164
+ const baseline = await captureFlowEventBaseline(v3);
165
+ const result = await v3.act(`Click the ${buttonText}`);
166
+ const events = await listRecordedFlowEventsSince(v3, baseline);
167
+ (0, test_1.expect)(result.success).toBe(true);
168
+ (0, test_1.expect)(await page.evaluate(() => document.body.dataset.clicked ?? "")).toBe("true");
169
+ const root = requireSingleEvent(events, "StagehandActEvent");
170
+ const completed = requireSingleEvent(events, "StagehandActCompletedEvent");
171
+ const llmRequest = requireSingleEvent(events, "LlmRequestEvent");
172
+ const llmResponse = requireSingleEvent(events, "LlmResponseEvent");
173
+ const understudy = requireSingleEvent(events, "UnderstudyClickEvent");
174
+ const understudyCompleted = requireSingleEvent(events, "UnderstudyClickCompletedEvent");
175
+ assertAllParentIdsResolve(events);
176
+ assertNonCdpEventCounts(events, {
177
+ LlmRequestEvent: 1,
178
+ LlmResponseEvent: 1,
179
+ StagehandActCompletedEvent: 1,
180
+ StagehandActEvent: 1,
181
+ UnderstudyClickCompletedEvent: 1,
182
+ UnderstudyClickEvent: 1,
183
+ });
184
+ assertSessionIds(events, v3.flowLoggerContext.sessionId);
185
+ expectRootEvent(root);
186
+ expectDirectParent(completed, root);
187
+ (0, test_1.expect)(llmRequest.eventParentIds).toEqual([root.eventId]);
188
+ (0, test_1.expect)(llmResponse.eventParentIds).toEqual([root.eventId]);
189
+ (0, test_1.expect)(understudy.eventParentIds).toEqual([root.eventId]);
190
+ expectDirectParent(understudyCompleted, understudy);
191
+ assertNoFloatingLlmEvents(events);
192
+ assertNoFloatingCdpEvents(events);
193
+ }
194
+ finally {
195
+ await (0, testUtils_js_1.closeV3)(v3);
196
+ }
197
+ });
198
+ (0, test_1.test)("observe and extract emit rooted trees with complete nested llm and cdp events", async () => {
199
+ const observeText = "Flow Logger Observe Button";
200
+ const extractTitle = "Flow Logger Extract Title";
201
+ const llmClient = (0, testUtils_js_1.createScriptedAisdkTestLlmClient)({
202
+ jsonResponses: {
203
+ Observation: (options) => ({
204
+ elements: [
205
+ {
206
+ elementId: (0, testUtils_js_1.findLastEncodedId)(options),
207
+ description: observeText,
208
+ method: "click",
209
+ arguments: [],
210
+ },
211
+ ],
212
+ }),
213
+ Extraction: {
214
+ title: extractTitle,
215
+ },
216
+ Metadata: {
217
+ completed: true,
218
+ progress: "done",
219
+ },
220
+ },
221
+ });
222
+ const v3 = createRecordedFlowLoggerV3({
223
+ llmClient,
224
+ });
225
+ await v3.init();
226
+ try {
227
+ const page = v3.context.pages()[0];
228
+ await page.goto(encodeHtml(`
229
+ <!doctype html>
230
+ <html>
231
+ <body>
232
+ <button id="observe-target">${observeText}</button>
233
+ <h1>${extractTitle}</h1>
234
+ </body>
235
+ </html>
236
+ `));
237
+ const observeBaseline = await captureFlowEventBaseline(v3);
238
+ const observeResult = await v3.observe(`Find the ${observeText}`);
239
+ (0, test_1.expect)(observeResult).toHaveLength(1);
240
+ (0, test_1.expect)(observeResult[0].method).toBe("click");
241
+ const observeEvents = await listRecordedFlowEventsSince(v3, observeBaseline);
242
+ const observeRoot = requireSingleEvent(observeEvents, "StagehandObserveEvent");
243
+ const observeCompleted = requireSingleEvent(observeEvents, "StagehandObserveCompletedEvent");
244
+ const observeLlmRequests = eventsOfType(observeEvents, "LlmRequestEvent");
245
+ const observeLlmResponses = eventsOfType(observeEvents, "LlmResponseEvent");
246
+ assertAllParentIdsResolve(observeEvents);
247
+ assertNonCdpEventCounts(observeEvents, {
248
+ LlmRequestEvent: 1,
249
+ LlmResponseEvent: 1,
250
+ StagehandObserveCompletedEvent: 1,
251
+ StagehandObserveEvent: 1,
252
+ });
253
+ assertSessionIds(observeEvents, v3.flowLoggerContext.sessionId);
254
+ expectRootEvent(observeRoot);
255
+ expectDirectParent(observeCompleted, observeRoot);
256
+ (0, test_1.expect)(observeLlmRequests).toHaveLength(1);
257
+ (0, test_1.expect)(observeLlmResponses).toHaveLength(1);
258
+ (0, test_1.expect)(observeLlmRequests[0].eventParentIds).toEqual([
259
+ observeRoot.eventId,
260
+ ]);
261
+ (0, test_1.expect)(observeLlmResponses[0].eventParentIds).toEqual([
262
+ observeRoot.eventId,
263
+ ]);
264
+ assertNoFloatingLlmEvents(observeEvents);
265
+ assertNoFloatingCdpEvents(observeEvents);
266
+ const extractBaseline = await captureFlowEventBaseline(v3);
267
+ const extractResult = await v3.extract("Extract the title", zod_1.z.object({ title: zod_1.z.string() }));
268
+ (0, test_1.expect)(extractResult).toEqual({ title: extractTitle });
269
+ const extractEvents = await listRecordedFlowEventsSince(v3, extractBaseline);
270
+ const extractRoot = requireSingleEvent(extractEvents, "StagehandExtractEvent");
271
+ const extractCompleted = requireSingleEvent(extractEvents, "StagehandExtractCompletedEvent");
272
+ const extractLlmRequests = eventsOfType(extractEvents, "LlmRequestEvent");
273
+ const extractLlmResponses = eventsOfType(extractEvents, "LlmResponseEvent");
274
+ assertAllParentIdsResolve(extractEvents);
275
+ assertNonCdpEventCounts(extractEvents, {
276
+ LlmRequestEvent: 2,
277
+ LlmResponseEvent: 2,
278
+ StagehandExtractCompletedEvent: 1,
279
+ StagehandExtractEvent: 1,
280
+ });
281
+ assertSessionIds(extractEvents, v3.flowLoggerContext.sessionId);
282
+ expectRootEvent(extractRoot);
283
+ expectDirectParent(extractCompleted, extractRoot);
284
+ (0, test_1.expect)(extractLlmRequests).toHaveLength(2);
285
+ (0, test_1.expect)(extractLlmResponses).toHaveLength(2);
286
+ for (const event of [...extractLlmRequests, ...extractLlmResponses]) {
287
+ (0, test_1.expect)(event.eventParentIds).toEqual([extractRoot.eventId]);
288
+ }
289
+ assertNoFloatingLlmEvents(extractEvents);
290
+ assertNoFloatingCdpEvents(extractEvents);
291
+ }
292
+ finally {
293
+ await (0, testUtils_js_1.closeV3)(v3);
294
+ }
295
+ });
296
+ (0, test_1.test)("agent.execute -> act carries the full agent -> stagehand -> understudy -> cdp + llm hierarchy", async () => {
297
+ const buttonText = "Agent Act Button";
298
+ const llmClient = (0, testUtils_js_1.createScriptedAisdkTestLlmClient)({
299
+ jsonResponses: {
300
+ act: (options) => ({
301
+ elementId: (0, testUtils_js_1.findLastEncodedId)(options),
302
+ description: `click ${buttonText}`,
303
+ method: "click",
304
+ arguments: [],
305
+ twoStep: false,
306
+ }),
307
+ },
308
+ generateResponses: [
309
+ (0, testUtils_js_1.toolCallResponse)("act", { action: `click the ${buttonText}` }, "act-1"),
310
+ (0, testUtils_js_1.doneToolResponse)("finished", true, "done-1"),
311
+ ],
312
+ });
313
+ const v3 = createRecordedFlowLoggerV3({
314
+ experimental: true,
315
+ llmClient,
316
+ });
317
+ await v3.init();
318
+ try {
319
+ const page = v3.context.pages()[0];
320
+ await page.goto(encodeHtml(`
321
+ <!doctype html>
322
+ <html>
323
+ <body>
324
+ <button
325
+ id="agent-act-target"
326
+ onclick="document.body.dataset.agentAct='true'"
327
+ >
328
+ ${buttonText}
329
+ </button>
330
+ </body>
331
+ </html>
332
+ `));
333
+ const baseline = await captureFlowEventBaseline(v3);
334
+ const result = await v3.agent().execute({
335
+ instruction: `Click the ${buttonText} and finish.`,
336
+ maxSteps: 2,
337
+ });
338
+ const events = await listRecordedFlowEventsSince(v3, baseline);
339
+ (0, test_1.expect)(result.success).toBe(true);
340
+ (0, test_1.expect)(await page.evaluate(() => document.body.dataset.agentAct ?? "")).toBe("true");
341
+ const agentRoot = assertCompletedEnvelope(events, "AgentExecuteEvent");
342
+ const actRoot = requireSingleEvent(events, "StagehandActEvent");
343
+ const actCompleted = requireSingleEvent(events, "StagehandActCompletedEvent");
344
+ const understudy = requireSingleEvent(events, "UnderstudyClickEvent");
345
+ const understudyCompleted = requireSingleEvent(events, "UnderstudyClickCompletedEvent");
346
+ assertAllParentIdsResolve(events);
347
+ assertNonCdpEventCounts(events, {
348
+ AgentExecuteCompletedEvent: 1,
349
+ AgentExecuteEvent: 1,
350
+ LlmRequestEvent: 3,
351
+ LlmResponseEvent: 3,
352
+ StagehandActCompletedEvent: 1,
353
+ StagehandActEvent: 1,
354
+ UnderstudyClickCompletedEvent: 1,
355
+ UnderstudyClickEvent: 1,
356
+ });
357
+ assertSessionIds(events, v3.flowLoggerContext.sessionId);
358
+ expectRootEvent(agentRoot);
359
+ (0, test_1.expect)(actRoot.eventParentIds).toEqual([agentRoot.eventId]);
360
+ expectDirectParent(actCompleted, actRoot);
361
+ expectDirectParent(understudy, actRoot);
362
+ expectDirectParent(understudyCompleted, understudy);
363
+ (0, test_1.expect)(directChildrenOfType(events, agentRoot, "LlmRequestEvent")).toHaveLength(2);
364
+ (0, test_1.expect)(directChildrenOfType(events, agentRoot, "LlmResponseEvent")).toHaveLength(2);
365
+ (0, test_1.expect)(directChildrenOfType(events, actRoot, "LlmRequestEvent")).toHaveLength(1);
366
+ (0, test_1.expect)(directChildrenOfType(events, actRoot, "LlmResponseEvent")).toHaveLength(1);
367
+ assertNoFloatingLlmEvents(events);
368
+ assertNoFloatingCdpEvents(events);
369
+ }
370
+ finally {
371
+ await (0, testUtils_js_1.closeV3)(v3);
372
+ }
373
+ });
374
+ (0, test_1.test)("agent.execute -> fillForm carries the observe -> act -> understudy hierarchy with no missing layers", async () => {
375
+ const llmClient = (0, testUtils_js_1.createScriptedAisdkTestLlmClient)({
376
+ jsonResponses: {
377
+ Observation: (options) => ({
378
+ elements: [
379
+ {
380
+ elementId: (0, testUtils_js_1.findLastEncodedId)(options),
381
+ description: "name input",
382
+ method: "fill",
383
+ arguments: ["hello"],
384
+ },
385
+ ],
386
+ }),
387
+ },
388
+ generateResponses: [
389
+ (0, testUtils_js_1.toolCallResponse)("fillForm", {
390
+ fields: [
391
+ {
392
+ action: "type hello into the name field",
393
+ value: "hello",
394
+ },
395
+ ],
396
+ }, "fillform-1"),
397
+ (0, testUtils_js_1.doneToolResponse)("finished", true, "done-1"),
398
+ ],
399
+ });
400
+ const v3 = createRecordedFlowLoggerV3({
401
+ experimental: true,
402
+ llmClient,
403
+ });
404
+ await v3.init();
405
+ try {
406
+ const page = v3.context.pages()[0];
407
+ await page.goto(encodeHtml(`
408
+ <!doctype html>
409
+ <html>
410
+ <body>
411
+ <input id="name" />
412
+ </body>
413
+ </html>
414
+ `));
415
+ const baseline = await captureFlowEventBaseline(v3);
416
+ const result = await v3.agent().execute({
417
+ instruction: "Fill the form and finish.",
418
+ maxSteps: 2,
419
+ });
420
+ const events = await listRecordedFlowEventsSince(v3, baseline);
421
+ (0, test_1.expect)(result.success).toBe(true);
422
+ (0, test_1.expect)(await page.locator("#name").inputValue()).toBe("hello");
423
+ const agentRoot = assertCompletedEnvelope(events, "AgentExecuteEvent");
424
+ const observeRoot = requireSingleEvent(events, "StagehandObserveEvent");
425
+ const observeCompleted = requireSingleEvent(events, "StagehandObserveCompletedEvent");
426
+ const actRoot = requireSingleEvent(events, "StagehandActEvent");
427
+ const actCompleted = requireSingleEvent(events, "StagehandActCompletedEvent");
428
+ const understudyFill = requireSingleEvent(events, "UnderstudyFillEvent");
429
+ const understudyFillCompleted = requireSingleEvent(events, "UnderstudyFillCompletedEvent");
430
+ assertAllParentIdsResolve(events);
431
+ assertNonCdpEventCounts(events, {
432
+ AgentExecuteCompletedEvent: 1,
433
+ AgentExecuteEvent: 1,
434
+ LlmRequestEvent: 3,
435
+ LlmResponseEvent: 3,
436
+ StagehandActCompletedEvent: 1,
437
+ StagehandActEvent: 1,
438
+ StagehandObserveCompletedEvent: 1,
439
+ StagehandObserveEvent: 1,
440
+ UnderstudyFillCompletedEvent: 1,
441
+ UnderstudyFillEvent: 1,
442
+ });
443
+ assertSessionIds(events, v3.flowLoggerContext.sessionId);
444
+ expectRootEvent(agentRoot);
445
+ (0, test_1.expect)(observeRoot.eventParentIds).toEqual([agentRoot.eventId]);
446
+ expectDirectParent(observeCompleted, observeRoot);
447
+ (0, test_1.expect)(actRoot.eventParentIds).toEqual([agentRoot.eventId]);
448
+ expectDirectParent(actCompleted, actRoot);
449
+ expectDirectParent(understudyFill, actRoot);
450
+ expectDirectParent(understudyFillCompleted, understudyFill);
451
+ (0, test_1.expect)(directChildrenOfType(events, observeRoot, "LlmRequestEvent")).toHaveLength(1);
452
+ (0, test_1.expect)(directChildrenOfType(events, observeRoot, "LlmResponseEvent")).toHaveLength(1);
453
+ (0, test_1.expect)(directChildrenOfType(events, agentRoot, "LlmRequestEvent")).toHaveLength(2);
454
+ (0, test_1.expect)(directChildrenOfType(events, agentRoot, "LlmResponseEvent")).toHaveLength(2);
455
+ (0, test_1.expect)(directChildrenOfType(events, actRoot, "LlmRequestEvent")).toHaveLength(0);
456
+ (0, test_1.expect)(directChildrenOfType(events, actRoot, "LlmResponseEvent")).toHaveLength(0);
457
+ assertNoFloatingLlmEvents(events);
458
+ assertNoFloatingCdpEvents(events);
459
+ }
460
+ finally {
461
+ await (0, testUtils_js_1.closeV3)(v3);
462
+ }
463
+ });
464
+ (0, test_1.test)("agent.execute -> extract carries the full agent -> extract -> cdp + llm hierarchy", async () => {
465
+ const extractTitle = "Agent Extract Title";
466
+ const llmClient = (0, testUtils_js_1.createScriptedAisdkTestLlmClient)({
467
+ jsonResponses: {
468
+ Extraction: {
469
+ title: extractTitle,
470
+ },
471
+ Metadata: {
472
+ completed: true,
473
+ progress: "done",
474
+ },
475
+ },
476
+ generateResponses: [
477
+ (0, testUtils_js_1.toolCallResponse)("extract", {
478
+ instruction: "extract the title",
479
+ schema: {
480
+ type: "object",
481
+ properties: {
482
+ title: { type: "string" },
483
+ },
484
+ },
485
+ }, "extract-1"),
486
+ (0, testUtils_js_1.doneToolResponse)("finished", true, "done-1"),
487
+ ],
488
+ });
489
+ const v3 = createRecordedFlowLoggerV3({
490
+ experimental: true,
491
+ llmClient,
492
+ });
493
+ await v3.init();
494
+ try {
495
+ const page = v3.context.pages()[0];
496
+ await page.goto(encodeHtml(`
497
+ <!doctype html>
498
+ <html>
499
+ <body>
500
+ <h1>${extractTitle}</h1>
501
+ </body>
502
+ </html>
503
+ `));
504
+ const baseline = await captureFlowEventBaseline(v3);
505
+ const result = await v3.agent().execute({
506
+ instruction: "Extract the title and finish.",
507
+ maxSteps: 2,
508
+ });
509
+ (0, test_1.expect)(result.success).toBe(true);
510
+ const events = await listRecordedFlowEventsSince(v3, baseline);
511
+ const agentRoot = assertCompletedEnvelope(events, "AgentExecuteEvent");
512
+ const extractRoot = requireSingleEvent(events, "StagehandExtractEvent");
513
+ const extractCompleted = requireSingleEvent(events, "StagehandExtractCompletedEvent");
514
+ assertAllParentIdsResolve(events);
515
+ assertNonCdpEventCounts(events, {
516
+ AgentExecuteCompletedEvent: 1,
517
+ AgentExecuteEvent: 1,
518
+ LlmRequestEvent: 4,
519
+ LlmResponseEvent: 4,
520
+ StagehandExtractCompletedEvent: 1,
521
+ StagehandExtractEvent: 1,
522
+ });
523
+ assertSessionIds(events, v3.flowLoggerContext.sessionId);
524
+ expectRootEvent(agentRoot);
525
+ (0, test_1.expect)(extractRoot.eventParentIds).toEqual([agentRoot.eventId]);
526
+ expectDirectParent(extractCompleted, extractRoot);
527
+ (0, test_1.expect)(directChildrenOfType(events, agentRoot, "LlmRequestEvent")).toHaveLength(2);
528
+ (0, test_1.expect)(directChildrenOfType(events, agentRoot, "LlmResponseEvent")).toHaveLength(2);
529
+ (0, test_1.expect)(directChildrenOfType(events, extractRoot, "LlmRequestEvent")).toHaveLength(2);
530
+ (0, test_1.expect)(directChildrenOfType(events, extractRoot, "LlmResponseEvent")).toHaveLength(2);
531
+ assertNoFloatingLlmEvents(events);
532
+ assertNoFloatingCdpEvents(events);
533
+ }
534
+ finally {
535
+ await (0, testUtils_js_1.closeV3)(v3);
536
+ }
537
+ });
538
+ (0, test_1.test)("agent.execute nests page events under the agent root and direct page calls root themselves", async () => {
539
+ const agentPageUrl = encodeHtml(`
540
+ <!doctype html>
541
+ <html>
542
+ <body>
543
+ <h1>Agent Flow Logger Page</h1>
544
+ </body>
545
+ </html>
546
+ `);
547
+ const agentLlmClient = (0, testUtils_js_1.createScriptedAisdkTestLlmClient)({
548
+ generateResponses: [
549
+ (0, testUtils_js_1.toolCallResponse)("goto", { url: agentPageUrl }, "goto-1"),
550
+ (0, testUtils_js_1.toolCallResponse)("screenshot", {}, "screenshot-1"),
551
+ (0, testUtils_js_1.doneToolResponse)("finished", true, "done-1"),
552
+ ],
553
+ });
554
+ const agentV3 = createRecordedFlowLoggerV3({
555
+ experimental: true,
556
+ llmClient: agentLlmClient,
557
+ });
558
+ await agentV3.init();
559
+ try {
560
+ const baseline = await captureFlowEventBaseline(agentV3);
561
+ const result = await agentV3.agent().execute({
562
+ instruction: "Go to the test page, take a screenshot, and finish.",
563
+ maxSteps: 3,
564
+ });
565
+ (0, test_1.expect)(result.success).toBe(true);
566
+ (0, test_1.expect)(result.completed).toBe(true);
567
+ const events = await listRecordedFlowEventsSince(agentV3, baseline);
568
+ const root = assertCompletedEnvelope(events, "AgentExecuteEvent");
569
+ const pageGoto = requireSingleEvent(events, "PageGotoEvent");
570
+ const pageGotoCompleted = requireSingleEvent(events, "PageGotoCompletedEvent");
571
+ const pageScreenshot = requireSingleEvent(events, "PageScreenshotEvent");
572
+ const pageScreenshotCompleted = requireSingleEvent(events, "PageScreenshotCompletedEvent");
573
+ const llmRequests = eventsOfType(events, "LlmRequestEvent");
574
+ const llmResponses = eventsOfType(events, "LlmResponseEvent");
575
+ assertAllParentIdsResolve(events);
576
+ assertNonCdpEventCounts(events, {
577
+ AgentExecuteCompletedEvent: 1,
578
+ AgentExecuteEvent: 1,
579
+ LlmRequestEvent: 3,
580
+ LlmResponseEvent: 3,
581
+ PageGotoCompletedEvent: 1,
582
+ PageGotoEvent: 1,
583
+ PageScreenshotCompletedEvent: 1,
584
+ PageScreenshotEvent: 1,
585
+ });
586
+ assertSessionIds(events, agentV3.flowLoggerContext.sessionId);
587
+ expectRootEvent(root);
588
+ (0, test_1.expect)(pageGoto.eventParentIds).toEqual([root.eventId]);
589
+ expectDirectParent(pageGotoCompleted, pageGoto);
590
+ (0, test_1.expect)(pageScreenshot.eventParentIds).toEqual([root.eventId]);
591
+ expectDirectParent(pageScreenshotCompleted, pageScreenshot);
592
+ (0, test_1.expect)(llmRequests).toHaveLength(3);
593
+ (0, test_1.expect)(llmResponses).toHaveLength(3);
594
+ for (const event of [...llmRequests, ...llmResponses]) {
595
+ (0, test_1.expect)(event.eventParentIds).toEqual([root.eventId]);
596
+ }
597
+ assertNoFloatingLlmEvents(events);
598
+ assertNoFloatingCdpEvents(events);
599
+ }
600
+ finally {
601
+ await (0, testUtils_js_1.closeV3)(agentV3);
602
+ }
603
+ const directV3 = createRecordedFlowLoggerV3();
604
+ await directV3.init();
605
+ try {
606
+ const page = directV3.context.pages()[0];
607
+ const baseline = await captureFlowEventBaseline(directV3);
608
+ await page.goto(agentPageUrl);
609
+ await page.screenshot({ fullPage: false });
610
+ const events = await listRecordedFlowEventsSince(directV3, baseline);
611
+ const pageGoto = requireSingleEvent(events, "PageGotoEvent");
612
+ const pageGotoCompleted = requireSingleEvent(events, "PageGotoCompletedEvent");
613
+ const pageScreenshot = requireSingleEvent(events, "PageScreenshotEvent");
614
+ const pageScreenshotCompleted = requireSingleEvent(events, "PageScreenshotCompletedEvent");
615
+ assertAllParentIdsResolve(events);
616
+ assertNonCdpEventCounts(events, {
617
+ PageGotoCompletedEvent: 1,
618
+ PageGotoEvent: 1,
619
+ PageScreenshotCompletedEvent: 1,
620
+ PageScreenshotEvent: 1,
621
+ });
622
+ assertSessionIds(events, directV3.flowLoggerContext.sessionId);
623
+ expectRootEvent(pageGoto);
624
+ expectDirectParent(pageGotoCompleted, pageGoto);
625
+ expectRootEvent(pageScreenshot);
626
+ expectDirectParent(pageScreenshotCompleted, pageScreenshot);
627
+ (0, test_1.expect)(eventsOfType(events, "LlmRequestEvent")).toHaveLength(0);
628
+ (0, test_1.expect)(eventsOfType(events, "LlmResponseEvent")).toHaveLength(0);
629
+ assertNoFloatingCdpEvents(events);
630
+ }
631
+ finally {
632
+ await (0, testUtils_js_1.closeV3)(directV3);
633
+ }
634
+ });
635
+ (0, test_1.test)("direct page methods, direct understudy calls, and direct sendCDP all attach complete event trees to the session", async () => {
636
+ const v3 = createRecordedFlowLoggerV3();
637
+ await v3.init();
638
+ try {
639
+ const page = v3.context.pages()[0];
640
+ await page.goto(encodeHtml(`
641
+ <!doctype html>
642
+ <html>
643
+ <body>
644
+ <button
645
+ id="direct-click"
646
+ onclick="document.body.dataset.directClick='true'"
647
+ >
648
+ Direct Click
649
+ </button>
650
+ <div id="ready">ready</div>
651
+ </body>
652
+ </html>
653
+ `));
654
+ let baseline = await captureFlowEventBaseline(v3);
655
+ await page.evaluate(() => document.getElementById("ready")?.textContent);
656
+ let events = await listRecordedFlowEventsSince(v3, baseline);
657
+ let root = assertCompletedEnvelope(events, "PageEvaluateEvent");
658
+ assertAllParentIdsResolve(events);
659
+ assertNonCdpEventCounts(events, {
660
+ PageEvaluateCompletedEvent: 1,
661
+ PageEvaluateEvent: 1,
662
+ });
663
+ assertSessionIds(events, v3.flowLoggerContext.sessionId);
664
+ expectRootEvent(root);
665
+ (0, test_1.expect)(eventsOfType(events, "LlmRequestEvent")).toHaveLength(0);
666
+ (0, test_1.expect)(eventsOfType(events, "LlmResponseEvent")).toHaveLength(0);
667
+ assertNoFloatingCdpEvents(events);
668
+ baseline = await captureFlowEventBaseline(v3);
669
+ await page.snapshot();
670
+ events = await listRecordedFlowEventsSince(v3, baseline);
671
+ root = assertCompletedEnvelope(events, "PageSnapshotEvent");
672
+ assertAllParentIdsResolve(events);
673
+ assertNonCdpEventCounts(events, {
674
+ PageSnapshotCompletedEvent: 1,
675
+ PageSnapshotEvent: 1,
676
+ });
677
+ assertSessionIds(events, v3.flowLoggerContext.sessionId);
678
+ expectRootEvent(root);
679
+ (0, test_1.expect)(eventsOfType(events, "LlmRequestEvent")).toHaveLength(0);
680
+ (0, test_1.expect)(eventsOfType(events, "LlmResponseEvent")).toHaveLength(0);
681
+ assertNoFloatingCdpEvents(events);
682
+ baseline = await captureFlowEventBaseline(v3);
683
+ await (0, actHandlerUtils_js_1.performUnderstudyMethod)(page, page.mainFrame(), "click", "/html/body/button", [], 30_000);
684
+ events = await listRecordedFlowEventsSince(v3, baseline);
685
+ root = assertCompletedEnvelope(events, "UnderstudyClickEvent");
686
+ assertAllParentIdsResolve(events);
687
+ assertNonCdpEventCounts(events, {
688
+ UnderstudyClickCompletedEvent: 1,
689
+ UnderstudyClickEvent: 1,
690
+ });
691
+ assertSessionIds(events, v3.flowLoggerContext.sessionId);
692
+ expectRootEvent(root);
693
+ (0, test_1.expect)(eventsOfType(events, "LlmRequestEvent")).toHaveLength(0);
694
+ (0, test_1.expect)(eventsOfType(events, "LlmResponseEvent")).toHaveLength(0);
695
+ assertNoFloatingCdpEvents(events);
696
+ (0, test_1.expect)(await page.evaluate(() => document.body.dataset.directClick ?? "")).toBe("true");
697
+ baseline = await captureFlowEventBaseline(v3);
698
+ const cdpResult = await page.sendCDP("Runtime.evaluate", {
699
+ expression: "2 + 2",
700
+ returnByValue: true,
701
+ });
702
+ events = await listRecordedFlowEventsSince(v3, baseline);
703
+ (0, test_1.expect)(cdpResult.result?.value).toBe(4);
704
+ (0, test_1.expect)(eventsOfType(events, "LlmRequestEvent")).toHaveLength(0);
705
+ (0, test_1.expect)(eventsOfType(events, "LlmResponseEvent")).toHaveLength(0);
706
+ assertAllParentIdsResolve(events);
707
+ assertDirectRootCdpEvents(events, v3.flowLoggerContext.sessionId);
708
+ }
709
+ finally {
710
+ await (0, testUtils_js_1.closeV3)(v3);
711
+ }
712
+ });
713
+ });
714
+ //# sourceMappingURL=flowLogger.spec.js.map