@bigbinary/neeto-playwright-reporter 1.3.14 → 1.3.16

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/index.d.ts CHANGED
@@ -15,7 +15,6 @@ declare class MyReporter implements Reporter {
15
15
  retryAttemptStartedAt: Date;
16
16
  testResultCalls: Promise<unknown>[];
17
17
  totalTestCount: number;
18
- reportedTestCount: number;
19
18
  tags: string[] | string;
20
19
  unreportedAttemptCount: number;
21
20
  hasRunStarted: boolean;
package/index.js CHANGED
@@ -10,8 +10,8 @@ import require$$1$2 from 'tty';
10
10
  import require$$0$2 from 'os';
11
11
  import zlib from 'zlib';
12
12
  import EventEmitter from 'events';
13
- import childProcess from 'child_process';
14
13
  import crypto from 'crypto';
14
+ import childProcess from 'child_process';
15
15
 
16
16
  function bind(fn, thisArg) {
17
17
  return function wrap() {
@@ -18449,6 +18449,8 @@ const getDirectUploadURL = (payload) => axios.post(`${API_BASE_URL}/reporter/dir
18449
18449
  });
18450
18450
  const uploadToS3 = (data, { url, headers }) => axios.put(url, data, { headers });
18451
18451
 
18452
+ const VALID_ASSET_TYPES = ["screenshot", "video", "trace"];
18453
+
18452
18454
  const ERRORS = {
18453
18455
  onBegin: {
18454
18456
  noTestsToReport: "No tests to report",
@@ -18464,6 +18466,9 @@ const ERRORS = {
18464
18466
  onEnd: {
18465
18467
  failedToReportRunStatus: "Failed to report run status",
18466
18468
  },
18469
+ onTestEnd: {
18470
+ attemptAlreadyReported: "Attempt was already reported",
18471
+ },
18467
18472
  heartbeat: {
18468
18473
  stopped: "Run was stopped at the reporter",
18469
18474
  },
@@ -18471,7 +18476,7 @@ const ERRORS = {
18471
18476
 
18472
18477
  const MESSAGES = {
18473
18478
  onBegin: {
18474
- testStarted: "Run has started reporting to neetoPlaydash",
18479
+ testStarted: "Started reporting to NeetoPlaydash 🎭",
18475
18480
  ciBuildId: (currentCiBuildId) => `CI BUILD ID: ${currentCiBuildId}`,
18476
18481
  totalShards: (totalShards) => `Total shards: ${totalShards}`,
18477
18482
  currentShard: (currentShard) => `Current shard: ${currentShard}`,
@@ -18480,41 +18485,60 @@ const MESSAGES = {
18480
18485
  startingTest: (titlePath) => `Starting ${titlePath}`,
18481
18486
  },
18482
18487
  onTestEnd: {
18483
- reportedTest: (title) => `Reported ${title} to neetoPlaydash`,
18488
+ reportedTest: (title) => `Reported ${title} to NeetoPlaydash`,
18484
18489
  },
18485
18490
  onEnd: {
18486
- runReported: "Run completed and reported to neetoPlaydash 🎉",
18491
+ runReported: "Run completed and reported to NeetoPlaydash 🎉",
18487
18492
  },
18488
18493
  };
18489
18494
 
18490
- const consoleLogFormatted = {
18491
- bold: (message) => console.log("\x1b[1m", message, "\x1b[0m"),
18492
- dim: (message) => console.log("\x1b[2m", message, "\x1b[0m"),
18493
- underline: (message) => console.log("\x1b[4m", message, "\x1b[0m"),
18494
- invertBackground: (message) => console.log("\x1b[7m", message, "\x1b[0m"),
18495
- hidden: (message) => console.log("\x1b[8m", message, "\x1b[0m"),
18496
- error: (message) => console.log("\u001b[31m", "\x1b[1m", message, "\x1b[0m", "\u001b[0m"),
18497
- warning: (message) => console.log("\u001b[33m", "\x1b[1m", message, "\x1b[0m", "\u001b[0m"),
18498
- };
18499
- const executeCommandLine = ({ command, messageOnError, shouldThrowError = false, logLevel = "warning", }) => {
18500
- try {
18501
- return childProcess.execSync(command).toString().trim();
18502
- }
18503
- catch (err) {
18504
- if (shouldThrowError) {
18505
- throw err;
18506
- }
18507
- else {
18508
- consoleLogFormatted[logLevel](messageOnError);
18509
- }
18510
- }
18511
- };
18512
-
18513
18495
  const createShardObject = ({ currentShard = 0, status = "running", duration = null, }) => ({
18514
18496
  [currentShard]: { status, duration },
18515
18497
  });
18516
18498
  const waitUntilTimeout = (timeout) => new Promise(resolve => setTimeout(resolve, timeout));
18517
18499
 
18500
+ const LOG_LEVEL_FORMATTERS = {
18501
+ bold: "\x1b[1m",
18502
+ dim: "\x1b[2m",
18503
+ underline: "\x1b[4m",
18504
+ invertBackground: "\x1b[7m",
18505
+ hidden: "\x1b[8m",
18506
+ error: "\u001b[31m\x1b[1m",
18507
+ redText: "\u001b[31m\x1b[1m", // Same ANSI style as error but in log level printing important errors
18508
+ warning: "\u001b[33m\x1b[1m",
18509
+ };
18510
+
18511
+ class ConsoleLogFormatted {
18512
+ constructor() {
18513
+ this.LOG_LEVELS = {
18514
+ info: ["bold", "dim", "underline", "invertBackground", "hidden", "redText"],
18515
+ get warning() {
18516
+ return [...this.info, "warning"];
18517
+ },
18518
+ get error() {
18519
+ return [...this.warning, "error"];
18520
+ },
18521
+ };
18522
+ this.shouldPrintMessage = (type) => {
18523
+ var _a;
18524
+ const logLevel = ((_a = process.env.PLAYDASH_LOG_LEVEL) !== null && _a !== void 0 ? _a : "info");
18525
+ const validMethods = this.LOG_LEVELS[logLevel] || [];
18526
+ return validMethods.includes(type);
18527
+ };
18528
+ Object.entries(LOG_LEVEL_FORMATTERS).forEach(([logLevel, ansiFormatter]) => {
18529
+ this.createMethod(logLevel, ansiFormatter);
18530
+ });
18531
+ }
18532
+ createMethod(logLevel, ansiFormatter) {
18533
+ this[logLevel] = (message) => {
18534
+ if (this.shouldPrintMessage(logLevel)) {
18535
+ console.log(`${ansiFormatter}${message}\x1b[0m\u001b[0m`);
18536
+ }
18537
+ };
18538
+ }
18539
+ }
18540
+ var consoleLogFormatted = new ConsoleLogFormatted();
18541
+
18518
18542
  const getFileData = (file, contentType, filename) => {
18519
18543
  const byte_size = file.byteLength;
18520
18544
  const checksum = crypto.createHash("md5").update(file).digest("base64");
@@ -18530,6 +18554,20 @@ const update = (ciBuildId, payload) => axios.put(`${API_BASE_URL}/reporter/runs/
18530
18554
  const heartbeat = (ciBuildId) => axios.get(`${API_BASE_URL}/reporter/runs/${ciBuildId}/heartbeat`);
18531
18555
  const runsApi = { create: create$1, update, heartbeat };
18532
18556
 
18557
+ const executeCommandLine = ({ command, messageOnError, shouldThrowError = false, logLevel = "warning", }) => {
18558
+ try {
18559
+ return childProcess.execSync(command).toString().trim();
18560
+ }
18561
+ catch (err) {
18562
+ if (shouldThrowError) {
18563
+ throw err;
18564
+ }
18565
+ else {
18566
+ consoleLogFormatted[logLevel](messageOnError);
18567
+ }
18568
+ }
18569
+ };
18570
+
18533
18571
  const getDescribePath = ({ titlePath, title, project, spec, }) => titlePath.filter((item, index) => index !== 0 && item !== title && item !== project && item !== spec);
18534
18572
  const getCurrentCommitSha = () => executeCommandLine({
18535
18573
  command: "git rev-parse HEAD",
@@ -18561,7 +18599,7 @@ const sendHeartBeatSignal = async (ciBuildId) => {
18561
18599
  await runsApi.heartbeat(ciBuildId);
18562
18600
  }
18563
18601
  catch (error) {
18564
- console.log(error.message);
18602
+ consoleLogFormatted.redText(error.message);
18565
18603
  consoleLogFormatted.error(ERRORS.heartbeat.stopped);
18566
18604
  process.exit(1);
18567
18605
  }
@@ -18595,7 +18633,6 @@ class MyReporter {
18595
18633
  this.currentShard = shard === null || shard === void 0 ? void 0 : shard.current;
18596
18634
  let attempts;
18597
18635
  this.totalTestCount = rootSuite.allTests().length;
18598
- consoleLogFormatted.bold("Started reporting to neetoPlaydash 🎭");
18599
18636
  try {
18600
18637
  const runDetails = {
18601
18638
  commit_id: getCurrentCommitSha(),
@@ -18620,7 +18657,9 @@ class MyReporter {
18620
18657
  catch (error) {
18621
18658
  const data = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
18622
18659
  consoleLogFormatted.error((_b = data === null || data === void 0 ? void 0 : data.error) !== null && _b !== void 0 ? _b : error.message);
18623
- throw new Error(ERRORS.onBegin.failedToInitializeRun);
18660
+ consoleLogFormatted.error(ERRORS.onBegin.failedToInitializeRun);
18661
+ process.kill(process.pid, "SIGKILL");
18662
+ process.exit(1);
18624
18663
  }
18625
18664
  consoleLogFormatted.underline(MESSAGES.onBegin.testStarted);
18626
18665
  consoleLogFormatted.dim(MESSAGES.onBegin.ciBuildId(this.ciBuildId));
@@ -18663,6 +18702,7 @@ class MyReporter {
18663
18702
  catch (error) {
18664
18703
  consoleLogFormatted.error(error.message);
18665
18704
  consoleLogFormatted.error(ERRORS.onTestBegin.failedToReportTest(title, id));
18705
+ await sendHeartBeatSignal(this.ciBuildId);
18666
18706
  }
18667
18707
  };
18668
18708
  this.onTestEnd = async (testCase, { status, duration, errors, error, retry, attachments }) => {
@@ -18687,7 +18727,7 @@ class MyReporter {
18687
18727
  consoleLogFormatted.underline(title);
18688
18728
  await Promise.all(attachments.map(async ({ name, path, body, contentType, }) => {
18689
18729
  consoleLogFormatted.dim(`${name}: ${path}`);
18690
- if (["screenshot", "video", "trace"].includes(name)) {
18730
+ if (VALID_ASSET_TYPES.includes(name)) {
18691
18731
  const buffer = path ? require$$6.readFileSync(path) : body;
18692
18732
  const fileName = path
18693
18733
  ? path.split("/").slice(-1)[0]
@@ -18707,19 +18747,17 @@ class MyReporter {
18707
18747
  catch (error) {
18708
18748
  consoleLogFormatted.error(error.message);
18709
18749
  consoleLogFormatted.error(ERRORS.onTestBegin.failedToReportTest(title, id));
18750
+ await sendHeartBeatSignal(this.ciBuildId);
18710
18751
  }
18711
18752
  finally {
18712
18753
  this.unreportedAttemptCount--;
18713
- retry === 0 && this.reportedTestCount++;
18714
18754
  consoleLogFormatted.invertBackground(MESSAGES.onTestEnd.reportedTest(title));
18715
18755
  }
18716
18756
  };
18717
18757
  this.onEnd = async ({ status, duration }) => {
18718
18758
  var _a, _b;
18719
18759
  try {
18720
- while (!(this.hasRunStarted &&
18721
- this.totalTestCount === this.reportedTestCount &&
18722
- this.unreportedAttemptCount === 0))
18760
+ while (!(this.hasRunStarted && this.unreportedAttemptCount === 0))
18723
18761
  await waitUntilTimeout(100);
18724
18762
  await Promise.allSettled(this.testResultCalls);
18725
18763
  await runsApi.update(this.ciBuildId, {
@@ -18732,8 +18770,8 @@ class MyReporter {
18732
18770
  }
18733
18771
  catch (error) {
18734
18772
  const data = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
18735
- consoleLogFormatted.error((_b = data === null || data === void 0 ? void 0 : data.error) !== null && _b !== void 0 ? _b : error.message);
18736
- throw new Error(ERRORS.onEnd.failedToReportRunStatus);
18773
+ consoleLogFormatted.error((_b = data.error) !== null && _b !== void 0 ? _b : error.message);
18774
+ consoleLogFormatted.error(ERRORS.onEnd.failedToReportRunStatus);
18737
18775
  }
18738
18776
  finally {
18739
18777
  consoleLogFormatted.invertBackground(MESSAGES.onEnd.runReported);
@@ -18746,13 +18784,13 @@ class MyReporter {
18746
18784
  this.retryAttemptStartedAt = new Date();
18747
18785
  this.testResultCalls = [];
18748
18786
  this.totalTestCount = 0;
18749
- this.reportedTestCount = 0;
18750
18787
  this.unreportedAttemptCount = 0;
18751
18788
  this.hasRunStarted = false;
18752
18789
  this.testAttemptIds = [];
18753
- process.on("unhandledRejection", error => {
18790
+ process.on("unhandledRejection", async (error) => {
18754
18791
  var _a, _b, _c;
18755
18792
  const data = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
18793
+ await sendHeartBeatSignal(this.ciBuildId);
18756
18794
  consoleLogFormatted.error((_c = (_b = data === null || data === void 0 ? void 0 : data.error) !== null && _b !== void 0 ? _b : error.message) !== null && _c !== void 0 ? _c : JSON.stringify(error));
18757
18795
  });
18758
18796
  }