@qualflare/cucumberjs 0.2.0 → 0.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/README.md +9 -3
- package/dist/formatter/index.cjs +22 -7
- package/dist/formatter/index.cjs.map +1 -1
- package/dist/formatter/index.js +22 -7
- package/dist/formatter/index.js.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,11 +106,17 @@ Every option can be set either as a `formatOptions` entry or via a `QUALFLARE_*`
|
|
|
106
106
|
variable. Full table, precedence rules, and auto-detection behavior (git branch/commit, CI
|
|
107
107
|
provider/build/PR) in [`docs/CONFIGURATION.md`](./docs/CONFIGURATION.md).
|
|
108
108
|
|
|
109
|
+
One option is worth calling out because it fails late: `environment` is matched against the
|
|
110
|
+
environment's **uid (slug)**, not its display name, so **Staging** in the UI is `staging` here. A
|
|
111
|
+
wrong value cannot fail at run time — this package makes no network calls — so the run succeeds and
|
|
112
|
+
`collect` 404s afterwards. See
|
|
113
|
+
[the note in the configuration docs](./docs/CONFIGURATION.md#environment-is-matched-by-uid-not-display-name).
|
|
114
|
+
|
|
109
115
|
## Known limitations
|
|
110
116
|
|
|
111
|
-
-
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
- **A stale `outputDir` is refused, not merged** — each report carries a `runId`, and `qf collect`
|
|
118
|
+
errors rather than merging files from two different runs. Needs `@qualflare/cli` v0.1.19+; older
|
|
119
|
+
CLIs merge as before.
|
|
114
120
|
- **`shardIndex` is best-effort** — cucumber-js routes its own `--shard` flag somewhere a formatter
|
|
115
121
|
cannot read, so it is recovered from `QUALFLARE_SHARD_INDEX` or by scanning `process.argv`. It is
|
|
116
122
|
only an attribution label; merging never depends on it. See
|
package/dist/formatter/index.cjs
CHANGED
|
@@ -35,11 +35,14 @@ __export(formatter_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(formatter_exports);
|
|
36
36
|
|
|
37
37
|
// src/formatter/formatter.ts
|
|
38
|
-
var
|
|
38
|
+
var import_node_crypto3 = require("crypto");
|
|
39
39
|
var fs3 = __toESM(require("fs"), 1);
|
|
40
40
|
var path4 = __toESM(require("path"), 1);
|
|
41
41
|
var import_cucumber = require("@cucumber/cucumber");
|
|
42
42
|
|
|
43
|
+
// src/config/resolve-config.ts
|
|
44
|
+
var import_node_crypto = require("crypto");
|
|
45
|
+
|
|
43
46
|
// src/shared/constants.ts
|
|
44
47
|
var RESERVED_MESSAGE_MEDIA_TYPE = "application/vnd.qualflare.message+json";
|
|
45
48
|
var MAX_SUITES_PER_LAUNCH = 2e3;
|
|
@@ -65,6 +68,7 @@ var PROVIDERS = [
|
|
|
65
68
|
detect: (env) => env.GITHUB_ACTIONS === "true",
|
|
66
69
|
providerName: "GitHub Actions",
|
|
67
70
|
buildNumber: (env) => nonEmpty(env.GITHUB_RUN_NUMBER),
|
|
71
|
+
runId: (env) => nonEmpty(env.GITHUB_RUN_ID),
|
|
68
72
|
runUrl: (env) => env.GITHUB_SERVER_URL && env.GITHUB_REPOSITORY && env.GITHUB_RUN_ID ? `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}` : void 0,
|
|
69
73
|
prNumber: (env) => {
|
|
70
74
|
const match = /^refs\/pull\/(\d+)\/merge$/.exec(env.GITHUB_REF ?? "");
|
|
@@ -75,6 +79,7 @@ var PROVIDERS = [
|
|
|
75
79
|
detect: (env) => env.GITLAB_CI === "true",
|
|
76
80
|
providerName: "GitLab CI",
|
|
77
81
|
buildNumber: (env) => nonEmpty(env.CI_PIPELINE_IID),
|
|
82
|
+
runId: (env) => nonEmpty(env.CI_PIPELINE_ID),
|
|
78
83
|
runUrl: (env) => nonEmpty(env.CI_PIPELINE_URL),
|
|
79
84
|
prNumber: (env) => parsePositiveInt(env.CI_MERGE_REQUEST_IID)
|
|
80
85
|
},
|
|
@@ -82,6 +87,7 @@ var PROVIDERS = [
|
|
|
82
87
|
detect: (env) => env.CIRCLECI === "true",
|
|
83
88
|
providerName: "CircleCI",
|
|
84
89
|
buildNumber: (env) => nonEmpty(env.CIRCLE_BUILD_NUM),
|
|
90
|
+
runId: (env) => nonEmpty(env.CIRCLE_WORKFLOW_ID ?? env.CIRCLE_BUILD_NUM),
|
|
85
91
|
runUrl: (env) => nonEmpty(env.CIRCLE_BUILD_URL),
|
|
86
92
|
prNumber: (env) => parsePositiveInt(env.CIRCLE_PR_NUMBER)
|
|
87
93
|
},
|
|
@@ -89,6 +95,7 @@ var PROVIDERS = [
|
|
|
89
95
|
detect: (env) => env.BUILDKITE === "true",
|
|
90
96
|
providerName: "Buildkite",
|
|
91
97
|
buildNumber: (env) => nonEmpty(env.BUILDKITE_BUILD_NUMBER),
|
|
98
|
+
runId: (env) => nonEmpty(env.BUILDKITE_BUILD_ID),
|
|
92
99
|
runUrl: (env) => nonEmpty(env.BUILDKITE_BUILD_URL),
|
|
93
100
|
prNumber: (env) => {
|
|
94
101
|
const raw = env.BUILDKITE_PULL_REQUEST;
|
|
@@ -104,6 +111,7 @@ var PROVIDERS = [
|
|
|
104
111
|
detect: (env) => Boolean(env.JENKINS_URL),
|
|
105
112
|
providerName: "Jenkins",
|
|
106
113
|
buildNumber: (env) => nonEmpty(env.BUILD_NUMBER),
|
|
114
|
+
runId: (env) => nonEmpty(env.BUILD_TAG ?? env.BUILD_NUMBER),
|
|
107
115
|
runUrl: (env) => nonEmpty(env.BUILD_URL)
|
|
108
116
|
// Jenkins has no standardized PR-number env var across its many PR
|
|
109
117
|
// plugins (Multibranch, GitHub Branch Source, etc.) — deliberately
|
|
@@ -113,6 +121,7 @@ var PROVIDERS = [
|
|
|
113
121
|
detect: (env) => env.TF_BUILD === "True" || env.TF_BUILD === "true",
|
|
114
122
|
providerName: "Azure Pipelines",
|
|
115
123
|
buildNumber: (env) => nonEmpty(env.BUILD_BUILDID),
|
|
124
|
+
runId: (env) => nonEmpty(env.BUILD_BUILDID),
|
|
116
125
|
runUrl: (env) => {
|
|
117
126
|
const collectionUri = env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI;
|
|
118
127
|
const project = env.SYSTEM_TEAMPROJECT;
|
|
@@ -128,6 +137,7 @@ var PROVIDERS = [
|
|
|
128
137
|
detect: (env) => Boolean(env.BITBUCKET_BUILD_NUMBER),
|
|
129
138
|
providerName: "Bitbucket Pipelines",
|
|
130
139
|
buildNumber: (env) => nonEmpty(env.BITBUCKET_BUILD_NUMBER),
|
|
140
|
+
runId: (env) => nonEmpty(env.BITBUCKET_BUILD_NUMBER),
|
|
131
141
|
runUrl: (env) => {
|
|
132
142
|
const origin = env.BITBUCKET_GIT_HTTP_ORIGIN;
|
|
133
143
|
if (!origin) {
|
|
@@ -149,6 +159,8 @@ function detectCi(env = process.env) {
|
|
|
149
159
|
if (runUrl !== void 0) result.ciRunUrl = runUrl;
|
|
150
160
|
const prNumber = provider.prNumber?.(env);
|
|
151
161
|
if (prNumber !== void 0) result.ciPrNumber = prNumber;
|
|
162
|
+
const runId = provider.runId?.(env);
|
|
163
|
+
if (runId !== void 0) result.ciRunId = runId;
|
|
152
164
|
return result;
|
|
153
165
|
}
|
|
154
166
|
if (ciInfo.name) {
|
|
@@ -256,6 +268,7 @@ function resolveConfig(options, deps = {}) {
|
|
|
256
268
|
const ciBuildNumber = options.ciBuildNumber ?? detectedCi.ciBuildNumber;
|
|
257
269
|
const ciRunUrl = options.ciRunUrl ?? detectedCi.ciRunUrl;
|
|
258
270
|
const ciPrNumber = options.ciPrNumber ?? detectedCi.ciPrNumber;
|
|
271
|
+
const runId = options.runId ?? firstEnv2("QUALFLARE_RUN_ID") ?? detectedCi.ciRunId ?? (0, import_node_crypto.randomUUID)();
|
|
259
272
|
return {
|
|
260
273
|
// `||` (truthy check), not `??`, for these three REQUIRED-non-empty wire
|
|
261
274
|
// fields — an explicit `''` option must not silently win over the
|
|
@@ -275,6 +288,7 @@ function resolveConfig(options, deps = {}) {
|
|
|
275
288
|
ciBuildNumber,
|
|
276
289
|
ciRunUrl,
|
|
277
290
|
ciPrNumber,
|
|
291
|
+
runId,
|
|
278
292
|
attachScreenshots: options.attachScreenshots ?? envBool("QUALFLARE_ATTACH_SCREENSHOTS") ?? true,
|
|
279
293
|
includeStepHooks: options.includeStepHooks ?? envBool("QUALFLARE_INCLUDE_STEP_HOOKS") ?? false,
|
|
280
294
|
maxAttachmentBytes: options.maxAttachmentBytes ?? envInt("QUALFLARE_MAX_ATTACHMENT_BYTES") ?? 15e5,
|
|
@@ -308,8 +322,8 @@ var logger = {
|
|
|
308
322
|
var fs2 = __toESM(require("fs"), 1);
|
|
309
323
|
var path2 = __toESM(require("path"), 1);
|
|
310
324
|
|
|
311
|
-
// src/formatter/video-
|
|
312
|
-
var
|
|
325
|
+
// src/formatter/video-writer.ts
|
|
326
|
+
var import_node_crypto2 = require("crypto");
|
|
313
327
|
var fs = __toESM(require("fs"), 1);
|
|
314
328
|
var path = __toESM(require("path"), 1);
|
|
315
329
|
var VIDEO_MIME_TYPES_BY_EXTENSION = {
|
|
@@ -338,7 +352,7 @@ function writeVideoAttachment(pending, outputDir, maxVideoBytes) {
|
|
|
338
352
|
logger.warn(`skipping video attachment "${pending.name}": unsupported video format.`);
|
|
339
353
|
return void 0;
|
|
340
354
|
}
|
|
341
|
-
const localVideoPath = `${(0,
|
|
355
|
+
const localVideoPath = `${(0, import_node_crypto2.randomUUID)()}${resolved.extension}`;
|
|
342
356
|
const destination = path.join(outputDir, localVideoPath);
|
|
343
357
|
if (pending.path !== void 0) {
|
|
344
358
|
let fileSize;
|
|
@@ -987,7 +1001,7 @@ function timestampMs(ts) {
|
|
|
987
1001
|
var os = __toESM(require("os"), 1);
|
|
988
1002
|
|
|
989
1003
|
// src/config/version.ts
|
|
990
|
-
var PACKAGE_VERSION = "0.
|
|
1004
|
+
var PACKAGE_VERSION = "0.3.0";
|
|
991
1005
|
|
|
992
1006
|
// src/formatter/collect-builder.ts
|
|
993
1007
|
function resolveOs(config) {
|
|
@@ -1010,7 +1024,8 @@ function buildCollectPayload(suites, config) {
|
|
|
1010
1024
|
metadata: {
|
|
1011
1025
|
version: PACKAGE_VERSION,
|
|
1012
1026
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1013
|
-
cliName: "qualflare-cucumberjs"
|
|
1027
|
+
cliName: "qualflare-cucumberjs",
|
|
1028
|
+
runId: config.runId
|
|
1014
1029
|
},
|
|
1015
1030
|
properties: config.properties,
|
|
1016
1031
|
suites,
|
|
@@ -1343,7 +1358,7 @@ var QualflareCucumberFormatter = class extends import_cucumber.Formatter {
|
|
|
1343
1358
|
}
|
|
1344
1359
|
}
|
|
1345
1360
|
fs3.mkdirSync(this.config.outputDir, { recursive: true });
|
|
1346
|
-
const outputPath = path4.join(this.config.outputDir, `${(0,
|
|
1361
|
+
const outputPath = path4.join(this.config.outputDir, `${(0, import_node_crypto3.randomUUID)()}.json`);
|
|
1347
1362
|
fs3.writeFileSync(outputPath, JSON.stringify(payload));
|
|
1348
1363
|
logger.info(
|
|
1349
1364
|
`wrote Collect payload to ${outputPath} \u2014 run \`qualflare-cli collect ${this.config.outputDir}\` to upload it.`
|