@qualflare/cucumberjs 0.4.0 → 0.5.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/README.md +16 -1
- package/dist/formatter/index.cjs +41 -3
- package/dist/formatter/index.cjs.map +1 -1
- package/dist/formatter/index.js +41 -3
- package/dist/formatter/index.js.map +1 -1
- package/package.json +1 -1
package/dist/formatter/index.js
CHANGED
|
@@ -1004,7 +1004,7 @@ function timestampMs(ts) {
|
|
|
1004
1004
|
import * as os from "os";
|
|
1005
1005
|
|
|
1006
1006
|
// src/config/version.ts
|
|
1007
|
-
var PACKAGE_VERSION = "0.
|
|
1007
|
+
var PACKAGE_VERSION = "0.5.0";
|
|
1008
1008
|
|
|
1009
1009
|
// src/formatter/collect-builder.ts
|
|
1010
1010
|
function resolveOs(config) {
|
|
@@ -1131,23 +1131,52 @@ function buildHookIndex(supportCodeLibrary) {
|
|
|
1131
1131
|
|
|
1132
1132
|
// src/formatter/run-hook-tracker.ts
|
|
1133
1133
|
var RunHookTracker = class {
|
|
1134
|
+
constructor(config, budget) {
|
|
1135
|
+
this.config = config;
|
|
1136
|
+
this.budget = budget;
|
|
1137
|
+
}
|
|
1138
|
+
config;
|
|
1139
|
+
budget;
|
|
1134
1140
|
/** `testRunHookStartedId` -> the hook it started, so `finish()` can look
|
|
1135
1141
|
* up its kind/name. `TestRunHookFinished.result.duration` already gives
|
|
1136
1142
|
* an accurate duration directly — no start/finish timestamp delta needed. */
|
|
1137
1143
|
started = /* @__PURE__ */ new Map();
|
|
1138
1144
|
failed = [];
|
|
1145
|
+
/** `testRunHookStartedId` -> attachments made during that hook, unresolved. */
|
|
1146
|
+
pending = /* @__PURE__ */ new Map();
|
|
1139
1147
|
start(e) {
|
|
1140
1148
|
this.started.set(e.id, e.hookId);
|
|
1141
1149
|
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Buffers one attachment made from inside a `BeforeAll`/`AfterAll`. Returns
|
|
1152
|
+
* whether it was claimed, so the caller can tell a run-hook attachment from
|
|
1153
|
+
* one that simply has no home.
|
|
1154
|
+
*
|
|
1155
|
+
* `testRunHookStartedId` is optional in the message schema and only populated
|
|
1156
|
+
* by newer cucumber-js; when it is absent this returns false and the
|
|
1157
|
+
* attachment is dropped exactly as it was before.
|
|
1158
|
+
*/
|
|
1159
|
+
attachment(e) {
|
|
1160
|
+
if (!e.testRunHookStartedId) {
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
const content = e.contentEncoding === "BASE64" ? e.body : Buffer.from(e.body, "utf8").toString("base64");
|
|
1164
|
+
const list = this.pending.get(e.testRunHookStartedId) ?? [];
|
|
1165
|
+
list.push({ name: e.fileName || "attachment", mimeType: e.mediaType, content });
|
|
1166
|
+
this.pending.set(e.testRunHookStartedId, list);
|
|
1167
|
+
return true;
|
|
1168
|
+
}
|
|
1142
1169
|
finish(e, hookIndex) {
|
|
1143
1170
|
const hookId = this.started.get(e.testRunHookStartedId);
|
|
1144
1171
|
this.started.delete(e.testRunHookStartedId);
|
|
1145
1172
|
const status = mapStatus(e.result.status);
|
|
1146
1173
|
if (status === "passed" || status === "skipped") {
|
|
1174
|
+
this.pending.delete(e.testRunHookStartedId);
|
|
1147
1175
|
return;
|
|
1148
1176
|
}
|
|
1149
1177
|
const hook = hookId ? hookIndex.get(hookId) : void 0;
|
|
1150
1178
|
const label = hook?.kind === "afterAll" ? "AfterAll hook" : "BeforeAll hook";
|
|
1179
|
+
const attachments = this.takeAttachments(e.testRunHookStartedId);
|
|
1151
1180
|
this.failed.push({
|
|
1152
1181
|
id: `global-hook:${e.testRunHookStartedId}`,
|
|
1153
1182
|
name: hook?.name || label,
|
|
@@ -1156,9 +1185,17 @@ var RunHookTracker = class {
|
|
|
1156
1185
|
// `result.message` first — see `step-mapper.ts`'s `formatError()` doc
|
|
1157
1186
|
// comment for why (verified empirically to be the version-safe field
|
|
1158
1187
|
// across the peer-dependency range; `exception.stackTrace` is not).
|
|
1159
|
-
error: e.result.message || e.result.exception?.stackTrace || e.result.exception?.message
|
|
1188
|
+
error: e.result.message || e.result.exception?.stackTrace || e.result.exception?.message,
|
|
1189
|
+
...attachments.length > 0 ? { attachments } : {}
|
|
1160
1190
|
});
|
|
1161
1191
|
}
|
|
1192
|
+
/** Resolves and clears the buffer for one hook. Called only for a FAILED
|
|
1193
|
+
* hook, so the budget is never spent on a passing one's attachments. */
|
|
1194
|
+
takeAttachments(testRunHookStartedId) {
|
|
1195
|
+
const buffered = this.pending.get(testRunHookStartedId) ?? [];
|
|
1196
|
+
this.pending.delete(testRunHookStartedId);
|
|
1197
|
+
return buffered.map((pending) => resolvePendingAttachment(pending, this.config, this.budget)).filter((a) => a !== void 0);
|
|
1198
|
+
}
|
|
1162
1199
|
/** Returns `undefined` if no run-hook failed — see the class doc comment
|
|
1163
1200
|
* for why a passing BeforeAll/AfterAll produces no Case at all. */
|
|
1164
1201
|
buildSuite() {
|
|
@@ -1230,7 +1267,7 @@ var QualflareCucumberFormatter = class extends Formatter {
|
|
|
1230
1267
|
testCaseIndex = /* @__PURE__ */ new Map();
|
|
1231
1268
|
attachmentBudget;
|
|
1232
1269
|
attemptTracker;
|
|
1233
|
-
runHookTracker
|
|
1270
|
+
runHookTracker;
|
|
1234
1271
|
finishedCases = [];
|
|
1235
1272
|
/** One promise per `testCaseFinished` envelope, resolving once that
|
|
1236
1273
|
* scenario's `AttemptTracker.finish()` (which itself awaits any pending
|
|
@@ -1245,6 +1282,7 @@ var QualflareCucumberFormatter = class extends Formatter {
|
|
|
1245
1282
|
this.config = resolveConfig(options.parsedArgvOptions);
|
|
1246
1283
|
this.hookIndex = buildHookIndex(options.supportCodeLibrary);
|
|
1247
1284
|
this.attachmentBudget = new AttachmentBudget(this.config.maxTotalAttachmentBytes);
|
|
1285
|
+
this.runHookTracker = new RunHookTracker(this.config, this.attachmentBudget);
|
|
1248
1286
|
this.attemptTracker = new AttemptTracker(
|
|
1249
1287
|
this.hookIndex,
|
|
1250
1288
|
this.gherkin,
|