@bigbinary/neeto-playwright-reporter 1.2.1 → 1.3.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/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,
@@ -18588,6 +18601,7 @@ class MyReporter {
18588
18601
  this.onBegin = async (config, rootSuite) => {
18589
18602
  const shard = config.shard;
18590
18603
  let attempts;
18604
+ this.totalTestCount = rootSuite.allTests().length;
18591
18605
  try {
18592
18606
  const runDetails = {
18593
18607
  commit_id: getCurrentCommitSha(),
@@ -18621,11 +18635,28 @@ class MyReporter {
18621
18635
  this.onTestBegin = async ({ id, title }, { retry }) => {
18622
18636
  consoleLogFormatted.invertBackground(MESSAGES.onTestBegin.startingTest(title));
18623
18637
  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));
18638
+ this.retryAttemptStartedAt = new Date();
18639
+ while (!this.attempts[id]["0"])
18640
+ await waitUntilTimeout(100); // Poll every 100 milliseconds
18641
+ if (retry === 0) {
18642
+ await attemptsApi.update(this.ciBuildId, id, this.attempts[id]["0"], {
18643
+ status: "running",
18644
+ started_at: new Date().toString(),
18645
+ });
18646
+ }
18647
+ else {
18648
+ const { data: { history_id, attempt_id }, } = await attemptsApi.create(this.ciBuildId, id, {
18649
+ status: "running",
18650
+ started_at: new Date().toString(),
18651
+ });
18652
+ this.attempts = {
18653
+ ...this.attempts,
18654
+ [history_id]: {
18655
+ ...this.attempts[history_id],
18656
+ [String(retry)]: attempt_id,
18657
+ },
18658
+ };
18659
+ }
18629
18660
  }
18630
18661
  catch (error) {
18631
18662
  consoleLogFormatted.error(error.message);
@@ -18633,6 +18664,7 @@ class MyReporter {
18633
18664
  }
18634
18665
  };
18635
18666
  this.onTestEnd = async (testCase, { status, duration, errors, retry, attachments }) => {
18667
+ const completedAt = new Date();
18636
18668
  const { id, title, expectedStatus } = testCase;
18637
18669
  try {
18638
18670
  const testResult = {
@@ -18641,33 +18673,44 @@ class MyReporter {
18641
18673
  status,
18642
18674
  duration,
18643
18675
  log: errors.map(error => { var _a; return (_a = error.message) !== null && _a !== void 0 ? _a : ""; }).join("\n"),
18676
+ screenshots: [],
18677
+ videos: [],
18678
+ traces: [],
18679
+ completed_at: completedAt.toString(),
18644
18680
  };
18645
18681
  consoleLogFormatted.underline(title);
18646
- const formData = new FormData();
18647
- attachments.map(({ name, path, body, contentType }) => {
18682
+ await Promise.all(attachments.map(async ({ name, path, body, contentType, }) => {
18648
18683
  consoleLogFormatted.dim(`${name}: ${path}`);
18649
18684
  if (["screenshot", "video", "trace"].includes(name)) {
18650
18685
  const buffer = path ? require$$6__default["default"].readFileSync(path) : body;
18651
- formData.append(`attempt[${name}s][]`, convertBufferToBlob(buffer, contentType));
18686
+ const fileName = path
18687
+ ? path.split("/").slice(-1)[0]
18688
+ : `${name}.${contentType.split("/").slice(-1)[0]}`;
18689
+ const { file, ...metadata } = getFileData(buffer, contentType, fileName);
18690
+ const { data: { signed_id, direct_upload }, } = await getDirectUploadURL(metadata);
18691
+ const pluralizedAsset = `${name}s`;
18692
+ testResult[pluralizedAsset].push(signed_id);
18693
+ return uploadToS3(file, direct_upload);
18652
18694
  }
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);
18695
+ }));
18696
+ while (!this.attempts[id][retry])
18697
+ await waitUntilTimeout(100);
18698
+ this.testResultCalls.push(attemptsApi.update(this.ciBuildId, id, this.attempts[id][retry], testResult));
18662
18699
  consoleLogFormatted.invertBackground(MESSAGES.onTestEnd.reportedTest(title));
18663
18700
  }
18664
18701
  catch (error) {
18665
18702
  consoleLogFormatted.error(error.message);
18666
18703
  consoleLogFormatted.error(ERRORS.onTestBegin.failedToReportTest(title, id));
18667
18704
  }
18705
+ finally {
18706
+ retry === 0 && this.reportedTestCount++;
18707
+ }
18668
18708
  };
18669
18709
  this.onEnd = async ({ status, duration }) => {
18670
18710
  try {
18711
+ await Promise.allSettled(this.testResultCalls);
18712
+ while (this.totalTestCount !== this.reportedTestCount)
18713
+ await waitUntilTimeout(100);
18671
18714
  await runsApi.update(this.ciBuildId, {
18672
18715
  shards: createShardObject({
18673
18716
  currentShard: this.currentShard,
@@ -18684,6 +18727,10 @@ class MyReporter {
18684
18727
  initializeAxios(options);
18685
18728
  this.attempts = {};
18686
18729
  this.ciBuildId = options.ciBuildId;
18730
+ this.retryAttemptStartedAt = new Date();
18731
+ this.testResultCalls = [];
18732
+ this.totalTestCount = 0;
18733
+ this.reportedTestCount = 0;
18687
18734
  }
18688
18735
  }
18689
18736