@bigbinary/neeto-playwright-reporter 1.0.1 → 1.1.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 +188 -33
- package/index.cjs.js.map +1 -1
- package/index.d.ts +15 -3
- package/index.js +186 -32
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.cjs.js
CHANGED
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var require$$6 = require('fs');
|
|
3
4
|
var require$$1 = require('util');
|
|
4
5
|
var stream = require('stream');
|
|
5
6
|
var require$$1$1 = require('path');
|
|
6
7
|
var require$$3 = require('http');
|
|
7
8
|
var require$$4 = require('https');
|
|
8
9
|
var require$$0$1 = require('url');
|
|
9
|
-
var require$$6 = require('fs');
|
|
10
10
|
var require$$4$1 = require('assert');
|
|
11
11
|
var require$$1$2 = require('tty');
|
|
12
12
|
var require$$0$2 = require('os');
|
|
13
13
|
var zlib = require('zlib');
|
|
14
14
|
var EventEmitter = require('events');
|
|
15
|
+
var childProcess = require('child_process');
|
|
15
16
|
|
|
16
17
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
17
18
|
|
|
19
|
+
var require$$6__default = /*#__PURE__*/_interopDefaultLegacy(require$$6);
|
|
18
20
|
var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
|
|
19
21
|
var stream__default = /*#__PURE__*/_interopDefaultLegacy(stream);
|
|
20
22
|
var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
|
|
21
23
|
var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
|
|
22
24
|
var require$$4__default = /*#__PURE__*/_interopDefaultLegacy(require$$4);
|
|
23
25
|
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
|
|
24
|
-
var require$$6__default = /*#__PURE__*/_interopDefaultLegacy(require$$6);
|
|
25
26
|
var require$$4__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$4$1);
|
|
26
27
|
var require$$1__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$1$2);
|
|
27
28
|
var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2);
|
|
28
29
|
var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
|
|
29
30
|
var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
|
|
31
|
+
var childProcess__default = /*#__PURE__*/_interopDefaultLegacy(childProcess);
|
|
30
32
|
|
|
31
33
|
function bind(fn, thisArg) {
|
|
32
34
|
return function wrap() {
|
|
@@ -18446,54 +18448,207 @@ axios.HttpStatusCode = HttpStatusCode;
|
|
|
18446
18448
|
|
|
18447
18449
|
axios.default = axios;
|
|
18448
18450
|
|
|
18449
|
-
// dummy endpoint until neeto-playwright-reporter dashboard is up
|
|
18450
|
-
const create = (payload) => axios.post(`https://webhook.site/1bff83d0-03a0-412f-a70a-2f11f3209534`, payload);
|
|
18451
|
-
const dummyApi = { create };
|
|
18452
|
-
|
|
18453
|
-
const getDescribePath = ({ titlePath, title, project, spec, }) => {
|
|
18454
|
-
const describePaths = titlePath.filter((item, index) => index !== 0 && item !== title && item !== project && item !== spec);
|
|
18455
|
-
return describePaths.join(" > ");
|
|
18456
|
-
};
|
|
18457
|
-
|
|
18458
18451
|
const HEADERS_KEYS = {
|
|
18459
18452
|
applicationKey: "Application-Key",
|
|
18460
|
-
xCsrfToken: "X-CSRF-TOKEN",
|
|
18461
18453
|
contentType: "Content-Type",
|
|
18462
18454
|
accept: "Accept",
|
|
18455
|
+
apiKey: "X-Api-Key",
|
|
18456
|
+
projectKey: "Project-Key",
|
|
18457
|
+
};
|
|
18458
|
+
const API_BASE_URL = "/api/v1";
|
|
18459
|
+
|
|
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 attemptsApi = { create: create$2, update: update$1 };
|
|
18463
|
+
|
|
18464
|
+
const ERRORS = {
|
|
18465
|
+
onBegin: {
|
|
18466
|
+
failedToGetCommitSha: "Failed to get current commit SHA.",
|
|
18467
|
+
failedToGetCommitMessage: "Failed to get current commit message.",
|
|
18468
|
+
failedToInitializeRun: "Failed to initialize run in reporter",
|
|
18469
|
+
},
|
|
18470
|
+
onTestBegin: {
|
|
18471
|
+
failedToReportTest: (testTitle, historyId) => `Failed to report test "${testTitle}" with history ID ${historyId}`,
|
|
18472
|
+
},
|
|
18473
|
+
onEnd: {
|
|
18474
|
+
failedToReportRunStatus: "Failed to report run status",
|
|
18475
|
+
},
|
|
18476
|
+
};
|
|
18477
|
+
|
|
18478
|
+
const MESSAGES = {
|
|
18479
|
+
onBegin: {
|
|
18480
|
+
testStarted: "Test has started reporting to neetoPlaywrightReporter",
|
|
18481
|
+
ciBuildId: (currentCiBuildId) => `CI BUILD ID: ${currentCiBuildId}`,
|
|
18482
|
+
totalShards: (totalShards) => `Total shards: ${totalShards}`,
|
|
18483
|
+
currentShard: (currentShard) => `Current shard: ${currentShard}`,
|
|
18484
|
+
},
|
|
18485
|
+
};
|
|
18486
|
+
|
|
18487
|
+
const consoleLogFormatted = {
|
|
18488
|
+
bold: (message) => console.log(console.log("\x1b[1m", message, "\x1b[0m")),
|
|
18489
|
+
dim: (message) => console.log(console.log("\x1b[2m", message, "\x1b[0m")),
|
|
18490
|
+
underline: (message) => console.log(console.log("\x1b[4m", message, "\x1b[0m")),
|
|
18491
|
+
invertBackground: (message) => console.log(console.log("\x1b[7m", message, "\x1b[0m")),
|
|
18492
|
+
hidden: (message) => console.log(console.log("\x1b[8m", message, "\x1b[0m")),
|
|
18493
|
+
error: (message) => console.log("\u001b[31m", "\x1b[1m", message, "\x1b[0m", "\u001b[0m"),
|
|
18494
|
+
warning: (message) => console.log("\u001b[33m", "\x1b[1m", message, "\x1b[0m", "\u001b[0m"),
|
|
18495
|
+
};
|
|
18496
|
+
const executeCommandLine = ({ command, messageOnError, shouldThrowError = false, logLevel = "warning", }) => {
|
|
18497
|
+
try {
|
|
18498
|
+
return childProcess__default["default"].execSync(command).toString().trim();
|
|
18499
|
+
}
|
|
18500
|
+
catch (err) {
|
|
18501
|
+
if (shouldThrowError) {
|
|
18502
|
+
throw err;
|
|
18503
|
+
}
|
|
18504
|
+
else {
|
|
18505
|
+
consoleLogFormatted[logLevel](messageOnError);
|
|
18506
|
+
}
|
|
18507
|
+
}
|
|
18463
18508
|
};
|
|
18464
18509
|
|
|
18465
|
-
const
|
|
18510
|
+
const createShardObject = ({ currentShard = 0, status = "running", duration = null, }) => ({
|
|
18511
|
+
[currentShard]: { status, duration },
|
|
18512
|
+
});
|
|
18513
|
+
const convertBufferToBlob = (buffer, contentType) => new Blob([buffer], { type: contentType });
|
|
18514
|
+
|
|
18515
|
+
const getDescribePath = ({ titlePath, title, project, spec, }) => titlePath.filter((item, index) => index !== 0 && item !== title && item !== project && item !== spec);
|
|
18516
|
+
const getCurrentCommitSha = () => executeCommandLine({
|
|
18517
|
+
command: "git rev-parse HEAD",
|
|
18518
|
+
messageOnError: ERRORS.onBegin.failedToGetCommitSha,
|
|
18519
|
+
});
|
|
18520
|
+
const getCurrentCommitMessage = () => executeCommandLine({
|
|
18521
|
+
command: "git show-branch --no-name HEAD",
|
|
18522
|
+
messageOnError: ERRORS.onBegin.failedToGetCommitMessage,
|
|
18523
|
+
});
|
|
18524
|
+
const getInitializerData = ({ rootDir }, rootSuite) => rootSuite.allTests().map(test => {
|
|
18525
|
+
var _a;
|
|
18526
|
+
const { title, parent, id: history_id, location: { file }, } = test;
|
|
18527
|
+
const titlePath = test.titlePath();
|
|
18528
|
+
const project = (_a = parent.project()) === null || _a === void 0 ? void 0 : _a.name;
|
|
18529
|
+
const spec = file.replace(`${rootDir}/`, "");
|
|
18530
|
+
const describe = getDescribePath({ titlePath, title, spec, project });
|
|
18531
|
+
return { title, describe, project, spec, history_id };
|
|
18532
|
+
});
|
|
18533
|
+
|
|
18534
|
+
const setAuthHeaders = (projectKey) => {
|
|
18535
|
+
var _a;
|
|
18466
18536
|
axios.defaults.headers = {
|
|
18467
18537
|
...axios.defaults.headers,
|
|
18468
|
-
[HEADERS_KEYS.
|
|
18538
|
+
[HEADERS_KEYS.projectKey]: projectKey,
|
|
18539
|
+
[HEADERS_KEYS.apiKey]: (_a = process.env.API_KEY) !== null && _a !== void 0 ? _a : "",
|
|
18469
18540
|
[HEADERS_KEYS.accept]: "application/json",
|
|
18470
18541
|
[HEADERS_KEYS.contentType]: "application/json",
|
|
18471
18542
|
};
|
|
18472
18543
|
};
|
|
18473
|
-
function initializeAxios(
|
|
18474
|
-
|
|
18544
|
+
function initializeAxios({ projectKey, baseURL, }) {
|
|
18545
|
+
axios.defaults.baseURL = baseURL;
|
|
18546
|
+
setAuthHeaders(projectKey);
|
|
18475
18547
|
}
|
|
18476
18548
|
|
|
18549
|
+
const create$1 = (payload) => axios.post(`${API_BASE_URL}/reporter/runs`, {
|
|
18550
|
+
run: payload,
|
|
18551
|
+
});
|
|
18552
|
+
const update = (ciBuildId, payload) => axios.put(`${API_BASE_URL}/reporter/runs/${ciBuildId}`, {
|
|
18553
|
+
run: payload,
|
|
18554
|
+
});
|
|
18555
|
+
const runsApi = { create: create$1, update };
|
|
18556
|
+
|
|
18557
|
+
const create = (ciBuildId, payload) => axios.post(`${API_BASE_URL}/reporter/runs/${ciBuildId}/test_entities`, {
|
|
18558
|
+
test_entity: payload,
|
|
18559
|
+
});
|
|
18560
|
+
const testEntitiesApi = { create };
|
|
18561
|
+
|
|
18477
18562
|
class MyReporter {
|
|
18478
18563
|
constructor(options) {
|
|
18479
|
-
this.onBegin = async (config,
|
|
18480
|
-
|
|
18481
|
-
|
|
18482
|
-
|
|
18483
|
-
|
|
18484
|
-
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
18490
|
-
|
|
18491
|
-
|
|
18492
|
-
|
|
18493
|
-
|
|
18494
|
-
|
|
18564
|
+
this.onBegin = async (config, rootSuite) => {
|
|
18565
|
+
const shard = config.shard;
|
|
18566
|
+
let attempts;
|
|
18567
|
+
try {
|
|
18568
|
+
const runDetails = {
|
|
18569
|
+
commit_id: getCurrentCommitSha(),
|
|
18570
|
+
commit_name: getCurrentCommitMessage(),
|
|
18571
|
+
ci_build_id: this.ciBuildId,
|
|
18572
|
+
configuration: config,
|
|
18573
|
+
shards: createShardObject({ currentShard: shard === null || shard === void 0 ? void 0 : shard.current }),
|
|
18574
|
+
};
|
|
18575
|
+
await runsApi.create(runDetails);
|
|
18576
|
+
({ data: attempts } = await testEntitiesApi.create(this.ciBuildId, {
|
|
18577
|
+
test_entities: getInitializerData(config, rootSuite),
|
|
18578
|
+
}));
|
|
18579
|
+
}
|
|
18580
|
+
catch (error) {
|
|
18581
|
+
consoleLogFormatted.error(error);
|
|
18582
|
+
throw new Error(ERRORS.onBegin.failedToInitializeRun);
|
|
18583
|
+
}
|
|
18584
|
+
consoleLogFormatted.underline(MESSAGES.onBegin.testStarted);
|
|
18585
|
+
consoleLogFormatted.dim(MESSAGES.onBegin.ciBuildId(this.ciBuildId));
|
|
18586
|
+
if (shard) {
|
|
18587
|
+
consoleLogFormatted.dim(MESSAGES.onBegin.totalShards(shard.total));
|
|
18588
|
+
consoleLogFormatted.dim(MESSAGES.onBegin.currentShard(shard.current));
|
|
18589
|
+
}
|
|
18590
|
+
this.attempts = attempts;
|
|
18591
|
+
this.config = config;
|
|
18592
|
+
this.currentShard = shard === null || shard === void 0 ? void 0 : shard.current;
|
|
18593
|
+
};
|
|
18594
|
+
this.onTestBegin = async ({ id, title }, { retry }) => {
|
|
18595
|
+
try {
|
|
18596
|
+
const formData = new FormData();
|
|
18597
|
+
formData.append("attempt[status]", "running");
|
|
18598
|
+
retry === 0 &&
|
|
18599
|
+
(await attemptsApi.update(this.ciBuildId, id, this.attempts[id], formData));
|
|
18600
|
+
}
|
|
18601
|
+
catch (error) {
|
|
18602
|
+
consoleLogFormatted.error(ERRORS.onTestBegin.failedToReportTest(title, id));
|
|
18603
|
+
console.log(error);
|
|
18604
|
+
}
|
|
18605
|
+
};
|
|
18606
|
+
this.onTestEnd = async ({ id, title }, { status, duration, errors, retry, attachments }) => {
|
|
18607
|
+
try {
|
|
18608
|
+
const testResult = {
|
|
18609
|
+
status,
|
|
18610
|
+
duration,
|
|
18611
|
+
log: errors.map(error => { var _a; return (_a = error.message) !== null && _a !== void 0 ? _a : ""; }).join("\n"),
|
|
18612
|
+
};
|
|
18613
|
+
consoleLogFormatted.underline(title);
|
|
18614
|
+
const formData = new FormData();
|
|
18615
|
+
attachments.map(({ name, path, body, contentType }) => {
|
|
18616
|
+
consoleLogFormatted.dim(`${name}: ${path}`);
|
|
18617
|
+
if (["screenshot", "video", "trace"].includes(name)) {
|
|
18618
|
+
const buffer = path ? require$$6__default["default"].readFileSync(path) : body;
|
|
18619
|
+
formData.append(`attempt[${name}s][]`, convertBufferToBlob(buffer, contentType));
|
|
18620
|
+
}
|
|
18621
|
+
});
|
|
18622
|
+
Object.entries(testResult).map(([resultKey, resultValue]) => {
|
|
18623
|
+
formData.append(`attempt[${resultKey}]`, resultValue.toString());
|
|
18624
|
+
});
|
|
18625
|
+
retry === 0
|
|
18626
|
+
? await attemptsApi.update(this.ciBuildId, id, this.attempts[id], formData)
|
|
18627
|
+
: await attemptsApi.create(this.ciBuildId, id, formData);
|
|
18628
|
+
}
|
|
18629
|
+
catch (error) {
|
|
18630
|
+
consoleLogFormatted.error(ERRORS.onTestBegin.failedToReportTest(title, id));
|
|
18631
|
+
console.log(error);
|
|
18632
|
+
}
|
|
18633
|
+
};
|
|
18634
|
+
this.onEnd = async ({ status, duration }) => {
|
|
18635
|
+
try {
|
|
18636
|
+
await runsApi.update(this.ciBuildId, {
|
|
18637
|
+
shards: createShardObject({
|
|
18638
|
+
currentShard: this.currentShard,
|
|
18639
|
+
status,
|
|
18640
|
+
duration,
|
|
18641
|
+
}),
|
|
18642
|
+
});
|
|
18643
|
+
}
|
|
18644
|
+
catch (error) {
|
|
18645
|
+
console.log(error);
|
|
18646
|
+
throw new Error(ERRORS.onEnd.failedToReportRunStatus);
|
|
18647
|
+
}
|
|
18495
18648
|
};
|
|
18496
|
-
initializeAxios(options
|
|
18649
|
+
initializeAxios(options);
|
|
18650
|
+
this.attempts = {};
|
|
18651
|
+
this.ciBuildId = options.ciBuildId;
|
|
18497
18652
|
}
|
|
18498
18653
|
}
|
|
18499
18654
|
|