@piwitests/reporter 0.55.0 → 0.57.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/dist/cli/index.js +1392 -1377
- package/dist/global-setup-module.js +32 -22
- package/dist/index.d.ts +9 -0
- package/dist/index.js +555 -347
- package/dist/internal/capture/capture-fixtures.d.ts +2 -1
- package/dist/internal/capture/capture-fixtures.js +1035 -980
- package/dist/internal/capture/locator-healing.js +70 -26
- package/dist/internal/capture/pick-on-failure.js +84 -54
- package/package.json +1 -1
|
@@ -35,7 +35,7 @@ __export(global_setup_module_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(global_setup_module_exports);
|
|
36
36
|
|
|
37
37
|
// src/public/global-setup.ts
|
|
38
|
-
var
|
|
38
|
+
var path7 = __toESM(require("path"));
|
|
39
39
|
|
|
40
40
|
// src/internal/support/errors.ts
|
|
41
41
|
function errorMessage(error) {
|
|
@@ -274,11 +274,15 @@ var HttpClient = class {
|
|
|
274
274
|
* @param logger Prefixed logger for verbose diagnostics.
|
|
275
275
|
* @param timeout Socket inactivity timeout in ms (default 30s), so a hung
|
|
276
276
|
* server fails fast rather than stalling the reporter.
|
|
277
|
+
* @param uploadTimeout Socket inactivity timeout of a multipart upload in ms
|
|
278
|
+
* (default 10 min): the dashboard answers one only once it
|
|
279
|
+
* has stored every report and trace in it.
|
|
277
280
|
*/
|
|
278
|
-
constructor(serverUrl, logger = new Logger(), timeout = 3e4) {
|
|
281
|
+
constructor(serverUrl, logger = new Logger(), timeout = 3e4, uploadTimeout = 10 * 60 * 1e3) {
|
|
279
282
|
this.serverUrl = serverUrl;
|
|
280
283
|
this.logger = logger;
|
|
281
284
|
this.timeout = timeout;
|
|
285
|
+
this.uploadTimeout = uploadTimeout;
|
|
282
286
|
/** Requests in flight, so `close` can abort them. */
|
|
283
287
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
284
288
|
/** Set by `close`: every later request fails with this reason. */
|
|
@@ -426,7 +430,7 @@ var HttpClient = class {
|
|
|
426
430
|
/** Send a multipart form-data POST request. Used for report and trace uploads. */
|
|
427
431
|
async postFormData(pathname, form, auth) {
|
|
428
432
|
const headers = form.getHeaders();
|
|
429
|
-
const res = await this.request("POST", pathname, { headers, form, auth });
|
|
433
|
+
const res = await this.request("POST", pathname, { headers, form, auth, timeout: this.uploadTimeout });
|
|
430
434
|
if (res.status < 200 || res.status >= 300) {
|
|
431
435
|
this.logger.debugError(`Response: ${res.text}`);
|
|
432
436
|
const detail = parseErrorMessage(res.text);
|
|
@@ -479,8 +483,9 @@ var HttpClient = class {
|
|
|
479
483
|
this.inFlight.add(req);
|
|
480
484
|
req.on("close", () => this.inFlight.delete(req));
|
|
481
485
|
req.on("error", reject);
|
|
482
|
-
|
|
483
|
-
|
|
486
|
+
const timeout = opts.timeout ?? this.timeout;
|
|
487
|
+
req.setTimeout(timeout, () => {
|
|
488
|
+
req.destroy(new Error(`Request to ${pathname} timed out after ${timeout}ms`));
|
|
484
489
|
});
|
|
485
490
|
if (opts.form) {
|
|
486
491
|
opts.form.on("error", (error) => req.destroy(error));
|
|
@@ -556,6 +561,16 @@ function resolveShardInfo(config, env = process.env) {
|
|
|
556
561
|
|
|
557
562
|
// src/internal/collect/metadata-collector.ts
|
|
558
563
|
var import_node_child_process = require("child_process");
|
|
564
|
+
|
|
565
|
+
// src/internal/support/test-paths.ts
|
|
566
|
+
var path2 = __toESM(require("path"));
|
|
567
|
+
function configDirFromConfig(config) {
|
|
568
|
+
if (config?.configFile) return path2.dirname(config.configFile);
|
|
569
|
+
if (config?.rootDir) return config.rootDir;
|
|
570
|
+
return process.cwd();
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// src/internal/collect/metadata-collector.ts
|
|
559
574
|
var DETACHED_HEAD = "HEAD";
|
|
560
575
|
function resolveScmBranch(env, gitBranch) {
|
|
561
576
|
const pick = (...names) => {
|
|
@@ -585,22 +600,22 @@ function normalizeRef(ref) {
|
|
|
585
600
|
}
|
|
586
601
|
|
|
587
602
|
// src/internal/support/setup-file.ts
|
|
588
|
-
var
|
|
603
|
+
var path3 = __toESM(require("path"));
|
|
589
604
|
var os3 = __toESM(require("os"));
|
|
590
605
|
var fs2 = __toESM(require("fs"));
|
|
591
606
|
function getSetupFilePath(projectName) {
|
|
592
|
-
return
|
|
607
|
+
return path3.join(os3.tmpdir(), `piwi-dashboard-setup-${hashForProject(projectName)}.json`);
|
|
593
608
|
}
|
|
594
609
|
|
|
595
610
|
// src/internal/support/aria-sampling.ts
|
|
596
|
-
var
|
|
611
|
+
var path4 = __toESM(require("path"));
|
|
597
612
|
var os4 = __toESM(require("os"));
|
|
598
613
|
var fs3 = __toESM(require("fs"));
|
|
599
614
|
function ariaSampleIdentity(filePath, title) {
|
|
600
615
|
return `${filePath}\0${title}`;
|
|
601
616
|
}
|
|
602
617
|
function getAriaSampleFilePath(projectName) {
|
|
603
|
-
return
|
|
618
|
+
return path4.join(os4.tmpdir(), `piwi-dashboard-aria-sample-${hashForProject(projectName)}.json`);
|
|
604
619
|
}
|
|
605
620
|
function writeAriaSampleFile(projectName, identities) {
|
|
606
621
|
try {
|
|
@@ -765,7 +780,7 @@ async function checkBaseUrls(config, options = {}) {
|
|
|
765
780
|
|
|
766
781
|
// src/internal/manifest/collect.ts
|
|
767
782
|
var fs4 = __toESM(require("fs"));
|
|
768
|
-
var
|
|
783
|
+
var path5 = __toESM(require("path"));
|
|
769
784
|
|
|
770
785
|
// src/internal/transport/backend-request.ts
|
|
771
786
|
var http2 = __toESM(require("http"));
|
|
@@ -799,7 +814,7 @@ function hasInstrumentationHeader(headers) {
|
|
|
799
814
|
return INSTRUMENTATION_HEADERS.some((h) => get(h) != null && get(h) !== "");
|
|
800
815
|
}
|
|
801
816
|
function readCommittedManifest(configDir) {
|
|
802
|
-
const file =
|
|
817
|
+
const file = path5.join(configDir, COMMITTED_MANIFEST_FILE);
|
|
803
818
|
try {
|
|
804
819
|
if (!fs4.existsSync(file)) return null;
|
|
805
820
|
return parseManifestJson(fs4.readFileSync(file, "utf8"));
|
|
@@ -807,18 +822,13 @@ function readCommittedManifest(configDir) {
|
|
|
807
822
|
return null;
|
|
808
823
|
}
|
|
809
824
|
}
|
|
810
|
-
function configDirFromConfig(config) {
|
|
811
|
-
if (config?.configFile) return path4.dirname(config.configFile);
|
|
812
|
-
if (config?.rootDir) return config.rootDir;
|
|
813
|
-
return process.cwd();
|
|
814
|
-
}
|
|
815
825
|
var INSTRUMENTATION_FETCH_TIMEOUT_MS = 5e3;
|
|
816
826
|
var MAX_MANIFEST_BYTES = 4 * 1024 * 1024;
|
|
817
827
|
function instrumentationManifestUrls(baseUrl) {
|
|
818
828
|
const base = new URL(baseUrl);
|
|
819
829
|
const root = new URL(INSTRUMENTATION_MANIFEST_PATH, base).toString();
|
|
820
|
-
const
|
|
821
|
-
return
|
|
830
|
+
const path8 = base.pathname.replace(/\/+$/, "");
|
|
831
|
+
return path8 ? [new URL(`${path8}${INSTRUMENTATION_MANIFEST_PATH}`, base).toString(), root] : [root];
|
|
822
832
|
}
|
|
823
833
|
async function fetchInstrumentationManifest(baseUrl, fetchImpl = fetch) {
|
|
824
834
|
try {
|
|
@@ -852,7 +862,7 @@ async function uploadManifest(httpClient, auth, projectId, upload, logger) {
|
|
|
852
862
|
// src/internal/collect/source-checksums.ts
|
|
853
863
|
var crypto2 = __toESM(require("crypto"));
|
|
854
864
|
var fs5 = __toESM(require("fs"));
|
|
855
|
-
var
|
|
865
|
+
var path6 = __toESM(require("path"));
|
|
856
866
|
|
|
857
867
|
// src/internal/collect/server-coverage.ts
|
|
858
868
|
var DEFAULT_COLLECTOR_LIMITS = {
|
|
@@ -874,14 +884,14 @@ function baseUrlsFromConfig(config) {
|
|
|
874
884
|
// src/public/global-setup.ts
|
|
875
885
|
function createGlobalSetup(options, userSetup) {
|
|
876
886
|
return async function globalSetupFn(config) {
|
|
877
|
-
const piwiReporterPath =
|
|
887
|
+
const piwiReporterPath = path7.resolve(__dirname, "./index.js");
|
|
878
888
|
let inlineReporterOptions = {};
|
|
879
889
|
if (Array.isArray(config?.reporter)) {
|
|
880
890
|
for (const r of config.reporter) {
|
|
881
891
|
if (!Array.isArray(r) || typeof r[0] !== "string") continue;
|
|
882
892
|
const isPiwi = r[0].toLowerCase().includes("piwi") || (() => {
|
|
883
893
|
try {
|
|
884
|
-
return
|
|
894
|
+
return path7.resolve(require.resolve(r[0])) === piwiReporterPath;
|
|
885
895
|
} catch {
|
|
886
896
|
return false;
|
|
887
897
|
}
|
|
@@ -917,7 +927,7 @@ function createGlobalSetup(options, userSetup) {
|
|
|
917
927
|
if (!Array.isArray(r) || typeof r[0] !== "string") return false;
|
|
918
928
|
if (r[0].toLowerCase().includes("piwi")) return true;
|
|
919
929
|
try {
|
|
920
|
-
return
|
|
930
|
+
return path7.resolve(require.resolve(r[0])) === piwiReporterPath;
|
|
921
931
|
} catch {
|
|
922
932
|
return false;
|
|
923
933
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -451,6 +451,8 @@ declare class PiwiDashboardReporter {
|
|
|
451
451
|
private reportedTestIds;
|
|
452
452
|
/** Per-test attempt history, keyed by `test.id`; snapshotted onto every attempt's payload. */
|
|
453
453
|
private attemptsByTest;
|
|
454
|
+
/** The folder test files are named relative to: the Playwright config's, set in `onBegin`. */
|
|
455
|
+
private testPathBase;
|
|
454
456
|
/** Derived in `onBegin`, once the shard is known. */
|
|
455
457
|
private instanceId;
|
|
456
458
|
private shardInfo;
|
|
@@ -504,6 +506,13 @@ declare class PiwiDashboardReporter {
|
|
|
504
506
|
static wrapConfig: typeof wrapConfig;
|
|
505
507
|
static createGlobalSetup: typeof createGlobalSetup;
|
|
506
508
|
constructor(rawOptions?: Record<string, any>);
|
|
509
|
+
/**
|
|
510
|
+
* Playwright reporter hook: whether this reporter writes the run's progress to
|
|
511
|
+
* the terminal. It does not (it prints only its own `[Piwi Dashboard]` lines),
|
|
512
|
+
* so Playwright keeps its own terminal reporter when Piwi is the only one
|
|
513
|
+
* configured.
|
|
514
|
+
*/
|
|
515
|
+
printsToStdio(): boolean;
|
|
507
516
|
/** Playwright reporter hook: called once at the start of the test run */
|
|
508
517
|
onBegin(config: FullConfig, suite: Suite): void;
|
|
509
518
|
/** Playwright reporter hook: called when an individual test begins */
|