@bigbinary/neeto-playwright-reporter 1.2.1 → 1.3.1

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.cjs.js CHANGED
@@ -13,6 +13,7 @@ var require$$0$2 = require('os');
13
13
  var zlib = require('zlib');
14
14
  var EventEmitter = require('events');
15
15
  var childProcess = require('child_process');
16
+ var crypto = require('crypto');
16
17
 
17
18
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
19
 
@@ -29,6 +30,7 @@ var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2);
29
30
  var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
30
31
  var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
31
32
  var childProcess__default = /*#__PURE__*/_interopDefaultLegacy(childProcess);
33
+ var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto);
32
34
 
33
35
  function bind(fn, thisArg) {
34
36
  return function wrap() {
@@ -18457,10 +18459,15 @@ const HEADERS_KEYS = {
18457
18459
  };
18458
18460
  const API_BASE_URL = "/api/v1";
18459
18461
 
18460
- const create$2 = (ciBuildId, history_id, payload) => axios.post(`${API_BASE_URL}/reporter/runs/${ciBuildId}/test_entities/${history_id}/attempts`, payload, { headers: { "Content-Type": "multipart/form-data" } });
18461
- const update$1 = (ciBuildId, history_id, id, payload) => axios.put(`${API_BASE_URL}/reporter/runs/${ciBuildId}/test_entities/${history_id}/attempts/${id}`, payload, { headers: { "Content-Type": "multipart/form-data" } });
18462
+ const create$2 = (ciBuildId, history_id, payload) => axios.post(`${API_BASE_URL}/reporter/runs/${ciBuildId}/test_entities/${history_id}/attempts`, payload);
18463
+ const update$1 = (ciBuildId, history_id, id, payload) => axios.put(`${API_BASE_URL}/reporter/runs/${ciBuildId}/test_entities/${history_id}/attempts/${id}`, payload);
18462
18464
  const attemptsApi = { create: create$2, update: update$1 };
18463
18465
 
18466
+ const getDirectUploadURL = (payload) => axios.post(`${API_BASE_URL}/reporter/direct_uploads`, {
18467
+ blob: payload,
18468
+ });
18469
+ const uploadToS3 = (data, { url, headers }) => axios.put(url, data, { headers });
18470
+
18464
18471
  const ERRORS = {
18465
18472
  onBegin: {
18466
18473
  failedToGetCommitSha: "Failed to get current commit SHA.",
@@ -18520,7 +18527,13 @@ const executeCommandLine = ({ command, messageOnError, shouldThrowError = false,
18520
18527
  const createShardObject = ({ currentShard = 0, status = "running", duration = null, }) => ({
18521
18528
  [currentShard]: { status, duration },
18522
18529
  });
18523
- const convertBufferToBlob = (buffer, contentType) => new Blob([buffer], { type: contentType });
18530
+ const waitUntilTimeout = (timeout) => new Promise(resolve => setTimeout(resolve, timeout));
18531
+
18532
+ const getFileData = (file, contentType, filename) => {
18533
+ const byte_size = file.byteLength;
18534
+ const checksum = crypto__default["default"].createHash("md5").update(file).digest("base64");
18535
+ return { file, filename, checksum, byte_size, content_type: contentType };
18536
+ };
18524
18537
 
18525
18538
  const create$1 = (payload) => axios.post(`${API_BASE_URL}/reporter/runs`, {
18526
18539
  run: payload,
@@ -18558,6 +18571,7 @@ const sendHeartBeatSignal = async (ciBuildId) => {
18558
18571
  await runsApi.heartbeat(ciBuildId);
18559
18572
  }
18560
18573
  catch (error) {
18574
+ console.log(error.message);
18561
18575
  consoleLogFormatted.error(ERRORS.heartbeat.stopped);
18562
18576
  process.exit(1);
18563
18577
  }
@@ -18588,6 +18602,7 @@ class MyReporter {
18588
18602
  this.onBegin = async (config, rootSuite) => {
18589
18603
  const shard = config.shard;
18590
18604
  let attempts;
18605
+ this.totalTestCount = rootSuite.allTests().length;
18591
18606
  try {
18592
18607
  const runDetails = {
18593
18608
  commit_id: getCurrentCommitSha(),
@@ -18619,13 +18634,31 @@ class MyReporter {
18619
18634
  this.currentShard = shard === null || shard === void 0 ? void 0 : shard.current;
18620
18635
  };
18621
18636
  this.onTestBegin = async ({ id, title }, { retry }) => {
18637
+ var _a, _b;
18622
18638
  consoleLogFormatted.invertBackground(MESSAGES.onTestBegin.startingTest(title));
18623
18639
  try {
18624
- const formData = new FormData();
18625
- formData.append("attempt[status]", "running");
18626
- formData.append("attempt[started_at]", new Date().toString());
18627
- retry === 0 &&
18628
- (await attemptsApi.update(this.ciBuildId, id, this.attempts[id], formData));
18640
+ this.retryAttemptStartedAt = new Date();
18641
+ while (!((_b = (_a = this.attempts) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b["0"]))
18642
+ await waitUntilTimeout(100); // Poll every 100 milliseconds
18643
+ if (retry === 0) {
18644
+ await attemptsApi.update(this.ciBuildId, id, this.attempts[id]["0"], {
18645
+ status: "running",
18646
+ started_at: new Date().toString(),
18647
+ });
18648
+ }
18649
+ else {
18650
+ const { data: { history_id, attempt_id }, } = await attemptsApi.create(this.ciBuildId, id, {
18651
+ status: "running",
18652
+ started_at: new Date().toString(),
18653
+ });
18654
+ this.attempts = {
18655
+ ...this.attempts,
18656
+ [history_id]: {
18657
+ ...this.attempts[history_id],
18658
+ [String(retry)]: attempt_id,
18659
+ },
18660
+ };
18661
+ }
18629
18662
  }
18630
18663
  catch (error) {
18631
18664
  consoleLogFormatted.error(error.message);
@@ -18633,6 +18666,7 @@ class MyReporter {
18633
18666
  }
18634
18667
  };
18635
18668
  this.onTestEnd = async (testCase, { status, duration, errors, retry, attachments }) => {
18669
+ const completedAt = new Date();
18636
18670
  const { id, title, expectedStatus } = testCase;
18637
18671
  try {
18638
18672
  const testResult = {
@@ -18641,33 +18675,44 @@ class MyReporter {
18641
18675
  status,
18642
18676
  duration,
18643
18677
  log: errors.map(error => { var _a; return (_a = error.message) !== null && _a !== void 0 ? _a : ""; }).join("\n"),
18678
+ screenshots: [],
18679
+ videos: [],
18680
+ traces: [],
18681
+ completed_at: completedAt.toString(),
18644
18682
  };
18645
18683
  consoleLogFormatted.underline(title);
18646
- const formData = new FormData();
18647
- attachments.map(({ name, path, body, contentType }) => {
18684
+ await Promise.all(attachments.map(async ({ name, path, body, contentType, }) => {
18648
18685
  consoleLogFormatted.dim(`${name}: ${path}`);
18649
18686
  if (["screenshot", "video", "trace"].includes(name)) {
18650
18687
  const buffer = path ? require$$6__default["default"].readFileSync(path) : body;
18651
- formData.append(`attempt[${name}s][]`, convertBufferToBlob(buffer, contentType));
18688
+ const fileName = path
18689
+ ? path.split("/").slice(-1)[0]
18690
+ : `${name}.${contentType.split("/").slice(-1)[0]}`;
18691
+ const { file, ...metadata } = getFileData(buffer, contentType, fileName);
18692
+ const { data: { signed_id, direct_upload }, } = await getDirectUploadURL(metadata);
18693
+ const pluralizedAsset = `${name}s`;
18694
+ testResult[pluralizedAsset].push(signed_id);
18695
+ return uploadToS3(file, direct_upload);
18652
18696
  }
18653
- });
18654
- Object.entries(testResult).map(([resultKey, resultValue]) => {
18655
- formData.append(`attempt[${resultKey}]`, resultValue.toString());
18656
- });
18657
- retry !== 0 &&
18658
- formData.append("attempt[started_at]", new Date().toString());
18659
- retry === 0
18660
- ? await attemptsApi.update(this.ciBuildId, id, this.attempts[id], formData)
18661
- : await attemptsApi.create(this.ciBuildId, id, formData);
18697
+ }));
18698
+ while (!this.attempts[id][retry])
18699
+ await waitUntilTimeout(100);
18700
+ this.testResultCalls.push(attemptsApi.update(this.ciBuildId, id, this.attempts[id][retry], testResult));
18662
18701
  consoleLogFormatted.invertBackground(MESSAGES.onTestEnd.reportedTest(title));
18663
18702
  }
18664
18703
  catch (error) {
18665
18704
  consoleLogFormatted.error(error.message);
18666
18705
  consoleLogFormatted.error(ERRORS.onTestBegin.failedToReportTest(title, id));
18667
18706
  }
18707
+ finally {
18708
+ retry === 0 && this.reportedTestCount++;
18709
+ }
18668
18710
  };
18669
18711
  this.onEnd = async ({ status, duration }) => {
18670
18712
  try {
18713
+ await Promise.allSettled(this.testResultCalls);
18714
+ while (this.totalTestCount !== this.reportedTestCount)
18715
+ await waitUntilTimeout(100);
18671
18716
  await runsApi.update(this.ciBuildId, {
18672
18717
  shards: createShardObject({
18673
18718
  currentShard: this.currentShard,
@@ -18684,6 +18729,10 @@ class MyReporter {
18684
18729
  initializeAxios(options);
18685
18730
  this.attempts = {};
18686
18731
  this.ciBuildId = options.ciBuildId;
18732
+ this.retryAttemptStartedAt = new Date();
18733
+ this.testResultCalls = [];
18734
+ this.totalTestCount = 0;
18735
+ this.reportedTestCount = 0;
18687
18736
  }
18688
18737
  }
18689
18738