momentic 0.0.10 → 0.0.12

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 (3) hide show
  1. package/bin/cli.js +1325 -1170
  2. package/dist/index.js +1085 -982
  3. package/package.json +3 -1
package/bin/cli.js CHANGED
@@ -1,10 +1,62 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
33
+ var __async = (__this, __arguments, generator) => {
34
+ return new Promise((resolve, reject) => {
35
+ var fulfilled = (value) => {
36
+ try {
37
+ step(generator.next(value));
38
+ } catch (e) {
39
+ reject(e);
40
+ }
41
+ };
42
+ var rejected = (value) => {
43
+ try {
44
+ step(generator.throw(value));
45
+ } catch (e) {
46
+ reject(e);
47
+ }
48
+ };
49
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
50
+ step((generator = generator.apply(__this, __arguments)).next());
51
+ });
52
+ };
2
53
 
3
54
  // src/cli.ts
4
55
  import exec from "@actions/exec";
5
56
  import io from "@actions/io";
6
57
  import chalk from "chalk";
7
58
  import { Command as Command4, Option } from "commander";
59
+ import { registry } from "playwright-core/lib/server";
8
60
  import quote from "quote";
9
61
  import parseArgsStringToArgv2 from "string-argv";
10
62
  import waitOnFn from "wait-on";
@@ -383,11 +435,10 @@ function parseCookieString(cookie) {
383
435
  if (!parsedCookie.path && parsedCookie.domain) {
384
436
  parsedCookie.path = "/";
385
437
  }
386
- const result = {
387
- ...parsedCookie,
438
+ const result = __spreadProps(__spreadValues({}, parsedCookie), {
388
439
  expires: parsedCookie.expires ? parsedCookie.expires.getTime() / 1e3 : void 0,
389
440
  sameSite
390
- };
441
+ });
391
442
  return result;
392
443
  }
393
444
 
@@ -724,18 +775,6 @@ var defaultA11yNodeSerializeParams = {
724
775
  noProperties: false
725
776
  };
726
777
  var ProcessedA11yNode = class {
727
- id;
728
- role;
729
- name;
730
- content;
731
- properties;
732
- // css-like selector from the root of the tree to the current node
733
- pathFromRoot;
734
- parent;
735
- // md5 hash - set lazily in most cases (not used at the moment)
736
- // md5Sum: string;
737
- children;
738
- backendNodeID;
739
778
  constructor(params) {
740
779
  this.id = params.id;
741
780
  this.role = params.role;
@@ -747,10 +786,11 @@ var ProcessedA11yNode = class {
747
786
  this.backendNodeID = params.backendNodeID;
748
787
  }
749
788
  getLogForm() {
789
+ var _a, _b;
750
790
  return JSON.stringify({
751
791
  id: this.id,
752
- name: this.name ?? "",
753
- role: this.role ?? "",
792
+ name: (_a = this.name) != null ? _a : "",
793
+ role: (_b = this.role) != null ? _b : "",
754
794
  backendNodeId: this.backendNodeID
755
795
  });
756
796
  }
@@ -843,7 +883,7 @@ function getNodePathIdentifier(node) {
843
883
  return `"${node.nodeId}"`;
844
884
  }
845
885
  function processA11yTreeDFS(node, parent, inputNodeMap, outputNodeMap) {
846
- var _a, _b, _c, _d, _e, _f;
886
+ var _a, _b, _c, _d, _e, _f, _g;
847
887
  if (!parent && node.parentId) {
848
888
  throw new Error(
849
889
  `Got no parent for accessibility node ${node.nodeId}: ${JSON.stringify(
@@ -871,7 +911,7 @@ function processA11yTreeDFS(node, parent, inputNodeMap, outputNodeMap) {
871
911
  });
872
912
  }
873
913
  outputNodeMap.set(processedNode.id, processedNode);
874
- const children = node.childIds ?? [];
914
+ const children = (_f = node.childIds) != null ? _f : [];
875
915
  for (const childId of children) {
876
916
  if (!childId) {
877
917
  continue;
@@ -896,7 +936,7 @@ function processA11yTreeDFS(node, parent, inputNodeMap, outputNodeMap) {
896
936
  }
897
937
  if (processedNode.children.length === 1 && processedNode.children[0].role === "StaticText") {
898
938
  const currentName = processedNode.name;
899
- const childName = (_f = processedNode.children[0]) == null ? void 0 : _f.name;
939
+ const childName = (_g = processedNode.children[0]) == null ? void 0 : _g.name;
900
940
  if (currentName === childName || !childName) {
901
941
  processedNode.children = [];
902
942
  }
@@ -1099,20 +1139,14 @@ function isRequestRelevantForPageLoad(request, currentURL) {
1099
1139
  }
1100
1140
 
1101
1141
  // ../../packages/web-agent/src/browsers/chrome.ts
1102
- async function initCDPSession(cdpClient) {
1103
- await cdpClient.send("Accessibility.enable");
1104
- await cdpClient.send("DOM.enable");
1105
- await cdpClient.send("Overlay.enable");
1142
+ function initCDPSession(cdpClient) {
1143
+ return __async(this, null, function* () {
1144
+ yield cdpClient.send("Accessibility.enable");
1145
+ yield cdpClient.send("DOM.enable");
1146
+ yield cdpClient.send("Overlay.enable");
1147
+ });
1106
1148
  }
1107
- var ChromeBrowser = class _ChromeBrowser {
1108
- browser;
1109
- context;
1110
- page;
1111
- // key is nodeId, according to the a11y tree
1112
- nodeMap = /* @__PURE__ */ new Map();
1113
- cdpClient;
1114
- logger;
1115
- baseURL;
1149
+ var _ChromeBrowser = class _ChromeBrowser {
1116
1150
  constructor({
1117
1151
  browser,
1118
1152
  context,
@@ -1121,6 +1155,8 @@ var ChromeBrowser = class _ChromeBrowser {
1121
1155
  cdpClient,
1122
1156
  logger
1123
1157
  }) {
1158
+ // key is nodeId, according to the a11y tree
1159
+ this.nodeMap = /* @__PURE__ */ new Map();
1124
1160
  this.browser = browser;
1125
1161
  this.context = context;
1126
1162
  this.page = page;
@@ -1128,106 +1164,117 @@ var ChromeBrowser = class _ChromeBrowser {
1128
1164
  this.cdpClient = cdpClient;
1129
1165
  this.logger = logger;
1130
1166
  }
1131
- static USER_AGENT = devices["Desktop Chrome"].userAgent;
1132
1167
  /**
1133
1168
  * Creates a new browser and waits for navigation to the given test URL.
1134
1169
  */
1135
- static async init(baseURL, logger, onScreenshot, timeout = MAX_LOAD_TIMEOUT_MS) {
1136
- const browser = await chromium.launch({ headless: true });
1137
- const context = await browser.newContext({
1138
- viewport: {
1139
- width: 1920,
1140
- height: 1080
1141
- },
1142
- // comment out the below if you are on Mac OS but you're using a monitor
1143
- deviceScaleFactor: process.platform === "darwin" ? RETINA_WINDOW_SCALE_FACTOR : 1,
1144
- userAgent: devices["Desktop Chrome"].userAgent,
1145
- geolocation: { latitude: 37.7749, longitude: -122.4194 },
1146
- // san francisco
1147
- locale: "en-US",
1148
- timezoneId: "America/Los_Angeles"
1149
- });
1150
- const page = await context.newPage();
1151
- const cdpClient = await context.newCDPSession(page);
1152
- const chrome = new _ChromeBrowser({
1153
- browser,
1154
- context,
1155
- page,
1156
- baseURL,
1157
- cdpClient,
1158
- logger
1159
- });
1160
- let completed = false;
1161
- const navigateAndInitCDP = async () => {
1162
- try {
1163
- await chrome.navigate(baseURL, false);
1164
- await initCDPSession(cdpClient);
1165
- } catch (err) {
1166
- logger.error({ err }, "Failed to initialize chrome browser");
1167
- } finally {
1168
- completed = true;
1169
- }
1170
- };
1171
- void navigateAndInitCDP();
1172
- const sendScreenshot = async () => {
1173
- if (!onScreenshot) {
1174
- return;
1170
+ static init(_0, _1, _2) {
1171
+ return __async(this, arguments, function* (baseURL, logger, onScreenshot, timeout = MAX_LOAD_TIMEOUT_MS) {
1172
+ const browser = yield chromium.launch({ headless: true });
1173
+ const context = yield browser.newContext({
1174
+ viewport: {
1175
+ width: 1920,
1176
+ height: 1080
1177
+ },
1178
+ // comment out the below if you are on Mac OS but you're using a monitor
1179
+ deviceScaleFactor: process.platform === "darwin" ? RETINA_WINDOW_SCALE_FACTOR : 1,
1180
+ userAgent: devices["Desktop Chrome"].userAgent,
1181
+ geolocation: { latitude: 37.7749, longitude: -122.4194 },
1182
+ // san francisco
1183
+ locale: "en-US",
1184
+ timezoneId: "America/Los_Angeles"
1185
+ });
1186
+ const page = yield context.newPage();
1187
+ const cdpClient = yield context.newCDPSession(page);
1188
+ const chrome = new _ChromeBrowser({
1189
+ browser,
1190
+ context,
1191
+ page,
1192
+ baseURL,
1193
+ cdpClient,
1194
+ logger
1195
+ });
1196
+ let completed = false;
1197
+ const navigateAndInitCDP = () => __async(this, null, function* () {
1198
+ try {
1199
+ yield chrome.navigate(baseURL, false);
1200
+ yield initCDPSession(cdpClient);
1201
+ } catch (err) {
1202
+ logger.error({ err }, "Failed to initialize chrome browser");
1203
+ } finally {
1204
+ completed = true;
1205
+ }
1206
+ });
1207
+ void navigateAndInitCDP();
1208
+ const sendScreenshot = () => __async(this, null, function* () {
1209
+ if (!onScreenshot) {
1210
+ return;
1211
+ }
1212
+ try {
1213
+ onScreenshot({
1214
+ viewport: chrome.viewport,
1215
+ buffer: yield chrome.screenshot()
1216
+ });
1217
+ } catch (err) {
1218
+ logger.error({ err }, "Failed to take screenshot");
1219
+ }
1220
+ });
1221
+ void sendScreenshot();
1222
+ const screenshotInterval = setInterval(() => {
1223
+ void sendScreenshot();
1224
+ }, 250);
1225
+ const startTime = Date.now();
1226
+ while (!completed && Date.now() - startTime < timeout) {
1227
+ yield sleep(CHECK_INTERVAL_MS);
1175
1228
  }
1176
- try {
1177
- onScreenshot({
1178
- viewport: chrome.viewport,
1179
- buffer: await chrome.screenshot()
1180
- });
1181
- } catch (err) {
1182
- logger.error({ err }, "Failed to take screenshot");
1229
+ clearInterval(screenshotInterval);
1230
+ if (!completed) {
1231
+ logger.warn(
1232
+ "Timeout elapsed waiting for browser to initialize - are you sure this page is accessible?"
1233
+ );
1183
1234
  }
1184
- };
1185
- void sendScreenshot();
1186
- const screenshotInterval = setInterval(() => {
1187
- void sendScreenshot();
1188
- }, 250);
1189
- const startTime = Date.now();
1190
- while (!completed && Date.now() - startTime < timeout) {
1191
- await sleep(CHECK_INTERVAL_MS);
1192
- }
1193
- clearInterval(screenshotInterval);
1194
- if (!completed) {
1195
- logger.warn(
1196
- "Timeout elapsed waiting for browser to initialize - are you sure this page is accessible?"
1197
- );
1198
- }
1199
- return chrome;
1235
+ return chrome;
1236
+ });
1200
1237
  }
1201
1238
  // Things to do on every page load
1202
- async pageSetup() {
1203
- await this.page.evaluate(addCursorScript);
1204
- await this.page.evaluate(addIDsScript);
1239
+ pageSetup() {
1240
+ return __async(this, null, function* () {
1241
+ yield this.page.evaluate(addCursorScript);
1242
+ yield this.page.evaluate(addIDsScript);
1243
+ });
1205
1244
  }
1206
- async wait(timeoutMs) {
1207
- await this.page.waitForTimeout(timeoutMs);
1245
+ wait(timeoutMs) {
1246
+ return __async(this, null, function* () {
1247
+ yield this.page.waitForTimeout(timeoutMs);
1248
+ });
1208
1249
  }
1209
- async cleanup() {
1210
- await this.page.close();
1211
- await this.context.close();
1212
- await this.browser.close();
1250
+ cleanup() {
1251
+ return __async(this, null, function* () {
1252
+ yield this.page.close();
1253
+ yield this.context.close();
1254
+ yield this.browser.close();
1255
+ });
1213
1256
  }
1214
1257
  get closed() {
1215
1258
  return this.page.isClosed() || !this.browser.isConnected();
1216
1259
  }
1217
- async html() {
1218
- return await this.page.content();
1260
+ html() {
1261
+ return __async(this, null, function* () {
1262
+ return yield this.page.content();
1263
+ });
1219
1264
  }
1220
1265
  get url() {
1221
1266
  return this.page.url();
1222
1267
  }
1223
- async screenshot(quality = 100, scale = "device") {
1224
- return await this.page.screenshot({
1225
- fullPage: false,
1226
- quality,
1227
- scale,
1228
- type: "jpeg",
1229
- // allow the blinking text cursor thing to remain there
1230
- caret: "initial"
1268
+ screenshot(quality = 100, scale = "device") {
1269
+ return __async(this, null, function* () {
1270
+ return yield this.page.screenshot({
1271
+ fullPage: false,
1272
+ quality,
1273
+ scale,
1274
+ type: "jpeg",
1275
+ // allow the blinking text cursor thing to remain there
1276
+ caret: "initial"
1277
+ });
1231
1278
  });
1232
1279
  }
1233
1280
  get viewport() {
@@ -1237,539 +1284,595 @@ var ChromeBrowser = class _ChromeBrowser {
1237
1284
  }
1238
1285
  return viewport;
1239
1286
  }
1240
- async navigate(url, wrapPossibleNavigation = true) {
1241
- this.logger.debug(`Navigating to ${url}`);
1242
- const startTime = Date.now();
1243
- const doNav = async () => {
1244
- try {
1245
- await this.page.goto(url, {
1246
- timeout: MAX_LOAD_TIMEOUT_MS
1247
- });
1248
- this.logger.debug(
1249
- { url },
1250
- `Got load event in ${Math.floor(Date.now() - startTime)}ms`
1251
- );
1252
- } catch (e) {
1253
- this.logger.warn(
1254
- { url, type: "navigate", err: e },
1255
- "Timeout elapsed waiting for page to load, continuing anyways..."
1287
+ navigate(url, wrapPossibleNavigation = true) {
1288
+ return __async(this, null, function* () {
1289
+ this.logger.debug(`Navigating to ${url}`);
1290
+ const startTime = Date.now();
1291
+ const doNav = () => __async(this, null, function* () {
1292
+ try {
1293
+ yield this.page.goto(url, {
1294
+ timeout: MAX_LOAD_TIMEOUT_MS
1295
+ });
1296
+ this.logger.debug(
1297
+ { url },
1298
+ `Got load event in ${Math.floor(Date.now() - startTime)}ms`
1299
+ );
1300
+ } catch (e) {
1301
+ this.logger.warn(
1302
+ { url, type: "navigate", err: e },
1303
+ "Timeout elapsed waiting for page to load, continuing anyways..."
1304
+ );
1305
+ }
1306
+ });
1307
+ if (wrapPossibleNavigation) {
1308
+ yield this.wrapPossibleNavigation(doNav);
1309
+ } else {
1310
+ yield doNav();
1311
+ }
1312
+ if (CHROME_INTERNAL_URLS.has(this.url) && process.env.NODE_ENV === "production") {
1313
+ throw new Error(
1314
+ `${url} took too long to load \u{1F61E}. Please ensure the site and your internet are working.`
1256
1315
  );
1257
1316
  }
1258
- };
1259
- if (wrapPossibleNavigation) {
1260
- await this.wrapPossibleNavigation(doNav);
1261
- } else {
1262
- await doNav();
1263
- }
1264
- if (CHROME_INTERNAL_URLS.has(this.url) && process.env.NODE_ENV === "production") {
1265
- throw new Error(
1266
- `${url} took too long to load \u{1F61E}. Please ensure the site and your internet are working.`
1267
- );
1268
- }
1269
- await this.pageSetup();
1270
- this.logger.debug({ url }, "Navigation complete");
1271
- }
1272
- async fill(target, text, options = {}) {
1273
- const element = await this.click(target, {
1274
- doubleClick: false,
1275
- rightClick: false
1276
- });
1277
- await this.type(text, options);
1278
- return element;
1279
- }
1280
- async type(text, options = {}) {
1281
- const { clearContent = true, pressKeysSequentially = false } = options;
1282
- if (clearContent) {
1283
- await this.page.keyboard.press("Meta+A");
1284
- await this.page.keyboard.press("Backspace");
1285
- }
1286
- if (pressKeysSequentially) {
1287
- await this.page.keyboard.type(text);
1288
- } else {
1289
- await this.page.keyboard.insertText(text);
1290
- }
1317
+ yield this.pageSetup();
1318
+ this.logger.debug({ url }, "Navigation complete");
1319
+ });
1291
1320
  }
1292
- async clickByA11yID(index, options = {}) {
1293
- const node = this.nodeMap.get(`${index}`);
1294
- if (!node) {
1295
- throw new Error(`Could not find node in DOM with index: ${index}`);
1296
- }
1297
- const nodeClicked = await this.clickUsingCDP(node, options);
1298
- await this.highlightNode(nodeClicked);
1299
- return node.serialize({ noChildren: true, noProperties: true, noID: true });
1300
- }
1301
- async selectOptionByA11yID(index, option) {
1302
- const node = this.nodeMap.get(`${index}`);
1303
- if (!node) {
1304
- throw new Error(`Could not find node in DOM with index: ${index}`);
1305
- }
1306
- if (!node.backendNodeID) {
1307
- throw new Error(
1308
- `Select target missing backend node id: ${node.getLogForm()}`
1309
- );
1310
- }
1311
- const locator = await this.getLocatorFromBackendID(node.backendNodeID);
1312
- await locator.selectOption(option, {
1313
- timeout: COMPLICATED_BROWSER_ACTION_TIMEOUT_MS
1321
+ fill(_0, _1) {
1322
+ return __async(this, arguments, function* (target, text, options = {}) {
1323
+ const element = yield this.click(target, {
1324
+ doubleClick: false,
1325
+ rightClick: false
1326
+ });
1327
+ yield this.type(text, options);
1328
+ return element;
1314
1329
  });
1315
- await this.highlightNode(node);
1316
- return node.serialize({ noChildren: true, noProperties: true, noID: true });
1317
1330
  }
1318
- async highlight(target) {
1319
- try {
1320
- await this.highlightByA11yID(target.id);
1321
- } catch (err) {
1322
- this.logger.warn({ err, target }, "Failed to highlight target");
1323
- }
1331
+ type(_0) {
1332
+ return __async(this, arguments, function* (text, options = {}) {
1333
+ const { clearContent = true, pressKeysSequentially = false } = options;
1334
+ if (clearContent) {
1335
+ yield this.page.keyboard.press("Meta+A");
1336
+ yield this.page.keyboard.press("Backspace");
1337
+ }
1338
+ if (pressKeysSequentially) {
1339
+ yield this.page.keyboard.type(text);
1340
+ } else {
1341
+ yield this.page.keyboard.insertText(text);
1342
+ }
1343
+ });
1324
1344
  }
1325
- async highlightByA11yID(index) {
1326
- const node = this.nodeMap.get(`${index}`);
1327
- if (!node) {
1328
- throw new Error(`Could not find node in DOM with index: ${index}`);
1329
- }
1330
- if (!node.backendNodeID) {
1331
- throw new Error(
1332
- `Select target missing backend node id: ${node.getLogForm()}`
1333
- );
1334
- }
1335
- await this.highlightNode(node);
1345
+ clickByA11yID(_0) {
1346
+ return __async(this, arguments, function* (index, options = {}) {
1347
+ const node = this.nodeMap.get(`${index}`);
1348
+ if (!node) {
1349
+ throw new Error(`Could not find node in DOM with index: ${index}`);
1350
+ }
1351
+ const nodeClicked = yield this.clickUsingCDP(node, options);
1352
+ yield this.highlightNode(nodeClicked);
1353
+ return node.serialize({ noChildren: true, noProperties: true, noID: true });
1354
+ });
1336
1355
  }
1337
- async highlightNode(node) {
1338
- try {
1339
- await this.cdpClient.send("Overlay.highlightNode", {
1340
- highlightConfig: NODE_HIGHLIGHT_CONFIG,
1341
- backendNodeId: node.backendNodeID
1356
+ selectOptionByA11yID(index, option) {
1357
+ return __async(this, null, function* () {
1358
+ const node = this.nodeMap.get(`${index}`);
1359
+ if (!node) {
1360
+ throw new Error(`Could not find node in DOM with index: ${index}`);
1361
+ }
1362
+ if (!node.backendNodeID) {
1363
+ throw new Error(
1364
+ `Select target missing backend node id: ${node.getLogForm()}`
1365
+ );
1366
+ }
1367
+ const locator = yield this.getLocatorFromBackendID(node.backendNodeID);
1368
+ yield locator.selectOption(option, {
1369
+ timeout: COMPLICATED_BROWSER_ACTION_TIMEOUT_MS
1342
1370
  });
1343
- } catch (err) {
1344
- this.logger.warn({ err }, "Failed to add node highlight");
1345
- }
1346
- const hideHighlight = async () => {
1371
+ yield this.highlightNode(node);
1372
+ return node.serialize({ noChildren: true, noProperties: true, noID: true });
1373
+ });
1374
+ }
1375
+ highlight(target) {
1376
+ return __async(this, null, function* () {
1377
+ try {
1378
+ yield this.highlightByA11yID(target.id);
1379
+ } catch (err) {
1380
+ this.logger.warn({ err, target }, "Failed to highlight target");
1381
+ }
1382
+ });
1383
+ }
1384
+ highlightByA11yID(index) {
1385
+ return __async(this, null, function* () {
1386
+ const node = this.nodeMap.get(`${index}`);
1387
+ if (!node) {
1388
+ throw new Error(`Could not find node in DOM with index: ${index}`);
1389
+ }
1390
+ if (!node.backendNodeID) {
1391
+ throw new Error(
1392
+ `Select target missing backend node id: ${node.getLogForm()}`
1393
+ );
1394
+ }
1395
+ yield this.highlightNode(node);
1396
+ });
1397
+ }
1398
+ highlightNode(node) {
1399
+ return __async(this, null, function* () {
1347
1400
  try {
1348
- await this.cdpClient.send("Overlay.hideHighlight", {
1401
+ yield this.cdpClient.send("Overlay.highlightNode", {
1402
+ highlightConfig: NODE_HIGHLIGHT_CONFIG,
1349
1403
  backendNodeId: node.backendNodeID
1350
1404
  });
1351
1405
  } catch (err) {
1352
- this.logger.debug({ err }, "Failed to remove node highlight");
1406
+ this.logger.warn({ err }, "Failed to add node highlight");
1353
1407
  }
1354
- };
1355
- setTimeout(() => {
1356
- void hideHighlight();
1357
- }, HIGHLIGHT_DURATION_MS);
1358
- }
1359
- async wrapPossibleNavigation(fn, timeoutMS = MAX_LOAD_TIMEOUT_MS) {
1360
- const startTime = Date.now();
1361
- const startURL = this.url;
1362
- let lastRequestReceived = Date.now();
1363
- const firedRequests = /* @__PURE__ */ new Map();
1364
- const finishedRequests = /* @__PURE__ */ new Map();
1365
- const requestFinishedListener = (request) => {
1366
- const key = serializeRequest(request);
1367
- finishedRequests.set(key, (finishedRequests.get(key) ?? 0) + 1);
1368
- };
1369
- const requestFiredListener = (request) => {
1370
- if (!isRequestRelevantForPageLoad(request, this.url)) {
1408
+ const hideHighlight = () => __async(this, null, function* () {
1409
+ try {
1410
+ yield this.cdpClient.send("Overlay.hideHighlight", {
1411
+ backendNodeId: node.backendNodeID
1412
+ });
1413
+ } catch (err) {
1414
+ this.logger.debug({ err }, "Failed to remove node highlight");
1415
+ }
1416
+ });
1417
+ setTimeout(() => {
1418
+ void hideHighlight();
1419
+ }, HIGHLIGHT_DURATION_MS);
1420
+ });
1421
+ }
1422
+ wrapPossibleNavigation(_0) {
1423
+ return __async(this, arguments, function* (fn, timeoutMS = MAX_LOAD_TIMEOUT_MS) {
1424
+ const startTime = Date.now();
1425
+ const startURL = this.url;
1426
+ let lastRequestReceived = Date.now();
1427
+ const firedRequests = /* @__PURE__ */ new Map();
1428
+ const finishedRequests = /* @__PURE__ */ new Map();
1429
+ const requestFinishedListener = (request) => {
1430
+ var _a;
1431
+ const key = serializeRequest(request);
1432
+ finishedRequests.set(key, ((_a = finishedRequests.get(key)) != null ? _a : 0) + 1);
1433
+ };
1434
+ const requestFiredListener = (request) => {
1435
+ var _a;
1436
+ if (!isRequestRelevantForPageLoad(request, this.url)) {
1437
+ this.logger.debug(
1438
+ {
1439
+ uri: serializeRequest(request)
1440
+ },
1441
+ "Ignoring request for page load network stability"
1442
+ );
1443
+ return;
1444
+ }
1445
+ const key = serializeRequest(request);
1371
1446
  this.logger.debug(
1372
1447
  {
1373
- uri: serializeRequest(request)
1448
+ uri: key
1374
1449
  },
1375
- "Ignoring request for page load network stability"
1450
+ "Request fired on page load, delaying network stability"
1376
1451
  );
1377
- return;
1378
- }
1379
- const key = serializeRequest(request);
1380
- this.logger.debug(
1381
- {
1382
- uri: key
1383
- },
1384
- "Request fired on page load, delaying network stability"
1385
- );
1386
- firedRequests.set(key, (firedRequests.get(key) ?? 0) + 1);
1387
- lastRequestReceived = Date.now();
1388
- };
1389
- this.page.on("requestfinished", requestFinishedListener);
1390
- this.page.on("request", requestFiredListener);
1391
- let rejected = false;
1392
- const retPromise = fn().catch((e) => {
1393
- rejected = true;
1394
- if (e instanceof Error)
1395
- return e;
1396
- return new Error(`${e}`);
1397
- });
1398
- await sleep(CHECK_INTERVAL_MS);
1399
- const unwrapAndThrowError = async (p) => {
1400
- const v = await p;
1401
- if (v instanceof Error) {
1402
- throw v;
1403
- }
1404
- return v;
1405
- };
1406
- let unfinishedRequests = /* @__PURE__ */ new Set();
1407
- const waitForNetworkIdle = async () => {
1408
- while (!rejected && Date.now() - startTime < timeoutMS) {
1409
- unfinishedRequests = /* @__PURE__ */ new Set();
1410
- await sleep(CHECK_INTERVAL_MS);
1411
- if (Date.now() - lastRequestReceived <= NETWORK_STABLE_DURATION_MS) {
1412
- continue;
1452
+ firedRequests.set(key, ((_a = firedRequests.get(key)) != null ? _a : 0) + 1);
1453
+ lastRequestReceived = Date.now();
1454
+ };
1455
+ this.page.on("requestfinished", requestFinishedListener);
1456
+ this.page.on("request", requestFiredListener);
1457
+ let rejected = false;
1458
+ const retPromise = fn().catch((e) => {
1459
+ rejected = true;
1460
+ if (e instanceof Error)
1461
+ return e;
1462
+ return new Error(`${e}`);
1463
+ });
1464
+ yield sleep(CHECK_INTERVAL_MS);
1465
+ const unwrapAndThrowError = (p) => __async(this, null, function* () {
1466
+ const v = yield p;
1467
+ if (v instanceof Error) {
1468
+ throw v;
1413
1469
  }
1414
- let anyDifference = false;
1415
- for (const key of firedRequests.keys()) {
1416
- if (firedRequests.get(key) !== finishedRequests.get(key)) {
1417
- this.logger.debug({ uri: key }, "Waiting on request to finish");
1418
- anyDifference = true;
1419
- unfinishedRequests.add(key);
1470
+ return v;
1471
+ });
1472
+ let unfinishedRequests = /* @__PURE__ */ new Set();
1473
+ const waitForNetworkIdle = () => __async(this, null, function* () {
1474
+ while (!rejected && Date.now() - startTime < timeoutMS) {
1475
+ unfinishedRequests = /* @__PURE__ */ new Set();
1476
+ yield sleep(CHECK_INTERVAL_MS);
1477
+ if (Date.now() - lastRequestReceived <= NETWORK_STABLE_DURATION_MS) {
1478
+ continue;
1479
+ }
1480
+ let anyDifference = false;
1481
+ for (const key of firedRequests.keys()) {
1482
+ if (firedRequests.get(key) !== finishedRequests.get(key)) {
1483
+ this.logger.debug({ uri: key }, "Waiting on request to finish");
1484
+ anyDifference = true;
1485
+ unfinishedRequests.add(key);
1486
+ }
1487
+ }
1488
+ if (!anyDifference) {
1489
+ this.logger.debug(
1490
+ {
1491
+ url: this.url,
1492
+ requests: JSON.stringify(Array.from(firedRequests.entries()))
1493
+ },
1494
+ `Network idle in ${Math.floor(Date.now() - startTime)}ms`
1495
+ );
1496
+ return true;
1420
1497
  }
1421
1498
  }
1422
- if (!anyDifference) {
1423
- this.logger.debug(
1499
+ if (!rejected) {
1500
+ this.logger.warn(
1424
1501
  {
1425
1502
  url: this.url,
1426
- requests: JSON.stringify(Array.from(firedRequests.entries()))
1503
+ requests: JSON.stringify(Array.from(unfinishedRequests.entries()))
1427
1504
  },
1428
- `Network idle in ${Math.floor(Date.now() - startTime)}ms`
1505
+ "Timeout elapsed waiting for network idle, continuing anyways..."
1429
1506
  );
1430
- return true;
1431
1507
  }
1508
+ return false;
1509
+ });
1510
+ const waitResult = yield waitForNetworkIdle();
1511
+ this.page.off("requestfinished", requestFinishedListener);
1512
+ this.page.off("request", requestFiredListener);
1513
+ if (!waitResult) {
1514
+ return unwrapAndThrowError(retPromise);
1432
1515
  }
1433
- if (!rejected) {
1434
- this.logger.warn(
1435
- {
1436
- url: this.url,
1437
- requests: JSON.stringify(Array.from(unfinishedRequests.entries()))
1438
- },
1439
- "Timeout elapsed waiting for network idle, continuing anyways..."
1516
+ if (!rejected && urlChanged(this.url, startURL)) {
1517
+ this.logger.debug(
1518
+ `Detected url change in wrapPossibleNavigation, waiting for load state`
1440
1519
  );
1520
+ try {
1521
+ yield this.page.waitForLoadState("load", {
1522
+ timeout: timeoutMS - (Date.now() - startTime)
1523
+ });
1524
+ } catch (e) {
1525
+ this.logger.warn(
1526
+ { url: this.url },
1527
+ "Timeout elapsed waiting for load state to fire, continuing anyways..."
1528
+ );
1529
+ }
1441
1530
  }
1442
- return false;
1443
- };
1444
- const waitResult = await waitForNetworkIdle();
1445
- this.page.off("requestfinished", requestFinishedListener);
1446
- this.page.off("request", requestFiredListener);
1447
- if (!waitResult) {
1448
1531
  return unwrapAndThrowError(retPromise);
1449
- }
1450
- if (!rejected && urlChanged(this.url, startURL)) {
1451
- this.logger.debug(
1452
- `Detected url change in wrapPossibleNavigation, waiting for load state`
1453
- );
1454
- try {
1455
- await this.page.waitForLoadState("load", {
1456
- timeout: timeoutMS - (Date.now() - startTime)
1457
- });
1458
- } catch (e) {
1459
- this.logger.warn(
1460
- { url: this.url },
1461
- "Timeout elapsed waiting for load state to fire, continuing anyways..."
1462
- );
1463
- }
1464
- }
1465
- return unwrapAndThrowError(retPromise);
1532
+ });
1466
1533
  }
1467
- async click(target, options = {}) {
1468
- const elementInteracted = await this.wrapPossibleNavigation(
1469
- () => this.clickByA11yID(target.id, options)
1470
- );
1471
- return elementInteracted;
1534
+ click(_0) {
1535
+ return __async(this, arguments, function* (target, options = {}) {
1536
+ const elementInteracted = yield this.wrapPossibleNavigation(
1537
+ () => this.clickByA11yID(target.id, options)
1538
+ );
1539
+ return elementInteracted;
1540
+ });
1472
1541
  }
1473
- async selectOption(target, option) {
1474
- return this.selectOptionByA11yID(target.id, option);
1542
+ selectOption(target, option) {
1543
+ return __async(this, null, function* () {
1544
+ return this.selectOptionByA11yID(target.id, option);
1545
+ });
1475
1546
  }
1476
- async press(key) {
1477
- await this.wrapPossibleNavigation(() => this.page.keyboard.press(key));
1547
+ press(key) {
1548
+ return __async(this, null, function* () {
1549
+ yield this.wrapPossibleNavigation(() => this.page.keyboard.press(key));
1550
+ });
1478
1551
  }
1479
- async refresh() {
1480
- await this.page.reload();
1481
- await this.pageSetup();
1552
+ refresh() {
1553
+ return __async(this, null, function* () {
1554
+ yield this.page.reload();
1555
+ yield this.pageSetup();
1556
+ });
1482
1557
  }
1483
- async getA11yTree() {
1484
- let processedTree = null;
1485
- let attempt = 0;
1486
- const url = this.url;
1487
- while (!processedTree) {
1488
- try {
1489
- this.logger.debug(`Getting a11y tree at ${url}`);
1490
- const graph = await this.getRawA11yTree();
1491
- if (!graph.root || graph.allNodes.length === 0) {
1492
- throw new Error("No a11y tree found on page");
1493
- }
1494
- processedTree = processA11yTree(graph);
1495
- } catch (e) {
1496
- this.logger.error({ err: e, url }, "Error fetching a11y tree");
1497
- if (attempt === 0) {
1498
- await sleep(1e3);
1499
- attempt++;
1500
- } else {
1501
- throw new Error(`Max retries exceeded fetching a11y tree: ${e}`);
1558
+ getA11yTree() {
1559
+ return __async(this, null, function* () {
1560
+ let processedTree = null;
1561
+ let attempt = 0;
1562
+ const url = this.url;
1563
+ while (!processedTree) {
1564
+ try {
1565
+ this.logger.debug(`Getting a11y tree at ${url}`);
1566
+ const graph = yield this.getRawA11yTree();
1567
+ if (!graph.root || graph.allNodes.length === 0) {
1568
+ throw new Error("No a11y tree found on page");
1569
+ }
1570
+ processedTree = processA11yTree(graph);
1571
+ } catch (e) {
1572
+ this.logger.error({ err: e, url }, "Error fetching a11y tree");
1573
+ if (attempt === 0) {
1574
+ yield sleep(1e3);
1575
+ attempt++;
1576
+ } else {
1577
+ throw new Error(`Max retries exceeded fetching a11y tree: ${e}`);
1578
+ }
1502
1579
  }
1503
1580
  }
1504
- }
1505
- if (!processedTree.root) {
1506
- this.logger.warn("A11y tree was pruned entirely");
1507
- }
1508
- this.nodeMap = processedTree.nodeMap;
1509
- return processedTree;
1510
- }
1511
- async getRawA11yTree() {
1512
- const url = this.page.url();
1513
- let lastTreeUpdateTimestamp = Date.now();
1514
- const treeUpdateListener = () => {
1515
- lastTreeUpdateTimestamp = Date.now();
1516
- };
1517
- this.cdpClient.addListener(
1518
- "Accessibility.nodesUpdated",
1519
- treeUpdateListener
1520
- );
1521
- let accessibilityTreeLoadFired = false;
1522
- const accessibilityLoadListener = () => {
1523
- this.logger.info({ url }, `A11y tree load event fired`);
1524
- accessibilityTreeLoadFired = true;
1525
- };
1526
- this.cdpClient.addListener(
1527
- "Accessibility.loadComplete",
1528
- accessibilityLoadListener
1529
- );
1530
- const a11yLoadStart = Date.now();
1531
- let timeoutTriggered = true;
1532
- while (Date.now() - a11yLoadStart < A11Y_STABLE_TIMEOUT_MS) {
1533
- await sleep(CHECK_INTERVAL_MS);
1534
- if (!accessibilityTreeLoadFired && Date.now() - a11yLoadStart < A11Y_LOAD_TIMEOUT_MS) {
1535
- this.logger.debug({ url }, `A11y tree not loaded yet, waiting...`);
1536
- continue;
1537
- }
1538
- if (Date.now() - lastTreeUpdateTimestamp >= A11Y_STABLE_DURATION_MS) {
1539
- this.logger.debug({ url }, `A11y tree not stable yet, waiting...`);
1540
- continue;
1581
+ if (!processedTree.root) {
1582
+ this.logger.warn("A11y tree was pruned entirely");
1541
1583
  }
1542
- timeoutTriggered = false;
1543
- break;
1544
- }
1545
- this.logger.debug(
1546
- {
1547
- duration: Date.now() - a11yLoadStart,
1548
- eventReceived: accessibilityTreeLoadFired,
1549
- timeoutTriggered
1550
- },
1551
- "A11y wait phase completed"
1552
- );
1553
- const { node: root } = await this.cdpClient.send(
1554
- "Accessibility.getRootAXNode"
1555
- );
1556
- const { nodes } = await this.cdpClient.send("Accessibility.queryAXTree", {
1557
- backendNodeId: root.backendDOMNodeId
1584
+ this.nodeMap = processedTree.nodeMap;
1585
+ return processedTree;
1558
1586
  });
1559
- this.cdpClient.removeListener(
1560
- "Accessibility.loadComplete",
1561
- accessibilityLoadListener
1562
- );
1563
- this.cdpClient.removeListener(
1564
- "Accessibility.nodesUpdated",
1565
- treeUpdateListener
1566
- );
1567
- return {
1568
- root,
1569
- allNodes: nodes
1570
- };
1571
1587
  }
1572
- async clickUsingVisualCoordinates(backendNodeId) {
1573
- const location = await this.getElementLocation(backendNodeId);
1574
- if (!location) {
1575
- throw new Error(
1576
- `Could not find element location with backend node id: ${backendNodeId}`
1588
+ getRawA11yTree() {
1589
+ return __async(this, null, function* () {
1590
+ const url = this.page.url();
1591
+ let lastTreeUpdateTimestamp = Date.now();
1592
+ const treeUpdateListener = () => {
1593
+ lastTreeUpdateTimestamp = Date.now();
1594
+ };
1595
+ this.cdpClient.addListener(
1596
+ "Accessibility.nodesUpdated",
1597
+ treeUpdateListener
1577
1598
  );
1578
- }
1579
- this.logger.debug({ location }, "Executing mouse click");
1580
- await this.page.mouse.click(location.centerX, location.centerY);
1581
- }
1582
- // Get the "id" attribute value from an HTML element.
1583
- async getIDAttributeUsingCDP(objectId) {
1584
- await this.cdpClient.send("DOM.getDocument", { depth: 0 });
1585
- const cdpNodeResult = await this.cdpClient.send("DOM.requestNode", {
1586
- objectId
1587
- });
1588
- const attrResult = await this.cdpClient.send("DOM.getAttributes", {
1589
- nodeId: cdpNodeResult.nodeId
1590
- });
1591
- const attributes = attrResult.attributes;
1592
- const indexAttr = attributes.findIndex((s) => s === "data-momentic-id");
1593
- if (indexAttr === -1) {
1594
- return "";
1595
- }
1596
- return attributes[indexAttr + 1] || "";
1597
- }
1598
- async getLocatorFromBackendID(backendNodeId) {
1599
- await this.page.evaluate(addIDsScript);
1600
- const cdpResolveResult = await this.cdpClient.send("DOM.resolveNode", {
1601
- backendNodeId
1602
- });
1603
- if (!cdpResolveResult || !cdpResolveResult.object.objectId) {
1604
- throw new Error(`Could not resolve backend node ${backendNodeId}`);
1605
- }
1606
- try {
1607
- const id = await this.getIDAttributeUsingCDP(
1608
- cdpResolveResult.object.objectId
1599
+ let accessibilityTreeLoadFired = false;
1600
+ const accessibilityLoadListener = () => {
1601
+ this.logger.info({ url }, `A11y tree load event fired`);
1602
+ accessibilityTreeLoadFired = true;
1603
+ };
1604
+ this.cdpClient.addListener(
1605
+ "Accessibility.loadComplete",
1606
+ accessibilityLoadListener
1609
1607
  );
1610
- if (!id) {
1611
- throw new Error("Failed getting data-momentic-id attribute using CDP");
1608
+ const a11yLoadStart = Date.now();
1609
+ let timeoutTriggered = true;
1610
+ while (Date.now() - a11yLoadStart < A11Y_STABLE_TIMEOUT_MS) {
1611
+ yield sleep(CHECK_INTERVAL_MS);
1612
+ if (!accessibilityTreeLoadFired && Date.now() - a11yLoadStart < A11Y_LOAD_TIMEOUT_MS) {
1613
+ this.logger.debug({ url }, `A11y tree not loaded yet, waiting...`);
1614
+ continue;
1615
+ }
1616
+ if (Date.now() - lastTreeUpdateTimestamp >= A11Y_STABLE_DURATION_MS) {
1617
+ this.logger.debug({ url }, `A11y tree not stable yet, waiting...`);
1618
+ continue;
1619
+ }
1620
+ timeoutTriggered = false;
1621
+ break;
1612
1622
  }
1613
- return this.page.locator(`[data-momentic-id="${id}"]`);
1614
- } catch (err) {
1615
- this.logger.error(
1623
+ this.logger.debug(
1616
1624
  {
1617
- err
1625
+ duration: Date.now() - a11yLoadStart,
1626
+ eventReceived: accessibilityTreeLoadFired,
1627
+ timeoutTriggered
1618
1628
  },
1619
- "Failed to get ID attribute"
1629
+ "A11y wait phase completed"
1620
1630
  );
1621
- throw err;
1622
- }
1631
+ const { node: root } = yield this.cdpClient.send(
1632
+ "Accessibility.getRootAXNode"
1633
+ );
1634
+ const { nodes } = yield this.cdpClient.send("Accessibility.queryAXTree", {
1635
+ backendNodeId: root.backendDOMNodeId
1636
+ });
1637
+ this.cdpClient.removeListener(
1638
+ "Accessibility.loadComplete",
1639
+ accessibilityLoadListener
1640
+ );
1641
+ this.cdpClient.removeListener(
1642
+ "Accessibility.nodesUpdated",
1643
+ treeUpdateListener
1644
+ );
1645
+ return {
1646
+ root,
1647
+ allNodes: nodes
1648
+ };
1649
+ });
1623
1650
  }
1624
- async clickUsingCDP(originalNode, options = {}) {
1625
- let clickAttempts = 0;
1626
- let candidateNode = originalNode;
1627
- while (clickAttempts < MAX_BROWSER_ACTION_ATTEMPTS) {
1628
- if (!candidateNode || candidateNode.role === "RootWebArea") {
1651
+ clickUsingVisualCoordinates(backendNodeId) {
1652
+ return __async(this, null, function* () {
1653
+ const location = yield this.getElementLocation(backendNodeId);
1654
+ if (!location) {
1629
1655
  throw new Error(
1630
- `Attempted to click node with no clickable surrounding elements: ${originalNode.getLogForm()}`
1656
+ `Could not find element location with backend node id: ${backendNodeId}`
1631
1657
  );
1632
1658
  }
1633
- if (candidateNode.role === "StaticText") {
1634
- candidateNode = candidateNode.parent;
1635
- continue;
1659
+ this.logger.debug({ location }, "Executing mouse click");
1660
+ yield this.page.mouse.click(location.centerX, location.centerY);
1661
+ });
1662
+ }
1663
+ // Get the "id" attribute value from an HTML element.
1664
+ getIDAttributeUsingCDP(objectId) {
1665
+ return __async(this, null, function* () {
1666
+ yield this.cdpClient.send("DOM.getDocument", { depth: 0 });
1667
+ const cdpNodeResult = yield this.cdpClient.send("DOM.requestNode", {
1668
+ objectId
1669
+ });
1670
+ const attrResult = yield this.cdpClient.send("DOM.getAttributes", {
1671
+ nodeId: cdpNodeResult.nodeId
1672
+ });
1673
+ const attributes = attrResult.attributes;
1674
+ const indexAttr = attributes.findIndex((s) => s === "data-momentic-id");
1675
+ if (indexAttr === -1) {
1676
+ return "";
1636
1677
  }
1637
- const candidateNodeID = candidateNode.backendNodeID;
1638
- if (!candidateNodeID) {
1639
- this.logger.warn(
1640
- { node: candidateNode.getLogForm() },
1641
- "Click candidate had no backend node ID"
1642
- );
1643
- candidateNode = candidateNode.parent;
1644
- continue;
1678
+ return attributes[indexAttr + 1] || "";
1679
+ });
1680
+ }
1681
+ getLocatorFromBackendID(backendNodeId) {
1682
+ return __async(this, null, function* () {
1683
+ yield this.page.evaluate(addIDsScript);
1684
+ const cdpResolveResult = yield this.cdpClient.send("DOM.resolveNode", {
1685
+ backendNodeId
1686
+ });
1687
+ if (!cdpResolveResult || !cdpResolveResult.object.objectId) {
1688
+ throw new Error(`Could not resolve backend node ${backendNodeId}`);
1645
1689
  }
1646
1690
  try {
1647
- const locator = await this.getLocatorFromBackendID(candidateNodeID);
1648
- if (options.doubleClick) {
1649
- await locator.dblclick({
1650
- timeout: BROWSER_ACTION_TIMEOUT_MS
1651
- });
1652
- } else {
1653
- await locator.click({
1654
- timeout: BROWSER_ACTION_TIMEOUT_MS,
1655
- button: options.rightClick ? "right" : "left"
1656
- });
1657
- }
1658
- if (candidateNode.id !== originalNode.id) {
1659
- this.logger.info(
1660
- {
1661
- oldNode: originalNode.getLogForm(),
1662
- newNode: candidateNode.getLogForm()
1663
- },
1664
- `Redirected click successfully to new element`
1665
- );
1691
+ const id = yield this.getIDAttributeUsingCDP(
1692
+ cdpResolveResult.object.objectId
1693
+ );
1694
+ if (!id) {
1695
+ throw new Error("Failed getting data-momentic-id attribute using CDP");
1666
1696
  }
1667
- return candidateNode;
1697
+ return this.page.locator(`[data-momentic-id="${id}"]`);
1668
1698
  } catch (err) {
1669
1699
  this.logger.error(
1670
- { err, node: candidateNode.getLogForm() },
1671
- "Failed click or click timed out"
1700
+ {
1701
+ err
1702
+ },
1703
+ "Failed to get ID attribute"
1672
1704
  );
1673
- clickAttempts++;
1674
- candidateNode = candidateNode.parent;
1705
+ throw err;
1675
1706
  }
1676
- }
1677
- throw new Error(
1678
- `Max click redirection attempts exhausted on original element: ${originalNode.getLogForm()}`
1679
- );
1707
+ });
1708
+ }
1709
+ clickUsingCDP(_0) {
1710
+ return __async(this, arguments, function* (originalNode, options = {}) {
1711
+ let clickAttempts = 0;
1712
+ let candidateNode = originalNode;
1713
+ while (clickAttempts < MAX_BROWSER_ACTION_ATTEMPTS) {
1714
+ if (!candidateNode || candidateNode.role === "RootWebArea") {
1715
+ throw new Error(
1716
+ `Attempted to click node with no clickable surrounding elements: ${originalNode.getLogForm()}`
1717
+ );
1718
+ }
1719
+ if (candidateNode.role === "StaticText") {
1720
+ candidateNode = candidateNode.parent;
1721
+ continue;
1722
+ }
1723
+ const candidateNodeID = candidateNode.backendNodeID;
1724
+ if (!candidateNodeID) {
1725
+ this.logger.warn(
1726
+ { node: candidateNode.getLogForm() },
1727
+ "Click candidate had no backend node ID"
1728
+ );
1729
+ candidateNode = candidateNode.parent;
1730
+ continue;
1731
+ }
1732
+ try {
1733
+ const locator = yield this.getLocatorFromBackendID(candidateNodeID);
1734
+ if (options.doubleClick) {
1735
+ yield locator.dblclick({
1736
+ timeout: BROWSER_ACTION_TIMEOUT_MS
1737
+ });
1738
+ } else {
1739
+ yield locator.click({
1740
+ timeout: BROWSER_ACTION_TIMEOUT_MS,
1741
+ button: options.rightClick ? "right" : "left"
1742
+ });
1743
+ }
1744
+ if (candidateNode.id !== originalNode.id) {
1745
+ this.logger.info(
1746
+ {
1747
+ oldNode: originalNode.getLogForm(),
1748
+ newNode: candidateNode.getLogForm()
1749
+ },
1750
+ `Redirected click successfully to new element`
1751
+ );
1752
+ }
1753
+ return candidateNode;
1754
+ } catch (err) {
1755
+ this.logger.error(
1756
+ { err, node: candidateNode.getLogForm() },
1757
+ "Failed click or click timed out"
1758
+ );
1759
+ clickAttempts++;
1760
+ candidateNode = candidateNode.parent;
1761
+ }
1762
+ }
1763
+ throw new Error(
1764
+ `Max click redirection attempts exhausted on original element: ${originalNode.getLogForm()}`
1765
+ );
1766
+ });
1680
1767
  }
1681
1768
  /**
1682
1769
  * Currently unused, but could be useful for vision model integration.
1683
1770
  * Gets x/y position of an a11y node.
1684
1771
  */
1685
- async getElementLocation(backendNodeId) {
1686
- const tree = await this.cdpClient.send("DOMSnapshot.captureSnapshot", {
1687
- computedStyles: [],
1688
- includeDOMRects: true,
1689
- includePaintOrder: true
1690
- });
1691
- let devicePixelRatio = await this.page.evaluate(
1692
- () => window.devicePixelRatio
1693
- );
1694
- if (process.platform === "darwin" && devicePixelRatio === 1) {
1695
- devicePixelRatio = RETINA_WINDOW_SCALE_FACTOR;
1696
- }
1697
- const document2 = tree["documents"][0];
1698
- const layout = document2["layout"];
1699
- const nodes = document2["nodes"];
1700
- const nodeNames = nodes["nodeName"] || [];
1701
- const backendNodeIds = nodes["backendNodeId"] || [];
1702
- const layoutNodeIndex = layout["nodeIndex"];
1703
- const bounds = layout["bounds"];
1704
- let cursor2 = -1;
1705
- for (let i = 0; i < nodeNames.length; i++) {
1706
- if (backendNodeIds[i] === backendNodeId) {
1707
- cursor2 = layoutNodeIndex.indexOf(i);
1708
- break;
1709
- }
1710
- }
1711
- if (cursor2 === -1) {
1712
- throw new Error(
1713
- `Could not find any backend node with ID ${backendNodeId}`
1772
+ getElementLocation(backendNodeId) {
1773
+ return __async(this, null, function* () {
1774
+ const tree = yield this.cdpClient.send("DOMSnapshot.captureSnapshot", {
1775
+ computedStyles: [],
1776
+ includeDOMRects: true,
1777
+ includePaintOrder: true
1778
+ });
1779
+ let devicePixelRatio = yield this.page.evaluate(
1780
+ () => window.devicePixelRatio
1714
1781
  );
1715
- }
1716
- let [x = 0, y = 0, width = 0, height = 0] = bounds[cursor2];
1717
- x /= devicePixelRatio;
1718
- y /= devicePixelRatio;
1719
- width /= devicePixelRatio;
1720
- height /= devicePixelRatio;
1721
- const centerX = x + width / 2;
1722
- const centerY = y + height / 2;
1723
- return { centerX, centerY };
1782
+ if (process.platform === "darwin" && devicePixelRatio === 1) {
1783
+ devicePixelRatio = RETINA_WINDOW_SCALE_FACTOR;
1784
+ }
1785
+ const document2 = tree["documents"][0];
1786
+ const layout = document2["layout"];
1787
+ const nodes = document2["nodes"];
1788
+ const nodeNames = nodes["nodeName"] || [];
1789
+ const backendNodeIds = nodes["backendNodeId"] || [];
1790
+ const layoutNodeIndex = layout["nodeIndex"];
1791
+ const bounds = layout["bounds"];
1792
+ let cursor2 = -1;
1793
+ for (let i = 0; i < nodeNames.length; i++) {
1794
+ if (backendNodeIds[i] === backendNodeId) {
1795
+ cursor2 = layoutNodeIndex.indexOf(i);
1796
+ break;
1797
+ }
1798
+ }
1799
+ if (cursor2 === -1) {
1800
+ throw new Error(
1801
+ `Could not find any backend node with ID ${backendNodeId}`
1802
+ );
1803
+ }
1804
+ let [x = 0, y = 0, width = 0, height = 0] = bounds[cursor2];
1805
+ x /= devicePixelRatio;
1806
+ y /= devicePixelRatio;
1807
+ width /= devicePixelRatio;
1808
+ height /= devicePixelRatio;
1809
+ const centerX = x + width / 2;
1810
+ const centerY = y + height / 2;
1811
+ return { centerX, centerY };
1812
+ });
1724
1813
  }
1725
- async scrollUp() {
1726
- await this.page.evaluate(() => {
1727
- (document.scrollingElement || document.body).scrollTop = (document.scrollingElement || document.body).scrollTop - window.innerHeight;
1814
+ scrollUp() {
1815
+ return __async(this, null, function* () {
1816
+ yield this.page.evaluate(() => {
1817
+ (document.scrollingElement || document.body).scrollTop = (document.scrollingElement || document.body).scrollTop - window.innerHeight;
1818
+ });
1819
+ yield this.page.evaluate(() => {
1820
+ (document.scrollingElement || document.body).scrollTop = (document.scrollingElement || document.body).scrollTop + window.innerHeight;
1821
+ });
1728
1822
  });
1729
- await this.page.evaluate(() => {
1730
- (document.scrollingElement || document.body).scrollTop = (document.scrollingElement || document.body).scrollTop + window.innerHeight;
1823
+ }
1824
+ scrollDown() {
1825
+ return __async(this, null, function* () {
1826
+ yield this.page.evaluate(() => {
1827
+ (document.scrollingElement || document.body).scrollTop = (document.scrollingElement || document.body).scrollTop + window.innerHeight;
1828
+ });
1731
1829
  });
1732
1830
  }
1733
- async scrollDown() {
1734
- await this.page.evaluate(() => {
1735
- (document.scrollingElement || document.body).scrollTop = (document.scrollingElement || document.body).scrollTop + window.innerHeight;
1831
+ goForward() {
1832
+ return __async(this, null, function* () {
1833
+ yield this.wrapPossibleNavigation(
1834
+ () => this.page.goForward({ timeout: MAX_LOAD_TIMEOUT_MS })
1835
+ );
1836
+ yield this.pageSetup();
1736
1837
  });
1737
1838
  }
1738
- async goForward() {
1739
- await this.wrapPossibleNavigation(
1740
- () => this.page.goForward({ timeout: MAX_LOAD_TIMEOUT_MS })
1741
- );
1742
- await this.pageSetup();
1839
+ goBack() {
1840
+ return __async(this, null, function* () {
1841
+ yield this.wrapPossibleNavigation(
1842
+ () => this.page.goBack({ timeout: MAX_LOAD_TIMEOUT_MS })
1843
+ );
1844
+ yield this.pageSetup();
1845
+ });
1743
1846
  }
1744
- async goBack() {
1745
- await this.wrapPossibleNavigation(
1746
- () => this.page.goBack({ timeout: MAX_LOAD_TIMEOUT_MS })
1747
- );
1748
- await this.pageSetup();
1749
- }
1750
- async switchToPage(urlSubstring) {
1751
- const allPages = await this.context.pages();
1752
- for (let i = 0; i < allPages.length; i++) {
1753
- const page = allPages[i];
1754
- if (page.url().includes(urlSubstring)) {
1755
- this.page = page;
1756
- await page.waitForLoadState("load", {
1757
- timeout: MAX_LOAD_TIMEOUT_MS
1758
- });
1759
- await this.pageSetup();
1760
- this.cdpClient = await this.context.newCDPSession(page);
1761
- await initCDPSession(this.cdpClient);
1762
- this.logger.info(`Switching to tab ${i} with url ${page.url()}`);
1763
- return;
1847
+ switchToPage(urlSubstring) {
1848
+ return __async(this, null, function* () {
1849
+ const allPages = yield this.context.pages();
1850
+ for (let i = 0; i < allPages.length; i++) {
1851
+ const page = allPages[i];
1852
+ if (page.url().includes(urlSubstring)) {
1853
+ this.page = page;
1854
+ yield page.waitForLoadState("load", {
1855
+ timeout: MAX_LOAD_TIMEOUT_MS
1856
+ });
1857
+ yield this.pageSetup();
1858
+ this.cdpClient = yield this.context.newCDPSession(page);
1859
+ yield initCDPSession(this.cdpClient);
1860
+ this.logger.info(`Switching to tab ${i} with url ${page.url()}`);
1861
+ return;
1862
+ }
1764
1863
  }
1765
- }
1766
- throw new Error(`Could not find page with url containing ${urlSubstring}`);
1864
+ throw new Error(`Could not find page with url containing ${urlSubstring}`);
1865
+ });
1767
1866
  }
1768
- async setCookie(cookie) {
1769
- const cookieSettings = parseCookieString(cookie);
1770
- await this.context.addCookies([cookieSettings]);
1867
+ setCookie(cookie) {
1868
+ return __async(this, null, function* () {
1869
+ const cookieSettings = parseCookieString(cookie);
1870
+ yield this.context.addCookies([cookieSettings]);
1871
+ });
1771
1872
  }
1772
1873
  };
1874
+ _ChromeBrowser.USER_AGENT = devices["Desktop Chrome"].userAgent;
1875
+ var ChromeBrowser = _ChromeBrowser;
1773
1876
 
1774
1877
  // ../../packages/web-agent/src/configs/controller.ts
1775
1878
  var A11Y_CONTROLLER_CONFIG = {
@@ -1785,18 +1888,6 @@ import dedent2 from "dedent";
1785
1888
  import diffLines from "diff-lines";
1786
1889
  var MAX_HISTORY_CHAR_LENGTH = 1e4;
1787
1890
  var AgentController = class {
1788
- // Instance of browser to interact with
1789
- browser;
1790
- // Stack of queued-up instructions
1791
- pendingInstructions;
1792
- // manager for all AI generation
1793
- generator;
1794
- // Stack of commands previously executed.
1795
- // Top of stack can be a pending command that hasn't been executed yet.
1796
- // Should not contain intermediate successes due to granular commands.
1797
- commandHistory;
1798
- config;
1799
- logger;
1800
1891
  constructor({ browser, config, generator, logger }) {
1801
1892
  this.browser = browser;
1802
1893
  this.generator = generator;
@@ -1831,16 +1922,20 @@ var AgentController = class {
1831
1922
  /**
1832
1923
  * Reset controller and browser state.
1833
1924
  */
1834
- async resetState() {
1835
- this.resetHistory();
1836
- await this.browser.navigate(this.browser.baseURL);
1925
+ resetState() {
1926
+ return __async(this, null, function* () {
1927
+ this.resetHistory();
1928
+ yield this.browser.navigate(this.browser.baseURL);
1929
+ });
1837
1930
  }
1838
1931
  /**
1839
1932
  * Get the browser state as a string
1840
1933
  */
1841
- async getBrowserState() {
1842
- const a11yTree = await this.browser.getA11yTree();
1843
- return a11yTree.serialize();
1934
+ getBrowserState() {
1935
+ return __async(this, null, function* () {
1936
+ const a11yTree = yield this.browser.getA11yTree();
1937
+ return a11yTree.serialize();
1938
+ });
1844
1939
  }
1845
1940
  getSerializedHistory(url, currentBrowserState) {
1846
1941
  let history;
@@ -1851,99 +1946,105 @@ var AgentController = class {
1851
1946
  }
1852
1947
  return history;
1853
1948
  }
1854
- async splitUserGoal(type, goal, disableCache) {
1855
- if (type === "AI_ACTION" /* AI_ACTION */ && goal.match(/[,!;.]|(?:and)|(?:then)/) && this.config.useGoalSplitter) {
1856
- const granularInstructions = await this.generator.getGranularGoals(
1857
- { goal, url: this.browser.url },
1858
- disableCache
1859
- );
1860
- this.pendingInstructions = granularInstructions.reverse();
1861
- } else {
1862
- this.pendingInstructions = [goal];
1863
- }
1949
+ splitUserGoal(type, goal, disableCache) {
1950
+ return __async(this, null, function* () {
1951
+ if (type === "AI_ACTION" /* AI_ACTION */ && goal.match(/[,!;.]|(?:and)|(?:then)/) && this.config.useGoalSplitter) {
1952
+ const granularInstructions = yield this.generator.getGranularGoals(
1953
+ { goal, url: this.browser.url },
1954
+ disableCache
1955
+ );
1956
+ this.pendingInstructions = granularInstructions.reverse();
1957
+ } else {
1958
+ this.pendingInstructions = [goal];
1959
+ }
1960
+ });
1864
1961
  }
1865
1962
  /**
1866
1963
  * Given previously executed commands, generate command for the current prompt.
1867
1964
  * Should only be used for AI action.
1868
1965
  */
1869
- async promptToCommand(type, goal, disableCache) {
1870
- if (this.pendingInstructions.length === 0) {
1871
- await this.splitUserGoal(type, goal, disableCache);
1872
- }
1873
- const currInstruction = this.pendingInstructions[this.pendingInstructions.length - 1];
1874
- this.logger.info({ goal: currInstruction }, "Starting prompt translation");
1875
- const getBrowserStateStart = Date.now();
1876
- const url = this.browser.url;
1877
- const browserState = await this.getBrowserState();
1878
- this.logger.info(
1879
- {
1880
- duration: Date.now() - getBrowserStateStart,
1881
- url
1882
- },
1883
- "Got browser state"
1884
- );
1885
- const numPrevious = this.commandHistory.length;
1886
- this.commandHistory.push({
1887
- state: "PENDING",
1888
- browserStateBeforeCommand: browserState,
1889
- urlBeforeCommand: url,
1890
- type
1891
- });
1892
- const history = this.getSerializedHistory(url, browserState);
1893
- const getCommandProposalStart = Date.now();
1894
- const proposedCommand = await this.generator.getProposedCommand(
1895
- {
1896
- url,
1897
- numPrevious,
1898
- browserState,
1899
- history,
1900
- goal: currInstruction,
1901
- lastCommand: this.lastExecutedCommand
1902
- },
1903
- disableCache
1904
- );
1905
- this.logger.info(
1906
- { duration: Date.now() - getCommandProposalStart },
1907
- "Got proposed command"
1908
- );
1909
- if (proposedCommand.type === "SUCCESS" /* SUCCESS */) {
1910
- const finishedInstruction = this.pendingInstructions.pop();
1966
+ promptToCommand(type, goal, disableCache) {
1967
+ return __async(this, null, function* () {
1968
+ if (this.pendingInstructions.length === 0) {
1969
+ yield this.splitUserGoal(type, goal, disableCache);
1970
+ }
1971
+ const currInstruction = this.pendingInstructions[this.pendingInstructions.length - 1];
1972
+ this.logger.info({ goal: currInstruction }, "Starting prompt translation");
1973
+ const getBrowserStateStart = Date.now();
1974
+ const url = this.browser.url;
1975
+ const browserState = yield this.getBrowserState();
1911
1976
  this.logger.info(
1912
1977
  {
1913
- finishedInstruction,
1914
- remainingInstructions: this.pendingInstructions
1978
+ duration: Date.now() - getBrowserStateStart,
1979
+ url
1915
1980
  },
1916
- "Removing pending instruction due to SUCCESS"
1981
+ "Got browser state"
1917
1982
  );
1918
- if (this.pendingInstructions.length !== 0) {
1919
- this.commandHistory.pop();
1920
- return this.promptToCommand(type, "", disableCache);
1921
- }
1922
- } else if (
1923
- // on failure, we don't continue to execute
1924
- proposedCommand.type === "FAILURE"
1925
- ) {
1926
- this.logger.info(
1983
+ const numPrevious = this.commandHistory.length;
1984
+ this.commandHistory.push({
1985
+ state: "PENDING",
1986
+ browserStateBeforeCommand: browserState,
1987
+ urlBeforeCommand: url,
1988
+ type
1989
+ });
1990
+ const history = this.getSerializedHistory(url, browserState);
1991
+ const getCommandProposalStart = Date.now();
1992
+ const proposedCommand = yield this.generator.getProposedCommand(
1927
1993
  {
1928
- remainingInstructions: this.pendingInstructions
1994
+ url,
1995
+ numPrevious,
1996
+ browserState,
1997
+ history,
1998
+ goal: currInstruction,
1999
+ lastCommand: this.lastExecutedCommand
1929
2000
  },
1930
- "Removing pending instructions due to FAILURE"
2001
+ disableCache
1931
2002
  );
1932
- this.pendingInstructions = [];
1933
- }
1934
- return proposedCommand;
2003
+ this.logger.info(
2004
+ { duration: Date.now() - getCommandProposalStart },
2005
+ "Got proposed command"
2006
+ );
2007
+ if (proposedCommand.type === "SUCCESS" /* SUCCESS */) {
2008
+ const finishedInstruction = this.pendingInstructions.pop();
2009
+ this.logger.info(
2010
+ {
2011
+ finishedInstruction,
2012
+ remainingInstructions: this.pendingInstructions
2013
+ },
2014
+ "Removing pending instruction due to SUCCESS"
2015
+ );
2016
+ if (this.pendingInstructions.length !== 0) {
2017
+ this.commandHistory.pop();
2018
+ return this.promptToCommand(type, "", disableCache);
2019
+ }
2020
+ } else if (
2021
+ // on failure, we don't continue to execute
2022
+ proposedCommand.type === "FAILURE"
2023
+ ) {
2024
+ this.logger.info(
2025
+ {
2026
+ remainingInstructions: this.pendingInstructions
2027
+ },
2028
+ "Removing pending instructions due to FAILURE"
2029
+ );
2030
+ this.pendingInstructions = [];
2031
+ }
2032
+ return proposedCommand;
2033
+ });
1935
2034
  }
1936
- async locateElement(description, disableCache) {
1937
- const locator = await this.generator.getElementLocation(
1938
- { browserState: await this.getBrowserState(), goal: description },
1939
- disableCache
1940
- );
1941
- if (locator.id < 0) {
1942
- throw new Error(
1943
- `Unable to locate element with description: ${description}`
2035
+ locateElement(description, disableCache) {
2036
+ return __async(this, null, function* () {
2037
+ const locator = yield this.generator.getElementLocation(
2038
+ { browserState: yield this.getBrowserState(), goal: description },
2039
+ disableCache
1944
2040
  );
1945
- }
1946
- return locator;
2041
+ if (locator.id < 0) {
2042
+ throw new Error(
2043
+ `Unable to locate element with description: ${description}`
2044
+ );
2045
+ }
2046
+ return locator;
2047
+ });
1947
2048
  }
1948
2049
  /**
1949
2050
  * Construct a detailed history that can be passed to the LLM.
@@ -2001,104 +2102,108 @@ var AgentController = class {
2001
2102
  * @param [stateless=false] Execute this command in a stateless fashion, without modifying any controller state such as
2002
2103
  * pending instructions. Useful when executing cached instructions.
2003
2104
  */
2004
- async executeCommand(command, disableCache, stateless = false) {
2005
- const pendingHistory = this.commandHistory[this.commandHistory.length - 1];
2006
- if (!stateless) {
2007
- if (!pendingHistory || pendingHistory.state !== "PENDING") {
2008
- throw new Error(
2009
- "Executing command but there is no pending entry in the history"
2010
- );
2105
+ executeCommand(command, disableCache, stateless = false) {
2106
+ return __async(this, null, function* () {
2107
+ const pendingHistory = this.commandHistory[this.commandHistory.length - 1];
2108
+ if (!stateless) {
2109
+ if (!pendingHistory || pendingHistory.state !== "PENDING") {
2110
+ throw new Error(
2111
+ "Executing command but there is no pending entry in the history"
2112
+ );
2113
+ }
2114
+ } else {
2115
+ yield this.browser.getA11yTree();
2011
2116
  }
2012
- } else {
2013
- await this.browser.getA11yTree();
2014
- }
2015
- let result;
2016
- try {
2017
- const executionStart = Date.now();
2018
- result = await this.executePresetStep(
2019
- command,
2020
- disableCache
2021
- );
2022
- this.logger.info(
2023
- { result, duration: Date.now() - executionStart },
2024
- "Got execution result"
2025
- );
2026
- } catch (e) {
2027
- if (e instanceof Error) {
2028
- throw new BrowserExecutionError(`Failed to execute command: ${e}`, {
2029
- cause: e
2030
- });
2117
+ let result;
2118
+ try {
2119
+ const executionStart = Date.now();
2120
+ result = yield this.executePresetStep(
2121
+ command,
2122
+ disableCache
2123
+ );
2124
+ this.logger.info(
2125
+ { result, duration: Date.now() - executionStart },
2126
+ "Got execution result"
2127
+ );
2128
+ } catch (e) {
2129
+ if (e instanceof Error) {
2130
+ throw new BrowserExecutionError(`Failed to execute command: ${e}`, {
2131
+ cause: e
2132
+ });
2133
+ }
2134
+ throw new BrowserExecutionError(
2135
+ `Unexpected throw from executing command`,
2136
+ {
2137
+ cause: new Error(`${e}`)
2138
+ }
2139
+ );
2031
2140
  }
2032
- throw new BrowserExecutionError(
2033
- `Unexpected throw from executing command`,
2034
- {
2035
- cause: new Error(`${e}`)
2141
+ if (result.succeedImmediately && !stateless) {
2142
+ this.pendingInstructions.pop();
2143
+ if (this.pendingInstructions.length > 0) {
2144
+ result.succeedImmediately = false;
2036
2145
  }
2037
- );
2038
- }
2039
- if (result.succeedImmediately && !stateless) {
2040
- this.pendingInstructions.pop();
2041
- if (this.pendingInstructions.length > 0) {
2042
- result.succeedImmediately = false;
2043
2146
  }
2044
- }
2045
- if (result.elementInteracted && "target" in command && !command.target.elementDescriptor) {
2046
- command.target.elementDescriptor = result.elementInteracted.trim();
2047
- }
2048
- if (!stateless) {
2049
- pendingHistory.generatedStep = command;
2050
- pendingHistory.serializedCommand = serializeCommand(command);
2051
- pendingHistory.state = "DONE";
2052
- }
2053
- return result;
2147
+ if (result.elementInteracted && "target" in command && !command.target.elementDescriptor) {
2148
+ command.target.elementDescriptor = result.elementInteracted.trim();
2149
+ }
2150
+ if (!stateless) {
2151
+ pendingHistory.generatedStep = command;
2152
+ pendingHistory.serializedCommand = serializeCommand(command);
2153
+ pendingHistory.state = "DONE";
2154
+ }
2155
+ return result;
2156
+ });
2054
2157
  }
2055
- async executeAssertion(urlBeforeCommand, command) {
2056
- let params;
2057
- if (command.useVision) {
2058
- params = {
2059
- goal: command.assertion,
2060
- url: urlBeforeCommand,
2061
- // used for vision only
2062
- screenshot: await this.browser.screenshot(),
2063
- // unused for visual assertion
2064
- browserState: "",
2065
- history: "",
2066
- numPrevious: -1,
2067
- lastCommand: null
2068
- };
2069
- } else {
2070
- const browserState = await this.getBrowserState();
2071
- const history = this.getSerializedHistory(urlBeforeCommand, browserState);
2072
- params = {
2073
- goal: command.assertion,
2074
- url: urlBeforeCommand,
2075
- // used for text only
2076
- browserState,
2077
- history,
2078
- lastCommand: this.lastExecutedCommand,
2079
- numPrevious: this.commandHistory.length
2080
- };
2081
- }
2082
- const assertionEval = await this.generator.getAssertionResult(
2083
- params,
2084
- command.useVision,
2085
- command.disableCache
2086
- );
2087
- if (assertionEval.relevantElements) {
2088
- void Promise.all(
2089
- assertionEval.relevantElements.map(
2090
- (id) => this.browser.highlight({ id })
2091
- )
2158
+ executeAssertion(urlBeforeCommand, command) {
2159
+ return __async(this, null, function* () {
2160
+ let params;
2161
+ if (command.useVision) {
2162
+ params = {
2163
+ goal: command.assertion,
2164
+ url: urlBeforeCommand,
2165
+ // used for vision only
2166
+ screenshot: yield this.browser.screenshot(),
2167
+ // unused for visual assertion
2168
+ browserState: "",
2169
+ history: "",
2170
+ numPrevious: -1,
2171
+ lastCommand: null
2172
+ };
2173
+ } else {
2174
+ const browserState = yield this.getBrowserState();
2175
+ const history = this.getSerializedHistory(urlBeforeCommand, browserState);
2176
+ params = {
2177
+ goal: command.assertion,
2178
+ url: urlBeforeCommand,
2179
+ // used for text only
2180
+ browserState,
2181
+ history,
2182
+ lastCommand: this.lastExecutedCommand,
2183
+ numPrevious: this.commandHistory.length
2184
+ };
2185
+ }
2186
+ const assertionEval = yield this.generator.getAssertionResult(
2187
+ params,
2188
+ command.useVision,
2189
+ command.disableCache
2092
2190
  );
2093
- }
2094
- if (!assertionEval.result) {
2095
- throw new Error(assertionEval.thoughts);
2096
- }
2097
- return {
2098
- succeedImmediately: false,
2099
- thoughts: assertionEval.thoughts,
2100
- urlAfterCommand: urlBeforeCommand
2101
- };
2191
+ if (assertionEval.relevantElements) {
2192
+ void Promise.all(
2193
+ assertionEval.relevantElements.map(
2194
+ (id) => this.browser.highlight({ id })
2195
+ )
2196
+ );
2197
+ }
2198
+ if (!assertionEval.result) {
2199
+ throw new Error(assertionEval.thoughts);
2200
+ }
2201
+ return {
2202
+ succeedImmediately: false,
2203
+ thoughts: assertionEval.thoughts,
2204
+ urlAfterCommand: urlBeforeCommand
2205
+ };
2206
+ });
2102
2207
  }
2103
2208
  /**
2104
2209
  * Executes a preset command.
@@ -2106,157 +2211,159 @@ var AgentController = class {
2106
2211
  * For assertions, an AssertionResult with thoughts is returned.
2107
2212
  * Throws on failure.
2108
2213
  */
2109
- async executePresetStep(command, disableCache) {
2110
- var _a, _b, _c;
2111
- const urlBeforeCommand = this.browser.url;
2112
- switch (command.type) {
2113
- case "SUCCESS" /* SUCCESS */:
2114
- if ((_a = command.condition) == null ? void 0 : _a.assertion.trim()) {
2115
- return this.executeAssertion(urlBeforeCommand, command.condition);
2214
+ executePresetStep(command, disableCache) {
2215
+ return __async(this, null, function* () {
2216
+ var _a, _b, _c;
2217
+ const urlBeforeCommand = this.browser.url;
2218
+ switch (command.type) {
2219
+ case "SUCCESS" /* SUCCESS */:
2220
+ if ((_a = command.condition) == null ? void 0 : _a.assertion.trim()) {
2221
+ return this.executeAssertion(urlBeforeCommand, command.condition);
2222
+ }
2223
+ return {
2224
+ succeedImmediately: false,
2225
+ urlAfterCommand: this.browser.url
2226
+ };
2227
+ case "AI_ASSERTION" /* AI_ASSERTION */: {
2228
+ return this.executeAssertion(urlBeforeCommand, command);
2116
2229
  }
2117
- return {
2118
- succeedImmediately: false,
2119
- urlAfterCommand: this.browser.url
2120
- };
2121
- case "AI_ASSERTION" /* AI_ASSERTION */: {
2122
- return this.executeAssertion(urlBeforeCommand, command);
2123
- }
2124
- case "NAVIGATE" /* NAVIGATE */:
2125
- await this.browser.navigate(command.url);
2126
- break;
2127
- case "GO_BACK" /* GO_BACK */:
2128
- await this.browser.goBack();
2129
- break;
2130
- case "GO_FORWARD" /* GO_FORWARD */:
2131
- await this.browser.goForward();
2132
- break;
2133
- case "SCROLL_DOWN" /* SCROLL_DOWN */:
2134
- await this.browser.scrollDown();
2135
- break;
2136
- case "SCROLL_UP" /* SCROLL_UP */:
2137
- await this.browser.scrollUp();
2138
- break;
2139
- case "WAIT" /* WAIT */:
2140
- await this.browser.wait(command.delay * 1e3);
2141
- break;
2142
- case "REFRESH" /* REFRESH */:
2143
- await this.browser.refresh();
2144
- break;
2145
- case "CLICK" /* CLICK */: {
2146
- let id;
2147
- if (command.target.a11yData) {
2148
- id = (_b = command.target.a11yData) == null ? void 0 : _b.id;
2149
- } else {
2150
- const locator = await this.locateElement(
2151
- command.target.elementDescriptor,
2152
- disableCache
2230
+ case "NAVIGATE" /* NAVIGATE */:
2231
+ yield this.browser.navigate(command.url);
2232
+ break;
2233
+ case "GO_BACK" /* GO_BACK */:
2234
+ yield this.browser.goBack();
2235
+ break;
2236
+ case "GO_FORWARD" /* GO_FORWARD */:
2237
+ yield this.browser.goForward();
2238
+ break;
2239
+ case "SCROLL_DOWN" /* SCROLL_DOWN */:
2240
+ yield this.browser.scrollDown();
2241
+ break;
2242
+ case "SCROLL_UP" /* SCROLL_UP */:
2243
+ yield this.browser.scrollUp();
2244
+ break;
2245
+ case "WAIT" /* WAIT */:
2246
+ yield this.browser.wait(command.delay * 1e3);
2247
+ break;
2248
+ case "REFRESH" /* REFRESH */:
2249
+ yield this.browser.refresh();
2250
+ break;
2251
+ case "CLICK" /* CLICK */: {
2252
+ let id;
2253
+ if (command.target.a11yData) {
2254
+ id = (_b = command.target.a11yData) == null ? void 0 : _b.id;
2255
+ } else {
2256
+ const locator = yield this.locateElement(
2257
+ command.target.elementDescriptor,
2258
+ disableCache
2259
+ );
2260
+ id = locator.id;
2261
+ }
2262
+ const elementInteracted = yield this.browser.click(
2263
+ {
2264
+ id
2265
+ },
2266
+ {
2267
+ doubleClick: command.doubleClick,
2268
+ rightClick: command.rightClick
2269
+ }
2153
2270
  );
2154
- id = locator.id;
2155
- }
2156
- const elementInteracted = await this.browser.click(
2157
- {
2158
- id
2159
- },
2160
- {
2161
- doubleClick: command.doubleClick,
2162
- rightClick: command.rightClick
2271
+ const result2 = {
2272
+ urlAfterCommand: this.browser.url,
2273
+ succeedImmediately: false,
2274
+ elementInteracted
2275
+ };
2276
+ if (urlChanged(urlBeforeCommand, result2.urlAfterCommand)) {
2277
+ result2.succeedImmediately = true;
2278
+ result2.succeedImmediatelyReason = "URL changed";
2163
2279
  }
2164
- );
2165
- const result2 = {
2166
- urlAfterCommand: this.browser.url,
2167
- succeedImmediately: false,
2168
- elementInteracted
2169
- };
2170
- if (urlChanged(urlBeforeCommand, result2.urlAfterCommand)) {
2171
- result2.succeedImmediately = true;
2172
- result2.succeedImmediatelyReason = "URL changed";
2280
+ return result2;
2173
2281
  }
2174
- return result2;
2175
- }
2176
- case "SELECT_OPTION" /* SELECT_OPTION */: {
2177
- let id;
2178
- if (command.target.a11yData) {
2179
- id = (_c = command.target.a11yData) == null ? void 0 : _c.id;
2180
- } else {
2181
- const locator = await this.locateElement(
2182
- command.target.elementDescriptor,
2183
- disableCache
2282
+ case "SELECT_OPTION" /* SELECT_OPTION */: {
2283
+ let id;
2284
+ if (command.target.a11yData) {
2285
+ id = (_c = command.target.a11yData) == null ? void 0 : _c.id;
2286
+ } else {
2287
+ const locator = yield this.locateElement(
2288
+ command.target.elementDescriptor,
2289
+ disableCache
2290
+ );
2291
+ id = locator.id;
2292
+ }
2293
+ const elementInteracted = yield this.browser.selectOption(
2294
+ {
2295
+ id
2296
+ },
2297
+ command.option
2184
2298
  );
2185
- id = locator.id;
2299
+ return {
2300
+ succeedImmediately: false,
2301
+ urlAfterCommand: this.browser.url,
2302
+ elementInteracted
2303
+ };
2186
2304
  }
2187
- const elementInteracted = await this.browser.selectOption(
2188
- {
2189
- id
2190
- },
2191
- command.option
2192
- );
2193
- return {
2194
- succeedImmediately: false,
2195
- urlAfterCommand: this.browser.url,
2196
- elementInteracted
2197
- };
2198
- }
2199
- case "TAB" /* TAB */:
2200
- await this.browser.switchToPage(command.url);
2201
- break;
2202
- case "COOKIE" /* COOKIE */:
2203
- await this.browser.setCookie(command.value);
2204
- break;
2205
- case "TYPE" /* TYPE */: {
2206
- let elementInteracted;
2207
- const target = command.target;
2208
- if (target.a11yData) {
2209
- elementInteracted = await this.browser.click({
2210
- id: target.a11yData.id
2211
- });
2212
- } else if (target.elementDescriptor.length > 0) {
2213
- const locator = await this.locateElement(
2214
- command.target.elementDescriptor,
2215
- disableCache
2216
- );
2217
- elementInteracted = await this.browser.click({
2218
- id: locator.id
2305
+ case "TAB" /* TAB */:
2306
+ yield this.browser.switchToPage(command.url);
2307
+ break;
2308
+ case "COOKIE" /* COOKIE */:
2309
+ yield this.browser.setCookie(command.value);
2310
+ break;
2311
+ case "TYPE" /* TYPE */: {
2312
+ let elementInteracted;
2313
+ const target = command.target;
2314
+ if (target.a11yData) {
2315
+ elementInteracted = yield this.browser.click({
2316
+ id: target.a11yData.id
2317
+ });
2318
+ } else if (target.elementDescriptor.length > 0) {
2319
+ const locator = yield this.locateElement(
2320
+ command.target.elementDescriptor,
2321
+ disableCache
2322
+ );
2323
+ elementInteracted = yield this.browser.click({
2324
+ id: locator.id
2325
+ });
2326
+ }
2327
+ yield this.browser.type(command.value, {
2328
+ clearContent: command.clearContent,
2329
+ pressKeysSequentially: command.pressKeysSequentially
2219
2330
  });
2331
+ if (command.pressEnter) {
2332
+ yield this.browser.press("Enter");
2333
+ }
2334
+ const result2 = {
2335
+ urlAfterCommand: this.browser.url,
2336
+ succeedImmediately: false,
2337
+ elementInteracted
2338
+ };
2339
+ if (urlChanged(urlBeforeCommand, result2.urlAfterCommand)) {
2340
+ result2.succeedImmediately = true;
2341
+ result2.succeedImmediatelyReason = "URL changed";
2342
+ }
2343
+ return result2;
2220
2344
  }
2221
- await this.browser.type(command.value, {
2222
- clearContent: command.clearContent,
2223
- pressKeysSequentially: command.pressKeysSequentially
2224
- });
2225
- if (command.pressEnter) {
2226
- await this.browser.press("Enter");
2227
- }
2228
- const result2 = {
2229
- urlAfterCommand: this.browser.url,
2230
- succeedImmediately: false,
2231
- elementInteracted
2232
- };
2233
- if (urlChanged(urlBeforeCommand, result2.urlAfterCommand)) {
2234
- result2.succeedImmediately = true;
2235
- result2.succeedImmediatelyReason = "URL changed";
2236
- }
2237
- return result2;
2345
+ case "PRESS" /* PRESS */:
2346
+ yield this.browser.press(command.value);
2347
+ const result = {
2348
+ urlAfterCommand: this.browser.url,
2349
+ succeedImmediately: false
2350
+ };
2351
+ if (urlChanged(urlBeforeCommand, result.urlAfterCommand)) {
2352
+ result.succeedImmediately = true;
2353
+ result.succeedImmediatelyReason = "URL changed";
2354
+ }
2355
+ return result;
2356
+ default:
2357
+ const assertUnreachable = (_x) => {
2358
+ throw "If Typescript complains about the line below, you missed a case or break in the switch above";
2359
+ };
2360
+ return assertUnreachable(command);
2238
2361
  }
2239
- case "PRESS" /* PRESS */:
2240
- await this.browser.press(command.value);
2241
- const result = {
2242
- urlAfterCommand: this.browser.url,
2243
- succeedImmediately: false
2244
- };
2245
- if (urlChanged(urlBeforeCommand, result.urlAfterCommand)) {
2246
- result.succeedImmediately = true;
2247
- result.succeedImmediatelyReason = "URL changed";
2248
- }
2249
- return result;
2250
- default:
2251
- const assertUnreachable = (_x) => {
2252
- throw "If Typescript complains about the line below, you missed a case or break in the switch above";
2253
- };
2254
- return assertUnreachable(command);
2255
- }
2256
- return {
2257
- succeedImmediately: false,
2258
- urlAfterCommand: this.browser.url
2259
- };
2362
+ return {
2363
+ succeedImmediately: false,
2364
+ urlAfterCommand: this.browser.url
2365
+ };
2366
+ });
2260
2367
  }
2261
2368
  };
2262
2369
 
@@ -2265,96 +2372,104 @@ import fetchRetry from "fetch-retry";
2265
2372
  var fetch2 = fetchRetry(global.fetch);
2266
2373
  var API_VERSION = "v1";
2267
2374
  var APIGenerator = class {
2268
- baseURL;
2269
- apiKey;
2270
2375
  constructor(params) {
2271
2376
  this.baseURL = params.baseURL;
2272
2377
  this.apiKey = params.apiKey;
2273
2378
  }
2274
- async getElementLocation(context, disableCache) {
2275
- const result = await this.sendRequest(
2276
- `/${API_VERSION}/web-agent/locate-element`,
2277
- {
2278
- browserState: context.browserState,
2279
- goal: context.goal,
2280
- disableCache
2281
- }
2282
- );
2283
- return LocateResponseSchema.parse(result);
2379
+ getElementLocation(context, disableCache) {
2380
+ return __async(this, null, function* () {
2381
+ const result = yield this.sendRequest(
2382
+ `/${API_VERSION}/web-agent/locate-element`,
2383
+ {
2384
+ browserState: context.browserState,
2385
+ goal: context.goal,
2386
+ disableCache
2387
+ }
2388
+ );
2389
+ return LocateResponseSchema.parse(result);
2390
+ });
2284
2391
  }
2285
- async getAssertionResult(context, useVision, disableCache) {
2286
- var _a;
2287
- if (useVision) {
2288
- const result2 = await this.sendRequest(
2392
+ getAssertionResult(context, useVision, disableCache) {
2393
+ return __async(this, null, function* () {
2394
+ var _a;
2395
+ if (useVision) {
2396
+ const result2 = yield this.sendRequest(
2397
+ `/${API_VERSION}/web-agent/assertion`,
2398
+ {
2399
+ url: context.url,
2400
+ goal: context.goal,
2401
+ screenshot: (_a = context.screenshot) == null ? void 0 : _a.toString("base64"),
2402
+ disableCache,
2403
+ vision: true
2404
+ }
2405
+ );
2406
+ return GetAssertionResponseSchema.parse(result2);
2407
+ }
2408
+ const result = yield this.sendRequest(
2289
2409
  `/${API_VERSION}/web-agent/assertion`,
2290
2410
  {
2291
2411
  url: context.url,
2412
+ browserState: context.browserState,
2292
2413
  goal: context.goal,
2293
- screenshot: (_a = context.screenshot) == null ? void 0 : _a.toString("base64"),
2414
+ history: context.history,
2415
+ numPrevious: context.numPrevious,
2416
+ lastCommand: context.lastCommand,
2294
2417
  disableCache,
2295
- vision: true
2418
+ vision: false
2296
2419
  }
2297
2420
  );
2298
- return GetAssertionResponseSchema.parse(result2);
2299
- }
2300
- const result = await this.sendRequest(
2301
- `/${API_VERSION}/web-agent/assertion`,
2302
- {
2303
- url: context.url,
2304
- browserState: context.browserState,
2305
- goal: context.goal,
2306
- history: context.history,
2307
- numPrevious: context.numPrevious,
2308
- lastCommand: context.lastCommand,
2309
- disableCache,
2310
- vision: false
2311
- }
2312
- );
2313
- return GetAssertionResponseSchema.parse(result);
2314
- }
2315
- async getProposedCommand(context, disableCache) {
2316
- const result = await this.sendRequest(
2317
- `/${API_VERSION}/web-agent/next-command`,
2318
- {
2319
- url: context.url,
2320
- browserState: context.browserState,
2321
- goal: context.goal,
2322
- history: context.history,
2323
- numPrevious: context.numPrevious,
2324
- lastCommand: context.lastCommand,
2325
- disableCache
2326
- }
2327
- );
2328
- return GetNextCommandResponseSchema.parse(result);
2329
- }
2330
- async getGranularGoals(context, disableCache) {
2331
- const result = await this.sendRequest(
2332
- `/${API_VERSION}/web-agent/split-goal`,
2333
- {
2334
- url: context.url,
2335
- goal: context.goal,
2336
- disableCache
2337
- }
2338
- );
2339
- return SplitGoalResponseSchema.parse(result);
2340
- }
2341
- async sendRequest(path, body) {
2342
- const response = await fetch2(`${this.baseURL}${path}`, {
2343
- retries: 3,
2344
- retryDelay: 1e3,
2345
- method: "POST",
2346
- body: JSON.stringify(body),
2347
- headers: {
2348
- "Content-Type": "application/json",
2349
- Authorization: `Bearer ${this.apiKey}`
2350
- }
2421
+ return GetAssertionResponseSchema.parse(result);
2351
2422
  });
2352
- if (!response.ok) {
2353
- throw new Error(
2354
- `Request to ${path} failed with status ${response.status}: ${await response.text()}`
2423
+ }
2424
+ getProposedCommand(context, disableCache) {
2425
+ return __async(this, null, function* () {
2426
+ const result = yield this.sendRequest(
2427
+ `/${API_VERSION}/web-agent/next-command`,
2428
+ {
2429
+ url: context.url,
2430
+ browserState: context.browserState,
2431
+ goal: context.goal,
2432
+ history: context.history,
2433
+ numPrevious: context.numPrevious,
2434
+ lastCommand: context.lastCommand,
2435
+ disableCache
2436
+ }
2355
2437
  );
2356
- }
2357
- return response.json();
2438
+ return GetNextCommandResponseSchema.parse(result);
2439
+ });
2440
+ }
2441
+ getGranularGoals(context, disableCache) {
2442
+ return __async(this, null, function* () {
2443
+ const result = yield this.sendRequest(
2444
+ `/${API_VERSION}/web-agent/split-goal`,
2445
+ {
2446
+ url: context.url,
2447
+ goal: context.goal,
2448
+ disableCache
2449
+ }
2450
+ );
2451
+ return SplitGoalResponseSchema.parse(result);
2452
+ });
2453
+ }
2454
+ sendRequest(path, body) {
2455
+ return __async(this, null, function* () {
2456
+ const response = yield fetch2(`${this.baseURL}${path}`, {
2457
+ retries: 3,
2458
+ retryDelay: 1e3,
2459
+ method: "POST",
2460
+ body: JSON.stringify(body),
2461
+ headers: {
2462
+ "Content-Type": "application/json",
2463
+ Authorization: `Bearer ${this.apiKey}`
2464
+ }
2465
+ });
2466
+ if (!response.ok) {
2467
+ throw new Error(
2468
+ `Request to ${path} failed with status ${response.status}: ${yield response.text()}`
2469
+ );
2470
+ }
2471
+ return response.json();
2472
+ });
2358
2473
  }
2359
2474
  };
2360
2475
 
@@ -2364,62 +2479,72 @@ var version = "1.0.0";
2364
2479
  // src/api-client.ts
2365
2480
  var API_VERSION2 = "v1";
2366
2481
  var APIClient = class {
2367
- baseURL;
2368
- apiKey;
2369
2482
  constructor(params) {
2370
2483
  this.baseURL = params.baseURL;
2371
2484
  this.apiKey = params.apiKey;
2372
2485
  }
2373
- async getRun(runId) {
2374
- const result = await this.sendRequest(`/${API_VERSION2}/runs/${runId}`, {
2375
- method: "GET"
2486
+ getRun(runId) {
2487
+ return __async(this, null, function* () {
2488
+ const result = yield this.sendRequest(`/${API_VERSION2}/runs/${runId}`, {
2489
+ method: "GET"
2490
+ });
2491
+ return GetRunResponseSchema.parse(result);
2376
2492
  });
2377
- return GetRunResponseSchema.parse(result);
2378
2493
  }
2379
- async createRun(body) {
2380
- const result = await this.sendRequest(`/${API_VERSION2}/runs`, {
2381
- method: "POST",
2382
- body
2494
+ createRun(body) {
2495
+ return __async(this, null, function* () {
2496
+ const result = yield this.sendRequest(`/${API_VERSION2}/runs`, {
2497
+ method: "POST",
2498
+ body
2499
+ });
2500
+ return CreateRunResponseSchema.parse(result);
2383
2501
  });
2384
- return CreateRunResponseSchema.parse(result);
2385
2502
  }
2386
- async updateRun(runId, body) {
2387
- await this.sendRequest(`/${API_VERSION2}/runs/${runId}`, {
2388
- method: "PATCH",
2389
- body
2503
+ updateRun(runId, body) {
2504
+ return __async(this, null, function* () {
2505
+ yield this.sendRequest(`/${API_VERSION2}/runs/${runId}`, {
2506
+ method: "PATCH",
2507
+ body
2508
+ });
2390
2509
  });
2391
2510
  }
2392
- async getTest(testId) {
2393
- const result = await this.sendRequest(`/${API_VERSION2}/tests/${testId}`, {
2394
- method: "GET"
2511
+ getTest(testId) {
2512
+ return __async(this, null, function* () {
2513
+ const result = yield this.sendRequest(`/${API_VERSION2}/tests/${testId}`, {
2514
+ method: "GET"
2515
+ });
2516
+ return GetTestResponseSchema.parse(result);
2395
2517
  });
2396
- return GetTestResponseSchema.parse(result);
2397
2518
  }
2398
- async uploadScreenshot(body) {
2399
- const result = await this.sendRequest(`/${API_VERSION2}/screenshots`, {
2400
- method: "POST",
2401
- body
2519
+ uploadScreenshot(body) {
2520
+ return __async(this, null, function* () {
2521
+ const result = yield this.sendRequest(`/${API_VERSION2}/screenshots`, {
2522
+ method: "POST",
2523
+ body
2524
+ });
2525
+ return CreateScreenshotResponseSchema.parse(result);
2402
2526
  });
2403
- return CreateScreenshotResponseSchema.parse(result);
2404
2527
  }
2405
- async sendRequest(path, options) {
2406
- const response = await fetch(`${this.baseURL}${path}`, {
2407
- method: options.method,
2408
- body: options.body ? JSON.stringify(options.body) : void 0,
2409
- headers: {
2410
- "Content-Type": "application/json",
2411
- Authorization: `Bearer ${this.apiKey}`
2528
+ sendRequest(path, options) {
2529
+ return __async(this, null, function* () {
2530
+ const response = yield fetch(`${this.baseURL}${path}`, {
2531
+ method: options.method,
2532
+ body: options.body ? JSON.stringify(options.body) : void 0,
2533
+ headers: {
2534
+ "Content-Type": "application/json",
2535
+ Authorization: `Bearer ${this.apiKey}`
2536
+ }
2537
+ });
2538
+ if (!response.ok) {
2539
+ throw new Error(
2540
+ `Request to ${path} failed with status ${response.status}: ${yield response.text()}`
2541
+ );
2542
+ }
2543
+ if (response.status === 204) {
2544
+ return response.text();
2412
2545
  }
2546
+ return response.json();
2413
2547
  });
2414
- if (!response.ok) {
2415
- throw new Error(
2416
- `Request to ${path} failed with status ${response.status}: ${await response.text()}`
2417
- );
2418
- }
2419
- if (response.status === 204) {
2420
- return response.text();
2421
- }
2422
- return response.json();
2423
2548
  }
2424
2549
  };
2425
2550
 
@@ -2427,25 +2552,29 @@ var APIClient = class {
2427
2552
  var MAX_COMMANDS_PER_STEP = 20;
2428
2553
 
2429
2554
  // ../../packages/execute/src/steps/ai.ts
2430
- var executeAIStep = async ({
2431
- controller,
2432
- step,
2433
- logger,
2434
- advanced,
2435
- ...callbacks
2436
- }) => {
2437
- var _a, _b, _c, _d, _e, _f;
2438
- (_a = callbacks.onStarted) == null ? void 0 : _a.call(callbacks);
2555
+ var executeAIStep = (_a) => __async(void 0, null, function* () {
2556
+ var _b = _a, {
2557
+ controller,
2558
+ step,
2559
+ logger,
2560
+ advanced
2561
+ } = _b, callbacks = __objRest(_b, [
2562
+ "controller",
2563
+ "step",
2564
+ "logger",
2565
+ "advanced"
2566
+ ]);
2567
+ var _a2, _b2, _c, _d, _e, _f, _g;
2568
+ (_a2 = callbacks.onStarted) == null ? void 0 : _a2.call(callbacks);
2439
2569
  controller.resetHistory();
2440
- const result = {
2441
- ...step,
2570
+ const result = __spreadProps(__spreadValues({}, step), {
2442
2571
  startedAt: /* @__PURE__ */ new Date(),
2443
2572
  userAgent: ChromeBrowser.USER_AGENT,
2444
2573
  // placeholder values
2445
2574
  finishedAt: /* @__PURE__ */ new Date(),
2446
2575
  results: [],
2447
2576
  status: "SUCCESS" /* SUCCESS */
2448
- };
2577
+ });
2449
2578
  try {
2450
2579
  let commandIndex = 0;
2451
2580
  let useSavedCommands = step.commands && step.commands.length > 0;
@@ -2457,8 +2586,8 @@ var executeAIStep = async ({
2457
2586
  }
2458
2587
  let command;
2459
2588
  const startedAt = /* @__PURE__ */ new Date();
2460
- const beforeScreenshotBuffer = await controller.browser.screenshot();
2461
- const beforeScreenshot = await callbacks.onSaveScreenshot(
2589
+ const beforeScreenshotBuffer = yield controller.browser.screenshot();
2590
+ const beforeScreenshot = yield callbacks.onSaveScreenshot(
2462
2591
  beforeScreenshotBuffer
2463
2592
  );
2464
2593
  if (useSavedCommands) {
@@ -2469,7 +2598,7 @@ var executeAIStep = async ({
2469
2598
  );
2470
2599
  }
2471
2600
  } else {
2472
- command = await controller.promptToCommand(
2601
+ command = yield controller.promptToCommand(
2473
2602
  step.type,
2474
2603
  step.text,
2475
2604
  advanced.disableAICaching
@@ -2481,7 +2610,7 @@ var executeAIStep = async ({
2481
2610
  result.message = command.thoughts;
2482
2611
  break;
2483
2612
  }
2484
- (_b = callbacks.onCommandGenerated) == null ? void 0 : _b.call(callbacks, {
2613
+ (_b2 = callbacks.onCommandGenerated) == null ? void 0 : _b2.call(callbacks, {
2485
2614
  commandIndex,
2486
2615
  message: CARD_DISPLAY_NAMES[command.type] || `Unknown command (${command.type})`
2487
2616
  });
@@ -2498,7 +2627,7 @@ var executeAIStep = async ({
2498
2627
  `Executing command ${commandIndex}: ${serializeCommand(command)}`
2499
2628
  );
2500
2629
  try {
2501
- const executionResult = await controller.executeCommand(
2630
+ const executionResult = yield controller.executeCommand(
2502
2631
  command,
2503
2632
  advanced.disableAICaching,
2504
2633
  useSavedCommands
@@ -2509,8 +2638,8 @@ var executeAIStep = async ({
2509
2638
  message: serializeCommand(command),
2510
2639
  command
2511
2640
  });
2512
- const afterScreenshotBuffer = await controller.browser.screenshot();
2513
- const afterScreenshot = await callbacks.onSaveScreenshot(
2641
+ const afterScreenshotBuffer = yield controller.browser.screenshot();
2642
+ const afterScreenshot = yield callbacks.onSaveScreenshot(
2514
2643
  afterScreenshotBuffer
2515
2644
  );
2516
2645
  cmdResult.afterScreenshot = afterScreenshot;
@@ -2528,7 +2657,7 @@ var executeAIStep = async ({
2528
2657
  if (command.type === "SUCCESS" /* SUCCESS */) {
2529
2658
  result.finishedAt = /* @__PURE__ */ new Date();
2530
2659
  result.status = "SUCCESS" /* SUCCESS */;
2531
- result.message = executionResult.thoughts ?? "All commands completed.";
2660
+ result.message = (_d = executionResult.thoughts) != null ? _d : "All commands completed.";
2532
2661
  break;
2533
2662
  }
2534
2663
  if (executionResult.succeedImmediately && !useSavedCommands) {
@@ -2538,15 +2667,14 @@ var executeAIStep = async ({
2538
2667
  command = {
2539
2668
  type: "SUCCESS" /* SUCCESS */
2540
2669
  };
2541
- (_d = callbacks.onCommandExecuted) == null ? void 0 : _d.call(callbacks, {
2670
+ (_e = callbacks.onCommandExecuted) == null ? void 0 : _e.call(callbacks, {
2542
2671
  commandIndex: commandIndex + 1,
2543
2672
  message: serializeCommand(command),
2544
2673
  command
2545
2674
  });
2546
- result.results.push({
2547
- ...presetActionResult,
2675
+ result.results.push(__spreadProps(__spreadValues({}, presetActionResult), {
2548
2676
  command
2549
- });
2677
+ }));
2550
2678
  break;
2551
2679
  }
2552
2680
  } catch (err) {
@@ -2583,54 +2711,57 @@ var executeAIStep = async ({
2583
2711
  result.status = "FAILED" /* FAILED */;
2584
2712
  }
2585
2713
  if (result.status === "SUCCESS" /* SUCCESS */) {
2586
- (_e = callbacks.onSuccess) == null ? void 0 : _e.call(callbacks, {
2714
+ (_f = callbacks.onSuccess) == null ? void 0 : _f.call(callbacks, {
2587
2715
  message: result.message || "AI step succeeded.",
2588
2716
  startedAt: result.startedAt.getTime(),
2589
2717
  durationMs: result.finishedAt.getTime() - result.startedAt.getTime()
2590
2718
  });
2591
2719
  } else {
2592
- (_f = callbacks.onFailure) == null ? void 0 : _f.call(callbacks, {
2720
+ (_g = callbacks.onFailure) == null ? void 0 : _g.call(callbacks, {
2593
2721
  message: result.message || "AI step errored.",
2594
2722
  startedAt: result.startedAt.getTime(),
2595
2723
  durationMs: result.finishedAt.getTime() - result.startedAt.getTime()
2596
2724
  });
2597
2725
  }
2598
2726
  return result;
2599
- };
2727
+ });
2600
2728
 
2601
2729
  // ../../packages/execute/src/steps/preset.ts
2602
- var executePresetStep = async ({
2603
- controller,
2604
- step,
2605
- advanced,
2606
- ...callbacks
2607
- }) => {
2608
- var _a, _b, _c;
2609
- (_a = callbacks.onStarted) == null ? void 0 : _a.call(callbacks);
2730
+ var executePresetStep = (_a) => __async(void 0, null, function* () {
2731
+ var _b = _a, {
2732
+ controller,
2733
+ step,
2734
+ advanced
2735
+ } = _b, callbacks = __objRest(_b, [
2736
+ "controller",
2737
+ "step",
2738
+ "advanced"
2739
+ ]);
2740
+ var _a2, _b2, _c;
2741
+ (_a2 = callbacks.onStarted) == null ? void 0 : _a2.call(callbacks);
2610
2742
  const startedAt = /* @__PURE__ */ new Date();
2611
2743
  const beforeUrl = controller.browser.url;
2612
- const beforeScreenshotBuffer = await controller.browser.screenshot();
2613
- const beforeScreenshot = await callbacks.onSaveScreenshot(
2744
+ const beforeScreenshotBuffer = yield controller.browser.screenshot();
2745
+ const beforeScreenshot = yield callbacks.onSaveScreenshot(
2614
2746
  beforeScreenshotBuffer
2615
2747
  );
2616
2748
  try {
2617
- const execResult = await controller.executePresetStep(
2749
+ const execResult = yield controller.executePresetStep(
2618
2750
  step.command,
2619
2751
  advanced.disableAICaching
2620
2752
  );
2621
- const afterScreenshotBuffer = await controller.browser.screenshot();
2622
- const afterScreenshot = await callbacks.onSaveScreenshot(
2753
+ const afterScreenshotBuffer = yield controller.browser.screenshot();
2754
+ const afterScreenshot = yield callbacks.onSaveScreenshot(
2623
2755
  afterScreenshotBuffer
2624
2756
  );
2625
2757
  const finishedAt = /* @__PURE__ */ new Date();
2626
- const result = {
2627
- ...step,
2758
+ const result = __spreadProps(__spreadValues({}, step), {
2628
2759
  startedAt,
2629
2760
  finishedAt,
2630
2761
  // placeholder values
2631
2762
  status: "SUCCESS" /* SUCCESS */,
2632
2763
  results: []
2633
- };
2764
+ });
2634
2765
  let message = "Successfully executed preset action.";
2635
2766
  if (step.command.type === "AI_ASSERTION" /* AI_ASSERTION */) {
2636
2767
  message = execResult.thoughts || "Assertion passed.";
@@ -2648,7 +2779,7 @@ var executePresetStep = async ({
2648
2779
  result.status = "SUCCESS" /* SUCCESS */;
2649
2780
  result.results = [cmdMetadata];
2650
2781
  result.message = message;
2651
- (_b = callbacks.onSuccess) == null ? void 0 : _b.call(callbacks, {
2782
+ (_b2 = callbacks.onSuccess) == null ? void 0 : _b2.call(callbacks, {
2652
2783
  message,
2653
2784
  startedAt: startedAt.getTime(),
2654
2785
  durationMs: finishedAt.getTime() - startedAt.getTime()
@@ -2656,8 +2787,7 @@ var executePresetStep = async ({
2656
2787
  return result;
2657
2788
  } catch (err) {
2658
2789
  const finishedAt = /* @__PURE__ */ new Date();
2659
- const result = {
2660
- ...step,
2790
+ const result = __spreadProps(__spreadValues({}, step), {
2661
2791
  startedAt,
2662
2792
  finishedAt,
2663
2793
  status: "FAILED" /* FAILED */,
@@ -2675,7 +2805,7 @@ var executePresetStep = async ({
2675
2805
  message: `${err}`
2676
2806
  }
2677
2807
  ]
2678
- };
2808
+ });
2679
2809
  (_c = callbacks.onFailure) == null ? void 0 : _c.call(callbacks, {
2680
2810
  message: `${err}`,
2681
2811
  startedAt: startedAt.getTime(),
@@ -2683,18 +2813,23 @@ var executePresetStep = async ({
2683
2813
  });
2684
2814
  return result;
2685
2815
  }
2686
- };
2816
+ });
2687
2817
 
2688
2818
  // ../../packages/execute/src/steps/module.ts
2689
- var executeModuleStep = async ({
2690
- controller,
2691
- step,
2692
- advanced,
2693
- logger,
2694
- ...callbacks
2695
- }) => {
2696
- var _a, _b, _c;
2697
- (_a = callbacks.onStarted) == null ? void 0 : _a.call(callbacks);
2819
+ var executeModuleStep = (_a) => __async(void 0, null, function* () {
2820
+ var _b = _a, {
2821
+ controller,
2822
+ step,
2823
+ advanced,
2824
+ logger
2825
+ } = _b, callbacks = __objRest(_b, [
2826
+ "controller",
2827
+ "step",
2828
+ "advanced",
2829
+ "logger"
2830
+ ]);
2831
+ var _a2, _b2, _c;
2832
+ (_a2 = callbacks.onStarted) == null ? void 0 : _a2.call(callbacks);
2698
2833
  const result = {
2699
2834
  type: "MODULE" /* MODULE */,
2700
2835
  moduleId: step.moduleId,
@@ -2711,19 +2846,19 @@ var executeModuleStep = async ({
2711
2846
  let moduleStepResult;
2712
2847
  switch (moduleStep.type) {
2713
2848
  case "PRESET_ACTION" /* PRESET_ACTION */:
2714
- moduleStepResult = await executePresetStep({
2849
+ moduleStepResult = yield executePresetStep({
2715
2850
  controller,
2716
2851
  step: moduleStep,
2717
2852
  advanced,
2718
2853
  logger,
2719
2854
  onSaveScreenshot: callbacks.onSaveScreenshot,
2720
2855
  onStarted() {
2721
- var _a2;
2722
- (_a2 = callbacks.onStepStarted) == null ? void 0 : _a2.call(callbacks, { index: i });
2856
+ var _a3;
2857
+ (_a3 = callbacks.onStepStarted) == null ? void 0 : _a3.call(callbacks, { index: i });
2723
2858
  },
2724
2859
  onSuccess({ message, startedAt, durationMs }) {
2725
- var _a2;
2726
- (_a2 = callbacks.onStepSuccess) == null ? void 0 : _a2.call(callbacks, {
2860
+ var _a3;
2861
+ (_a3 = callbacks.onStepSuccess) == null ? void 0 : _a3.call(callbacks, {
2727
2862
  index: i,
2728
2863
  message,
2729
2864
  startedAt,
@@ -2731,8 +2866,8 @@ var executeModuleStep = async ({
2731
2866
  });
2732
2867
  },
2733
2868
  onFailure({ message, startedAt, durationMs }) {
2734
- var _a2;
2735
- (_a2 = callbacks.onStepFailure) == null ? void 0 : _a2.call(callbacks, {
2869
+ var _a3;
2870
+ (_a3 = callbacks.onStepFailure) == null ? void 0 : _a3.call(callbacks, {
2736
2871
  index: i,
2737
2872
  message,
2738
2873
  startedAt,
@@ -2742,19 +2877,19 @@ var executeModuleStep = async ({
2742
2877
  });
2743
2878
  break;
2744
2879
  case "AI_ACTION" /* AI_ACTION */:
2745
- moduleStepResult = await executeAIStep({
2880
+ moduleStepResult = yield executeAIStep({
2746
2881
  controller,
2747
2882
  step: moduleStep,
2748
2883
  advanced,
2749
2884
  logger,
2750
2885
  onSaveScreenshot: callbacks.onSaveScreenshot,
2751
2886
  onStarted() {
2752
- var _a2;
2753
- (_a2 = callbacks.onStepStarted) == null ? void 0 : _a2.call(callbacks, { index: i });
2887
+ var _a3;
2888
+ (_a3 = callbacks.onStepStarted) == null ? void 0 : _a3.call(callbacks, { index: i });
2754
2889
  },
2755
2890
  onSuccess({ message, startedAt, durationMs }) {
2756
- var _a2;
2757
- (_a2 = callbacks.onStepSuccess) == null ? void 0 : _a2.call(callbacks, {
2891
+ var _a3;
2892
+ (_a3 = callbacks.onStepSuccess) == null ? void 0 : _a3.call(callbacks, {
2758
2893
  index: i,
2759
2894
  message,
2760
2895
  startedAt,
@@ -2762,8 +2897,8 @@ var executeModuleStep = async ({
2762
2897
  });
2763
2898
  },
2764
2899
  onFailure({ message, startedAt, durationMs }) {
2765
- var _a2;
2766
- (_a2 = callbacks.onStepFailure) == null ? void 0 : _a2.call(callbacks, {
2900
+ var _a3;
2901
+ (_a3 = callbacks.onStepFailure) == null ? void 0 : _a3.call(callbacks, {
2767
2902
  index: i,
2768
2903
  message,
2769
2904
  startedAt,
@@ -2771,12 +2906,12 @@ var executeModuleStep = async ({
2771
2906
  });
2772
2907
  },
2773
2908
  onCommandGenerated({ commandIndex, message }) {
2774
- var _a2;
2775
- (_a2 = callbacks.onCommandGenerated) == null ? void 0 : _a2.call(callbacks, { index: i, commandIndex, message });
2909
+ var _a3;
2910
+ (_a3 = callbacks.onCommandGenerated) == null ? void 0 : _a3.call(callbacks, { index: i, commandIndex, message });
2776
2911
  },
2777
2912
  onCommandExecuted({ commandIndex, message, command }) {
2778
- var _a2;
2779
- (_a2 = callbacks.onCommandExecuted) == null ? void 0 : _a2.call(callbacks, {
2913
+ var _a3;
2914
+ (_a3 = callbacks.onCommandExecuted) == null ? void 0 : _a3.call(callbacks, {
2780
2915
  index: i,
2781
2916
  commandIndex,
2782
2917
  message,
@@ -2797,22 +2932,21 @@ var executeModuleStep = async ({
2797
2932
  result.finishedAt = /* @__PURE__ */ new Date();
2798
2933
  for (let j = i + 1; j < step.steps.length; j++) {
2799
2934
  const skippedStep = step.steps[j];
2800
- const skippedResult = {
2801
- ...skippedStep,
2935
+ const skippedResult = __spreadProps(__spreadValues({}, skippedStep), {
2802
2936
  status: "CANCELLED" /* CANCELLED */,
2803
2937
  startedAt: /* @__PURE__ */ new Date(),
2804
2938
  finishedAt: /* @__PURE__ */ new Date(),
2805
2939
  userAgent: ChromeBrowser.USER_AGENT,
2806
2940
  results: [],
2807
2941
  message: "Cancelled due to previous failure."
2808
- };
2942
+ });
2809
2943
  result.results.push(skippedResult);
2810
2944
  }
2811
2945
  break;
2812
2946
  }
2813
2947
  }
2814
2948
  if (result.status === "SUCCESS" /* SUCCESS */) {
2815
- (_b = callbacks.onSuccess) == null ? void 0 : _b.call(callbacks, {
2949
+ (_b2 = callbacks.onSuccess) == null ? void 0 : _b2.call(callbacks, {
2816
2950
  message: "Executed module step.",
2817
2951
  startedAt: result.startedAt.getTime(),
2818
2952
  durationMs: result.finishedAt.getTime() - result.startedAt.getTime()
@@ -2825,20 +2959,20 @@ var executeModuleStep = async ({
2825
2959
  });
2826
2960
  }
2827
2961
  return result;
2828
- };
2962
+ });
2829
2963
 
2830
2964
  // ../../packages/execute/src/test.ts
2831
- var executeTest = async ({
2965
+ var executeTest = (_0) => __async(void 0, [_0], function* ({
2832
2966
  test,
2833
2967
  runId,
2834
2968
  controller,
2835
2969
  logger,
2836
2970
  onUpdateRun,
2837
2971
  onSaveScreenshot
2838
- }) => {
2972
+ }) {
2839
2973
  const advanced = TestAdvancedSettingsSchema.parse(test.advanced);
2840
2974
  logger.info(`Starting run ${runId} for test ${test.id}`);
2841
- await onUpdateRun({
2975
+ yield onUpdateRun({
2842
2976
  status: "RUNNING",
2843
2977
  startedAt: /* @__PURE__ */ new Date()
2844
2978
  });
@@ -2849,7 +2983,7 @@ var executeTest = async ({
2849
2983
  let result;
2850
2984
  switch (step.type) {
2851
2985
  case "PRESET_ACTION" /* PRESET_ACTION */:
2852
- result = await executePresetStep({
2986
+ result = yield executePresetStep({
2853
2987
  controller,
2854
2988
  step,
2855
2989
  advanced,
@@ -2858,7 +2992,7 @@ var executeTest = async ({
2858
2992
  });
2859
2993
  break;
2860
2994
  case "AI_ACTION" /* AI_ACTION */:
2861
- result = await executeAIStep({
2995
+ result = yield executeAIStep({
2862
2996
  controller,
2863
2997
  step,
2864
2998
  advanced,
@@ -2867,7 +3001,7 @@ var executeTest = async ({
2867
3001
  });
2868
3002
  break;
2869
3003
  case "RESOLVED_MODULE":
2870
- result = await executeModuleStep({
3004
+ result = yield executeModuleStep({
2871
3005
  controller,
2872
3006
  step,
2873
3007
  advanced,
@@ -2882,7 +3016,7 @@ var executeTest = async ({
2882
3016
  return assertUnreachable(step);
2883
3017
  }
2884
3018
  results.push(result);
2885
- await onUpdateRun({
3019
+ yield onUpdateRun({
2886
3020
  results
2887
3021
  });
2888
3022
  if (result.status === "FAILED" /* FAILED */) {
@@ -2896,28 +3030,26 @@ var executeTest = async ({
2896
3030
  startedAt: /* @__PURE__ */ new Date(),
2897
3031
  userAgent: ChromeBrowser.USER_AGENT,
2898
3032
  results: skippedStep.steps.map((s) => {
2899
- return {
2900
- ...s,
3033
+ return __spreadProps(__spreadValues({}, s), {
2901
3034
  status: "CANCELLED" /* CANCELLED */,
2902
3035
  startedAt: /* @__PURE__ */ new Date(),
2903
3036
  finishedAt: /* @__PURE__ */ new Date(),
2904
3037
  userAgent: ChromeBrowser.USER_AGENT,
2905
3038
  results: []
2906
- };
3039
+ });
2907
3040
  }),
2908
3041
  finishedAt: /* @__PURE__ */ new Date(),
2909
3042
  status: "CANCELLED" /* CANCELLED */
2910
3043
  };
2911
3044
  results.push(skippedResult);
2912
3045
  } else {
2913
- const skippedResult = {
2914
- ...skippedStep,
3046
+ const skippedResult = __spreadProps(__spreadValues({}, skippedStep), {
2915
3047
  status: "CANCELLED" /* CANCELLED */,
2916
3048
  startedAt: /* @__PURE__ */ new Date(),
2917
3049
  finishedAt: /* @__PURE__ */ new Date(),
2918
3050
  userAgent: ChromeBrowser.USER_AGENT,
2919
3051
  results: []
2920
- };
3052
+ });
2921
3053
  results.push(skippedResult);
2922
3054
  }
2923
3055
  }
@@ -2926,14 +3058,14 @@ var executeTest = async ({
2926
3058
  break;
2927
3059
  }
2928
3060
  }
2929
- await onUpdateRun({
3061
+ yield onUpdateRun({
2930
3062
  status: failed ? "FAILED" : "PASSED",
2931
3063
  finishedAt: /* @__PURE__ */ new Date(),
2932
3064
  results
2933
3065
  });
2934
- await controller.browser.cleanup();
3066
+ yield controller.browser.cleanup();
2935
3067
  return failed;
2936
- };
3068
+ });
2937
3069
 
2938
3070
  // src/logger.ts
2939
3071
  var consoleLogger = {
@@ -2947,52 +3079,66 @@ var consoleLogger = {
2947
3079
  };
2948
3080
 
2949
3081
  // src/run-test.ts
2950
- async function runTest({
2951
- testId,
2952
- apiClient,
2953
- generator
2954
- }) {
2955
- const test = await apiClient.getTest(testId);
2956
- const browser = await ChromeBrowser.init(test.baseUrl, consoleLogger);
2957
- const controller = new AgentController({
2958
- browser,
3082
+ function runTest(_0) {
3083
+ return __async(this, arguments, function* ({
3084
+ testId,
3085
+ apiClient,
2959
3086
  generator,
2960
- config: DEFAULT_CONTROLLER_CONFIG,
2961
- logger: consoleLogger
2962
- });
2963
- const run = await apiClient.createRun({
2964
- testId
2965
- });
2966
- let failed = true;
2967
- try {
2968
- failed = await executeTest({
2969
- test,
2970
- runId: run.id,
2971
- controller,
2972
- logger: consoleLogger,
2973
- onSaveScreenshot: async (buffer) => {
2974
- const { key } = await apiClient.uploadScreenshot({
2975
- screenshot: buffer.toString("base64")
2976
- });
2977
- return key;
2978
- },
2979
- onUpdateRun: async (data) => {
2980
- await apiClient.updateRun(run.id, data);
2981
- }
3087
+ newBaseURL
3088
+ }) {
3089
+ const test = yield apiClient.getTest(testId);
3090
+ const originalURL = new URL(test.baseUrl);
3091
+ const newURL = new URL(newBaseURL);
3092
+ originalURL.hostname = newURL.hostname;
3093
+ originalURL.protocol = newURL.protocol;
3094
+ originalURL.port = newURL.port;
3095
+ const browser = yield ChromeBrowser.init(
3096
+ originalURL.toString(),
3097
+ consoleLogger
3098
+ );
3099
+ const controller = new AgentController({
3100
+ browser,
3101
+ generator,
3102
+ config: DEFAULT_CONTROLLER_CONFIG,
3103
+ logger: consoleLogger
2982
3104
  });
2983
- } catch (err) {
2984
- consoleLogger.error(err);
2985
- await apiClient.updateRun(run.id, {
2986
- status: "FAILED",
2987
- finishedAt: /* @__PURE__ */ new Date()
3105
+ const run = yield apiClient.createRun({
3106
+ testId
2988
3107
  });
2989
- }
2990
- return failed;
3108
+ let failed = true;
3109
+ try {
3110
+ failed = yield executeTest({
3111
+ test,
3112
+ runId: run.id,
3113
+ controller,
3114
+ logger: consoleLogger,
3115
+ onSaveScreenshot: (buffer) => __async(this, null, function* () {
3116
+ const { key } = yield apiClient.uploadScreenshot({
3117
+ screenshot: buffer.toString("base64")
3118
+ });
3119
+ return key;
3120
+ }),
3121
+ onUpdateRun: (data) => __async(this, null, function* () {
3122
+ yield apiClient.updateRun(run.id, data);
3123
+ })
3124
+ });
3125
+ } catch (err) {
3126
+ consoleLogger.error(err);
3127
+ yield apiClient.updateRun(run.id, {
3128
+ status: "FAILED",
3129
+ finishedAt: /* @__PURE__ */ new Date()
3130
+ });
3131
+ }
3132
+ return failed;
3133
+ });
2991
3134
  }
2992
3135
 
2993
3136
  // src/cli.ts
2994
3137
  var program = new Command4();
2995
3138
  program.name("momentic").description("Momentic CLI").version(version);
3139
+ program.command("install-browsers").action(() => __async(void 0, null, function* () {
3140
+ yield installBrowsers();
3141
+ }));
2996
3142
  program.command("run-tests").addOption(
2997
3143
  new Option(
2998
3144
  "--tests <tests...>",
@@ -3014,10 +3160,10 @@ program.command("run-tests").addOption(
3014
3160
  ).default(60, "one minute")
3015
3161
  ).addOption(
3016
3162
  new Option("--api-key <key>", "API key for authenticating").env("MOMENTIC_API_KEY").makeOptionMandatory(true)
3017
- ).action(async (options) => {
3163
+ ).action((options) => __async(void 0, null, function* () {
3018
3164
  const { tests, start, waitOn, waitOnTimeout, apiKey } = options;
3019
- await execCommand(start, false);
3020
- await waitOnFn({
3165
+ yield execCommand(start, false);
3166
+ yield waitOnFn({
3021
3167
  resources: [waitOn],
3022
3168
  timeout: waitOnTimeout * 1e3
3023
3169
  });
@@ -3029,15 +3175,16 @@ program.command("run-tests").addOption(
3029
3175
  baseURL: "https://api.momentic.ai",
3030
3176
  apiKey
3031
3177
  });
3032
- const promises = tests.map(async (testId) => {
3033
- const failed = await runTest({
3178
+ const promises = tests.map((testId) => __async(void 0, null, function* () {
3179
+ const failed = yield runTest({
3034
3180
  testId,
3035
3181
  apiClient,
3036
- generator: apiGenerator
3182
+ generator: apiGenerator,
3183
+ newBaseURL: waitOn
3037
3184
  });
3038
3185
  return { failed, testId };
3039
- });
3040
- const results = await Promise.all(promises);
3186
+ }));
3187
+ const results = yield Promise.all(promises);
3041
3188
  const failedResults = results.filter((result) => result.failed);
3042
3189
  if (failedResults.length > 0) {
3043
3190
  console.log(
@@ -3051,17 +3198,25 @@ program.command("run-tests").addOption(
3051
3198
  process.exit(1);
3052
3199
  }
3053
3200
  console.log(chalk.green(`All ${results.length} tests passed!`));
3054
- });
3055
- var execCommand = async (fullCommand, waitToFinish = true) => {
3201
+ }));
3202
+ var execCommand = (fullCommand, waitToFinish = true) => __async(void 0, null, function* () {
3056
3203
  const args = parseArgsStringToArgv2(fullCommand);
3057
- const toolPath = await io.which(args[0], true);
3204
+ const toolPath = yield io.which(args[0], true);
3058
3205
  const toolArguments = args.slice(1);
3059
3206
  const promise = exec.exec(quote(toolPath), toolArguments);
3060
3207
  if (waitToFinish) {
3061
3208
  return promise;
3062
3209
  }
3063
- };
3064
- async function main() {
3065
- await program.parseAsync(process.argv);
3210
+ });
3211
+ function installBrowsers() {
3212
+ return __async(this, null, function* () {
3213
+ const executables = registry.defaultExecutables();
3214
+ yield registry.install(executables, false);
3215
+ });
3216
+ }
3217
+ function main() {
3218
+ return __async(this, null, function* () {
3219
+ yield program.parseAsync(process.argv);
3220
+ });
3066
3221
  }
3067
3222
  void main();