@qualflare/playwright 0.1.0 → 0.2.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/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/reporter/index.cjs +21 -6
- package/dist/reporter/index.cjs.map +1 -1
- package/dist/reporter/index.d.cts +2 -2
- package/dist/reporter/index.d.ts +2 -2
- package/dist/reporter/index.js +21 -6
- package/dist/reporter/index.js.map +1 -1
- package/dist/{resolve-config-CSjXFl7v.d.cts → resolve-config-CQe-oDpg.d.cts} +17 -0
- package/dist/{resolve-config-CSjXFl7v.d.ts → resolve-config-CQe-oDpg.d.ts} +17 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,12 @@ Every option has an environment-variable override, and everything has a sensible
|
|
|
105
105
|
[`docs/CONFIGURATION.md`](./docs/CONFIGURATION.md). There is no `token` option: this reporter makes
|
|
106
106
|
no requests, so it has no credential.
|
|
107
107
|
|
|
108
|
+
One option is worth calling out because it fails late: `environment` is matched against the
|
|
109
|
+
environment's **uid (slug)**, not its display name, so **Staging** in the UI is `staging` here. A
|
|
110
|
+
wrong value cannot fail at test time — the reporter makes no requests — so the run succeeds and
|
|
111
|
+
`collect` 404s afterwards. See
|
|
112
|
+
[the note in the configuration docs](./docs/CONFIGURATION.md#environment-is-matched-by-uid-not-display-name).
|
|
113
|
+
|
|
108
114
|
## Known limitations
|
|
109
115
|
|
|
110
116
|
- **Traces are not uploaded.** Playwright traces are `application/zip`, which Qualflare's attachment
|
|
@@ -113,9 +119,9 @@ no requests, so it has no credential.
|
|
|
113
119
|
- **`pw:api` and `fixture` steps are filtered out by default** (`includeApiSteps`) — a single
|
|
114
120
|
browser test emits hundreds, which buries the steps you actually wrote. A *failed* one is always
|
|
115
121
|
kept.
|
|
116
|
-
-
|
|
117
|
-
|
|
118
|
-
|
|
122
|
+
- **A stale `outputDir` is refused, not merged** — each report carries a `runId`, and `qf collect`
|
|
123
|
+
errors rather than merging files from two different runs. Needs `@qualflare/cli` v0.1.19+; older
|
|
124
|
+
CLIs merge as before.
|
|
119
125
|
- **`merge-reports` mode is not supported** in v0.1.0 — use the `outputDir` flow above rather than
|
|
120
126
|
Playwright's `blob` reporter.
|
|
121
127
|
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReporterDescription } from '@playwright/test';
|
|
2
|
-
import { L as LinkType, C as CasePriority, Q as QualflarePlaywrightOptions } from './resolve-config-
|
|
3
|
-
export { A as Attachment, a as Case, b as CaseStatus, c as Collect, F as FrameworkCategory, d as Label, e as Link, M as Metadata, N as NanosecondDuration, P as Parameter, f as Platform, R as ResolvedReporterConfig, S as Step, g as Suite } from './resolve-config-
|
|
2
|
+
import { L as LinkType, C as CasePriority, Q as QualflarePlaywrightOptions } from './resolve-config-CQe-oDpg.cjs';
|
|
3
|
+
export { A as Attachment, a as Case, b as CaseStatus, c as Collect, F as FrameworkCategory, d as Label, e as Link, M as Metadata, N as NanosecondDuration, P as Parameter, f as Platform, R as ResolvedReporterConfig, S as Step, g as Suite } from './resolve-config-CQe-oDpg.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Author-facing metadata API. Import it in a spec and annotate tests with
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReporterDescription } from '@playwright/test';
|
|
2
|
-
import { L as LinkType, C as CasePriority, Q as QualflarePlaywrightOptions } from './resolve-config-
|
|
3
|
-
export { A as Attachment, a as Case, b as CaseStatus, c as Collect, F as FrameworkCategory, d as Label, e as Link, M as Metadata, N as NanosecondDuration, P as Parameter, f as Platform, R as ResolvedReporterConfig, S as Step, g as Suite } from './resolve-config-
|
|
2
|
+
import { L as LinkType, C as CasePriority, Q as QualflarePlaywrightOptions } from './resolve-config-CQe-oDpg.js';
|
|
3
|
+
export { A as Attachment, a as Case, b as CaseStatus, c as Collect, F as FrameworkCategory, d as Label, e as Link, M as Metadata, N as NanosecondDuration, P as Parameter, f as Platform, R as ResolvedReporterConfig, S as Step, g as Suite } from './resolve-config-CQe-oDpg.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Author-facing metadata API. Import it in a spec and annotate tests with
|
package/dist/reporter/index.cjs
CHANGED
|
@@ -35,10 +35,13 @@ __export(reporter_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(reporter_exports);
|
|
36
36
|
|
|
37
37
|
// src/reporter/reporter.ts
|
|
38
|
-
var
|
|
38
|
+
var import_node_crypto3 = require("crypto");
|
|
39
39
|
var fs3 = __toESM(require("fs"), 1);
|
|
40
40
|
var path3 = __toESM(require("path"), 1);
|
|
41
41
|
|
|
42
|
+
// src/config/resolve-config.ts
|
|
43
|
+
var import_node_crypto = require("crypto");
|
|
44
|
+
|
|
42
45
|
// src/shared/constants.ts
|
|
43
46
|
var RESERVED_MESSAGE_MEDIA_TYPE = "application/vnd.qualflare.message+json";
|
|
44
47
|
var MAX_SUITES_PER_LAUNCH = 2e3;
|
|
@@ -68,6 +71,7 @@ var PROVIDERS = [
|
|
|
68
71
|
detect: (env) => env.GITHUB_ACTIONS === "true",
|
|
69
72
|
providerName: "GitHub Actions",
|
|
70
73
|
buildNumber: (env) => nonEmpty(env.GITHUB_RUN_NUMBER),
|
|
74
|
+
runId: (env) => nonEmpty(env.GITHUB_RUN_ID),
|
|
71
75
|
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,
|
|
72
76
|
prNumber: (env) => {
|
|
73
77
|
const match = /^refs\/pull\/(\d+)\/merge$/.exec(env.GITHUB_REF ?? "");
|
|
@@ -78,6 +82,7 @@ var PROVIDERS = [
|
|
|
78
82
|
detect: (env) => env.GITLAB_CI === "true",
|
|
79
83
|
providerName: "GitLab CI",
|
|
80
84
|
buildNumber: (env) => nonEmpty(env.CI_PIPELINE_IID),
|
|
85
|
+
runId: (env) => nonEmpty(env.CI_PIPELINE_ID),
|
|
81
86
|
runUrl: (env) => nonEmpty(env.CI_PIPELINE_URL),
|
|
82
87
|
prNumber: (env) => parsePositiveInt(env.CI_MERGE_REQUEST_IID)
|
|
83
88
|
},
|
|
@@ -85,6 +90,7 @@ var PROVIDERS = [
|
|
|
85
90
|
detect: (env) => env.CIRCLECI === "true",
|
|
86
91
|
providerName: "CircleCI",
|
|
87
92
|
buildNumber: (env) => nonEmpty(env.CIRCLE_BUILD_NUM),
|
|
93
|
+
runId: (env) => nonEmpty(env.CIRCLE_WORKFLOW_ID ?? env.CIRCLE_BUILD_NUM),
|
|
88
94
|
runUrl: (env) => nonEmpty(env.CIRCLE_BUILD_URL),
|
|
89
95
|
prNumber: (env) => parsePositiveInt(env.CIRCLE_PR_NUMBER)
|
|
90
96
|
},
|
|
@@ -92,6 +98,7 @@ var PROVIDERS = [
|
|
|
92
98
|
detect: (env) => env.BUILDKITE === "true",
|
|
93
99
|
providerName: "Buildkite",
|
|
94
100
|
buildNumber: (env) => nonEmpty(env.BUILDKITE_BUILD_NUMBER),
|
|
101
|
+
runId: (env) => nonEmpty(env.BUILDKITE_BUILD_ID),
|
|
95
102
|
runUrl: (env) => nonEmpty(env.BUILDKITE_BUILD_URL),
|
|
96
103
|
prNumber: (env) => {
|
|
97
104
|
const raw = env.BUILDKITE_PULL_REQUEST;
|
|
@@ -107,6 +114,7 @@ var PROVIDERS = [
|
|
|
107
114
|
detect: (env) => Boolean(env.JENKINS_URL),
|
|
108
115
|
providerName: "Jenkins",
|
|
109
116
|
buildNumber: (env) => nonEmpty(env.BUILD_NUMBER),
|
|
117
|
+
runId: (env) => nonEmpty(env.BUILD_TAG ?? env.BUILD_NUMBER),
|
|
110
118
|
runUrl: (env) => nonEmpty(env.BUILD_URL)
|
|
111
119
|
// Jenkins has no standardized PR-number env var across its many PR
|
|
112
120
|
// plugins (Multibranch, GitHub Branch Source, etc.) — deliberately
|
|
@@ -116,6 +124,7 @@ var PROVIDERS = [
|
|
|
116
124
|
detect: (env) => env.TF_BUILD === "True" || env.TF_BUILD === "true",
|
|
117
125
|
providerName: "Azure Pipelines",
|
|
118
126
|
buildNumber: (env) => nonEmpty(env.BUILD_BUILDID),
|
|
127
|
+
runId: (env) => nonEmpty(env.BUILD_BUILDID),
|
|
119
128
|
runUrl: (env) => {
|
|
120
129
|
const collectionUri = env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI;
|
|
121
130
|
const project = env.SYSTEM_TEAMPROJECT;
|
|
@@ -131,6 +140,7 @@ var PROVIDERS = [
|
|
|
131
140
|
detect: (env) => Boolean(env.BITBUCKET_BUILD_NUMBER),
|
|
132
141
|
providerName: "Bitbucket Pipelines",
|
|
133
142
|
buildNumber: (env) => nonEmpty(env.BITBUCKET_BUILD_NUMBER),
|
|
143
|
+
runId: (env) => nonEmpty(env.BITBUCKET_BUILD_NUMBER),
|
|
134
144
|
runUrl: (env) => {
|
|
135
145
|
const origin = env.BITBUCKET_GIT_HTTP_ORIGIN;
|
|
136
146
|
if (!origin) {
|
|
@@ -152,6 +162,8 @@ function detectCi(env = process.env) {
|
|
|
152
162
|
if (runUrl !== void 0) result.ciRunUrl = runUrl;
|
|
153
163
|
const prNumber = provider.prNumber?.(env);
|
|
154
164
|
if (prNumber !== void 0) result.ciPrNumber = prNumber;
|
|
165
|
+
const runId = provider.runId?.(env);
|
|
166
|
+
if (runId !== void 0) result.ciRunId = runId;
|
|
155
167
|
return result;
|
|
156
168
|
}
|
|
157
169
|
if (ciInfo.name) {
|
|
@@ -241,6 +253,7 @@ function resolveConfig(options, deps = {}) {
|
|
|
241
253
|
const ciBuildNumber = options.ciBuildNumber ?? detectedCi.ciBuildNumber;
|
|
242
254
|
const ciRunUrl = options.ciRunUrl ?? detectedCi.ciRunUrl;
|
|
243
255
|
const ciPrNumber = options.ciPrNumber ?? detectedCi.ciPrNumber;
|
|
256
|
+
const runId = options.runId ?? firstEnv2("QUALFLARE_RUN_ID") ?? detectedCi.ciRunId ?? (0, import_node_crypto.randomUUID)();
|
|
244
257
|
return {
|
|
245
258
|
// `||` (truthy check), not `??`, for these three REQUIRED-non-empty wire
|
|
246
259
|
// fields — an explicit `''` option must not silently win over the
|
|
@@ -260,6 +273,7 @@ function resolveConfig(options, deps = {}) {
|
|
|
260
273
|
ciBuildNumber,
|
|
261
274
|
ciRunUrl,
|
|
262
275
|
ciPrNumber,
|
|
276
|
+
runId,
|
|
263
277
|
attachScreenshots: options.attachScreenshots ?? envBool("QUALFLARE_ATTACH_SCREENSHOTS") ?? true,
|
|
264
278
|
includeApiSteps: options.includeApiSteps ?? envBool("QUALFLARE_INCLUDE_API_STEPS") ?? false,
|
|
265
279
|
maxAttachmentBytes: options.maxAttachmentBytes ?? envInt("QUALFLARE_MAX_ATTACHMENT_BYTES") ?? 15e5,
|
|
@@ -295,7 +309,7 @@ var fs2 = __toESM(require("fs"), 1);
|
|
|
295
309
|
// src/reporter/video-writer.ts
|
|
296
310
|
var fs = __toESM(require("fs"), 1);
|
|
297
311
|
var path = __toESM(require("path"), 1);
|
|
298
|
-
var
|
|
312
|
+
var import_node_crypto2 = require("crypto");
|
|
299
313
|
var VIDEO_MIME_TYPES_BY_EXTENSION = {
|
|
300
314
|
".mp4": "video/mp4",
|
|
301
315
|
".webm": "video/webm",
|
|
@@ -321,7 +335,7 @@ function copyVideoAttachment(filePath, outputDir, maxVideoBytes) {
|
|
|
321
335
|
);
|
|
322
336
|
return void 0;
|
|
323
337
|
}
|
|
324
|
-
const localVideoPath = `${(0,
|
|
338
|
+
const localVideoPath = `${(0, import_node_crypto2.randomUUID)()}${ext}`;
|
|
325
339
|
try {
|
|
326
340
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
327
341
|
fs.copyFileSync(filePath, path.join(outputDir, localVideoPath));
|
|
@@ -722,7 +736,7 @@ function buildCase(test, config, attachmentsByResult, budget) {
|
|
|
722
736
|
var os = __toESM(require("os"), 1);
|
|
723
737
|
|
|
724
738
|
// src/config/version.ts
|
|
725
|
-
var PACKAGE_VERSION = "0.
|
|
739
|
+
var PACKAGE_VERSION = "0.2.0";
|
|
726
740
|
|
|
727
741
|
// src/reporter/collect-builder.ts
|
|
728
742
|
function resolveOs(config) {
|
|
@@ -751,7 +765,8 @@ function buildCollectPayload(suites, config, browsers = []) {
|
|
|
751
765
|
metadata: {
|
|
752
766
|
version: PACKAGE_VERSION,
|
|
753
767
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
754
|
-
cliName: "qualflare-playwright"
|
|
768
|
+
cliName: "qualflare-playwright",
|
|
769
|
+
runId: config.runId
|
|
755
770
|
},
|
|
756
771
|
properties: config.properties,
|
|
757
772
|
suites,
|
|
@@ -901,7 +916,7 @@ var QualflareReporter = class {
|
|
|
901
916
|
}
|
|
902
917
|
const outputDir = this.resolveOutputDir(config.outputDir);
|
|
903
918
|
fs3.mkdirSync(outputDir, { recursive: true });
|
|
904
|
-
const outputPath = path3.join(outputDir, `${(0,
|
|
919
|
+
const outputPath = path3.join(outputDir, `${(0, import_node_crypto3.randomUUID)()}.json`);
|
|
905
920
|
fs3.writeFileSync(outputPath, JSON.stringify(collect));
|
|
906
921
|
logger.info(`wrote Collect payload to ${outputPath} \u2014 run \`qualflare-cli collect ${outputDir}\` to upload it.`);
|
|
907
922
|
}
|