momentic 0.0.10 → 0.0.11

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