@piwitests/reporter 0.7.0 → 0.9.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/internal/capture/capture-fixtures.d.ts +29 -0
- package/dist/internal/capture/capture-fixtures.js +71 -63
- package/dist/internal/streaming/stream-manager.d.ts +1 -1
- package/dist/internal/streaming/stream-manager.js +6 -3
- package/dist/internal/submit/run-submitter.d.ts +1 -0
- package/dist/internal/submit/run-submitter.js +2 -0
- package/dist/internal/submit/serializer.js +1 -0
- package/dist/internal/submit/uploader.d.ts +2 -0
- package/dist/internal/support/reporter-version.d.ts +2 -0
- package/dist/internal/support/reporter-version.js +54 -0
- package/dist/public/reporter.d.ts +1 -0
- package/dist/public/reporter.js +4 -1
- package/package.json +3 -1
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import type { Fixtures, Locator } from '@playwright/test';
|
|
2
|
+
/** Shape returned by the in-page element probe (see `wrapLocator`). */
|
|
3
|
+
interface CapturedAttrs {
|
|
4
|
+
tagName: string;
|
|
5
|
+
attributes: Record<string, string | null>;
|
|
6
|
+
textContent: string;
|
|
7
|
+
center: {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
};
|
|
11
|
+
/** True when the element has an associated <label> — gates getByLabel. */
|
|
12
|
+
hasLabel: boolean;
|
|
13
|
+
/** querySelectorAll match counts for candidate selectors (uniqueness probe). */
|
|
14
|
+
selectorCounts: {
|
|
15
|
+
testId?: number;
|
|
16
|
+
id?: number;
|
|
17
|
+
name?: number;
|
|
18
|
+
classes?: Record<string, number>;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
2
21
|
/**
|
|
3
22
|
* ARIA snapshot that tolerates every Playwright version the reporter supports,
|
|
4
23
|
* returning null instead of throwing so a capture can never fail the test. The
|
|
@@ -13,6 +32,15 @@ import type { Fixtures, Locator } from '@playwright/test';
|
|
|
13
32
|
* - < 1.49: `locator.ariaSnapshot` does not exist — returns null up front.
|
|
14
33
|
*/
|
|
15
34
|
export declare function ariaSnapshotBestEffort(target: Locator, timeout?: number): Promise<string | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Runs inside the browser via `evaluate()` — probes a captured element for its
|
|
37
|
+
* attributes, geometry, label association, and selector-uniqueness counts.
|
|
38
|
+
* Must stay a fully self-contained function (no references to this module's
|
|
39
|
+
* closure): Playwright serializes it and executes it in the page, browser-side.
|
|
40
|
+
* `el` is browser-context (no DOM lib in this Node package), hence `any`.
|
|
41
|
+
* Exported for unit testing; still passed directly to `evaluate()` below.
|
|
42
|
+
*/
|
|
43
|
+
export declare function probeElementAttrs(el: any, keep: string[]): CapturedAttrs;
|
|
16
44
|
/**
|
|
17
45
|
* Playwright fixtures that collect network requests, console entries,
|
|
18
46
|
* web vitals, ARIA snapshots, and locator interaction data during a test.
|
|
@@ -39,3 +67,4 @@ export declare const dashboardFixtures: Fixtures;
|
|
|
39
67
|
* ```
|
|
40
68
|
*/
|
|
41
69
|
export declare function extendDashboardFixtures<T>(test: T): T;
|
|
70
|
+
export {};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.dashboardFixtures = void 0;
|
|
4
4
|
exports.ariaSnapshotBestEffort = ariaSnapshotBestEffort;
|
|
5
|
+
exports.probeElementAttrs = probeElementAttrs;
|
|
5
6
|
exports.extendDashboardFixtures = extendDashboardFixtures;
|
|
6
7
|
const node_zlib_1 = require("node:zlib");
|
|
7
8
|
const locator_healing_js_1 = require("./locator-healing.js");
|
|
@@ -75,6 +76,75 @@ async function ariaSnapshotBestEffort(target, timeout) {
|
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Runs inside the browser via `evaluate()` — probes a captured element for its
|
|
81
|
+
* attributes, geometry, label association, and selector-uniqueness counts.
|
|
82
|
+
* Must stay a fully self-contained function (no references to this module's
|
|
83
|
+
* closure): Playwright serializes it and executes it in the page, browser-side.
|
|
84
|
+
* `el` is browser-context (no DOM lib in this Node package), hence `any`.
|
|
85
|
+
* Exported for unit testing; still passed directly to `evaluate()` below.
|
|
86
|
+
*/
|
|
87
|
+
function probeElementAttrs(el, keep) {
|
|
88
|
+
const attrMap = {};
|
|
89
|
+
for (const key of keep) {
|
|
90
|
+
const v = el.getAttribute(key) ?? el[key];
|
|
91
|
+
attrMap[key] = typeof v === 'string' ? v.slice(0, 200) : v ? String(v).slice(0, 200) : null;
|
|
92
|
+
}
|
|
93
|
+
const r = el.getBoundingClientRect();
|
|
94
|
+
// Uniqueness probe: how many elements each candidate selector matches. A
|
|
95
|
+
// count > 1 marks the alternative as ambiguous (strict-mode violation) so
|
|
96
|
+
// generateAlternatives drops it. All DOM/CSS access goes through `el` (no
|
|
97
|
+
// DOM lib here).
|
|
98
|
+
const selectorCounts = {};
|
|
99
|
+
try {
|
|
100
|
+
const doc = el.ownerDocument;
|
|
101
|
+
const cssEsc = (s) => doc.defaultView.CSS.escape(s);
|
|
102
|
+
const count = (sel) => {
|
|
103
|
+
try {
|
|
104
|
+
return doc.querySelectorAll(sel).length;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
if (attrMap['data-testid']) {
|
|
111
|
+
selectorCounts.testId = count(`[data-testid=${JSON.stringify(attrMap['data-testid'])}]`);
|
|
112
|
+
}
|
|
113
|
+
if (attrMap['id'])
|
|
114
|
+
selectorCounts.id = count(`#${cssEsc(attrMap['id'])}`);
|
|
115
|
+
if (attrMap['name'])
|
|
116
|
+
selectorCounts.name = count(`[name=${JSON.stringify(attrMap['name'])}]`);
|
|
117
|
+
const classList = (attrMap['class'] || '')
|
|
118
|
+
.split(/\s+/)
|
|
119
|
+
.filter((c) => c.length > 1)
|
|
120
|
+
.slice(0, 10);
|
|
121
|
+
if (classList.length > 0) {
|
|
122
|
+
const classCounts = {};
|
|
123
|
+
for (const cls of classList) {
|
|
124
|
+
const n = count(`.${cssEsc(cls)}`);
|
|
125
|
+
if (n !== undefined)
|
|
126
|
+
classCounts[cls] = n;
|
|
127
|
+
}
|
|
128
|
+
selectorCounts.classes = classCounts;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Uniqueness probing is best-effort — never fail the capture.
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
tagName: el.tagName?.toLowerCase?.() ?? 'unknown',
|
|
136
|
+
attributes: attrMap,
|
|
137
|
+
// Collapse whitespace so multi-line text can't produce a getByText
|
|
138
|
+
// suggestion with literal newlines in it.
|
|
139
|
+
textContent: (el.textContent || '').replace(/\s+/g, ' ').trim().slice(0, 80),
|
|
140
|
+
center: {
|
|
141
|
+
x: Math.round(r.x + r.width / 2),
|
|
142
|
+
y: Math.round(r.y + r.height / 2),
|
|
143
|
+
},
|
|
144
|
+
hasLabel: !!(el.labels && el.labels.length > 0),
|
|
145
|
+
selectorCounts,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
78
148
|
// Chain methods that take args and define a new locator scope (not just narrow).
|
|
79
149
|
// Origin method/args update to the chain call, e.g. .locator('.item') → locator('.item').
|
|
80
150
|
// Positional/filter chains that narrow but don't change locator identity.
|
|
@@ -140,70 +210,8 @@ function wrapLocator(page, locator, originMethod, originArgs) {
|
|
|
140
210
|
const resolveAttrs = (async () => {
|
|
141
211
|
let deadline;
|
|
142
212
|
try {
|
|
143
|
-
// `el` is browser-context (no DOM lib in this Node package), so it
|
|
144
|
-
// stays `any`; the callback's return type pins `attrs` to CapturedAttrs.
|
|
145
213
|
const attrs = await Promise.race([
|
|
146
|
-
target.evaluate(
|
|
147
|
-
const attrMap = {};
|
|
148
|
-
for (const key of keep) {
|
|
149
|
-
const v = el.getAttribute(key) ?? el[key];
|
|
150
|
-
attrMap[key] = typeof v === 'string' ? v.slice(0, 200) : v ? String(v).slice(0, 200) : null;
|
|
151
|
-
}
|
|
152
|
-
const r = el.getBoundingClientRect();
|
|
153
|
-
// Uniqueness probe: how many elements each candidate selector
|
|
154
|
-
// matches. A count > 1 marks the alternative as ambiguous
|
|
155
|
-
// (strict-mode violation) so generateAlternatives drops it.
|
|
156
|
-
// All DOM/CSS access goes through `el` (no DOM lib here).
|
|
157
|
-
const selectorCounts = {};
|
|
158
|
-
try {
|
|
159
|
-
const doc = el.ownerDocument;
|
|
160
|
-
const cssEsc = (s) => doc.defaultView.CSS.escape(s);
|
|
161
|
-
const count = (sel) => {
|
|
162
|
-
try {
|
|
163
|
-
return doc.querySelectorAll(sel).length;
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
return undefined;
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
if (attrMap['data-testid']) {
|
|
170
|
-
selectorCounts.testId = count(`[data-testid=${JSON.stringify(attrMap['data-testid'])}]`);
|
|
171
|
-
}
|
|
172
|
-
if (attrMap['id'])
|
|
173
|
-
selectorCounts.id = count(`#${cssEsc(attrMap['id'])}`);
|
|
174
|
-
if (attrMap['name'])
|
|
175
|
-
selectorCounts.name = count(`[name=${JSON.stringify(attrMap['name'])}]`);
|
|
176
|
-
const classList = (attrMap['class'] || '')
|
|
177
|
-
.split(/\s+/)
|
|
178
|
-
.filter((c) => c.length > 1)
|
|
179
|
-
.slice(0, 10);
|
|
180
|
-
if (classList.length > 0) {
|
|
181
|
-
const classCounts = {};
|
|
182
|
-
for (const cls of classList) {
|
|
183
|
-
const n = count(`.${cssEsc(cls)}`);
|
|
184
|
-
if (n !== undefined)
|
|
185
|
-
classCounts[cls] = n;
|
|
186
|
-
}
|
|
187
|
-
selectorCounts.classes = classCounts;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
catch {
|
|
191
|
-
// Uniqueness probing is best-effort — never fail the capture.
|
|
192
|
-
}
|
|
193
|
-
return {
|
|
194
|
-
tagName: el.tagName?.toLowerCase?.() ?? 'unknown',
|
|
195
|
-
attributes: attrMap,
|
|
196
|
-
// Collapse whitespace so multi-line text can't produce a
|
|
197
|
-
// getByText suggestion with literal newlines in it.
|
|
198
|
-
textContent: (el.textContent || '').replace(/\s+/g, ' ').trim().slice(0, 80),
|
|
199
|
-
center: {
|
|
200
|
-
x: Math.round(r.x + r.width / 2),
|
|
201
|
-
y: Math.round(r.y + r.height / 2),
|
|
202
|
-
},
|
|
203
|
-
hasLabel: !!(el.labels && el.labels.length > 0),
|
|
204
|
-
selectorCounts,
|
|
205
|
-
};
|
|
206
|
-
}, CAPTURED_ATTRS_ARG),
|
|
214
|
+
target.evaluate(probeElementAttrs, CAPTURED_ATTRS_ARG),
|
|
207
215
|
new Promise((_, reject) => {
|
|
208
216
|
deadline = setTimeout(() => reject(new Error('locator capture timeout')), 500);
|
|
209
217
|
}),
|
|
@@ -66,7 +66,7 @@ export declare class StreamManager {
|
|
|
66
66
|
*/
|
|
67
67
|
constructor(httpClient: HttpClient, streamBuffer: StreamBuffer, recovery: CrashRecovery, uploader: Uploader, fileHandler: FileHandler, options: PiwiDashboardOptions, logger?: Logger);
|
|
68
68
|
/** Begin the streaming session after `onBegin` fires. Non-blocking — the actual handshake runs asynchronously. */
|
|
69
|
-
start(startTime: string, metadata: Record<string, any>, instanceId: string, playwrightVersion?: string | null, shardInfo?: ShardInfo | null, isFullRun?: boolean, filterDetails?: FilterDetails | null): void;
|
|
69
|
+
start(startTime: string, metadata: Record<string, any>, instanceId: string, playwrightVersion?: string | null, reporterVersion?: string | null, shardInfo?: ShardInfo | null, isFullRun?: boolean, filterDetails?: FilterDetails | null): void;
|
|
70
70
|
private _doStart;
|
|
71
71
|
/** Queue a test-case `begin` event. Held in a pre-start buffer if the stream is not yet open, then prepended so it arrives before the matching `complete` event. */
|
|
72
72
|
queueBeginEvent(event: StreamEvent): void;
|
|
@@ -111,10 +111,10 @@ class StreamManager {
|
|
|
111
111
|
this._startPromise = null;
|
|
112
112
|
}
|
|
113
113
|
/** Begin the streaming session after `onBegin` fires. Non-blocking — the actual handshake runs asynchronously. */
|
|
114
|
-
start(startTime, metadata, instanceId, playwrightVersion, shardInfo, isFullRun, filterDetails) {
|
|
115
|
-
this._startPromise = this._doStart(startTime, metadata, instanceId, playwrightVersion, shardInfo, isFullRun, filterDetails);
|
|
114
|
+
start(startTime, metadata, instanceId, playwrightVersion, reporterVersion, shardInfo, isFullRun, filterDetails) {
|
|
115
|
+
this._startPromise = this._doStart(startTime, metadata, instanceId, playwrightVersion, reporterVersion, shardInfo, isFullRun, filterDetails);
|
|
116
116
|
}
|
|
117
|
-
async _doStart(startTime, metadata, instanceId, playwrightVersion, shardInfo, isFullRun, filterDetails) {
|
|
117
|
+
async _doStart(startTime, metadata, instanceId, playwrightVersion, reporterVersion, shardInfo, isFullRun, filterDetails) {
|
|
118
118
|
const setupInfo = (0, setup_file_js_1.readSetupInfo)(this.options.projectName);
|
|
119
119
|
try {
|
|
120
120
|
this._auth = await this.httpClient.resolveAuth(this.options);
|
|
@@ -129,6 +129,7 @@ class StreamManager {
|
|
|
129
129
|
totalTests: 0,
|
|
130
130
|
metadata,
|
|
131
131
|
playwrightVersion,
|
|
132
|
+
reporterVersion,
|
|
132
133
|
shardIndex,
|
|
133
134
|
shardTotal,
|
|
134
135
|
isFullRun,
|
|
@@ -150,6 +151,7 @@ class StreamManager {
|
|
|
150
151
|
metadata,
|
|
151
152
|
instanceId,
|
|
152
153
|
playwrightVersion,
|
|
154
|
+
reporterVersion,
|
|
153
155
|
shardIndex,
|
|
154
156
|
shardTotal,
|
|
155
157
|
isFullRun,
|
|
@@ -167,6 +169,7 @@ class StreamManager {
|
|
|
167
169
|
metadata,
|
|
168
170
|
instanceId,
|
|
169
171
|
playwrightVersion,
|
|
172
|
+
reporterVersion,
|
|
170
173
|
shardIndex,
|
|
171
174
|
shardTotal,
|
|
172
175
|
isFullRun,
|
|
@@ -97,6 +97,7 @@ class RunSubmitter {
|
|
|
97
97
|
metadata: run.metadata,
|
|
98
98
|
instanceId: run.instanceId,
|
|
99
99
|
playwrightVersion: run.playwrightVersion ?? undefined,
|
|
100
|
+
reporterVersion: run.reporterVersion ?? undefined,
|
|
100
101
|
testCases: run.testCases,
|
|
101
102
|
shardIndex: run.shardInfo?.current,
|
|
102
103
|
shardTotal: run.shardInfo?.total,
|
|
@@ -126,6 +127,7 @@ class RunSubmitter {
|
|
|
126
127
|
metadata: run.metadata,
|
|
127
128
|
hasPendingUploads: this.hasReports(run),
|
|
128
129
|
playwrightVersion: run.playwrightVersion ?? undefined,
|
|
130
|
+
reporterVersion: run.reporterVersion ?? undefined,
|
|
129
131
|
setupSteps: run.setupSteps.length > 0 ? run.setupSteps : undefined,
|
|
130
132
|
isFullRun: run.isFullRun,
|
|
131
133
|
filterDetails: run.filterDetails ?? null,
|
|
@@ -94,6 +94,7 @@ function serializeRun(payload, opts) {
|
|
|
94
94
|
metadata: payload.metadata,
|
|
95
95
|
instanceId: payload.instanceId,
|
|
96
96
|
playwrightVersion: payload.playwrightVersion,
|
|
97
|
+
reporterVersion: payload.reporterVersion,
|
|
97
98
|
shardIndex: payload.shardIndex,
|
|
98
99
|
shardTotal: payload.shardTotal,
|
|
99
100
|
isFullRun: payload.isFullRun ?? true,
|
|
@@ -33,6 +33,8 @@ export interface RunPayload {
|
|
|
33
33
|
testCases: CollectedTestCase[];
|
|
34
34
|
/** Playwright framework version used for this run */
|
|
35
35
|
playwrightVersion?: string;
|
|
36
|
+
/** Piwi reporter package version that produced this run */
|
|
37
|
+
reporterVersion?: string;
|
|
36
38
|
/** 1-based shard index (e.g. 1, 2, 3) */
|
|
37
39
|
shardIndex?: number;
|
|
38
40
|
/** Total number of shards (e.g. 3) */
|
|
@@ -0,0 +1,54 @@
|
|
|
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.getReporterVersion = getReporterVersion;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
let cachedVersion = null;
|
|
40
|
+
/** Read the reporter package's own version from `package.json`, memoized. Falls back to `'unknown'` if it can't be read (e.g. an unusual install layout). */
|
|
41
|
+
function getReporterVersion() {
|
|
42
|
+
if (cachedVersion)
|
|
43
|
+
return cachedVersion;
|
|
44
|
+
try {
|
|
45
|
+
const pkgPath = path.resolve(__dirname, '../../../package.json');
|
|
46
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
47
|
+
const version = pkg.version;
|
|
48
|
+
cachedVersion = typeof version === 'string' ? version : 'unknown';
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
cachedVersion = 'unknown';
|
|
52
|
+
}
|
|
53
|
+
return cachedVersion;
|
|
54
|
+
}
|
package/dist/public/reporter.js
CHANGED
|
@@ -46,6 +46,7 @@ const metadata_collector_js_1 = require("../internal/collect/metadata-collector.
|
|
|
46
46
|
const stream_manager_js_1 = require("../internal/streaming/stream-manager.js");
|
|
47
47
|
const step_analyzer_js_1 = require("../internal/collect/step-analyzer.js");
|
|
48
48
|
const instance_id_js_1 = require("../internal/support/instance-id.js");
|
|
49
|
+
const reporter_version_js_1 = require("../internal/support/reporter-version.js");
|
|
49
50
|
const source_snippet_js_1 = require("../internal/support/source-snippet.js");
|
|
50
51
|
const ci_js_1 = require("../internal/support/ci.js");
|
|
51
52
|
const worker_index_js_1 = require("../internal/support/worker-index.js");
|
|
@@ -79,6 +80,7 @@ class PiwiDashboardReporter {
|
|
|
79
80
|
this.testCases = [];
|
|
80
81
|
this.startTime = null;
|
|
81
82
|
this.playwrightVersion = null;
|
|
83
|
+
this.reporterVersion = (0, reporter_version_js_1.getReporterVersion)();
|
|
82
84
|
this.totalTests = 0;
|
|
83
85
|
this.passedTests = 0;
|
|
84
86
|
this.failedTests = 0;
|
|
@@ -154,7 +156,7 @@ class PiwiDashboardReporter {
|
|
|
154
156
|
this.shardInfo = { current: pwShard.current, total: pwShard.total };
|
|
155
157
|
this.logger.info(`Shard ${this.shardInfo.current}/${this.shardInfo.total} detected`);
|
|
156
158
|
}
|
|
157
|
-
this.streamManager?.start(this.startTime, this.metadata, this.instanceId, this.playwrightVersion, this.shardInfo, this.isFullRun, this.filterDetails);
|
|
159
|
+
this.streamManager?.start(this.startTime, this.metadata, this.instanceId, this.playwrightVersion, this.reporterVersion, this.shardInfo, this.isFullRun, this.filterDetails);
|
|
158
160
|
}
|
|
159
161
|
/** Playwright reporter hook: called when an individual test begins */
|
|
160
162
|
onTestBegin(test, result) {
|
|
@@ -353,6 +355,7 @@ class PiwiDashboardReporter {
|
|
|
353
355
|
testCases: this.testCases,
|
|
354
356
|
startTime: this.startTime,
|
|
355
357
|
playwrightVersion: this.playwrightVersion,
|
|
358
|
+
reporterVersion: this.reporterVersion,
|
|
356
359
|
totalTests: this.totalTests,
|
|
357
360
|
passedTests: this.passedTests,
|
|
358
361
|
failedTests: this.failedTests,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@piwitests/reporter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Playwright reporter for sending test results to Piwi Dashboard",
|
|
5
5
|
"url": "https://github.com/PiwiTests/platform",
|
|
6
6
|
"homepage": "https://piwitests.github.io",
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
"reporter:lint": "oxlint --config oxlint.config.mts .",
|
|
42
42
|
"reporter:lint:fix": "oxlint --config oxlint.config.mts . --fix",
|
|
43
43
|
"reporter:test": "vitest run",
|
|
44
|
+
"reporter:test:coverage": "vitest run --coverage",
|
|
44
45
|
"reporter:test:watch": "vitest",
|
|
46
|
+
"reporter:test:integration": "npm run reporter:build && playwright test --config=tests/integration/playwright.config.ts",
|
|
45
47
|
"test": "npm run reporter:test",
|
|
46
48
|
"prepublishOnly": "npm run reporter:build"
|
|
47
49
|
},
|