@piwitests/reporter 0.46.0 → 0.48.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
CHANGED
|
@@ -490,7 +490,7 @@ var DEFAULTS = {
|
|
|
490
490
|
defaultCapture: true,
|
|
491
491
|
checkBaseUrl: false,
|
|
492
492
|
streaming: true,
|
|
493
|
-
streamingBatchSize:
|
|
493
|
+
streamingBatchSize: 20,
|
|
494
494
|
streamingBatchDelay: 2e3,
|
|
495
495
|
maxStreamBufferBytes: 100 * 1024 * 1024,
|
|
496
496
|
submitTimeout: 15 * 60 * 1e3,
|
package/dist/index.d.ts
CHANGED
|
@@ -205,7 +205,11 @@ interface PiwiDashboardOptions {
|
|
|
205
205
|
pickLocatorOnFailure?: boolean;
|
|
206
206
|
/** Enable live streaming of results (falls back to batch if unsupported). Defaults to `true`. */
|
|
207
207
|
streaming?: boolean;
|
|
208
|
-
/**
|
|
208
|
+
/**
|
|
209
|
+
* Number of queued events that triggers a send during streaming: test starts
|
|
210
|
+
* and results, and live steps while someone has the run open on the
|
|
211
|
+
* dashboard. Defaults to `20`.
|
|
212
|
+
*/
|
|
209
213
|
streamingBatchSize?: number;
|
|
210
214
|
/** Max delay (ms) before flushing pending events during streaming. Defaults to `2000`. */
|
|
211
215
|
streamingBatchDelay?: number;
|
package/dist/index.js
CHANGED
|
@@ -91,7 +91,7 @@ var DEFAULTS = {
|
|
|
91
91
|
defaultCapture: true,
|
|
92
92
|
checkBaseUrl: false,
|
|
93
93
|
streaming: true,
|
|
94
|
-
streamingBatchSize:
|
|
94
|
+
streamingBatchSize: 20,
|
|
95
95
|
streamingBatchDelay: 2e3,
|
|
96
96
|
maxStreamBufferBytes: 100 * 1024 * 1024,
|
|
97
97
|
submitTimeout: 15 * 60 * 1e3,
|
|
@@ -1865,6 +1865,20 @@ var StreamManager = class {
|
|
|
1865
1865
|
this.heartbeatStopped = false;
|
|
1866
1866
|
this.lastActivityAt = 0;
|
|
1867
1867
|
this.heartbeatInterval = 15e3;
|
|
1868
|
+
/**
|
|
1869
|
+
* The heartbeat interval while nobody watches the run: during a long test no
|
|
1870
|
+
* other request goes out, so the heartbeat's answer is how the reporter learns
|
|
1871
|
+
* that someone opened the run.
|
|
1872
|
+
*/
|
|
1873
|
+
this.unwatchedHeartbeatInterval = 5e3;
|
|
1874
|
+
/**
|
|
1875
|
+
* Whether anyone has the run open live on the dashboard, from the `watched`
|
|
1876
|
+
* flag of the last answer to an events or heartbeat request; `null` until the
|
|
1877
|
+
* dashboard says, and for a dashboard that does not. Step events are live
|
|
1878
|
+
* progress only (each `complete` event carries its test's steps), so none are
|
|
1879
|
+
* queued while it is `false`.
|
|
1880
|
+
*/
|
|
1881
|
+
this.watched = null;
|
|
1868
1882
|
/** Tracks cases whose files have already been uploaded live, so `uploadRemaining` can skip them. */
|
|
1869
1883
|
this.uploadedCaseFiles = /* @__PURE__ */ new WeakSet();
|
|
1870
1884
|
/** Set when a test-result event left the live stream undelivered: too large to send, or still queued when the drain gave up. */
|
|
@@ -2035,8 +2049,13 @@ var StreamManager = class {
|
|
|
2035
2049
|
this.pendingBeginEvents.enqueue(event);
|
|
2036
2050
|
}
|
|
2037
2051
|
}
|
|
2038
|
-
/**
|
|
2052
|
+
/**
|
|
2053
|
+
* Queue a test-case event. Triggers an immediate flush when the batch size is
|
|
2054
|
+
* reached, otherwise schedules a timer-based flush. A step event is dropped
|
|
2055
|
+
* while nobody watches the run.
|
|
2056
|
+
*/
|
|
2039
2057
|
queueEvent(event) {
|
|
2058
|
+
if (this.watched === false && (event.type === "step-begin" || event.type === "step-end")) return;
|
|
2040
2059
|
this.pendingEvents.enqueue(event);
|
|
2041
2060
|
if (this.pendingEvents.length >= this.options.streamingBatchSize) {
|
|
2042
2061
|
this.flush();
|
|
@@ -2064,11 +2083,12 @@ var StreamManager = class {
|
|
|
2064
2083
|
while (chunks.length > 0) {
|
|
2065
2084
|
const chunk = chunks.shift();
|
|
2066
2085
|
try {
|
|
2067
|
-
await this.httpClient.postJSON(
|
|
2086
|
+
const response = await this.httpClient.postJSON(
|
|
2068
2087
|
`/api/test-runs/${this._runId}/events`,
|
|
2069
2088
|
{ streamToken: this._token, testCases: chunk },
|
|
2070
2089
|
this._auth
|
|
2071
2090
|
);
|
|
2091
|
+
this.noteWatched(response);
|
|
2072
2092
|
this.retryCount = 0;
|
|
2073
2093
|
this.lastActivityAt = Date.now();
|
|
2074
2094
|
} catch (error) {
|
|
@@ -2142,13 +2162,29 @@ var StreamManager = class {
|
|
|
2142
2162
|
if (this.pendingEvents.length > 0) this.flush();
|
|
2143
2163
|
}, delay);
|
|
2144
2164
|
}
|
|
2165
|
+
// Take the dashboard's answer on whether anyone watches the run. An answer
|
|
2166
|
+
// without the flag (an older dashboard) keeps step events flowing.
|
|
2167
|
+
noteWatched(response) {
|
|
2168
|
+
const watched = response?.watched;
|
|
2169
|
+
const next = typeof watched === "boolean" ? watched : null;
|
|
2170
|
+
if (next !== null && next !== this.watched) {
|
|
2171
|
+
this.logger.debug(
|
|
2172
|
+
next ? "The run is open on the dashboard: streaming live steps." : "Nobody is watching the run: live steps are not sent."
|
|
2173
|
+
);
|
|
2174
|
+
}
|
|
2175
|
+
this.watched = next;
|
|
2176
|
+
}
|
|
2177
|
+
// Idle time after which a heartbeat goes out.
|
|
2178
|
+
heartbeatDelay() {
|
|
2179
|
+
return this.watched === false ? this.unwatchedHeartbeatInterval : this.heartbeatInterval;
|
|
2180
|
+
}
|
|
2145
2181
|
// Schedule the next idle heartbeat. Self-rescheduling; cleared by stopHeartbeat.
|
|
2146
2182
|
scheduleHeartbeat() {
|
|
2147
2183
|
if (this.heartbeatStopped || this.heartbeatTimer) return;
|
|
2148
2184
|
this.heartbeatTimer = setTimeout(() => {
|
|
2149
2185
|
this.heartbeatTimer = null;
|
|
2150
2186
|
void this.sendHeartbeat();
|
|
2151
|
-
}, this.
|
|
2187
|
+
}, this.heartbeatDelay());
|
|
2152
2188
|
}
|
|
2153
2189
|
// Ping the server only when the run has actually been idle. Real event traffic
|
|
2154
2190
|
// already bumps the server's activity timestamp, so a recent flush (or pending
|
|
@@ -2156,16 +2192,17 @@ var StreamManager = class {
|
|
|
2156
2192
|
async sendHeartbeat() {
|
|
2157
2193
|
if (this.heartbeatStopped || !this._enabled || !this._runId || !this._token) return;
|
|
2158
2194
|
const idleFor = Date.now() - this.lastActivityAt;
|
|
2159
|
-
if (idleFor < this.
|
|
2195
|
+
if (idleFor < this.heartbeatDelay() || this.pendingEvents.length > 0) {
|
|
2160
2196
|
this.scheduleHeartbeat();
|
|
2161
2197
|
return;
|
|
2162
2198
|
}
|
|
2163
2199
|
try {
|
|
2164
|
-
await this.httpClient.postJSON(
|
|
2200
|
+
const response = await this.httpClient.postJSON(
|
|
2165
2201
|
`/api/test-runs/${this._runId}/heartbeat`,
|
|
2166
2202
|
{ streamToken: this._token },
|
|
2167
2203
|
this._auth
|
|
2168
2204
|
);
|
|
2205
|
+
this.noteWatched(response);
|
|
2169
2206
|
this.lastActivityAt = Date.now();
|
|
2170
2207
|
} catch (error) {
|
|
2171
2208
|
this.logger.debug(`Heartbeat failed: ${errorMessage(error)}`);
|
|
@@ -2158,7 +2158,7 @@ var DEFAULTS = {
|
|
|
2158
2158
|
defaultCapture: true,
|
|
2159
2159
|
checkBaseUrl: false,
|
|
2160
2160
|
streaming: true,
|
|
2161
|
-
streamingBatchSize:
|
|
2161
|
+
streamingBatchSize: 20,
|
|
2162
2162
|
streamingBatchDelay: 2e3,
|
|
2163
2163
|
maxStreamBufferBytes: 100 * 1024 * 1024,
|
|
2164
2164
|
submitTimeout: 15 * 60 * 1e3,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@piwitests/reporter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"description": "Playwright reporter that streams results, traces and HTML reports to a Piwi Dashboard instance",
|
|
5
5
|
"url": "https://github.com/PiwiTests/platform",
|
|
6
6
|
"homepage": "https://piwitests.dev",
|