@piwitests/reporter 0.12.0 → 0.13.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.
Files changed (77) hide show
  1. package/dist/global-setup-module.d.ts +2 -1
  2. package/dist/global-setup-module.js +432 -3
  3. package/dist/index.d.ts +204 -8
  4. package/dist/index.js +4724 -23
  5. package/dist/internal/capture/attachments.d.ts +8 -3
  6. package/dist/internal/capture/attachments.js +46 -21
  7. package/dist/internal/capture/capture-fixtures.d.ts +16 -14
  8. package/dist/internal/capture/capture-fixtures.js +2211 -971
  9. package/dist/internal/capture/inspect-on-failure.d.ts +50 -0
  10. package/dist/internal/capture/inspect-on-failure.js +66 -0
  11. package/dist/internal/capture/locator-healing.d.ts +33 -190
  12. package/dist/internal/capture/locator-healing.js +599 -815
  13. package/dist/internal/capture/pick-on-failure.d.ts +198 -0
  14. package/dist/internal/capture/pick-on-failure.js +1203 -0
  15. package/package.json +9 -4
  16. package/dist/internal/collect/error-text.d.ts +0 -18
  17. package/dist/internal/collect/error-text.js +0 -79
  18. package/dist/internal/collect/metadata-collector.d.ts +0 -32
  19. package/dist/internal/collect/metadata-collector.js +0 -246
  20. package/dist/internal/collect/skip-classify.d.ts +0 -27
  21. package/dist/internal/collect/skip-classify.js +0 -40
  22. package/dist/internal/collect/step-analyzer.d.ts +0 -103
  23. package/dist/internal/collect/step-analyzer.js +0 -221
  24. package/dist/internal/config/env.d.ts +0 -46
  25. package/dist/internal/config/env.js +0 -162
  26. package/dist/internal/files/compression.d.ts +0 -5
  27. package/dist/internal/files/compression.js +0 -69
  28. package/dist/internal/files/file-handler.d.ts +0 -38
  29. package/dist/internal/files/file-handler.js +0 -207
  30. package/dist/internal/streaming/crash-recovery.d.ts +0 -23
  31. package/dist/internal/streaming/crash-recovery.js +0 -106
  32. package/dist/internal/streaming/stream-buffer.d.ts +0 -17
  33. package/dist/internal/streaming/stream-buffer.js +0 -102
  34. package/dist/internal/streaming/stream-manager.d.ts +0 -88
  35. package/dist/internal/streaming/stream-manager.js +0 -395
  36. package/dist/internal/submit/run-submitter.d.ts +0 -67
  37. package/dist/internal/submit/run-submitter.js +0 -190
  38. package/dist/internal/submit/serializer.d.ts +0 -45
  39. package/dist/internal/submit/serializer.js +0 -108
  40. package/dist/internal/submit/uploader.d.ts +0 -89
  41. package/dist/internal/submit/uploader.js +0 -226
  42. package/dist/internal/support/ci.d.ts +0 -2
  43. package/dist/internal/support/ci.js +0 -32
  44. package/dist/internal/support/cli-filters.d.ts +0 -1
  45. package/dist/internal/support/cli-filters.js +0 -51
  46. package/dist/internal/support/errors.d.ts +0 -8
  47. package/dist/internal/support/errors.js +0 -15
  48. package/dist/internal/support/instance-id.d.ts +0 -4
  49. package/dist/internal/support/instance-id.js +0 -48
  50. package/dist/internal/support/limiter.d.ts +0 -2
  51. package/dist/internal/support/limiter.js +0 -27
  52. package/dist/internal/support/logger.d.ts +0 -26
  53. package/dist/internal/support/logger.js +0 -43
  54. package/dist/internal/support/reporter-version.d.ts +0 -2
  55. package/dist/internal/support/reporter-version.js +0 -54
  56. package/dist/internal/support/setup-file.d.ts +0 -13
  57. package/dist/internal/support/setup-file.js +0 -61
  58. package/dist/internal/support/source-snippet.d.ts +0 -12
  59. package/dist/internal/support/source-snippet.js +0 -97
  60. package/dist/internal/support/worker-index.d.ts +0 -7
  61. package/dist/internal/support/worker-index.js +0 -14
  62. package/dist/internal/transport/http-client.d.ts +0 -52
  63. package/dist/internal/transport/http-client.js +0 -201
  64. package/dist/public/config-wrapper.d.ts +0 -21
  65. package/dist/public/config-wrapper.js +0 -64
  66. package/dist/public/global-setup.d.ts +0 -13
  67. package/dist/public/global-setup.js +0 -146
  68. package/dist/public/options.d.ts +0 -86
  69. package/dist/public/options.js +0 -2
  70. package/dist/public/reporter.d.ts +0 -68
  71. package/dist/public/reporter.js +0 -376
  72. package/dist/types/collected.d.ts +0 -97
  73. package/dist/types/collected.js +0 -10
  74. package/dist/types/wire.d.ts +0 -176
  75. package/dist/types/wire.js +0 -14
  76. package/dist/types.d.ts +0 -11
  77. package/dist/types.js +0 -27
@@ -1,64 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.wrapConfig = wrapConfig;
4
- const env_js_1 = require("../internal/config/env.js");
5
- const PIWI_MODULE = '@piwitests/reporter';
6
- function isPiwiReporterEntry(entry) {
7
- if (typeof entry === 'string')
8
- return entry.toLowerCase().includes('piwi');
9
- if (Array.isArray(entry) && typeof entry[0] === 'string')
10
- return entry[0].toLowerCase().includes('piwi');
11
- return false;
12
- }
13
- function injectReporter(reporter, piwiOptions) {
14
- const piwiEntry = piwiOptions ? [PIWI_MODULE, piwiOptions] : [PIWI_MODULE];
15
- if (!reporter)
16
- return [piwiEntry];
17
- if (Array.isArray(reporter)) {
18
- if (reporter.some(isPiwiReporterEntry))
19
- return reporter;
20
- return [...reporter, piwiEntry];
21
- }
22
- return [[reporter], piwiEntry];
23
- }
24
- function resolveSetupModule() {
25
- try {
26
- return require.resolve('../global-setup-module.js');
27
- }
28
- catch {
29
- return require.resolve('../global-setup-module.ts');
30
- }
31
- }
32
- /**
33
- * Wrap a Playwright config to auto-inject the Piwi Dashboard reporter and
34
- * chain its global setup module. Returns a new config object (shallow merge)
35
- * without mutating the original.
36
- *
37
- * The `globalSetup` field is set to a `string` (or `string[]` if the user
38
- * already has a global setup) referencing the Piwi global setup module,
39
- * which registers the run on the server. The original setup path(s) are
40
- * preserved and executed first.
41
- *
42
- * Playwright options required in `globalSetup` are forwarded via `PIWI_*`
43
- * environment variables (see `applyOptionsToEnv` in `config.ts` for the
44
- * supported set — `serverUrl`, `projectName`, `verbose`, `apiKey`,
45
- * `username`, `password`, `environment`, `label`, `runLabel`).
46
- *
47
- * @param config The user's Playwright config.
48
- * @param piwiOptions Optional Piwi Dashboard options (serverUrl, projectName, …).
49
- */
50
- function wrapConfig(config, piwiOptions) {
51
- if (piwiOptions)
52
- (0, env_js_1.applyOptionsToEnv)(piwiOptions);
53
- const globalSetupModules = [];
54
- if (config.globalSetup) {
55
- const orig = Array.isArray(config.globalSetup) ? config.globalSetup : [config.globalSetup];
56
- globalSetupModules.push(...orig);
57
- }
58
- globalSetupModules.push(resolveSetupModule());
59
- return {
60
- ...config,
61
- reporter: injectReporter(config.reporter, piwiOptions),
62
- globalSetup: globalSetupModules.length === 1 ? globalSetupModules[0] : globalSetupModules,
63
- };
64
- }
@@ -1,13 +0,0 @@
1
- import type { PiwiDashboardOptions } from './options.js';
2
- /**
3
- * Create a Playwright `globalSetup` function that registers a test run on the
4
- * Piwi Dashboard server at the start of the run. An optional `userSetup` is
5
- * called afterward so existing setup logic is preserved.
6
- *
7
- * The server-run ID and a one-time token are written to a temp file so the
8
- * reporter instance can pick them up during the streaming handshake.
9
- *
10
- * @param options Piwi Dashboard options (uses `serverUrl`, `projectName`, …).
11
- * @param userSetup An existing global setup to chain after the Piwi registration.
12
- */
13
- export declare function createGlobalSetup(options?: PiwiDashboardOptions, userSetup?: (config: any) => any): (config: any) => Promise<any>;
@@ -1,146 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.createGlobalSetup = createGlobalSetup;
37
- const path = __importStar(require("node:path"));
38
- const errors_js_1 = require("../internal/support/errors.js");
39
- const fs = __importStar(require("node:fs"));
40
- const env_js_1 = require("../internal/config/env.js");
41
- const http_client_js_1 = require("../internal/transport/http-client.js");
42
- const logger_js_1 = require("../internal/support/logger.js");
43
- const instance_id_js_1 = require("../internal/support/instance-id.js");
44
- const ci_js_1 = require("../internal/support/ci.js");
45
- const setup_file_js_1 = require("../internal/support/setup-file.js");
46
- /**
47
- * Create a Playwright `globalSetup` function that registers a test run on the
48
- * Piwi Dashboard server at the start of the run. An optional `userSetup` is
49
- * called afterward so existing setup logic is preserved.
50
- *
51
- * The server-run ID and a one-time token are written to a temp file so the
52
- * reporter instance can pick them up during the streaming handshake.
53
- *
54
- * @param options Piwi Dashboard options (uses `serverUrl`, `projectName`, …).
55
- * @param userSetup An existing global setup to chain after the Piwi registration.
56
- */
57
- function createGlobalSetup(options, userSetup) {
58
- return async function globalSetupFn(config) {
59
- // This module compiles to `dist/public/global-setup.js`; the package entry
60
- // point is `dist/index.js`, one level up.
61
- const piwiReporterPath = path.resolve(__dirname, '../index.js');
62
- // Extract options from the Piwi reporter entry in the Playwright config so
63
- // that serverUrl / projectName etc. set inline in the reporters array are
64
- // visible here without requiring PIWI_* env vars or a separate wrapConfig call.
65
- let inlineReporterOptions = {};
66
- if (Array.isArray(config?.reporter)) {
67
- for (const r of config.reporter) {
68
- if (!Array.isArray(r) || typeof r[0] !== 'string')
69
- continue;
70
- const isPiwi = r[0].toLowerCase().includes('piwi') ||
71
- (() => {
72
- try {
73
- return path.resolve(require.resolve(r[0])) === piwiReporterPath;
74
- }
75
- catch {
76
- return false;
77
- }
78
- })();
79
- if (isPiwi && r[1] && typeof r[1] === 'object') {
80
- inlineReporterOptions = r[1];
81
- break;
82
- }
83
- }
84
- }
85
- const opts = (0, env_js_1.resolveOptions)({ ...inlineReporterOptions, ...options });
86
- const logger = new logger_js_1.Logger(opts.verbose ?? false);
87
- if (opts.enabled === false || !opts.serverUrl) {
88
- logger.info('Not enabled — set PIWI_DASHBOARD_URL or serverUrl to enable.');
89
- if (userSetup)
90
- return userSetup(config);
91
- return;
92
- }
93
- const hasPiwi = Object.keys(inlineReporterOptions).length > 0 ||
94
- (Array.isArray(config?.reporter) &&
95
- config.reporter.some((r) => {
96
- if (!Array.isArray(r) || typeof r[0] !== 'string')
97
- return false;
98
- if (r[0].toLowerCase().includes('piwi'))
99
- return true;
100
- try {
101
- return path.resolve(require.resolve(r[0])) === piwiReporterPath;
102
- }
103
- catch {
104
- return false;
105
- }
106
- }));
107
- if (!hasPiwi) {
108
- logger.debug('Not reporting — Piwi is not in the Playwright reporters list.');
109
- if (userSetup)
110
- return userSetup(config);
111
- return;
112
- }
113
- const httpClient = new http_client_js_1.HttpClient(opts.serverUrl, logger);
114
- try {
115
- const auth = await httpClient.resolveAuth(opts);
116
- const runLabel = opts.runLabel || (0, ci_js_1.detectCiRunLabel)();
117
- // Detect shard info from Playwright config (--shard=1/3)
118
- const pwShard = config.shard;
119
- const shardIndex = pwShard?.current;
120
- const shardTotal = pwShard?.total;
121
- const response = await httpClient.postJSON('/api/test-runs/setup', {
122
- projectName: opts.projectName,
123
- projectDescription: opts.projectDescription,
124
- environment: opts.environment || null,
125
- label: opts.label || null,
126
- startTime: new Date().toISOString(),
127
- instanceId: (0, instance_id_js_1.computeInstanceId)(opts.projectName, runLabel),
128
- shardIndex,
129
- shardTotal,
130
- }, auth);
131
- if (response?.runId && response?.setupToken) {
132
- fs.writeFileSync((0, setup_file_js_1.getSetupFilePath)(opts.projectName), JSON.stringify({
133
- runId: response.runId,
134
- setupToken: response.setupToken,
135
- projectName: opts.projectName,
136
- }));
137
- logger.debug(`Global setup: initialising run #${response.runId}`);
138
- }
139
- }
140
- catch (error) {
141
- logger.warn(`Could not register global setup: ${(0, errors_js_1.errorMessage)(error)}`);
142
- }
143
- if (userSetup)
144
- return userSetup(config);
145
- };
146
- }
@@ -1,86 +0,0 @@
1
- import type { PlaywrightTestConfig } from '@playwright/test';
2
- export type { PlaywrightTestConfig } from '@playwright/test';
3
- /**
4
- * Playwright shard info — mirrors `config.shard` shape.
5
- *
6
- * Internal shape: it is NOT re-exported from the package entry point, but it
7
- * lives here next to the configuration types because it describes the same
8
- * `config.shard` surface the options come from. May move to `types/wire.ts`.
9
- */
10
- export interface ShardInfo {
11
- current: number;
12
- total: number;
13
- }
14
- /** Options for configuring the Piwi Dashboard reporter */
15
- export interface PiwiDashboardOptions extends PlaywrightTestConfig {
16
- /** Explicitly enable or disable the reporter. Defaults to `true` when `serverUrl` is set. Set to `false` to disable even if `serverUrl` is provided. */
17
- enabled?: boolean;
18
- /** URL of the Piwi Dashboard server */
19
- serverUrl?: string;
20
- /** Name of the project to report results under. Defaults to `'default-project'`. */
21
- projectName?: string;
22
- /** Optional description of the project */
23
- projectDescription?: string;
24
- /** Upload trace files to the dashboard. Defaults to `true`. */
25
- uploadTraces?: boolean;
26
- /** Upload the Playwright HTML report. Defaults to `true`. */
27
- uploadReport?: boolean;
28
- /** Upload each test's trace and attachments as soon as the test finishes (streaming mode only). Defaults to `true`. */
29
- liveFileUploads?: boolean;
30
- /** Auto-collect git commit, branch, author. Defaults to `true`. */
31
- collectScmInfo?: boolean;
32
- /** Auto-collect CI environment info. Defaults to `true`. */
33
- collectCiInfo?: boolean;
34
- /** Collect step timings, network requests and web vitals. Defaults to `true`. */
35
- collectPerformanceMetrics?: boolean;
36
- /**
37
- * Capture per-action locator snapshots that power failure-time healing
38
- * suggestions. Adds a small per-action cost (one DOM read, sometimes an ARIA
39
- * snapshot) in the test worker. Defaults to `true`; automatically disabled
40
- * when `collectPerformanceMetrics` is `false` (the reporter discards the data
41
- * in that case anyway). Can also be forced off with `PIWI_CAPTURE_LOCATORS=false`.
42
- */
43
- captureLocators?: boolean;
44
- /**
45
- * Capture the page's state at test end (URL, history state, localStorage/
46
- * sessionStorage key names + value lengths, cookie names + flags). Values of
47
- * storage entries and cookies are never captured. Defaults to `true`;
48
- * automatically disabled when `collectPerformanceMetrics` is `false`. Can
49
- * also be forced off with `PIWI_CAPTURE_PAGE_STATE=false`.
50
- */
51
- capturePageState?: boolean;
52
- /** Enable live streaming of results (falls back to batch if unsupported). Defaults to `true`. */
53
- streaming?: boolean;
54
- /** Number of test results to batch before sending during streaming. Defaults to `5`. */
55
- streamingBatchSize?: number;
56
- /** Max delay (ms) before flushing pending events during streaming. Defaults to `2000`. */
57
- streamingBatchDelay?: number;
58
- /** Username for dashboard login (use `apiKey` instead when possible) */
59
- username?: string | null;
60
- /** Password for dashboard login (used with `username`) */
61
- password?: string | null;
62
- /** API key for authentication (preferred over `username`/`password` for CI) */
63
- apiKey?: string | null;
64
- /** Additional report types to upload. Each entry can specify `type`, optional `dir`, and optional `label`. */
65
- reports?: Array<{
66
- type: string;
67
- dir?: string;
68
- label?: string;
69
- }>;
70
- /** Stable label that ties shards together (e.g. CI run ID). Auto-detected from CI env; override if needed. */
71
- runLabel?: string;
72
- /** Deployment environment for this run, e.g. `"production"`, `"staging"`, `"integration"` */
73
- environment?: string;
74
- /** Optional display label for the test run (e.g. "v2.3.1 release") */
75
- label?: string;
76
- /** Related issue reference, e.g. `"JIRA-123"` */
77
- relatedIssue?: string;
78
- /** CI job information */
79
- ciInfo?: string;
80
- /** Tags to categorize the test run */
81
- tags?: string[];
82
- /** Additional custom metadata as key-value pairs */
83
- customData?: Record<string, unknown>;
84
- /** Enable verbose logging for debugging. Defaults to `false`. */
85
- verbose?: boolean;
86
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,68 +0,0 @@
1
- import type { FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
2
- import { createGlobalSetup } from './global-setup.js';
3
- import { wrapConfig } from './config-wrapper.js';
4
- /**
5
- * Piwi Dashboard Playwright reporter.
6
- *
7
- * Collects test results, metadata, performance metrics and trace files, then
8
- * hands the collected run to a `RunSubmitter` which drives the JSON / multipart
9
- * / streaming submit ladder. The reporter itself only owns the Playwright hooks
10
- * and the running counters.
11
- */
12
- export declare class PiwiDashboardReporter {
13
- private options;
14
- private testCases;
15
- private startTime;
16
- private playwrightVersion;
17
- private readonly reporterVersion;
18
- private totalTests;
19
- private passedTests;
20
- private failedTests;
21
- private skippedTests;
22
- private timedOutTests;
23
- private didNotRunTests;
24
- /** Full set of tests Playwright planned to run this shard (captured in `onBegin`). */
25
- private plannedTests;
26
- /** Ids of tests that actually reported via `onTestEnd`, to find the ones that never ran. */
27
- private reportedTestIds;
28
- private instanceId;
29
- private runLabel;
30
- private shardInfo;
31
- private metadata;
32
- private enabled;
33
- private isFullRun;
34
- private filterDetails;
35
- private httpClient;
36
- private uploader;
37
- private fileHandler;
38
- private metadataCollector;
39
- private streamManager;
40
- private recovery;
41
- private submitter;
42
- private readonly logger;
43
- static wrapConfig: typeof wrapConfig;
44
- static createGlobalSetup: typeof createGlobalSetup;
45
- constructor(rawOptions?: Record<string, any>);
46
- /** Playwright reporter hook: called once at the start of the test run */
47
- onBegin(config: FullConfig, suite: Suite): void;
48
- /** Playwright reporter hook: called when an individual test begins */
49
- onTestBegin(test: TestCase, result: TestResult): void;
50
- /** Track suite-level setup steps (beforeAll/afterAll) not tied to any test */
51
- private setupSteps;
52
- /** Playwright reporter hook: called when a step (including hook/fixture) begins */
53
- onStepBegin(test: TestCase | undefined, _result: TestResult | undefined, step: any): void;
54
- /** Playwright reporter hook: called when a step (including hook/fixture) ends */
55
- onStepEnd(test: TestCase | undefined, _result: TestResult | undefined, step: any): void;
56
- /** Playwright reporter hook: called when an individual test finishes */
57
- onTestEnd(test: TestCase, result: TestResult): void;
58
- /**
59
- * Synthesize `didnotrun` cases for tests Playwright planned but never reported
60
- * (no `onTestEnd`) — typically because `maxFailures` cut the run short. These
61
- * carry no result, so they're emitted with zero duration and no error. In
62
- * streaming mode they're queued as complete events so the pre-finish drain
63
- * sends them alongside the rest.
64
- */
65
- private materializeUnrunTests;
66
- /** Playwright reporter hook: called when the full test run finishes */
67
- onEnd(result: FullResult): Promise<void>;
68
- }