@testrelic/core 2.4.10 → 2.4.11-next.9
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/index.cjs +301 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +777 -0
- package/dist/index.d.ts +777 -0
- package/dist/index.js +257 -0
- package/dist/index.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @testrelic/core — Shared type definitions
|
|
3
|
+
*
|
|
4
|
+
* All interfaces for the JSON output schema, reporter configuration,
|
|
5
|
+
* and internal fixture-to-reporter communication.
|
|
6
|
+
*
|
|
7
|
+
* Schema Version: 1.0.0
|
|
8
|
+
*/
|
|
9
|
+
type NavigationType = 'goto' | 'navigation' | 'back' | 'forward' | 'refresh' | 'spa_route' | 'spa_replace' | 'hash_change' | 'link_click' | 'form_submit' | 'redirect' | 'popstate' | 'page_load' | 'manual_record' | 'fallback' | 'dummy';
|
|
10
|
+
interface TestRunReport {
|
|
11
|
+
readonly schemaVersion: string;
|
|
12
|
+
readonly testRunId: string;
|
|
13
|
+
readonly startedAt: string;
|
|
14
|
+
readonly completedAt: string;
|
|
15
|
+
readonly totalDuration: number;
|
|
16
|
+
readonly summary: Summary;
|
|
17
|
+
readonly ci: CIMetadata | null;
|
|
18
|
+
readonly metadata: Record<string, unknown> | null;
|
|
19
|
+
readonly timeline: readonly (TimelineEntry | TimelineStep)[];
|
|
20
|
+
readonly shardRunIds: string[] | null;
|
|
21
|
+
}
|
|
22
|
+
/** Breakdown of API calls by HTTP response status range. */
|
|
23
|
+
interface ApiCallsByStatusRange {
|
|
24
|
+
readonly '2xx': number;
|
|
25
|
+
readonly '3xx': number;
|
|
26
|
+
readonly '4xx': number;
|
|
27
|
+
readonly '5xx': number;
|
|
28
|
+
readonly error: number;
|
|
29
|
+
}
|
|
30
|
+
/** Statistical distribution of API call response times in milliseconds. */
|
|
31
|
+
interface ApiResponseTimeStats {
|
|
32
|
+
readonly avg: number;
|
|
33
|
+
readonly min: number;
|
|
34
|
+
readonly max: number;
|
|
35
|
+
readonly p50: number;
|
|
36
|
+
readonly p95: number;
|
|
37
|
+
readonly p99: number;
|
|
38
|
+
}
|
|
39
|
+
interface Summary {
|
|
40
|
+
readonly total: number;
|
|
41
|
+
readonly passed: number;
|
|
42
|
+
readonly failed: number;
|
|
43
|
+
readonly flaky: number;
|
|
44
|
+
readonly skipped: number;
|
|
45
|
+
readonly timedout: number;
|
|
46
|
+
readonly totalApiCalls: number;
|
|
47
|
+
readonly uniqueApiUrls: number;
|
|
48
|
+
readonly apiCallsByMethod: Record<string, number>;
|
|
49
|
+
readonly apiCallsByStatusRange: ApiCallsByStatusRange;
|
|
50
|
+
readonly apiResponseTime: ApiResponseTimeStats | null;
|
|
51
|
+
readonly totalAssertions: number;
|
|
52
|
+
readonly passedAssertions: number;
|
|
53
|
+
readonly failedAssertions: number;
|
|
54
|
+
readonly totalNavigations: number;
|
|
55
|
+
readonly uniqueNavigationUrls: number;
|
|
56
|
+
readonly totalTimelineSteps: number;
|
|
57
|
+
readonly totalActionSteps: number;
|
|
58
|
+
readonly actionStepsByCategory: Record<string, number>;
|
|
59
|
+
}
|
|
60
|
+
interface CIMetadata {
|
|
61
|
+
readonly provider: CIProvider;
|
|
62
|
+
readonly buildId: string | null;
|
|
63
|
+
readonly commitSha: string | null;
|
|
64
|
+
readonly branch: string | null;
|
|
65
|
+
readonly runUrl: string | null;
|
|
66
|
+
}
|
|
67
|
+
type CIProvider = 'github-actions' | 'gitlab-ci' | 'jenkins' | 'circleci' | 'bitbucket-pipelines' | 'unknown';
|
|
68
|
+
interface TimelineEntry {
|
|
69
|
+
readonly url: string;
|
|
70
|
+
readonly navigationType: NavigationType;
|
|
71
|
+
readonly visitedAt: string;
|
|
72
|
+
readonly duration: number;
|
|
73
|
+
readonly specFile: string;
|
|
74
|
+
readonly domContentLoadedAt: string | null;
|
|
75
|
+
readonly networkIdleAt: string | null;
|
|
76
|
+
readonly networkStats: NetworkStats | null;
|
|
77
|
+
readonly tests: TestResult[];
|
|
78
|
+
}
|
|
79
|
+
interface TestResult {
|
|
80
|
+
readonly title: string;
|
|
81
|
+
readonly status: TestStatus;
|
|
82
|
+
readonly duration: number;
|
|
83
|
+
readonly startedAt: string;
|
|
84
|
+
readonly completedAt: string;
|
|
85
|
+
readonly retryCount: number;
|
|
86
|
+
readonly tags: string[];
|
|
87
|
+
readonly failure: FailureDiagnostic | null;
|
|
88
|
+
readonly testId: string;
|
|
89
|
+
readonly filePath: string;
|
|
90
|
+
readonly suiteName: string;
|
|
91
|
+
readonly testType: TestType;
|
|
92
|
+
readonly isFlaky: boolean;
|
|
93
|
+
readonly retryStatus: string | null;
|
|
94
|
+
readonly expectedStatus: TestStatus;
|
|
95
|
+
readonly actualStatus: TestStatus;
|
|
96
|
+
readonly artifacts: TestArtifacts | null;
|
|
97
|
+
readonly networkRequests: CapturedNetworkRequest[] | null;
|
|
98
|
+
readonly apiCalls: readonly ApiCallRecord[] | null;
|
|
99
|
+
readonly apiAssertions: readonly ApiAssertion[] | null;
|
|
100
|
+
readonly actions: readonly ActionStep[] | null;
|
|
101
|
+
readonly consoleLogs: readonly ConsoleLogEntry[] | null;
|
|
102
|
+
}
|
|
103
|
+
type ResourceType = 'xhr' | 'document' | 'script' | 'stylesheet' | 'image' | 'font' | 'other';
|
|
104
|
+
interface CapturedNetworkRequest {
|
|
105
|
+
readonly url: string;
|
|
106
|
+
readonly method: string;
|
|
107
|
+
readonly resourceType: ResourceType;
|
|
108
|
+
readonly statusCode: number;
|
|
109
|
+
readonly responseTimeMs: number;
|
|
110
|
+
readonly startedAt: string;
|
|
111
|
+
readonly requestHeaders: Record<string, string> | null;
|
|
112
|
+
readonly requestBody: string | null;
|
|
113
|
+
readonly responseBody: string | null;
|
|
114
|
+
readonly responseHeaders: Record<string, string> | null;
|
|
115
|
+
readonly contentType: string | null;
|
|
116
|
+
readonly responseSize: number;
|
|
117
|
+
readonly requestBodyTruncated: boolean;
|
|
118
|
+
readonly responseBodyTruncated: boolean;
|
|
119
|
+
readonly isBinary: boolean;
|
|
120
|
+
readonly error: string | null;
|
|
121
|
+
}
|
|
122
|
+
interface TestArtifacts {
|
|
123
|
+
readonly screenshot?: string;
|
|
124
|
+
readonly video?: string;
|
|
125
|
+
readonly screenshotKey?: string;
|
|
126
|
+
readonly videoKey?: string;
|
|
127
|
+
}
|
|
128
|
+
type TestStatus = 'passed' | 'failed' | 'skipped' | 'flaky' | 'timedout';
|
|
129
|
+
type TestType = 'e2e' | 'api' | 'unit' | 'mobile' | 'unknown';
|
|
130
|
+
interface FailureDiagnostic {
|
|
131
|
+
readonly message: string;
|
|
132
|
+
readonly line: number | null;
|
|
133
|
+
readonly code: string | null;
|
|
134
|
+
readonly stack: string | null;
|
|
135
|
+
}
|
|
136
|
+
interface NetworkStats {
|
|
137
|
+
readonly totalRequests: number;
|
|
138
|
+
readonly failedRequests: number;
|
|
139
|
+
readonly failedRequestUrls: string[];
|
|
140
|
+
readonly totalBytes: number;
|
|
141
|
+
readonly byType: ResourceBreakdown;
|
|
142
|
+
}
|
|
143
|
+
interface ResourceBreakdown {
|
|
144
|
+
readonly xhr: number;
|
|
145
|
+
readonly document: number;
|
|
146
|
+
readonly script: number;
|
|
147
|
+
readonly stylesheet: number;
|
|
148
|
+
readonly image: number;
|
|
149
|
+
readonly font: number;
|
|
150
|
+
readonly other: number;
|
|
151
|
+
}
|
|
152
|
+
interface ApiCallRecord {
|
|
153
|
+
/** Unique call identifier within the test (e.g., "api-call-0") */
|
|
154
|
+
readonly id: string;
|
|
155
|
+
/** ISO 8601 timestamp when the call was initiated */
|
|
156
|
+
readonly timestamp: string;
|
|
157
|
+
/** HTTP method: GET, POST, PUT, PATCH, DELETE, HEAD, or custom via fetch() */
|
|
158
|
+
readonly method: string;
|
|
159
|
+
/** Full resolved URL (after baseURL resolution by Playwright) */
|
|
160
|
+
readonly url: string;
|
|
161
|
+
/** All request headers sent, or null if unavailable */
|
|
162
|
+
readonly requestHeaders: Record<string, string> | null;
|
|
163
|
+
/** Request payload as string (JSON-serialized for objects). Null for bodiless methods */
|
|
164
|
+
readonly requestBody: string | null;
|
|
165
|
+
/** HTTP response status code, or null if request errored before response */
|
|
166
|
+
readonly responseStatusCode: number | null;
|
|
167
|
+
/** HTTP response status text, or null if request errored before response */
|
|
168
|
+
readonly responseStatusText: string | null;
|
|
169
|
+
/** All response headers received, or null if request errored before response */
|
|
170
|
+
readonly responseHeaders: Record<string, string> | null;
|
|
171
|
+
/** Response body: string for text/JSON, base64 for binary. Null on error */
|
|
172
|
+
readonly responseBody: string | null;
|
|
173
|
+
/** Duration in milliseconds from request initiation to response received */
|
|
174
|
+
readonly responseTimeMs: number;
|
|
175
|
+
/** Whether the response body is stored as a base64-encoded binary string */
|
|
176
|
+
readonly isBinary: boolean;
|
|
177
|
+
/** Error message if the call failed (network error, timeout), null on success */
|
|
178
|
+
readonly error: string | null;
|
|
179
|
+
}
|
|
180
|
+
/** Categorization of the assertion being made. */
|
|
181
|
+
type AssertionType = 'status' | 'statusOk' | 'header' | 'bodyField' | 'bodyMatch' | 'bodyContains' | 'custom';
|
|
182
|
+
/** Source location where an assertion was made in the test file. */
|
|
183
|
+
interface AssertionLocation {
|
|
184
|
+
/** Absolute or relative file path to the test file */
|
|
185
|
+
readonly file: string;
|
|
186
|
+
/** Line number (1-based) */
|
|
187
|
+
readonly line: number;
|
|
188
|
+
/** Column number (1-based), if available */
|
|
189
|
+
readonly column?: number;
|
|
190
|
+
}
|
|
191
|
+
/** A single captured assertion on API response data. */
|
|
192
|
+
interface ApiAssertion {
|
|
193
|
+
/** Links to ApiCallRecord.id from the API proxy */
|
|
194
|
+
readonly callId: string;
|
|
195
|
+
/** Category of assertion */
|
|
196
|
+
readonly type: AssertionType;
|
|
197
|
+
/** What the test expected */
|
|
198
|
+
readonly expected: unknown;
|
|
199
|
+
/** What was actually received */
|
|
200
|
+
readonly actual: unknown;
|
|
201
|
+
/** Whether the assertion passed or failed */
|
|
202
|
+
readonly status: 'passed' | 'failed';
|
|
203
|
+
/** Source location of the assertion in the test file */
|
|
204
|
+
readonly location: AssertionLocation;
|
|
205
|
+
/** String representation of the assertion expression (best-effort) */
|
|
206
|
+
readonly expression?: string;
|
|
207
|
+
}
|
|
208
|
+
/** Test identity block attached to every timeline step. */
|
|
209
|
+
interface StepTestIdentity {
|
|
210
|
+
readonly title: string;
|
|
211
|
+
readonly fullTitle: readonly string[];
|
|
212
|
+
readonly status: TestStatus;
|
|
213
|
+
readonly duration: number;
|
|
214
|
+
readonly retries: number;
|
|
215
|
+
readonly retry: number;
|
|
216
|
+
readonly tags: readonly string[];
|
|
217
|
+
readonly failure: FailureDiagnostic | null;
|
|
218
|
+
}
|
|
219
|
+
/** Request details within an API call step. */
|
|
220
|
+
interface ApiCallStepRequest {
|
|
221
|
+
readonly headers: Record<string, string> | null;
|
|
222
|
+
readonly body: unknown;
|
|
223
|
+
}
|
|
224
|
+
/** Response details within an API call step. */
|
|
225
|
+
interface ApiCallStepResponse {
|
|
226
|
+
readonly statusCode: number;
|
|
227
|
+
readonly statusText: string;
|
|
228
|
+
readonly headers: Record<string, string> | null;
|
|
229
|
+
readonly body: unknown;
|
|
230
|
+
}
|
|
231
|
+
/** An assertion linked to an API call step (callId omitted — implicit from parent). */
|
|
232
|
+
interface StepAssertion {
|
|
233
|
+
readonly type: AssertionType;
|
|
234
|
+
readonly expected: unknown;
|
|
235
|
+
readonly actual: unknown;
|
|
236
|
+
readonly status: 'passed' | 'failed';
|
|
237
|
+
readonly location: AssertionLocation;
|
|
238
|
+
readonly expression?: string;
|
|
239
|
+
}
|
|
240
|
+
/** A browser navigation event in the unified timeline. */
|
|
241
|
+
interface NavigationStep {
|
|
242
|
+
readonly index: number;
|
|
243
|
+
readonly type: 'navigation';
|
|
244
|
+
readonly url: string;
|
|
245
|
+
readonly timestamp: string;
|
|
246
|
+
readonly durationOnUrl: number;
|
|
247
|
+
readonly navigationType: NavigationType;
|
|
248
|
+
readonly domContentLoadedAt: string | null;
|
|
249
|
+
readonly networkIdleAt: string | null;
|
|
250
|
+
readonly networkStats: NetworkStats | null;
|
|
251
|
+
readonly specFile: string;
|
|
252
|
+
readonly test: StepTestIdentity;
|
|
253
|
+
}
|
|
254
|
+
/** An API request event in the unified timeline. */
|
|
255
|
+
interface ApiCallStep {
|
|
256
|
+
readonly index: number;
|
|
257
|
+
readonly type: 'api_call';
|
|
258
|
+
readonly callId: string;
|
|
259
|
+
readonly method: string;
|
|
260
|
+
readonly url: string;
|
|
261
|
+
readonly timestamp: string;
|
|
262
|
+
readonly responseTime: number | null;
|
|
263
|
+
readonly request: ApiCallStepRequest;
|
|
264
|
+
readonly response: ApiCallStepResponse | null;
|
|
265
|
+
readonly error?: string | null;
|
|
266
|
+
readonly assertions: readonly StepAssertion[];
|
|
267
|
+
readonly specFile: string;
|
|
268
|
+
readonly test: StepTestIdentity;
|
|
269
|
+
}
|
|
270
|
+
/** Discriminated union of all timeline step types. */
|
|
271
|
+
type TimelineStep = NavigationStep | ApiCallStep;
|
|
272
|
+
/** Categorized type of a captured test action. */
|
|
273
|
+
type ActionCategory = 'ui_action' | 'assertion' | 'custom_step';
|
|
274
|
+
/** A single captured test action step. */
|
|
275
|
+
interface ActionStep {
|
|
276
|
+
readonly title: string;
|
|
277
|
+
readonly category: ActionCategory;
|
|
278
|
+
readonly timestamp: string;
|
|
279
|
+
readonly duration: number;
|
|
280
|
+
readonly videoOffset: number | null;
|
|
281
|
+
readonly status: 'passed' | 'failed';
|
|
282
|
+
readonly error: string | null;
|
|
283
|
+
readonly children: readonly ActionStep[];
|
|
284
|
+
}
|
|
285
|
+
/** Level of a captured console/terminal log message. */
|
|
286
|
+
type ConsoleLogLevel = 'log' | 'warn' | 'error' | 'info' | 'debug' | 'stdout' | 'stderr';
|
|
287
|
+
/** A single captured console or terminal log entry. */
|
|
288
|
+
interface ConsoleLogEntry {
|
|
289
|
+
/** Log level or stream type */
|
|
290
|
+
readonly level: ConsoleLogLevel;
|
|
291
|
+
/** Text content of the log message */
|
|
292
|
+
readonly text: string;
|
|
293
|
+
/** ISO 8601 timestamp when the log was captured */
|
|
294
|
+
readonly timestamp: string;
|
|
295
|
+
/** Source file location (browser console only, best-effort) */
|
|
296
|
+
readonly location: string | null;
|
|
297
|
+
}
|
|
298
|
+
/** Report generation mode. */
|
|
299
|
+
type ReportMode = 'streaming' | 'embedded' | 'auto';
|
|
300
|
+
interface ReporterConfig {
|
|
301
|
+
readonly outputPath?: string;
|
|
302
|
+
readonly includeStackTrace?: boolean;
|
|
303
|
+
readonly includeCodeSnippets?: boolean;
|
|
304
|
+
readonly codeContextLines?: number;
|
|
305
|
+
readonly includeNetworkStats?: boolean;
|
|
306
|
+
readonly navigationTypes?: NavigationType[] | null;
|
|
307
|
+
readonly redactPatterns?: (string | RegExp)[];
|
|
308
|
+
readonly testRunId?: string | null;
|
|
309
|
+
readonly metadata?: Record<string, unknown> | null;
|
|
310
|
+
readonly openReport?: boolean;
|
|
311
|
+
readonly htmlReportPath?: string;
|
|
312
|
+
readonly includeArtifacts?: boolean;
|
|
313
|
+
/** When false, disables API call interception in the unified fixture. Default: true */
|
|
314
|
+
readonly trackApiCalls?: boolean;
|
|
315
|
+
/** When true, suppresses console summary output. Default: false */
|
|
316
|
+
readonly quiet?: boolean;
|
|
317
|
+
/** When true, captures Playwright test steps (actions). Default: true */
|
|
318
|
+
readonly includeActionSteps?: boolean;
|
|
319
|
+
/** Capture request headers for API calls. Default: true */
|
|
320
|
+
readonly captureRequestHeaders?: boolean;
|
|
321
|
+
/** Capture response headers for API calls. Default: true */
|
|
322
|
+
readonly captureResponseHeaders?: boolean;
|
|
323
|
+
/** Capture request body for API calls. Default: true */
|
|
324
|
+
readonly captureRequestBody?: boolean;
|
|
325
|
+
/** Capture response body for API calls. Default: true */
|
|
326
|
+
readonly captureResponseBody?: boolean;
|
|
327
|
+
/** Capture API assertions (both pass and fail). Default: true */
|
|
328
|
+
readonly captureAssertions?: boolean;
|
|
329
|
+
/**
|
|
330
|
+
* Header names whose values are replaced with "[REDACTED]".
|
|
331
|
+
* Case-insensitive matching. Default: ['authorization', 'cookie', 'set-cookie', 'x-api-key']
|
|
332
|
+
*/
|
|
333
|
+
readonly redactHeaders?: string[];
|
|
334
|
+
/**
|
|
335
|
+
* Body field names whose values are replaced with "[REDACTED]" at any depth.
|
|
336
|
+
* Default: ['password', 'secret', 'token', 'apiKey', 'api_key']
|
|
337
|
+
*/
|
|
338
|
+
readonly redactBodyFields?: string[];
|
|
339
|
+
/**
|
|
340
|
+
* Only track API calls matching these URL patterns.
|
|
341
|
+
* Default: undefined (track all)
|
|
342
|
+
*/
|
|
343
|
+
readonly apiIncludeUrls?: (string | RegExp)[];
|
|
344
|
+
/**
|
|
345
|
+
* Exclude API calls matching these URL patterns. Takes precedence over include.
|
|
346
|
+
* Default: undefined (exclude none)
|
|
347
|
+
*/
|
|
348
|
+
readonly apiExcludeUrls?: (string | RegExp)[];
|
|
349
|
+
/** Capture browser console logs (E2E) and terminal output (API). Default: true */
|
|
350
|
+
readonly captureConsoleLogs?: boolean;
|
|
351
|
+
/** Cloud integration configuration. Default: undefined (local mode) */
|
|
352
|
+
readonly cloud?: CloudReporterOptions;
|
|
353
|
+
/**
|
|
354
|
+
* Report generation mode.
|
|
355
|
+
* - `'embedded'`: All data embedded in a single HTML file (current behavior)
|
|
356
|
+
* - `'streaming'`: Data streamed to disk per-test, served via local server
|
|
357
|
+
* - `'auto'`: Use embedded for < streamingThreshold tests, streaming otherwise
|
|
358
|
+
* Default: `'auto'`
|
|
359
|
+
*/
|
|
360
|
+
readonly reportMode?: ReportMode;
|
|
361
|
+
/**
|
|
362
|
+
* Test count threshold for auto mode. When the suite has >= this many tests,
|
|
363
|
+
* streaming mode is used. Default: 500
|
|
364
|
+
*/
|
|
365
|
+
readonly streamingThreshold?: number;
|
|
366
|
+
}
|
|
367
|
+
interface NavigationAnnotation {
|
|
368
|
+
readonly url: string;
|
|
369
|
+
readonly navigationType: NavigationType;
|
|
370
|
+
readonly timestamp: string;
|
|
371
|
+
readonly domContentLoadedAt?: string;
|
|
372
|
+
readonly networkIdleAt?: string;
|
|
373
|
+
readonly networkStats?: NetworkStats;
|
|
374
|
+
}
|
|
375
|
+
/** Consolidated data payload sent from a worker fixture to the reporter. */
|
|
376
|
+
interface TestRelicDataPayload {
|
|
377
|
+
/** Marker to identify TestRelic attachments. Always `true`. */
|
|
378
|
+
readonly testRelicData: true;
|
|
379
|
+
/** Payload format version (semver). */
|
|
380
|
+
readonly version: string;
|
|
381
|
+
/** Navigation events collected during the test. */
|
|
382
|
+
readonly navigations: readonly NavigationAnnotation[];
|
|
383
|
+
/** Captured network requests during the test. */
|
|
384
|
+
readonly networkRequests: readonly CapturedNetworkRequest[];
|
|
385
|
+
/** API calls made via APIRequestContext proxy. */
|
|
386
|
+
readonly apiCalls: readonly ApiCallRecord[];
|
|
387
|
+
/** Assertions captured on API responses. */
|
|
388
|
+
readonly apiAssertions: readonly ApiAssertion[];
|
|
389
|
+
/** Console/terminal logs captured during the test. Optional for backward compat. */
|
|
390
|
+
readonly consoleLogs?: readonly ConsoleLogEntry[];
|
|
391
|
+
}
|
|
392
|
+
/** Current payload format version. */
|
|
393
|
+
declare const PAYLOAD_VERSION = "2.0.0";
|
|
394
|
+
/** Legacy payload version (pre-streaming). */
|
|
395
|
+
declare const PAYLOAD_VERSION_LEGACY = "1.0.0";
|
|
396
|
+
/** Attachment name used for the consolidated payload. */
|
|
397
|
+
declare const ATTACHMENT_NAME = "testrelic-data";
|
|
398
|
+
/** Attachment content type. */
|
|
399
|
+
declare const ATTACHMENT_CONTENT_TYPE = "application/json";
|
|
400
|
+
/**
|
|
401
|
+
* File-based data payload (v2.0.0).
|
|
402
|
+
*
|
|
403
|
+
* Heavy data (network requests, console logs, API calls) is written to
|
|
404
|
+
* JSONL files on disk and referenced by path. Only lightweight data
|
|
405
|
+
* (navigations, assertions) is kept inline.
|
|
406
|
+
*/
|
|
407
|
+
interface TestRelicFilePayload {
|
|
408
|
+
/** Marker to identify TestRelic attachments. Always `true`. */
|
|
409
|
+
readonly testRelicData: true;
|
|
410
|
+
/** Payload format version — `"2.0.0"` for file-based payloads. */
|
|
411
|
+
readonly version: '2.0.0';
|
|
412
|
+
/** Navigation events (small, kept inline). */
|
|
413
|
+
readonly navigations: readonly NavigationAnnotation[];
|
|
414
|
+
/** API assertions (small, kept inline). */
|
|
415
|
+
readonly apiAssertions: readonly ApiAssertion[];
|
|
416
|
+
/** Absolute path to JSONL file containing CapturedNetworkRequest items. */
|
|
417
|
+
readonly networkRequestsFile: string | null;
|
|
418
|
+
/** Number of network request items in the file. */
|
|
419
|
+
readonly networkRequestsCount: number;
|
|
420
|
+
/** Absolute path to JSONL file containing ConsoleLogEntry items. */
|
|
421
|
+
readonly consoleLogsFile: string | null;
|
|
422
|
+
/** Number of console log items in the file. */
|
|
423
|
+
readonly consoleLogsCount: number;
|
|
424
|
+
/** Absolute path to JSONL file containing ApiCallRecord items. */
|
|
425
|
+
readonly apiCallsFile: string | null;
|
|
426
|
+
/** Number of API call items in the file. */
|
|
427
|
+
readonly apiCallsCount: number;
|
|
428
|
+
}
|
|
429
|
+
/** Type guard: validates that a parsed object is a v2 file-based payload. */
|
|
430
|
+
declare function isTestRelicFilePayload(obj: unknown): obj is TestRelicFilePayload;
|
|
431
|
+
/** Type guard: validates that a parsed object is a v1 inline data payload. */
|
|
432
|
+
declare function isTestRelicDataPayload(obj: unknown): obj is TestRelicDataPayload;
|
|
433
|
+
/** Upload strategy for cloud timeline data. */
|
|
434
|
+
type UploadStrategy = 'batch' | 'realtime' | 'both';
|
|
435
|
+
/** Current cloud/local operating mode. */
|
|
436
|
+
type AuthMode = 'cloud' | 'local' | 'pending';
|
|
437
|
+
/** Resolved cloud configuration, immutable after initialization. */
|
|
438
|
+
interface CloudConfig {
|
|
439
|
+
readonly apiKey: string | null;
|
|
440
|
+
readonly endpoint: string;
|
|
441
|
+
readonly uploadStrategy: UploadStrategy;
|
|
442
|
+
readonly timeout: number;
|
|
443
|
+
readonly projectName: string | null;
|
|
444
|
+
readonly queueMaxAge: number;
|
|
445
|
+
readonly queueDirectory: string;
|
|
446
|
+
readonly uploadArtifacts: boolean;
|
|
447
|
+
readonly artifactMaxSizeMb: number;
|
|
448
|
+
}
|
|
449
|
+
/** Mutable auth state tracked by the cloud client. */
|
|
450
|
+
interface AuthState {
|
|
451
|
+
mode: AuthMode;
|
|
452
|
+
accessToken: string | null;
|
|
453
|
+
refreshToken: string | null;
|
|
454
|
+
expiresAt: number | null;
|
|
455
|
+
orgId: string | null;
|
|
456
|
+
orgName: string | null;
|
|
457
|
+
userId: string | null;
|
|
458
|
+
userName: string | null;
|
|
459
|
+
}
|
|
460
|
+
/** Auto-collected git information. All fields nullable. */
|
|
461
|
+
interface GitMetadata {
|
|
462
|
+
readonly branch: string | null;
|
|
463
|
+
readonly commitSha: string | null;
|
|
464
|
+
readonly commitMessage: string | null;
|
|
465
|
+
readonly commitAuthor: string | null;
|
|
466
|
+
readonly remoteUrl: string | null;
|
|
467
|
+
}
|
|
468
|
+
/** Cached repo identity. */
|
|
469
|
+
interface RepoResolution {
|
|
470
|
+
readonly repoId: string;
|
|
471
|
+
readonly gitId: string;
|
|
472
|
+
readonly displayName: string;
|
|
473
|
+
readonly resolvedAt: number;
|
|
474
|
+
readonly apiKeyHash: string;
|
|
475
|
+
}
|
|
476
|
+
/** A single queued upload payload. */
|
|
477
|
+
interface QueueEntry {
|
|
478
|
+
readonly version: string;
|
|
479
|
+
readonly queuedAt: string;
|
|
480
|
+
readonly reason: string;
|
|
481
|
+
readonly retryCount: number;
|
|
482
|
+
readonly targetEndpoint: string;
|
|
483
|
+
readonly method: string;
|
|
484
|
+
readonly payload: Record<string, unknown>;
|
|
485
|
+
readonly headers: Record<string, string>;
|
|
486
|
+
}
|
|
487
|
+
/** Inline cloud configuration accepted via reporter options. */
|
|
488
|
+
interface CloudReporterOptions {
|
|
489
|
+
readonly apiKey?: string;
|
|
490
|
+
readonly endpoint?: string;
|
|
491
|
+
readonly upload?: UploadStrategy;
|
|
492
|
+
readonly timeout?: number;
|
|
493
|
+
readonly projectName?: string;
|
|
494
|
+
readonly queueMaxAge?: string;
|
|
495
|
+
readonly queueDirectory?: string;
|
|
496
|
+
readonly uploadArtifacts?: boolean;
|
|
497
|
+
readonly artifactMaxSizeMb?: number;
|
|
498
|
+
}
|
|
499
|
+
interface MergeOptions {
|
|
500
|
+
readonly output: string;
|
|
501
|
+
readonly testRunId?: string;
|
|
502
|
+
}
|
|
503
|
+
/** A single artifact file within a test's artifact folder. */
|
|
504
|
+
interface ArtifactFile {
|
|
505
|
+
/** File name (e.g., `screenshot.png`, `video.webm`) */
|
|
506
|
+
readonly name: string;
|
|
507
|
+
/** Artifact type for rendering */
|
|
508
|
+
readonly type: 'screenshot' | 'video' | 'other';
|
|
509
|
+
/** Path relative to the report output directory */
|
|
510
|
+
readonly relativePath: string;
|
|
511
|
+
/** File size in bytes */
|
|
512
|
+
readonly sizeBytes: number;
|
|
513
|
+
}
|
|
514
|
+
/** A single test's artifacts within a run folder. */
|
|
515
|
+
interface ArtifactTestEntry {
|
|
516
|
+
/** Sanitized test folder name */
|
|
517
|
+
readonly testName: string;
|
|
518
|
+
/** List of artifact files for this test */
|
|
519
|
+
readonly files: readonly ArtifactFile[];
|
|
520
|
+
}
|
|
521
|
+
/** A single test run's artifact folder in the manifest. */
|
|
522
|
+
interface ArtifactRunEntry {
|
|
523
|
+
/** Timestamp-based folder name (e.g., `2026-03-02T14-30-00`) */
|
|
524
|
+
readonly folderName: string;
|
|
525
|
+
/** ISO 8601 timestamp parsed from folder name */
|
|
526
|
+
readonly timestamp: string;
|
|
527
|
+
/** Sum of all file sizes in this run folder */
|
|
528
|
+
readonly totalSizeBytes: number;
|
|
529
|
+
/** Number of test artifact subdirectories */
|
|
530
|
+
readonly testCount: number;
|
|
531
|
+
/** Per-test artifact details */
|
|
532
|
+
readonly tests: readonly ArtifactTestEntry[];
|
|
533
|
+
/** Whether this folder belongs to the current report's run */
|
|
534
|
+
readonly isCurrentRun: boolean;
|
|
535
|
+
}
|
|
536
|
+
/** Top-level manifest structure written as `artifact-manifest.json`. */
|
|
537
|
+
interface ArtifactRunManifest {
|
|
538
|
+
/** Manifest schema version (starts at `"1.0"`) */
|
|
539
|
+
readonly schemaVersion: string;
|
|
540
|
+
/** ISO 8601 timestamp of manifest generation */
|
|
541
|
+
readonly generatedAt: string;
|
|
542
|
+
/** Relative path to artifacts directory from report (e.g., `"artifacts"`) */
|
|
543
|
+
readonly artifactBaseDir: string;
|
|
544
|
+
/** Sum of all run folder sizes */
|
|
545
|
+
readonly totalSizeBytes: number;
|
|
546
|
+
/** All discovered run folders, sorted newest first */
|
|
547
|
+
readonly runs: readonly ArtifactRunEntry[];
|
|
548
|
+
/** Port of the artifact management server, or null if not running */
|
|
549
|
+
readonly serverPort: number | null;
|
|
550
|
+
}
|
|
551
|
+
/** Compact index entry for a single test — kept in memory during run. */
|
|
552
|
+
interface TestIndexEntry {
|
|
553
|
+
/** Deterministic hash ID (first 12 chars of SHA-256) */
|
|
554
|
+
readonly id: string;
|
|
555
|
+
/** Test title (leaf name) */
|
|
556
|
+
readonly title: string;
|
|
557
|
+
/** Full title path (describe blocks + test name) */
|
|
558
|
+
readonly titlePath: readonly string[];
|
|
559
|
+
/** Relative path to test file */
|
|
560
|
+
readonly filePath: string;
|
|
561
|
+
/** Test outcome */
|
|
562
|
+
readonly status: TestStatus;
|
|
563
|
+
/** Test duration in milliseconds */
|
|
564
|
+
readonly duration: number;
|
|
565
|
+
/** Playwright project name */
|
|
566
|
+
readonly project: string;
|
|
567
|
+
/** Retry attempt number (0 = first run) */
|
|
568
|
+
readonly retryIndex: number;
|
|
569
|
+
/** Test tags */
|
|
570
|
+
readonly tags: readonly string[];
|
|
571
|
+
/** Whether this test has network request data */
|
|
572
|
+
readonly hasNetworkData: boolean;
|
|
573
|
+
/** Whether this test has console log data */
|
|
574
|
+
readonly hasConsoleData: boolean;
|
|
575
|
+
/** Whether this test has screenshot/video artifacts */
|
|
576
|
+
readonly hasArtifacts: boolean;
|
|
577
|
+
/** Whether this test has action step data */
|
|
578
|
+
readonly hasActionSteps: boolean;
|
|
579
|
+
/** First line of error message (failed/flaky tests only) */
|
|
580
|
+
readonly errorMessage: string | null;
|
|
581
|
+
/** Number of network requests captured */
|
|
582
|
+
readonly networkCount: number;
|
|
583
|
+
/** Number of console log entries captured */
|
|
584
|
+
readonly consoleCount: number;
|
|
585
|
+
/** Number of action steps captured */
|
|
586
|
+
readonly actionCount: number;
|
|
587
|
+
/** Whether this is a retry attempt (not the final attempt) */
|
|
588
|
+
readonly isRetry: boolean;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Full detail data for a single test, stored on disk.
|
|
592
|
+
*
|
|
593
|
+
* In v3 (stream-to-disk), heavy data (network requests, console logs,
|
|
594
|
+
* API calls) is stored in separate JSONL files alongside meta.json.
|
|
595
|
+
* The `has*` and `*Count` fields indicate availability without loading.
|
|
596
|
+
*/
|
|
597
|
+
interface TestDetailData {
|
|
598
|
+
/** Same as TestIndexEntry.id */
|
|
599
|
+
readonly id: string;
|
|
600
|
+
/** Page navigation events (inline — typically small) */
|
|
601
|
+
readonly navigations: readonly NavigationAnnotation[];
|
|
602
|
+
/** API assertion results (inline — typically small) */
|
|
603
|
+
readonly apiAssertions: readonly ApiAssertion[];
|
|
604
|
+
/** Nested action step tree (inline — typically small) */
|
|
605
|
+
readonly actions: readonly ActionStep[];
|
|
606
|
+
/** References to screenshot/video files */
|
|
607
|
+
readonly artifacts: TestArtifacts | null;
|
|
608
|
+
/** Error details for failed/flaky tests */
|
|
609
|
+
readonly failureDiagnostic: FailureDiagnostic | null;
|
|
610
|
+
/** Whether network.jsonl exists for this test */
|
|
611
|
+
readonly hasNetworkFile: boolean;
|
|
612
|
+
/** Number of items in network.jsonl */
|
|
613
|
+
readonly networkRequestsCount: number;
|
|
614
|
+
/** Whether console.jsonl exists for this test */
|
|
615
|
+
readonly hasConsoleFile: boolean;
|
|
616
|
+
/** Number of items in console.jsonl */
|
|
617
|
+
readonly consoleLogsCount: number;
|
|
618
|
+
/** Whether api-calls.jsonl exists for this test */
|
|
619
|
+
readonly hasApiCallsFile: boolean;
|
|
620
|
+
/** Number of items in api-calls.jsonl */
|
|
621
|
+
readonly apiCallsCount: number;
|
|
622
|
+
/** Test start time (ISO 8601) — used for video sync */
|
|
623
|
+
readonly startedAt?: string;
|
|
624
|
+
}
|
|
625
|
+
/** Streaming report summary — running counters written to summary.json. */
|
|
626
|
+
interface StreamingReportSummary {
|
|
627
|
+
/** Unique run identifier */
|
|
628
|
+
readonly testRunId: string;
|
|
629
|
+
/** ISO 8601 start timestamp */
|
|
630
|
+
readonly startedAt: string;
|
|
631
|
+
/** ISO 8601 completion timestamp */
|
|
632
|
+
readonly completedAt: string;
|
|
633
|
+
/** Wall-clock duration in ms */
|
|
634
|
+
readonly totalDuration: number;
|
|
635
|
+
/** Total number of test results */
|
|
636
|
+
readonly total: number;
|
|
637
|
+
/** Tests that passed */
|
|
638
|
+
readonly passed: number;
|
|
639
|
+
/** Tests that failed */
|
|
640
|
+
readonly failed: number;
|
|
641
|
+
/** Tests that passed on retry */
|
|
642
|
+
readonly flaky: number;
|
|
643
|
+
/** Tests that were skipped */
|
|
644
|
+
readonly skipped: number;
|
|
645
|
+
/** Tests that timed out */
|
|
646
|
+
readonly timedOut: number;
|
|
647
|
+
/** Tests that were interrupted */
|
|
648
|
+
readonly interrupted: number;
|
|
649
|
+
/** Total API calls across all tests */
|
|
650
|
+
readonly totalApiCalls: number;
|
|
651
|
+
/** Total assertions across all tests */
|
|
652
|
+
readonly totalAssertions: number;
|
|
653
|
+
/** Total page navigations */
|
|
654
|
+
readonly totalNavigations: number;
|
|
655
|
+
/** Total network requests captured */
|
|
656
|
+
readonly totalNetworkRequests: number;
|
|
657
|
+
/** Total console log entries captured */
|
|
658
|
+
readonly totalConsoleLogs: number;
|
|
659
|
+
/** Total action steps captured */
|
|
660
|
+
readonly totalActionSteps: number;
|
|
661
|
+
/** User-provided metadata */
|
|
662
|
+
readonly metadata: Record<string, unknown> | null;
|
|
663
|
+
/** Report generation mode */
|
|
664
|
+
readonly reportMode: ReportMode;
|
|
665
|
+
/** Per-file aggregation */
|
|
666
|
+
readonly files: readonly StreamingFileStats[];
|
|
667
|
+
/** Enriched summary (matches existing Summary interface) */
|
|
668
|
+
readonly enrichedSummary: Summary | null;
|
|
669
|
+
/** Validation cross-check data */
|
|
670
|
+
readonly validation: StreamingValidation | null;
|
|
671
|
+
/** Write errors encountered during streaming */
|
|
672
|
+
readonly writeErrors: readonly StreamingWriteError[];
|
|
673
|
+
}
|
|
674
|
+
/** Per-file test aggregation for streaming reports. */
|
|
675
|
+
interface StreamingFileStats {
|
|
676
|
+
readonly filePath: string;
|
|
677
|
+
readonly total: number;
|
|
678
|
+
readonly passed: number;
|
|
679
|
+
readonly failed: number;
|
|
680
|
+
readonly flaky: number;
|
|
681
|
+
readonly skipped: number;
|
|
682
|
+
readonly timedOut: number;
|
|
683
|
+
}
|
|
684
|
+
/** Validation cross-check between reporter counts and Playwright. */
|
|
685
|
+
interface StreamingValidation {
|
|
686
|
+
readonly reporterTotal: number;
|
|
687
|
+
readonly indexTotal: number;
|
|
688
|
+
readonly playwrightStatus: string;
|
|
689
|
+
readonly isValid: boolean;
|
|
690
|
+
}
|
|
691
|
+
/** A write error that occurred during streaming. */
|
|
692
|
+
interface StreamingWriteError {
|
|
693
|
+
readonly testId: string;
|
|
694
|
+
readonly error: string;
|
|
695
|
+
readonly timestamp: string;
|
|
696
|
+
}
|
|
697
|
+
/** Top-level manifest for a streaming report directory. */
|
|
698
|
+
interface StreamingReportManifest {
|
|
699
|
+
/** Schema version (`"2.0"` for streaming format) */
|
|
700
|
+
readonly schemaVersion: string;
|
|
701
|
+
/** ISO 8601 generation timestamp */
|
|
702
|
+
readonly generatedAt: string;
|
|
703
|
+
/** Report generation mode */
|
|
704
|
+
readonly reportMode: ReportMode;
|
|
705
|
+
/** Relative path to summary.json */
|
|
706
|
+
readonly summaryFile: string;
|
|
707
|
+
/** Relative path to index.json */
|
|
708
|
+
readonly indexFile: string;
|
|
709
|
+
/** Relative path to tests/ directory */
|
|
710
|
+
readonly testsDir: string;
|
|
711
|
+
/** Relative path to artifacts/ directory */
|
|
712
|
+
readonly artifactsDir: string;
|
|
713
|
+
/** Total number of test detail files */
|
|
714
|
+
readonly testCount: number;
|
|
715
|
+
/** Total size of all report data on disk */
|
|
716
|
+
readonly totalSizeBytes: number;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* @testrelic/core — Configurable logger
|
|
721
|
+
*
|
|
722
|
+
* Provides a Logger interface with a no-op default.
|
|
723
|
+
* Never uses console.* directly (Constitution SDK Constraint).
|
|
724
|
+
*/
|
|
725
|
+
interface Logger {
|
|
726
|
+
info(message: string, ...args: unknown[]): void;
|
|
727
|
+
warn(message: string, ...args: unknown[]): void;
|
|
728
|
+
error(message: string, ...args: unknown[]): void;
|
|
729
|
+
debug(message: string, ...args: unknown[]): void;
|
|
730
|
+
}
|
|
731
|
+
interface LoggerOptions {
|
|
732
|
+
readonly handler?: (level: LogLevel, message: string, args: unknown[]) => void;
|
|
733
|
+
}
|
|
734
|
+
type LogLevel = 'info' | 'warn' | 'error' | 'debug';
|
|
735
|
+
declare function createLogger(options?: LoggerOptions): Logger;
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* @testrelic/core — Structured error factory
|
|
739
|
+
*
|
|
740
|
+
* Machine-readable error codes for programmatic handling.
|
|
741
|
+
*/
|
|
742
|
+
declare const ErrorCode: {
|
|
743
|
+
readonly CONFIG_INVALID: "TESTRELIC_CONFIG_INVALID";
|
|
744
|
+
readonly OUTPUT_WRITE_FAILED: "TESTRELIC_OUTPUT_WRITE_FAILED";
|
|
745
|
+
readonly MERGE_INVALID_SCHEMA: "TESTRELIC_MERGE_INVALID_SCHEMA";
|
|
746
|
+
readonly MERGE_READ_FAILED: "TESTRELIC_MERGE_READ_FAILED";
|
|
747
|
+
readonly NAVIGATION_FLUSH_FAILED: "TESTRELIC_NAVIGATION_FLUSH_FAILED";
|
|
748
|
+
readonly CODE_EXTRACT_FAILED: "TESTRELIC_CODE_EXTRACT_FAILED";
|
|
749
|
+
readonly HTML_REPORT_FAILED: "TESTRELIC_HTML_REPORT_FAILED";
|
|
750
|
+
readonly CLOUD_AUTH_FAILED: "TESTRELIC_CLOUD_AUTH_FAILED";
|
|
751
|
+
readonly CLOUD_UPLOAD_FAILED: "TESTRELIC_CLOUD_UPLOAD_FAILED";
|
|
752
|
+
readonly CLOUD_CONFIG_INVALID: "TESTRELIC_CLOUD_CONFIG_INVALID";
|
|
753
|
+
readonly CLOUD_QUEUE_FAILED: "TESTRELIC_CLOUD_QUEUE_FAILED";
|
|
754
|
+
};
|
|
755
|
+
type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
|
|
756
|
+
declare class TestRelicError extends Error {
|
|
757
|
+
readonly code: ErrorCode;
|
|
758
|
+
constructor(code: ErrorCode, message: string, cause?: unknown);
|
|
759
|
+
}
|
|
760
|
+
declare function createError(code: ErrorCode, message: string, cause?: unknown): TestRelicError;
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* @testrelic/core — Lightweight runtime type guards
|
|
764
|
+
*
|
|
765
|
+
* Hand-written guards, no runtime schema libraries (Constitution SDK Constraint).
|
|
766
|
+
*/
|
|
767
|
+
|
|
768
|
+
declare function isValidNavigationType(value: unknown): value is NavigationType;
|
|
769
|
+
declare function isValidConfig(input: unknown): input is ReporterConfig;
|
|
770
|
+
declare function isValidApiKeyFormat(value: unknown): value is string;
|
|
771
|
+
declare function isValidUploadStrategy(value: unknown): value is UploadStrategy;
|
|
772
|
+
declare function isValidEndpointUrl(value: unknown): boolean;
|
|
773
|
+
declare function isValidCloudConfig(input: unknown): input is CloudConfig;
|
|
774
|
+
declare function isValidQueueEntry(input: unknown): input is QueueEntry;
|
|
775
|
+
declare function isValidTestRunReport(value: unknown): value is TestRunReport;
|
|
776
|
+
|
|
777
|
+
export { ATTACHMENT_CONTENT_TYPE, ATTACHMENT_NAME, type ActionCategory, type ActionStep, type ApiAssertion, type ApiCallRecord, type ApiCallStep, type ApiCallStepRequest, type ApiCallStepResponse, type ArtifactFile, type ArtifactRunEntry, type ArtifactRunManifest, type ArtifactTestEntry, type AssertionLocation, type AssertionType, type AuthMode, type AuthState, type CIMetadata, type CIProvider, type CapturedNetworkRequest, type CloudConfig, type CloudReporterOptions, type ConsoleLogEntry, type ConsoleLogLevel, ErrorCode, type FailureDiagnostic, type GitMetadata, type LogLevel, type Logger, type LoggerOptions, type MergeOptions, type NavigationAnnotation, type NavigationStep, type NavigationType, type NetworkStats, PAYLOAD_VERSION, PAYLOAD_VERSION_LEGACY, type QueueEntry, type RepoResolution, type ReportMode, type ReporterConfig, type ResourceBreakdown, type ResourceType, type StepAssertion, type StepTestIdentity, type StreamingFileStats, type StreamingReportManifest, type StreamingReportSummary, type StreamingValidation, type StreamingWriteError, type Summary, type TestArtifacts, type TestDetailData, type TestIndexEntry, type TestRelicDataPayload, TestRelicError, type TestRelicFilePayload, type TestResult, type TestRunReport, type TestStatus, type TestType, type TimelineEntry, type TimelineStep, type UploadStrategy, createError, createLogger, isTestRelicDataPayload, isTestRelicFilePayload, isValidApiKeyFormat, isValidCloudConfig, isValidConfig, isValidEndpointUrl, isValidNavigationType, isValidQueueEntry, isValidTestRunReport, isValidUploadStrategy };
|