@stanterprise/playwright-reporter 0.0.18 → 0.0.20
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 +96 -3
- package/dist/client/grpcClient.d.ts +3 -0
- package/dist/client/grpcClient.js +80 -5
- package/dist/reporter.js +3 -0
- package/dist/types.d.ts +27 -0
- package/dist/utils/debugLogger.d.ts +13 -0
- package/dist/utils/debugLogger.js +87 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/optionsMapper.js +11 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,12 +9,13 @@ Custom Playwright test reporter that sends test results to Stanterprise via gRPC
|
|
|
9
9
|
- 📎 **Attachment Support**: Handles screenshots, videos, and other test attachments
|
|
10
10
|
- 🔌 **gRPC Integration**: Communicates with Stanterprise backend via gRPC protocol
|
|
11
11
|
- ⚙️ **Configurable**: Supports environment variables and configuration options
|
|
12
|
+
- 🐛 **Debug Mode**: Captures outgoing gRPC messages to a JSONL file for troubleshooting
|
|
12
13
|
- 🛡️ **Error Resilient**: Graceful error handling that doesn't interrupt test execution
|
|
13
14
|
|
|
14
15
|
## Installation
|
|
15
16
|
|
|
16
17
|
```bash
|
|
17
|
-
npm install stanterprise
|
|
18
|
+
npm install @stanterprise/playwright-reporter --save-dev
|
|
18
19
|
```
|
|
19
20
|
|
|
20
21
|
## Configuration
|
|
@@ -27,7 +28,7 @@ Add the reporter to your `playwright.config.ts`:
|
|
|
27
28
|
import { defineConfig } from "@playwright/test";
|
|
28
29
|
|
|
29
30
|
export default defineConfig({
|
|
30
|
-
reporter: [["stanterprise
|
|
31
|
+
reporter: [["@stanterprise/playwright-reporter"]],
|
|
31
32
|
// ... other config
|
|
32
33
|
});
|
|
33
34
|
```
|
|
@@ -40,7 +41,7 @@ import { defineConfig } from "@playwright/test";
|
|
|
40
41
|
export default defineConfig({
|
|
41
42
|
reporter: [
|
|
42
43
|
[
|
|
43
|
-
"stanterprise
|
|
44
|
+
"@stanterprise/playwright-reporter",
|
|
44
45
|
{
|
|
45
46
|
grpcAddress: "localhost:50051", // gRPC server address
|
|
46
47
|
grpcEnabled: true, // Enable/disable gRPC reporting
|
|
@@ -48,6 +49,8 @@ export default defineConfig({
|
|
|
48
49
|
grpcMaxMessageSize: 104857600, // Max message size (100MB default)
|
|
49
50
|
maxAttachmentSize: 10485760, // Max attachment size (10MB default)
|
|
50
51
|
verbose: false, // Enable verbose logging
|
|
52
|
+
debug: false, // Enable debug mode (writes gRPC messages to JSONL file)
|
|
53
|
+
debugFile: "stanterprise-debug.jsonl", // Path for debug JSONL output
|
|
51
54
|
},
|
|
52
55
|
],
|
|
53
56
|
],
|
|
@@ -62,6 +65,8 @@ You can also configure the reporter using environment variables:
|
|
|
62
65
|
- `STANTERPRISE_GRPC_ADDRESS`: gRPC server address (default: `localhost:50051`)
|
|
63
66
|
- `STANTERPRISE_GRPC_ENABLED`: Enable/disable gRPC reporting (default: `true`)
|
|
64
67
|
- `STANTERPRISE_META_*`: Custom metadata fields for test runs (prefix will be stripped)
|
|
68
|
+
- `STANTERPRISE_DEBUG`: Enable debug mode — captures outgoing gRPC messages to a JSONL file (default: `false`; case-insensitive: `"true"`, `"TRUE"`, `"True"` all work)
|
|
69
|
+
- `STANTERPRISE_DEBUG_FILE`: File path for debug JSONL output (default: `stanterprise-debug.jsonl`)
|
|
65
70
|
|
|
66
71
|
#### Custom Metadata
|
|
67
72
|
|
|
@@ -92,6 +97,93 @@ npx playwright test
|
|
|
92
97
|
| `grpcMaxMessageSize` | number | `104857600` | Max message size in bytes (100MB default) |
|
|
93
98
|
| `maxAttachmentSize` | number | `10485760` | Max attachment content size in bytes (10MB default) |
|
|
94
99
|
| `verbose` | boolean | `false` | Enable verbose logging |
|
|
100
|
+
| `grpcMaxRetries` | number | `3` | Maximum number of retry attempts for failed gRPC calls |
|
|
101
|
+
| `grpcRetryDelay` | number | `100` | Initial delay for retries in ms (uses exponential backoff) |
|
|
102
|
+
| `debug` | boolean | `false` | Enable debug mode — writes all outgoing gRPC messages to a JSONL file. **Warning:** output may include sensitive request payloads and grow very large. Use only in controlled environments. |
|
|
103
|
+
| `debugFile` | string | `stanterprise-debug.jsonl` | File path for debug JSONL output. Parent directories are created automatically if they do not exist. |
|
|
104
|
+
|
|
105
|
+
### Retry Configuration
|
|
106
|
+
|
|
107
|
+
The reporter automatically retries failed gRPC calls for transient errors using exponential backoff:
|
|
108
|
+
|
|
109
|
+
- **Retryable errors**: `UNAVAILABLE`, `DEADLINE_EXCEEDED`, `INTERNAL`, `UNKNOWN`
|
|
110
|
+
- **Non-retryable errors**: `INVALID_ARGUMENT`, `NOT_FOUND`, `PERMISSION_DENIED`, `UNAUTHENTICATED`, `ALREADY_EXISTS`
|
|
111
|
+
|
|
112
|
+
**Exponential backoff formula**: `grpcRetryDelay * (2 ^ attemptNumber)`
|
|
113
|
+
|
|
114
|
+
Example with default settings (`grpcRetryDelay: 100`, `grpcMaxRetries: 3`):
|
|
115
|
+
- Initial attempt: Immediate
|
|
116
|
+
- Retry 1: Wait 100ms (100 * 2^0)
|
|
117
|
+
- Retry 2: Wait 200ms (100 * 2^1)
|
|
118
|
+
- Retry 3: Wait 400ms (100 * 2^2)
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
export default defineConfig({
|
|
122
|
+
reporter: [
|
|
123
|
+
[
|
|
124
|
+
"stanterprise-playwright-reporter",
|
|
125
|
+
{
|
|
126
|
+
grpcMaxRetries: 5, // Try up to 5 times
|
|
127
|
+
grpcRetryDelay: 200, // Start with 200ms delay
|
|
128
|
+
verbose: true, // Log retry attempts
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
],
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
To disable retries:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
{
|
|
139
|
+
grpcMaxRetries: 0 // No retries, fail fast
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Debug Mode
|
|
144
|
+
|
|
145
|
+
The reporter includes an opt-in debug mode that captures every outgoing gRPC message to a JSONL file. This is useful for troubleshooting, auditing what is sent to the backend, or diagnosing unexpected behavior.
|
|
146
|
+
|
|
147
|
+
> **Warning:** Debug output may include full request payloads — including attachment content and metadata — which can contain sensitive values. Debug files may also grow very large. Enable this only in controlled environments and handle the output file securely.
|
|
148
|
+
|
|
149
|
+
### Enabling Debug Mode
|
|
150
|
+
|
|
151
|
+
Via configuration:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
export default defineConfig({
|
|
155
|
+
reporter: [
|
|
156
|
+
[
|
|
157
|
+
"@stanterprise/playwright-reporter",
|
|
158
|
+
{
|
|
159
|
+
debug: true,
|
|
160
|
+
debugFile: "debug-output.jsonl", // optional, defaults to stanterprise-debug.jsonl
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
],
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Via environment variables:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
STANTERPRISE_DEBUG=true STANTERPRISE_DEBUG_FILE=debug-output.jsonl npx playwright test
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Debug File Format
|
|
174
|
+
|
|
175
|
+
Each line is a JSON object with three fields:
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{"timestamp":"2026-03-23T04:10:00.000Z","path":"/testsystem.v1.observer.TestEventCollector/ReportRunStart","message":{"run_id":"abc-123","name":"My Run"}}
|
|
179
|
+
{"timestamp":"2026-03-23T04:10:01.000Z","path":"/testsystem.v1.observer.TestEventCollector/ReportTestBegin","message":{"test_case":{"id":"t1","name":"login test"}}}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- `timestamp` — ISO 8601 timestamp when the message was sent
|
|
183
|
+
- `path` — gRPC method path
|
|
184
|
+
- `message` — full serialized request payload
|
|
185
|
+
|
|
186
|
+
The debug file is created/truncated at reporter initialization, so each test run starts with a clean file. Entries are only written for messages that are actually dispatched (i.e., when gRPC is enabled). Writes are performed asynchronously to minimize overhead.
|
|
95
187
|
|
|
96
188
|
## Sharding Support
|
|
97
189
|
|
|
@@ -279,6 +371,7 @@ The reporter is organized into several modules:
|
|
|
279
371
|
- **utils/statusMapper.ts**: Maps Playwright statuses to protobuf enums
|
|
280
372
|
- **utils/attachmentProcessor.ts**: Processes test attachments
|
|
281
373
|
- **utils/timeHelpers.ts**: Handles timestamp and duration conversions
|
|
374
|
+
- **utils/debugLogger.ts**: Writes outgoing gRPC messages to a JSONL file when debug mode is enabled
|
|
282
375
|
|
|
283
376
|
## Troubleshooting
|
|
284
377
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { StanterpriseReporterOptions } from "../types";
|
|
2
2
|
import * as grpc from "@grpc/grpc-js";
|
|
3
3
|
export default function getClient(options: StanterpriseReporterOptions): grpc.Client | null;
|
|
4
|
+
/**
|
|
5
|
+
* Helper: generic unary call using raw method path with retry support
|
|
6
|
+
*/
|
|
4
7
|
export declare function reportUnary(options: StanterpriseReporterOptions, grpcClient: grpc.Client, path: string, message: {
|
|
5
8
|
serialize?: (w?: any) => Uint8Array;
|
|
6
9
|
serializeBinary?: () => Uint8Array;
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.default = getClient;
|
|
37
37
|
exports.reportUnary = reportUnary;
|
|
38
38
|
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
39
|
+
const debugLogger_1 = require("../utils/debugLogger");
|
|
39
40
|
function getClient(options) {
|
|
40
41
|
try {
|
|
41
42
|
const maxMessageSize = options.grpcMaxMessageSize || 104857600; // 100MB default
|
|
@@ -49,11 +50,28 @@ function getClient(options) {
|
|
|
49
50
|
}
|
|
50
51
|
return null;
|
|
51
52
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Determines if a gRPC error code represents a transient failure worth retrying
|
|
55
|
+
*/
|
|
56
|
+
function shouldAttemptRetryForCode(errorCode) {
|
|
57
|
+
const transientCodes = new Set([
|
|
58
|
+
grpc.status.UNAVAILABLE,
|
|
59
|
+
grpc.status.DEADLINE_EXCEEDED,
|
|
60
|
+
grpc.status.INTERNAL,
|
|
61
|
+
grpc.status.UNKNOWN,
|
|
62
|
+
]);
|
|
63
|
+
return transientCodes.has(errorCode);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Calculates wait time using power-of-two exponential backoff
|
|
67
|
+
*/
|
|
68
|
+
function calculateWaitDuration(baseDelayMs, attemptsSoFar) {
|
|
69
|
+
return baseDelayMs * Math.pow(2, attemptsSoFar);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Performs a single gRPC unary request attempt
|
|
73
|
+
*/
|
|
74
|
+
function executeSingleAttempt(grpcClient, path, message, deadlineMs) {
|
|
57
75
|
const reqSerialize = (arg) => {
|
|
58
76
|
const m = arg;
|
|
59
77
|
const bytes = m?.serializeBinary
|
|
@@ -81,3 +99,60 @@ async function reportUnary(options, grpcClient, path, message, deadlineMs = 1000
|
|
|
81
99
|
}
|
|
82
100
|
});
|
|
83
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Pauses execution for specified milliseconds with unref'd timer to avoid blocking shutdown
|
|
104
|
+
*/
|
|
105
|
+
function pauseExecution(durationMs) {
|
|
106
|
+
return new Promise((resolve) => {
|
|
107
|
+
const timer = setTimeout(resolve, durationMs);
|
|
108
|
+
// Unref the timer so it doesn't keep the process alive
|
|
109
|
+
timer.unref();
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Attempts gRPC call with exponential backoff retry logic using iterative approach
|
|
114
|
+
*/
|
|
115
|
+
async function attemptWithRetries(options, grpcClient, path, message, deadlineMs, maxRetries) {
|
|
116
|
+
let attemptNumber = 0;
|
|
117
|
+
let lastError = null;
|
|
118
|
+
// Try initial attempt + retries
|
|
119
|
+
for (let retriesRemaining = maxRetries; retriesRemaining >= 0; retriesRemaining--) {
|
|
120
|
+
try {
|
|
121
|
+
return await executeSingleAttempt(grpcClient, path, message, deadlineMs);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
lastError = err;
|
|
125
|
+
const grpcErr = err;
|
|
126
|
+
const statusCode = grpcErr?.code ?? grpc.status.UNKNOWN;
|
|
127
|
+
// Check if we should retry this error
|
|
128
|
+
const isRetryable = shouldAttemptRetryForCode(statusCode);
|
|
129
|
+
const hasRetriesLeft = retriesRemaining > 0;
|
|
130
|
+
if (!isRetryable || !hasRetriesLeft) {
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
// Log retry attempt if verbose
|
|
134
|
+
if (options.verbose) {
|
|
135
|
+
console.log(`gRPC call failed (code: ${statusCode}), retrying... ` +
|
|
136
|
+
`(attempt ${attemptNumber + 1}, ${retriesRemaining} retries left)`);
|
|
137
|
+
}
|
|
138
|
+
// Calculate and wait for backoff duration
|
|
139
|
+
const baseDelay = options.grpcRetryDelay ?? 100;
|
|
140
|
+
const waitTime = calculateWaitDuration(baseDelay, attemptNumber);
|
|
141
|
+
await pauseExecution(waitTime);
|
|
142
|
+
attemptNumber++;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// This should never be reached due to the throw in the loop, but TypeScript needs it
|
|
146
|
+
throw lastError || new Error("Retry loop exhausted without result");
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Helper: generic unary call using raw method path with retry support
|
|
150
|
+
*/
|
|
151
|
+
async function reportUnary(options, grpcClient, path, message, deadlineMs = 1000) {
|
|
152
|
+
if (!options.grpcEnabled || !grpcClient) {
|
|
153
|
+
return Buffer.alloc(0);
|
|
154
|
+
}
|
|
155
|
+
await (0, debugLogger_1.writeDebugEntry)(options, path, message);
|
|
156
|
+
const maxRetries = options.grpcMaxRetries ?? 3;
|
|
157
|
+
return attemptWithRetries(options, grpcClient, path, message, deadlineMs, maxRetries);
|
|
158
|
+
}
|
package/dist/reporter.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const crypto_1 = require("crypto");
|
|
7
7
|
const optionsMapper_1 = __importDefault(require("./utils/optionsMapper"));
|
|
8
|
+
const debugLogger_1 = require("./utils/debugLogger");
|
|
8
9
|
const grpcClient_1 = __importDefault(require("./client/grpcClient"));
|
|
9
10
|
const handlers_1 = require("./handlers");
|
|
10
11
|
class StanterpriseReporter {
|
|
@@ -26,6 +27,8 @@ class StanterpriseReporter {
|
|
|
26
27
|
}
|
|
27
28
|
// Generate a UUID for runId
|
|
28
29
|
this.runId = process.env.STANTERPRISE_RUN_ID || (0, crypto_1.randomUUID)();
|
|
30
|
+
// Initialize debug file (creates/truncates it) when debug mode is enabled
|
|
31
|
+
(0, debugLogger_1.initDebugFile)(this.options);
|
|
29
32
|
}
|
|
30
33
|
onBegin(config, suite) {
|
|
31
34
|
// Lazily create the client if enabled.
|
package/dist/types.d.ts
CHANGED
|
@@ -36,6 +36,33 @@ export interface StanterpriseReporterOptions {
|
|
|
36
36
|
* @default false
|
|
37
37
|
*/
|
|
38
38
|
verbose?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Maximum number of retry attempts for failed gRPC calls
|
|
41
|
+
* @default 3
|
|
42
|
+
*/
|
|
43
|
+
grpcMaxRetries?: number;
|
|
44
|
+
/**
|
|
45
|
+
* Initial delay between retry attempts in milliseconds
|
|
46
|
+
* Actual delay uses exponential backoff: initialDelay * (2 ^ attemptNumber)
|
|
47
|
+
* @default 100
|
|
48
|
+
*/
|
|
49
|
+
grpcRetryDelay?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Whether to enable debug mode, which writes all outgoing gRPC messages to a JSONL file.
|
|
52
|
+
* Warning: debug output may include full request payloads, including attachment content
|
|
53
|
+
* and metadata, which can contain sensitive values. Debug files may also grow very large.
|
|
54
|
+
* Enable this only for troubleshooting in controlled environments.
|
|
55
|
+
* @default false or process.env.STANTERPRISE_DEBUG === "true"
|
|
56
|
+
*/
|
|
57
|
+
debug?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* File path for debug JSONL output when debug mode is enabled.
|
|
60
|
+
* Warning: the file may contain sensitive request data and can become very large,
|
|
61
|
+
* especially when attachments are included. Use only in controlled environments and
|
|
62
|
+
* handle the output file securely.
|
|
63
|
+
* @default "stanterprise-debug.jsonl" or process.env.STANTERPRISE_DEBUG_FILE
|
|
64
|
+
*/
|
|
65
|
+
debugFile?: string;
|
|
39
66
|
}
|
|
40
67
|
/**
|
|
41
68
|
* Internal type for managing test execution state
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StanterpriseReporterOptions } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Creates or truncates the debug JSONL file so each test run starts with a clean file.
|
|
4
|
+
* No-op when debug mode is disabled.
|
|
5
|
+
*/
|
|
6
|
+
export declare function initDebugFile(options: StanterpriseReporterOptions): void;
|
|
7
|
+
/**
|
|
8
|
+
* Appends a single JSONL entry for an outgoing gRPC message.
|
|
9
|
+
* Each entry is a JSON object on its own line containing the timestamp,
|
|
10
|
+
* gRPC method path, and the serialized message payload.
|
|
11
|
+
* No-op when debug mode is disabled.
|
|
12
|
+
*/
|
|
13
|
+
export declare function writeDebugEntry(options: StanterpriseReporterOptions, path: string, message: unknown): Promise<void>;
|
|
@@ -0,0 +1,87 @@
|
|
|
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.initDebugFile = initDebugFile;
|
|
37
|
+
exports.writeDebugEntry = writeDebugEntry;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const nodePath = __importStar(require("path"));
|
|
40
|
+
/**
|
|
41
|
+
* Ensures the parent directory of `filePath` exists, creating it recursively if needed.
|
|
42
|
+
*/
|
|
43
|
+
function ensureParentDir(filePath) {
|
|
44
|
+
const dir = nodePath.dirname(filePath);
|
|
45
|
+
if (dir && dir !== ".") {
|
|
46
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Creates or truncates the debug JSONL file so each test run starts with a clean file.
|
|
51
|
+
* No-op when debug mode is disabled.
|
|
52
|
+
*/
|
|
53
|
+
function initDebugFile(options) {
|
|
54
|
+
if (!options.debug)
|
|
55
|
+
return;
|
|
56
|
+
const filePath = options.debugFile || "stanterprise-debug.jsonl";
|
|
57
|
+
try {
|
|
58
|
+
ensureParentDir(filePath);
|
|
59
|
+
fs.writeFileSync(filePath, "");
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
console.error(`Stanterprise Reporter: Failed to initialize debug file "${filePath}":`, e);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Appends a single JSONL entry for an outgoing gRPC message.
|
|
67
|
+
* Each entry is a JSON object on its own line containing the timestamp,
|
|
68
|
+
* gRPC method path, and the serialized message payload.
|
|
69
|
+
* No-op when debug mode is disabled.
|
|
70
|
+
*/
|
|
71
|
+
async function writeDebugEntry(options, path, message) {
|
|
72
|
+
if (!options.debug)
|
|
73
|
+
return;
|
|
74
|
+
const filePath = options.debugFile || "stanterprise-debug.jsonl";
|
|
75
|
+
const entry = {
|
|
76
|
+
timestamp: new Date().toISOString(),
|
|
77
|
+
path,
|
|
78
|
+
message,
|
|
79
|
+
};
|
|
80
|
+
try {
|
|
81
|
+
ensureParentDir(filePath);
|
|
82
|
+
await fs.promises.appendFile(filePath, JSON.stringify(entry) + "\n");
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
console.error(`Stanterprise Reporter: Failed to write debug entry to "${filePath}":`, e);
|
|
86
|
+
}
|
|
87
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -16,6 +16,17 @@ function defineOptions(providedOptions) {
|
|
|
16
16
|
providedOptions.grpcEnabled ??
|
|
17
17
|
(process.env.STANTERPRISE_GRPC_ENABLED || "true").toLowerCase() !== "false";
|
|
18
18
|
result.grpcTimeout = providedOptions.grpcTimeout || 1000;
|
|
19
|
+
result.grpcMaxMessageSize = providedOptions.grpcMaxMessageSize || 104857600;
|
|
20
|
+
result.maxAttachmentSize = providedOptions.maxAttachmentSize || 10485760;
|
|
19
21
|
result.verbose = providedOptions.verbose || false;
|
|
22
|
+
result.grpcMaxRetries = providedOptions.grpcMaxRetries ?? 3;
|
|
23
|
+
result.grpcRetryDelay = providedOptions.grpcRetryDelay || 100;
|
|
24
|
+
result.debug =
|
|
25
|
+
providedOptions.debug ??
|
|
26
|
+
(process.env.STANTERPRISE_DEBUG || "").toLowerCase() === "true";
|
|
27
|
+
result.debugFile =
|
|
28
|
+
providedOptions.debugFile ||
|
|
29
|
+
process.env.STANTERPRISE_DEBUG_FILE ||
|
|
30
|
+
"stanterprise-debug.jsonl";
|
|
20
31
|
return result;
|
|
21
32
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stanterprise/playwright-reporter",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"description": "Custom Playwright test reporter that sends test results to Stanterprise via gRPC",
|
|
5
5
|
"homepage": "https://github.com/stanterprise/stanterprise-playwright-reporter#readme",
|
|
6
6
|
"bugs": {
|