@midscene/web 0.3.4 → 0.4.0

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.
package/dist/es/debug.js CHANGED
@@ -329,104 +329,31 @@ var require_dayjs_min = __commonJS({
329
329
  // src/debug/index.ts
330
330
  import { existsSync, mkdirSync, writeFileSync } from "fs";
331
331
  import path2 from "path";
332
- import { resizeImg, saveBase64Image } from "@midscene/core/image";
333
332
 
334
- // src/debug/img/index.ts
335
- import assert from "assert";
336
- import { Buffer as Buffer2 } from "buffer";
337
- import sharp from "sharp";
338
- var createSvgOverlay = (elements, imageWidth, imageHeight) => {
339
- let svgContent = `<svg width="${imageWidth}" height="${imageHeight}" xmlns="http://www.w3.org/2000/svg">`;
340
- const colors = [
341
- { rect: "blue", text: "white" },
342
- { rect: "green", text: "white" }
343
- ];
344
- svgContent += "<defs>";
345
- elements.forEach((element, index) => {
346
- svgContent += `
347
- <clipPath id="clip${index}">
348
- <rect x="${element.x}" y="${element.y}" width="${element.width}" height="${element.height}" />
349
- </clipPath>
350
- `;
351
- });
352
- svgContent += "</defs>";
353
- elements.forEach((element, index) => {
354
- const textWidth = element.label.length * 8;
355
- const textHeight = 12;
356
- const rectWidth = textWidth + 5;
357
- const rectHeight = textHeight + 4;
358
- let rectX = element.x - rectWidth;
359
- let rectY = element.y + element.height / 2 - textHeight / 2 - 2;
360
- let textX = rectX + rectWidth / 2;
361
- let textY = rectY + rectHeight / 2 + 6;
362
- if (rectX < 0) {
363
- rectX = element.x;
364
- rectY = element.y - rectHeight;
365
- textX = rectX + rectWidth / 2;
366
- textY = rectY + rectHeight / 2 + 6;
367
- }
368
- const color = colors[index % colors.length];
369
- svgContent += `
370
- <rect x="${element.x}" y="${element.y}" width="${element.width}" height="${element.height}"
371
- style="fill:none;stroke:${color.rect};stroke-width:4" clip-path="url(#clip${index})" />
372
- <rect x="${rectX}" y="${rectY}" width="${rectWidth}" height="${rectHeight}" style="fill:${color.rect};" />
373
- <text x="${textX}" y="${textY}"
374
- text-anchor="middle" dominant-baseline="middle" style="fill:${color.text};font-size:12px;font-weight:bold;">
375
- ${element.label}
376
- </text>
377
- `;
378
- });
379
- svgContent += "</svg>";
380
- return Buffer2.from(svgContent);
381
- };
382
- var processImageElementInfo = async (options) => {
383
- const base64Image = options.inputImgBase64.split(";base64,").pop();
384
- assert(base64Image, "base64Image is undefined");
385
- const imageBuffer = Buffer2.from(base64Image, "base64");
386
- const metadata = await sharp(imageBuffer).metadata();
387
- const { width, height } = metadata;
388
- if (width && height) {
389
- const svgOverlay = createSvgOverlay(
390
- options.elementsPositionInfo,
391
- width,
392
- height
393
- );
394
- const svgOverlayWithoutText = createSvgOverlay(
395
- options.elementsPositionInfoWithoutText,
396
- width,
397
- height
398
- );
399
- const compositeElementInfoImgBase64 = await sharp(imageBuffer).composite([{ input: svgOverlay, blend: "over" }]).toBuffer().then((data) => {
400
- return data.toString("base64");
401
- }).catch((err) => {
402
- throw err;
403
- });
404
- const compositeElementInfoImgWithoutTextBase64 = await sharp(imageBuffer).composite([{ input: svgOverlayWithoutText, blend: "over" }]).toBuffer().then((data) => {
405
- return data.toString("base64");
406
- }).catch((err) => {
407
- throw err;
408
- });
409
- return {
410
- compositeElementInfoImgBase64,
411
- compositeElementInfoImgWithoutTextBase64
412
- };
413
- }
414
- throw Error("Image processing failed because width or height is undefined");
415
- };
333
+ // src/extractor/constants.ts
334
+ import {
335
+ NodeType,
336
+ TEXT_MAX_SIZE,
337
+ TEXT_SIZE_THRESHOLD
338
+ } from "@midscene/shared/constants";
339
+
340
+ // src/debug/index.ts
341
+ import {
342
+ processImageElementInfo,
343
+ resizeImg,
344
+ saveBase64Image
345
+ } from "@midscene/shared/img";
416
346
 
417
347
  // src/common/utils.ts
418
348
  var import_dayjs = __toESM(require_dayjs_min());
419
- import assert2 from "assert";
349
+ import assert from "assert";
420
350
  import fs, { readFileSync } from "fs";
421
351
  import path from "path";
422
- import {
423
- base64Encoded,
424
- imageInfoOfBase64
425
- } from "@midscene/core/image";
426
352
  import { getTmpFile } from "@midscene/core/utils";
353
+ import { base64Encoded, imageInfoOfBase64 } from "@midscene/shared/img";
427
354
  async function getElementInfosFromPage(page) {
428
355
  const pathDir = findNearestPackageJson(__dirname);
429
- assert2(pathDir, `can't find pathDir, with ${__dirname}`);
356
+ assert(pathDir, `can't find pathDir, with ${__dirname}`);
430
357
  const scriptPath = path.join(pathDir, "./dist/script/htmlElement.js");
431
358
  const elementInfosScriptContent = readFileSync(scriptPath, "utf-8");
432
359
  const extraReturnLogic = `${elementInfosScriptContent}midscene_element_inspector.extractTextWithPosition()`;
@@ -445,34 +372,6 @@ function findNearestPackageJson(dir) {
445
372
  return findNearestPackageJson(parentDir);
446
373
  }
447
374
 
448
- // src/debug/img/util.ts
449
- async function getElementInfos(page) {
450
- const captureElementSnapshot = await getElementInfosFromPage(page);
451
- const elementsPositionInfo = captureElementSnapshot.map((elementInfo) => {
452
- return {
453
- label: elementInfo.indexId.toString(),
454
- x: elementInfo.rect.left,
455
- y: elementInfo.rect.top,
456
- width: elementInfo.rect.width,
457
- height: elementInfo.rect.height,
458
- attributes: elementInfo.attributes
459
- };
460
- });
461
- const elementsPositionInfoWithoutText = elementsPositionInfo.filter(
462
- (elementInfo) => {
463
- if (elementInfo.attributes.nodeType === "TEXT Node" /* TEXT */) {
464
- return false;
465
- }
466
- return true;
467
- }
468
- );
469
- return {
470
- elementsPositionInfo,
471
- captureElementSnapshot,
472
- elementsPositionInfoWithoutText
473
- };
474
- }
475
-
476
375
  // src/debug/index.ts
477
376
  async function generateExtractData(page, targetDir, saveImgType) {
478
377
  const buffer = await page.screenshot({
@@ -492,6 +391,7 @@ async function generateExtractData(page, targetDir, saveImgType) {
492
391
  );
493
392
  const resizeOutputImgPath = path2.join(targetDir, "resize-output.png");
494
393
  const snapshotJsonPath = path2.join(targetDir, "element-snapshot.json");
394
+ const startTime = Date.now();
495
395
  const {
496
396
  compositeElementInfoImgBase64,
497
397
  compositeElementInfoImgWithoutTextBase64
@@ -500,6 +400,9 @@ async function generateExtractData(page, targetDir, saveImgType) {
500
400
  elementsPositionInfoWithoutText,
501
401
  inputImgBase64
502
402
  });
403
+ const endTime = Date.now();
404
+ const executionTime = (endTime - startTime) / 1e3;
405
+ console.log(`Execution time: ${executionTime.toFixed(2)}s`);
503
406
  const resizeImgBase64 = await resizeImg(inputImgBase64);
504
407
  if (!(saveImgType == null ? void 0 : saveImgType.disableSnapshot)) {
505
408
  writeFileSyncWithDir(
@@ -552,8 +455,35 @@ function writeFileSyncWithDir(filePath, content, options = {}) {
552
455
  ensureDirectoryExistence(filePath);
553
456
  writeFileSync(filePath, content, options);
554
457
  }
458
+ async function getElementInfos(page) {
459
+ const captureElementSnapshot = await getElementInfosFromPage(page);
460
+ const elementsPositionInfo = captureElementSnapshot.map((elementInfo) => {
461
+ return {
462
+ label: elementInfo.indexId.toString(),
463
+ x: elementInfo.rect.left,
464
+ y: elementInfo.rect.top,
465
+ width: elementInfo.rect.width,
466
+ height: elementInfo.rect.height,
467
+ attributes: elementInfo.attributes
468
+ };
469
+ });
470
+ const elementsPositionInfoWithoutText = elementsPositionInfo.filter(
471
+ (elementInfo) => {
472
+ if (elementInfo.attributes.nodeType === NodeType.TEXT) {
473
+ return false;
474
+ }
475
+ return true;
476
+ }
477
+ );
478
+ return {
479
+ elementsPositionInfo,
480
+ captureElementSnapshot,
481
+ elementsPositionInfoWithoutText
482
+ };
483
+ }
555
484
  export {
556
485
  generateExtractData,
557
486
  generateTestDataPath,
487
+ getElementInfos,
558
488
  writeFileSyncWithDir
559
489
  };
package/dist/es/index.js CHANGED
@@ -352,8 +352,8 @@ import Insight, {
352
352
  Executor,
353
353
  plan
354
354
  } from "@midscene/core";
355
- import { base64Encoded as base64Encoded2 } from "@midscene/core/image";
356
355
  import { commonScreenshotParam, getTmpFile as getTmpFile2, sleep } from "@midscene/core/utils";
356
+ import { base64Encoded as base64Encoded2 } from "@midscene/shared/img";
357
357
 
358
358
  // src/common/task-cache.ts
359
359
  var TaskCache = class {
@@ -415,11 +415,8 @@ var import_dayjs = __toESM(require_dayjs_min());
415
415
  import assert from "assert";
416
416
  import fs, { readFileSync } from "fs";
417
417
  import path from "path";
418
- import {
419
- base64Encoded,
420
- imageInfoOfBase64
421
- } from "@midscene/core/image";
422
418
  import { getTmpFile } from "@midscene/core/utils";
419
+ import { base64Encoded, imageInfoOfBase64 } from "@midscene/shared/img";
423
420
 
424
421
  // src/web-element.ts
425
422
  var WebElementInfo = class {
@@ -477,10 +474,10 @@ async function getElementInfosFromPage(page) {
477
474
  }
478
475
  var sizeThreshold = 3;
479
476
  async function alignElements(screenshotBuffer, elements, page) {
480
- const textsAligned = [];
481
477
  const validElements = elements.filter((item) => {
482
478
  return item.rect.height >= sizeThreshold && item.rect.width >= sizeThreshold;
483
479
  });
480
+ const textsAligned = [];
484
481
  for (const item of validElements) {
485
482
  const { rect, id, content, attributes, locator } = item;
486
483
  textsAligned.push(
@@ -1013,7 +1010,7 @@ ${errorTask == null ? void 0 : errorTask.errorStack}`);
1013
1010
  this.writeOutActionDumps();
1014
1011
  if (!(output == null ? void 0 : output.pass)) {
1015
1012
  const errMsg = msg || `Assertion failed: ${assertion}`;
1016
- const reasonMsg = `Reason: ${output == null ? void 0 : output.thought} || (no_reason)`;
1013
+ const reasonMsg = `Reason: ${(output == null ? void 0 : output.thought) || "(no_reason)"}`;
1017
1014
  throw new Error(`${errMsg}
1018
1015
  ${reasonMsg}`);
1019
1016
  }
@@ -1244,120 +1241,20 @@ var PlaywrightAiFixture = () => {
1244
1241
  // src/debug/index.ts
1245
1242
  import { existsSync, mkdirSync, writeFileSync } from "fs";
1246
1243
  import path3 from "path";
1247
- import { resizeImg, saveBase64Image } from "@midscene/core/image";
1248
1244
 
1249
- // src/debug/img/index.ts
1250
- import assert3 from "assert";
1251
- import { Buffer as Buffer2 } from "buffer";
1252
- import sharp from "sharp";
1253
- var createSvgOverlay = (elements, imageWidth, imageHeight) => {
1254
- let svgContent = `<svg width="${imageWidth}" height="${imageHeight}" xmlns="http://www.w3.org/2000/svg">`;
1255
- const colors = [
1256
- { rect: "blue", text: "white" },
1257
- { rect: "green", text: "white" }
1258
- ];
1259
- svgContent += "<defs>";
1260
- elements.forEach((element, index) => {
1261
- svgContent += `
1262
- <clipPath id="clip${index}">
1263
- <rect x="${element.x}" y="${element.y}" width="${element.width}" height="${element.height}" />
1264
- </clipPath>
1265
- `;
1266
- });
1267
- svgContent += "</defs>";
1268
- elements.forEach((element, index) => {
1269
- const textWidth = element.label.length * 8;
1270
- const textHeight = 12;
1271
- const rectWidth = textWidth + 5;
1272
- const rectHeight = textHeight + 4;
1273
- let rectX = element.x - rectWidth;
1274
- let rectY = element.y + element.height / 2 - textHeight / 2 - 2;
1275
- let textX = rectX + rectWidth / 2;
1276
- let textY = rectY + rectHeight / 2 + 6;
1277
- if (rectX < 0) {
1278
- rectX = element.x;
1279
- rectY = element.y - rectHeight;
1280
- textX = rectX + rectWidth / 2;
1281
- textY = rectY + rectHeight / 2 + 6;
1282
- }
1283
- const color = colors[index % colors.length];
1284
- svgContent += `
1285
- <rect x="${element.x}" y="${element.y}" width="${element.width}" height="${element.height}"
1286
- style="fill:none;stroke:${color.rect};stroke-width:4" clip-path="url(#clip${index})" />
1287
- <rect x="${rectX}" y="${rectY}" width="${rectWidth}" height="${rectHeight}" style="fill:${color.rect};" />
1288
- <text x="${textX}" y="${textY}"
1289
- text-anchor="middle" dominant-baseline="middle" style="fill:${color.text};font-size:12px;font-weight:bold;">
1290
- ${element.label}
1291
- </text>
1292
- `;
1293
- });
1294
- svgContent += "</svg>";
1295
- return Buffer2.from(svgContent);
1296
- };
1297
- var processImageElementInfo = async (options) => {
1298
- const base64Image = options.inputImgBase64.split(";base64,").pop();
1299
- assert3(base64Image, "base64Image is undefined");
1300
- const imageBuffer = Buffer2.from(base64Image, "base64");
1301
- const metadata = await sharp(imageBuffer).metadata();
1302
- const { width, height } = metadata;
1303
- if (width && height) {
1304
- const svgOverlay = createSvgOverlay(
1305
- options.elementsPositionInfo,
1306
- width,
1307
- height
1308
- );
1309
- const svgOverlayWithoutText = createSvgOverlay(
1310
- options.elementsPositionInfoWithoutText,
1311
- width,
1312
- height
1313
- );
1314
- const compositeElementInfoImgBase64 = await sharp(imageBuffer).composite([{ input: svgOverlay, blend: "over" }]).toBuffer().then((data) => {
1315
- return data.toString("base64");
1316
- }).catch((err) => {
1317
- throw err;
1318
- });
1319
- const compositeElementInfoImgWithoutTextBase64 = await sharp(imageBuffer).composite([{ input: svgOverlayWithoutText, blend: "over" }]).toBuffer().then((data) => {
1320
- return data.toString("base64");
1321
- }).catch((err) => {
1322
- throw err;
1323
- });
1324
- return {
1325
- compositeElementInfoImgBase64,
1326
- compositeElementInfoImgWithoutTextBase64
1327
- };
1328
- }
1329
- throw Error("Image processing failed because width or height is undefined");
1330
- };
1331
-
1332
- // src/debug/img/util.ts
1333
- async function getElementInfos(page) {
1334
- const captureElementSnapshot = await getElementInfosFromPage(page);
1335
- const elementsPositionInfo = captureElementSnapshot.map((elementInfo) => {
1336
- return {
1337
- label: elementInfo.indexId.toString(),
1338
- x: elementInfo.rect.left,
1339
- y: elementInfo.rect.top,
1340
- width: elementInfo.rect.width,
1341
- height: elementInfo.rect.height,
1342
- attributes: elementInfo.attributes
1343
- };
1344
- });
1345
- const elementsPositionInfoWithoutText = elementsPositionInfo.filter(
1346
- (elementInfo) => {
1347
- if (elementInfo.attributes.nodeType === "TEXT Node" /* TEXT */) {
1348
- return false;
1349
- }
1350
- return true;
1351
- }
1352
- );
1353
- return {
1354
- elementsPositionInfo,
1355
- captureElementSnapshot,
1356
- elementsPositionInfoWithoutText
1357
- };
1358
- }
1245
+ // src/extractor/constants.ts
1246
+ import {
1247
+ NodeType,
1248
+ TEXT_MAX_SIZE,
1249
+ TEXT_SIZE_THRESHOLD
1250
+ } from "@midscene/shared/constants";
1359
1251
 
1360
1252
  // src/debug/index.ts
1253
+ import {
1254
+ processImageElementInfo,
1255
+ resizeImg,
1256
+ saveBase64Image
1257
+ } from "@midscene/shared/img";
1361
1258
  async function generateExtractData(page, targetDir, saveImgType) {
1362
1259
  const buffer = await page.screenshot({
1363
1260
  encoding: "base64"
@@ -1376,6 +1273,7 @@ async function generateExtractData(page, targetDir, saveImgType) {
1376
1273
  );
1377
1274
  const resizeOutputImgPath = path3.join(targetDir, "resize-output.png");
1378
1275
  const snapshotJsonPath = path3.join(targetDir, "element-snapshot.json");
1276
+ const startTime = Date.now();
1379
1277
  const {
1380
1278
  compositeElementInfoImgBase64,
1381
1279
  compositeElementInfoImgWithoutTextBase64
@@ -1384,6 +1282,9 @@ async function generateExtractData(page, targetDir, saveImgType) {
1384
1282
  elementsPositionInfoWithoutText,
1385
1283
  inputImgBase64
1386
1284
  });
1285
+ const endTime = Date.now();
1286
+ const executionTime = (endTime - startTime) / 1e3;
1287
+ console.log(`Execution time: ${executionTime.toFixed(2)}s`);
1387
1288
  const resizeImgBase64 = await resizeImg(inputImgBase64);
1388
1289
  if (!(saveImgType == null ? void 0 : saveImgType.disableSnapshot)) {
1389
1290
  writeFileSyncWithDir(
@@ -1428,6 +1329,32 @@ function writeFileSyncWithDir(filePath, content, options = {}) {
1428
1329
  ensureDirectoryExistence(filePath);
1429
1330
  writeFileSync(filePath, content, options);
1430
1331
  }
1332
+ async function getElementInfos(page) {
1333
+ const captureElementSnapshot = await getElementInfosFromPage(page);
1334
+ const elementsPositionInfo = captureElementSnapshot.map((elementInfo) => {
1335
+ return {
1336
+ label: elementInfo.indexId.toString(),
1337
+ x: elementInfo.rect.left,
1338
+ y: elementInfo.rect.top,
1339
+ width: elementInfo.rect.width,
1340
+ height: elementInfo.rect.height,
1341
+ attributes: elementInfo.attributes
1342
+ };
1343
+ });
1344
+ const elementsPositionInfoWithoutText = elementsPositionInfo.filter(
1345
+ (elementInfo) => {
1346
+ if (elementInfo.attributes.nodeType === NodeType.TEXT) {
1347
+ return false;
1348
+ }
1349
+ return true;
1350
+ }
1351
+ );
1352
+ return {
1353
+ elementsPositionInfo,
1354
+ captureElementSnapshot,
1355
+ elementsPositionInfoWithoutText
1356
+ };
1357
+ }
1431
1358
  export {
1432
1359
  PlaywrightAiFixture,
1433
1360
  PageAgent as PuppeteerAgent,
@@ -324,11 +324,8 @@ var import_dayjs = __toESM(require_dayjs_min());
324
324
  import assert from "assert";
325
325
  import fs, { readFileSync } from "fs";
326
326
  import path from "path";
327
- import {
328
- base64Encoded,
329
- imageInfoOfBase64
330
- } from "@midscene/core/image";
331
327
  import { getTmpFile } from "@midscene/core/utils";
328
+ import { base64Encoded, imageInfoOfBase64 } from "@midscene/shared/img";
332
329
  function reportFileName(tag = "web") {
333
330
  const dateTimeInFileName = (0, import_dayjs.default)().format("YYYY-MM-DD_HH-mm-ss-SSS");
334
331
  return `${tag}-${dateTimeInFileName}`;
@@ -352,8 +352,8 @@ import Insight, {
352
352
  Executor,
353
353
  plan
354
354
  } from "@midscene/core";
355
- import { base64Encoded as base64Encoded2 } from "@midscene/core/image";
356
355
  import { commonScreenshotParam, getTmpFile as getTmpFile2, sleep } from "@midscene/core/utils";
356
+ import { base64Encoded as base64Encoded2 } from "@midscene/shared/img";
357
357
 
358
358
  // src/common/task-cache.ts
359
359
  var TaskCache = class {
@@ -415,11 +415,8 @@ var import_dayjs = __toESM(require_dayjs_min());
415
415
  import assert from "assert";
416
416
  import fs, { readFileSync } from "fs";
417
417
  import path from "path";
418
- import {
419
- base64Encoded,
420
- imageInfoOfBase64
421
- } from "@midscene/core/image";
422
418
  import { getTmpFile } from "@midscene/core/utils";
419
+ import { base64Encoded, imageInfoOfBase64 } from "@midscene/shared/img";
423
420
 
424
421
  // src/web-element.ts
425
422
  var WebElementInfo = class {
@@ -477,10 +474,10 @@ async function getElementInfosFromPage(page) {
477
474
  }
478
475
  var sizeThreshold = 3;
479
476
  async function alignElements(screenshotBuffer, elements, page) {
480
- const textsAligned = [];
481
477
  const validElements = elements.filter((item) => {
482
478
  return item.rect.height >= sizeThreshold && item.rect.width >= sizeThreshold;
483
479
  });
480
+ const textsAligned = [];
484
481
  for (const item of validElements) {
485
482
  const { rect, id, content, attributes, locator } = item;
486
483
  textsAligned.push(
@@ -1013,7 +1010,7 @@ ${errorTask == null ? void 0 : errorTask.errorStack}`);
1013
1010
  this.writeOutActionDumps();
1014
1011
  if (!(output == null ? void 0 : output.pass)) {
1015
1012
  const errMsg = msg || `Assertion failed: ${assertion}`;
1016
- const reasonMsg = `Reason: ${output == null ? void 0 : output.thought} || (no_reason)`;
1013
+ const reasonMsg = `Reason: ${(output == null ? void 0 : output.thought) || "(no_reason)"}`;
1017
1014
  throw new Error(`${errMsg}
1018
1015
  ${reasonMsg}`);
1019
1016
  }
@@ -349,8 +349,8 @@ import Insight, {
349
349
  Executor,
350
350
  plan
351
351
  } from "@midscene/core";
352
- import { base64Encoded as base64Encoded2 } from "@midscene/core/image";
353
352
  import { commonScreenshotParam, getTmpFile as getTmpFile2, sleep } from "@midscene/core/utils";
353
+ import { base64Encoded as base64Encoded2 } from "@midscene/shared/img";
354
354
 
355
355
  // src/common/task-cache.ts
356
356
  var TaskCache = class {
@@ -412,11 +412,8 @@ var import_dayjs = __toESM(require_dayjs_min());
412
412
  import assert from "assert";
413
413
  import fs, { readFileSync } from "fs";
414
414
  import path from "path";
415
- import {
416
- base64Encoded,
417
- imageInfoOfBase64
418
- } from "@midscene/core/image";
419
415
  import { getTmpFile } from "@midscene/core/utils";
416
+ import { base64Encoded, imageInfoOfBase64 } from "@midscene/shared/img";
420
417
 
421
418
  // src/web-element.ts
422
419
  var WebElementInfo = class {
@@ -474,10 +471,10 @@ async function getElementInfosFromPage(page) {
474
471
  }
475
472
  var sizeThreshold = 3;
476
473
  async function alignElements(screenshotBuffer, elements, page) {
477
- const textsAligned = [];
478
474
  const validElements = elements.filter((item) => {
479
475
  return item.rect.height >= sizeThreshold && item.rect.width >= sizeThreshold;
480
476
  });
477
+ const textsAligned = [];
481
478
  for (const item of validElements) {
482
479
  const { rect, id, content, attributes, locator } = item;
483
480
  textsAligned.push(
@@ -1010,7 +1007,7 @@ ${errorTask == null ? void 0 : errorTask.errorStack}`);
1010
1007
  this.writeOutActionDumps();
1011
1008
  if (!(output == null ? void 0 : output.pass)) {
1012
1009
  const errMsg = msg || `Assertion failed: ${assertion}`;
1013
- const reasonMsg = `Reason: ${output == null ? void 0 : output.thought} || (no_reason)`;
1010
+ const reasonMsg = `Reason: ${(output == null ? void 0 : output.thought) || "(no_reason)"}`;
1014
1011
  throw new Error(`${errMsg}
1015
1012
  ${reasonMsg}`);
1016
1013
  }