@testrelic/maestro-analytics 1.0.0-next.14
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 +108 -0
- package/dist/cli.cjs +4078 -0
- package/dist/index.cjs +1256 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +583 -0
- package/dist/index.d.ts +583 -0
- package/dist/index.js +1256 -0
- package/dist/index.js.map +1 -0
- package/dist/merge.cjs +3 -0
- package/dist/merge.cjs.map +1 -0
- package/dist/merge.d.cts +10 -0
- package/dist/merge.d.ts +10 -0
- package/dist/merge.js +3 -0
- package/dist/merge.js.map +1 -0
- package/package.json +81 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
import { TestStatus, CloudReporterOptions, ReportMode, CloudConfig, TimelineEntry, Summary, TestRunReport, AuthMode, GitMetadata, TimelineStep, CIMetadata } from '@testrelic/core';
|
|
2
|
+
export { ActionCategory, ActionStep, ArtifactRunManifest, AuthMode, AuthState, CIMetadata, CIProvider, CloudConfig, CloudReporterOptions, ConsoleLogEntry, ConsoleLogLevel, FailureDiagnostic, GitMetadata, MergeOptions, QueueEntry, ReportMode, StreamingReportSummary, Summary, TestArtifacts, TestDetailData, TestIndexEntry, TestResult, TestRunReport, TestStatus, TimelineEntry, TimelineStep, UploadStrategy } from '@testrelic/core';
|
|
3
|
+
export { mergeReports, mergeReportsFromDirectory } from './merge.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @testrelic/maestro-analytics — Type definitions
|
|
7
|
+
*
|
|
8
|
+
* Maestro-specific types for configuration, parsed flow results,
|
|
9
|
+
* step-level command data, and AI defect reports.
|
|
10
|
+
* Re-exports shared types from @testrelic/core.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
type MaestroPlatform = 'android' | 'ios' | 'web' | 'unknown';
|
|
14
|
+
interface MaestroReporterConfig {
|
|
15
|
+
readonly outputPath?: string;
|
|
16
|
+
readonly htmlReportPath?: string;
|
|
17
|
+
readonly openReport?: boolean;
|
|
18
|
+
readonly includeScreenshots?: boolean;
|
|
19
|
+
readonly includeVideo?: boolean;
|
|
20
|
+
readonly includeAiAnalysis?: boolean;
|
|
21
|
+
readonly includeLogs?: boolean;
|
|
22
|
+
readonly includeFlowMetadata?: boolean;
|
|
23
|
+
readonly flowsDir?: string;
|
|
24
|
+
readonly testRunId?: string;
|
|
25
|
+
readonly metadata?: Record<string, unknown>;
|
|
26
|
+
readonly cloud?: CloudReporterOptions;
|
|
27
|
+
readonly reportMode?: ReportMode;
|
|
28
|
+
readonly quiet?: boolean;
|
|
29
|
+
}
|
|
30
|
+
interface ResolvedMaestroConfig {
|
|
31
|
+
readonly outputPath: string;
|
|
32
|
+
readonly htmlReportPath: string;
|
|
33
|
+
readonly openReport: boolean;
|
|
34
|
+
readonly includeScreenshots: boolean;
|
|
35
|
+
readonly includeVideo: boolean;
|
|
36
|
+
readonly includeAiAnalysis: boolean;
|
|
37
|
+
readonly includeLogs: boolean;
|
|
38
|
+
readonly includeFlowMetadata: boolean;
|
|
39
|
+
readonly flowsDir: string | null;
|
|
40
|
+
readonly testRunId: string | null;
|
|
41
|
+
readonly metadata: Record<string, unknown> | null;
|
|
42
|
+
readonly cloud: CloudConfig | null;
|
|
43
|
+
readonly reportMode: ReportMode;
|
|
44
|
+
readonly quiet: boolean;
|
|
45
|
+
}
|
|
46
|
+
interface JUnitProperty {
|
|
47
|
+
readonly name: string;
|
|
48
|
+
readonly value: string;
|
|
49
|
+
}
|
|
50
|
+
interface JUnitTestCase {
|
|
51
|
+
readonly id: string | null;
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly classname: string;
|
|
54
|
+
readonly time: number;
|
|
55
|
+
readonly status: 'SUCCESS' | 'FAILURE' | 'ERROR' | 'SKIPPED';
|
|
56
|
+
readonly failureMessage: string | null;
|
|
57
|
+
readonly failureType: string | null;
|
|
58
|
+
readonly errorMessage: string | null;
|
|
59
|
+
readonly errorType: string | null;
|
|
60
|
+
readonly properties: JUnitProperty[];
|
|
61
|
+
}
|
|
62
|
+
interface JUnitTestSuite {
|
|
63
|
+
readonly name: string;
|
|
64
|
+
readonly device: string | null;
|
|
65
|
+
readonly tests: number;
|
|
66
|
+
readonly failures: number;
|
|
67
|
+
readonly errors: number;
|
|
68
|
+
readonly skipped: number;
|
|
69
|
+
readonly time: number;
|
|
70
|
+
readonly testCases: JUnitTestCase[];
|
|
71
|
+
readonly properties: JUnitProperty[];
|
|
72
|
+
}
|
|
73
|
+
interface JUnitReport {
|
|
74
|
+
readonly testSuites: JUnitTestSuite[];
|
|
75
|
+
readonly totalTests: number;
|
|
76
|
+
readonly totalFailures: number;
|
|
77
|
+
readonly totalErrors: number;
|
|
78
|
+
readonly totalSkipped: number;
|
|
79
|
+
readonly totalTime: number;
|
|
80
|
+
}
|
|
81
|
+
type MaestroCommandCategory = 'interaction' | 'assertion' | 'navigation' | 'device' | 'media' | 'script' | 'flow_control' | 'recording' | 'ai' | 'other';
|
|
82
|
+
interface MaestroCommandStep {
|
|
83
|
+
readonly command: string;
|
|
84
|
+
readonly category: MaestroCommandCategory;
|
|
85
|
+
readonly status: 'completed' | 'failed' | 'skipped';
|
|
86
|
+
readonly duration: number;
|
|
87
|
+
readonly timestamp: string;
|
|
88
|
+
readonly selector?: string;
|
|
89
|
+
readonly error?: string;
|
|
90
|
+
readonly metadata?: Record<string, unknown>;
|
|
91
|
+
}
|
|
92
|
+
interface MaestroFlowMetadata {
|
|
93
|
+
readonly appId: string | null;
|
|
94
|
+
readonly name: string | null;
|
|
95
|
+
readonly tags: string[];
|
|
96
|
+
readonly env: Record<string, string>;
|
|
97
|
+
readonly properties: Record<string, string>;
|
|
98
|
+
readonly onFlowStart: string[];
|
|
99
|
+
readonly onFlowComplete: string[];
|
|
100
|
+
readonly subflowRefs: string[];
|
|
101
|
+
readonly filePath: string;
|
|
102
|
+
}
|
|
103
|
+
type AIDefectSeverity = 'critical' | 'warning' | 'info';
|
|
104
|
+
interface AIDefect {
|
|
105
|
+
readonly type: 'ui' | 'spelling' | 'i18n' | 'layout' | 'accessibility';
|
|
106
|
+
readonly severity: AIDefectSeverity;
|
|
107
|
+
readonly description: string;
|
|
108
|
+
readonly location: string | null;
|
|
109
|
+
readonly screenshot: string | null;
|
|
110
|
+
}
|
|
111
|
+
interface AIAnalysisReport {
|
|
112
|
+
readonly defects: AIDefect[];
|
|
113
|
+
readonly totalDefects: number;
|
|
114
|
+
readonly hasIssues: boolean;
|
|
115
|
+
readonly rawHtml: string | null;
|
|
116
|
+
}
|
|
117
|
+
interface MaestroLogEntry {
|
|
118
|
+
readonly timestamp: string;
|
|
119
|
+
readonly level: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';
|
|
120
|
+
readonly message: string;
|
|
121
|
+
readonly source: string | null;
|
|
122
|
+
}
|
|
123
|
+
interface CollectedArtifacts {
|
|
124
|
+
readonly screenshotPaths: string[];
|
|
125
|
+
readonly videoPaths: string[];
|
|
126
|
+
readonly logPaths: string[];
|
|
127
|
+
readonly commandJsonPaths: string[];
|
|
128
|
+
readonly aiReportPaths: string[];
|
|
129
|
+
readonly junitReportPath: string | null;
|
|
130
|
+
}
|
|
131
|
+
interface MaestroFlowResult {
|
|
132
|
+
readonly flowName: string;
|
|
133
|
+
readonly flowFile: string;
|
|
134
|
+
readonly appId: string | null;
|
|
135
|
+
readonly platform: MaestroPlatform;
|
|
136
|
+
/** Device serial / name used during this run, e.g. "emulator-5554" or "iPhone 15" */
|
|
137
|
+
readonly deviceId?: string;
|
|
138
|
+
readonly status: TestStatus;
|
|
139
|
+
readonly duration: number;
|
|
140
|
+
readonly startedAt: string;
|
|
141
|
+
readonly completedAt: string;
|
|
142
|
+
readonly tags: string[];
|
|
143
|
+
readonly properties: Record<string, string>;
|
|
144
|
+
readonly commands: MaestroCommandStep[];
|
|
145
|
+
readonly assertions: MaestroCommandStep[];
|
|
146
|
+
readonly screenshotPaths: string[];
|
|
147
|
+
readonly videoPath: string | null;
|
|
148
|
+
readonly aiDefects: AIDefect[];
|
|
149
|
+
readonly logEntries: MaestroLogEntry[];
|
|
150
|
+
readonly failureMessage: string | null;
|
|
151
|
+
readonly failureType: string | null;
|
|
152
|
+
readonly subflowRefs: string[];
|
|
153
|
+
readonly metadata: MaestroFlowMetadata | null;
|
|
154
|
+
}
|
|
155
|
+
interface MaestroTestOptions {
|
|
156
|
+
readonly flowPaths: string[];
|
|
157
|
+
readonly apiKey?: string;
|
|
158
|
+
readonly endpoint?: string;
|
|
159
|
+
readonly outputDir?: string;
|
|
160
|
+
readonly htmlReport?: string;
|
|
161
|
+
readonly openReport?: boolean;
|
|
162
|
+
readonly analyze?: boolean;
|
|
163
|
+
readonly platform?: string;
|
|
164
|
+
readonly device?: string;
|
|
165
|
+
readonly includeTags?: string;
|
|
166
|
+
readonly excludeTags?: string;
|
|
167
|
+
readonly shards?: number;
|
|
168
|
+
readonly config?: string;
|
|
169
|
+
readonly env?: Record<string, string>;
|
|
170
|
+
readonly quiet?: boolean;
|
|
171
|
+
readonly maestroArgs?: string[];
|
|
172
|
+
}
|
|
173
|
+
interface MaestroReportOptions {
|
|
174
|
+
readonly junitPath?: string;
|
|
175
|
+
readonly artifactsDir?: string;
|
|
176
|
+
readonly flowsDir?: string;
|
|
177
|
+
readonly outputDir?: string;
|
|
178
|
+
readonly htmlReport?: string;
|
|
179
|
+
readonly openReport?: boolean;
|
|
180
|
+
readonly apiKey?: string;
|
|
181
|
+
readonly endpoint?: string;
|
|
182
|
+
readonly quiet?: boolean;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Config resolution with prototype pollution prevention.
|
|
187
|
+
* Merges user options into defaults and freezes the result.
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
declare function resolveConfig(options?: Partial<MaestroReporterConfig>): ResolvedMaestroConfig;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* JUnit XML parser for Maestro test reports.
|
|
194
|
+
*
|
|
195
|
+
* Parses the JUnit XML generated by `maestro test --format junit`
|
|
196
|
+
* into structured JUnitReport objects.
|
|
197
|
+
*/
|
|
198
|
+
|
|
199
|
+
declare function parseJUnitXml(xmlContent: string): JUnitReport;
|
|
200
|
+
declare function parseJUnitFile(filePath: string): JUnitReport;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Parser for Maestro commands-*.json files.
|
|
204
|
+
*
|
|
205
|
+
* These files are generated in the --test-output-dir and contain
|
|
206
|
+
* per-command execution data for each flow.
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
declare function categorizeCommand(command: string): MaestroCommandCategory;
|
|
210
|
+
declare function parseCommandsJson(jsonContent: string, baseTimestamp?: string): MaestroCommandStep[];
|
|
211
|
+
declare function parseCommandsFile(filePath: string, baseTimestamp?: string): MaestroCommandStep[];
|
|
212
|
+
declare function discoverCommandFiles(artifactsDir: string): string[];
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Flow YAML header parser.
|
|
216
|
+
*
|
|
217
|
+
* Extracts metadata from Maestro Flow YAML files:
|
|
218
|
+
* appId, name, tags, properties, env, hooks, and subflow references.
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
declare function parseFlowYaml(content: string, filePath: string): MaestroFlowMetadata;
|
|
222
|
+
declare function parseFlowFile(filePath: string): MaestroFlowMetadata;
|
|
223
|
+
declare function discoverFlowFiles(dir: string): string[];
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Parser for maestro.log files.
|
|
227
|
+
*
|
|
228
|
+
* Extracts structured log entries with timestamps, levels, and messages.
|
|
229
|
+
* Also detects device/platform metadata from log content.
|
|
230
|
+
*/
|
|
231
|
+
|
|
232
|
+
declare function parseLogContent(content: string): MaestroLogEntry[];
|
|
233
|
+
declare function parseLogFile(filePath: string): MaestroLogEntry[];
|
|
234
|
+
declare function detectPlatformFromLogs(entries: MaestroLogEntry[]): MaestroPlatform;
|
|
235
|
+
declare function discoverLogFiles(dir: string): string[];
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Parser for Maestro AI analysis reports.
|
|
239
|
+
*
|
|
240
|
+
* Maestro's --analyze flag generates HTML insight reports identifying
|
|
241
|
+
* UI defects, spelling errors, and i18n issues. This parser extracts
|
|
242
|
+
* structured defect data from those reports.
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
declare function parseAiReportHtml(htmlContent: string): AIAnalysisReport;
|
|
246
|
+
declare function parseAiReportFile(filePath: string): AIAnalysisReport;
|
|
247
|
+
declare function discoverAiReports(dir: string): string[];
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Artifact collector for Maestro test output directories.
|
|
251
|
+
*
|
|
252
|
+
* Scans --test-output-dir and --debug-output for screenshots, video,
|
|
253
|
+
* logs, command JSONs, and AI reports.
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
declare function collectArtifacts(testOutputDir?: string, debugOutputDir?: string): CollectedArtifacts;
|
|
257
|
+
declare function getArtifactStats(artifacts: CollectedArtifacts): Record<string, number>;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Builds TimelineEntry arrays from parsed Maestro flow results.
|
|
261
|
+
* Maps Maestro data to the @testrelic/core TimelineEntry shape.
|
|
262
|
+
*/
|
|
263
|
+
|
|
264
|
+
declare function buildTimelineEntry(flow: MaestroFlowResult): TimelineEntry;
|
|
265
|
+
declare function buildTimeline(flows: MaestroFlowResult[]): TimelineEntry[];
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Computes Summary stats from TimelineEntry arrays.
|
|
269
|
+
*/
|
|
270
|
+
|
|
271
|
+
declare function buildSummary(timeline: readonly TimelineEntry[]): Summary;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Generate and write the HTML report file.
|
|
275
|
+
*
|
|
276
|
+
* Serialises report data + AI defects + screenshot paths to JSON
|
|
277
|
+
* and delegates to renderHtmlDocument() from html-template.ts.
|
|
278
|
+
*/
|
|
279
|
+
|
|
280
|
+
declare function generateHtmlReport(report: TestRunReport, aiDefects: AIDefect[], screenshotPaths: string[], outputPath: string): void;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* HTML Template for TestRelic Maestro Report.
|
|
284
|
+
*
|
|
285
|
+
* Orchestrator: imports CSS, logo, and JS modules; assembles them
|
|
286
|
+
* into a single self-contained HTML document. Same architecture as
|
|
287
|
+
* the Appium html-template.ts.
|
|
288
|
+
*/
|
|
289
|
+
declare function renderHtmlDocument(reportJson: string): string;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Formatted console summary output for Maestro test runs.
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
declare function printConsoleSummary(summary: Summary, outputPath: string, htmlReportPath: string, quiet: boolean, aiDefects?: AIDefect[]): void;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Open a file path in the user's default browser.
|
|
299
|
+
*/
|
|
300
|
+
declare function openInBrowser(filePath: string): void;
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Maestro CLI runner — spawns `maestro test` as a child process
|
|
304
|
+
* with injected flags for report generation and artifact capture.
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
interface MaestroRunResult {
|
|
308
|
+
readonly exitCode: number;
|
|
309
|
+
readonly junitPath: string;
|
|
310
|
+
readonly testOutputDir: string;
|
|
311
|
+
readonly debugOutputDir: string;
|
|
312
|
+
readonly stdout: string;
|
|
313
|
+
readonly stderr: string;
|
|
314
|
+
}
|
|
315
|
+
declare function buildMaestroArgs(options: MaestroTestOptions, tempDir: string): string[];
|
|
316
|
+
declare function runMaestro(options: MaestroTestOptions): Promise<MaestroRunResult>;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Report orchestrator — ties all parsers together to produce
|
|
320
|
+
* a TestRunReport from Maestro's output artifacts.
|
|
321
|
+
*/
|
|
322
|
+
|
|
323
|
+
interface OrchestratorInput {
|
|
324
|
+
readonly junitPath?: string;
|
|
325
|
+
readonly testOutputDir?: string;
|
|
326
|
+
readonly debugOutputDir?: string;
|
|
327
|
+
readonly flowsDir?: string;
|
|
328
|
+
readonly config: ResolvedMaestroConfig;
|
|
329
|
+
/** Device serial / name used during this run, e.g. "emulator-5554". Passed through to each flow result and uploaded as deviceName. */
|
|
330
|
+
readonly device?: string;
|
|
331
|
+
/**
|
|
332
|
+
* Explicit mobile platform override ('android' | 'ios').
|
|
333
|
+
* When set, this takes precedence over log-based detection so callers that
|
|
334
|
+
* already know the target platform (e.g. the E2E script using adb) do not
|
|
335
|
+
* rely on heuristic detection that may return 'unknown'.
|
|
336
|
+
*/
|
|
337
|
+
readonly platform?: MaestroPlatform;
|
|
338
|
+
}
|
|
339
|
+
interface OrchestratorResult {
|
|
340
|
+
readonly report: TestRunReport;
|
|
341
|
+
readonly flowResults: MaestroFlowResult[];
|
|
342
|
+
readonly aiDefects: AIDefect[];
|
|
343
|
+
readonly artifacts: CollectedArtifacts;
|
|
344
|
+
}
|
|
345
|
+
declare function orchestrateReport(input: OrchestratorInput): Promise<OrchestratorResult>;
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* CloudClient — manages cloud connectivity lifecycle for Maestro analytics.
|
|
349
|
+
* Handles auth, repo resolution, token refresh, and queue flush.
|
|
350
|
+
*/
|
|
351
|
+
|
|
352
|
+
declare class CloudClient {
|
|
353
|
+
private config;
|
|
354
|
+
private authState;
|
|
355
|
+
private gitMetadata;
|
|
356
|
+
private repoId;
|
|
357
|
+
private failureReason;
|
|
358
|
+
private flushPromise;
|
|
359
|
+
private healthCheckTimer;
|
|
360
|
+
constructor(cloudConfig: CloudConfig | null);
|
|
361
|
+
initialize(): Promise<void>;
|
|
362
|
+
getMode(): AuthMode;
|
|
363
|
+
isCloudMode(): boolean;
|
|
364
|
+
isLocalMode(): boolean;
|
|
365
|
+
getAccessToken(): string | null;
|
|
366
|
+
getRepoId(): string | null;
|
|
367
|
+
getGitMetadata(): GitMetadata | null;
|
|
368
|
+
getConfig(): CloudConfig | null;
|
|
369
|
+
getFailureReason(): string | null;
|
|
370
|
+
getEndpoint(): string;
|
|
371
|
+
ensureValidToken(): Promise<boolean>;
|
|
372
|
+
switchToLocalMode(reason: string): void;
|
|
373
|
+
dispose(): Promise<void>;
|
|
374
|
+
private setLocalMode;
|
|
375
|
+
private handleAuthError;
|
|
376
|
+
private resolveRepoId;
|
|
377
|
+
private readRepoCache;
|
|
378
|
+
private writeRepoCache;
|
|
379
|
+
private hashApiKey;
|
|
380
|
+
private startBackgroundFlush;
|
|
381
|
+
private startHealthCheck;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Cloud upload — batch and realtime upload functions.
|
|
386
|
+
* Adapted from appium-analytics with testFramework: 'maestro'.
|
|
387
|
+
*/
|
|
388
|
+
|
|
389
|
+
interface TestResultForUpload {
|
|
390
|
+
readonly testId: string;
|
|
391
|
+
readonly title: string;
|
|
392
|
+
readonly status: string;
|
|
393
|
+
readonly duration: number;
|
|
394
|
+
readonly suiteName: string;
|
|
395
|
+
readonly filePath: string;
|
|
396
|
+
readonly testType: string;
|
|
397
|
+
readonly isFlaky: boolean;
|
|
398
|
+
readonly startedAt: string;
|
|
399
|
+
readonly completedAt: string;
|
|
400
|
+
readonly tags: readonly string[];
|
|
401
|
+
readonly failure: unknown | null;
|
|
402
|
+
readonly retry: number;
|
|
403
|
+
readonly retryCount: number;
|
|
404
|
+
readonly retryStatus: string | null;
|
|
405
|
+
readonly source?: string;
|
|
406
|
+
readonly platform?: string;
|
|
407
|
+
/** Human-readable OS name, e.g. "Android", "iOS" */
|
|
408
|
+
readonly os?: string;
|
|
409
|
+
/** Device name / serial, e.g. "emulator-5554", "iPhone 15 Pro" */
|
|
410
|
+
readonly deviceName?: string;
|
|
411
|
+
}
|
|
412
|
+
interface RunUploadPayload {
|
|
413
|
+
readonly runId: string;
|
|
414
|
+
readonly repoGitId: string;
|
|
415
|
+
readonly startedAt: string;
|
|
416
|
+
readonly summary: Summary;
|
|
417
|
+
readonly timeline: readonly (TimelineEntry | TimelineStep | Record<string, unknown>)[];
|
|
418
|
+
readonly tests?: readonly TestResultForUpload[];
|
|
419
|
+
readonly branch?: string;
|
|
420
|
+
readonly commit?: string;
|
|
421
|
+
readonly commitMessage?: string;
|
|
422
|
+
readonly commitAuthor?: string;
|
|
423
|
+
readonly finishedAt?: string;
|
|
424
|
+
readonly duration?: number;
|
|
425
|
+
readonly ciProvider?: string;
|
|
426
|
+
readonly ciRunUrl?: string;
|
|
427
|
+
readonly environment?: string;
|
|
428
|
+
readonly testFramework?: string;
|
|
429
|
+
}
|
|
430
|
+
interface UploadResult {
|
|
431
|
+
readonly success: boolean;
|
|
432
|
+
readonly statusCode: number | null;
|
|
433
|
+
readonly error: string | null;
|
|
434
|
+
}
|
|
435
|
+
interface UploadFailure {
|
|
436
|
+
readonly success: false;
|
|
437
|
+
readonly reason: string;
|
|
438
|
+
readonly statusCode: number | null;
|
|
439
|
+
readonly payload: Record<string, unknown>;
|
|
440
|
+
readonly targetEndpoint: string;
|
|
441
|
+
readonly method: string;
|
|
442
|
+
}
|
|
443
|
+
declare function buildUploadPayload(report: TestRunReport, repoGitId: string, git: GitMetadata | null, ci: CIMetadata | null, tests?: readonly TestResultForUpload[]): RunUploadPayload;
|
|
444
|
+
declare function uploadBatchRun(endpoint: string, accessToken: string, payload: RunUploadPayload, onTokenRefresh?: () => Promise<string | null>): Promise<UploadResult | UploadFailure>;
|
|
445
|
+
interface RealtimeInitResult {
|
|
446
|
+
readonly runId: string;
|
|
447
|
+
}
|
|
448
|
+
declare function initRealtimeRun(endpoint: string, accessToken: string, payload: {
|
|
449
|
+
runId: string;
|
|
450
|
+
repoGitId: string;
|
|
451
|
+
branch: string | null;
|
|
452
|
+
commit: string | null;
|
|
453
|
+
commitMessage?: string | null;
|
|
454
|
+
commitAuthor?: string | null;
|
|
455
|
+
startedAt: string;
|
|
456
|
+
totalTests: number | null;
|
|
457
|
+
ciProvider: string | null;
|
|
458
|
+
ciRunUrl: string | null;
|
|
459
|
+
environment?: string | null;
|
|
460
|
+
testFramework?: string;
|
|
461
|
+
}): Promise<RealtimeInitResult | null>;
|
|
462
|
+
declare function finalizeRun(endpoint: string, accessToken: string, cloudRunId: string, payload: {
|
|
463
|
+
finishedAt: string;
|
|
464
|
+
duration: number;
|
|
465
|
+
summary: Summary;
|
|
466
|
+
commitMessage?: string | null;
|
|
467
|
+
}): Promise<boolean>;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Cloud reporter orchestration for Maestro analytics.
|
|
471
|
+
* Handles batch upload and artifact upload to the TestRelic platform.
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
/** A video (or other artifact) explicitly associated with a specific test/flow. */
|
|
475
|
+
interface PerTestArtifact {
|
|
476
|
+
readonly path: string;
|
|
477
|
+
readonly testId: string;
|
|
478
|
+
}
|
|
479
|
+
declare function finalizeAndUpload(cloudClient: CloudClient, cloudConfig: CloudConfig | undefined | null, testRunId: string, report: TestRunReport, completedAt: string, totalDuration: number, summary: Summary, screenshotPaths?: readonly string[], videoPaths?: readonly string[], tests?: readonly TestResultForUpload[],
|
|
480
|
+
/** Per-flow video artifacts — each is uploaded with its exact flow testId. */
|
|
481
|
+
videoArtifacts?: readonly PerTestArtifact[]): Promise<void>;
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Cloud authentication — token exchange and refresh.
|
|
485
|
+
* Ported from @testrelic/appium-analytics for Maestro integration.
|
|
486
|
+
*/
|
|
487
|
+
interface TokenExchangeResult {
|
|
488
|
+
readonly accessToken: string;
|
|
489
|
+
readonly refreshToken: string;
|
|
490
|
+
readonly expiresIn: number;
|
|
491
|
+
readonly orgId: string;
|
|
492
|
+
readonly orgName: string;
|
|
493
|
+
readonly userId: string;
|
|
494
|
+
readonly userName: string;
|
|
495
|
+
}
|
|
496
|
+
interface TokenRefreshResult {
|
|
497
|
+
readonly accessToken: string;
|
|
498
|
+
readonly refreshToken: string;
|
|
499
|
+
readonly expiresIn: number;
|
|
500
|
+
}
|
|
501
|
+
interface AuthError {
|
|
502
|
+
readonly code: 'invalid_key' | 'expired_key' | 'validation_error' | 'rate_limited' | 'server_error' | 'network_error' | 'timeout';
|
|
503
|
+
readonly message: string;
|
|
504
|
+
readonly statusCode: number | null;
|
|
505
|
+
}
|
|
506
|
+
declare function enforceHttps(endpoint: string): void;
|
|
507
|
+
declare function healthCheck(endpoint: string): Promise<boolean>;
|
|
508
|
+
declare function exchangeToken(endpoint: string, apiKey: string, timeout: number): Promise<TokenExchangeResult | AuthError>;
|
|
509
|
+
declare function isAuthError(result: TokenExchangeResult | AuthError): result is AuthError;
|
|
510
|
+
declare function refreshAccessToken(endpoint: string, currentRefreshToken: string, timeout: number): Promise<TokenRefreshResult | null>;
|
|
511
|
+
interface RepoResolveResult {
|
|
512
|
+
readonly repoId: string;
|
|
513
|
+
readonly displayName: string;
|
|
514
|
+
}
|
|
515
|
+
declare function resolveRepo(endpoint: string, accessToken: string, gitId: string, displayName: string, timeout: number, branch?: string | null): Promise<RepoResolveResult | null>;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Cloud configuration discovery, parsing, and merging.
|
|
519
|
+
*
|
|
520
|
+
* Discovers `.testrelic/testrelic-config.json` config files, resolves environment variable
|
|
521
|
+
* references, and merges configuration from multiple sources.
|
|
522
|
+
*
|
|
523
|
+
* Priority order (highest wins):
|
|
524
|
+
* 1. Environment variables (TESTRELIC_API_KEY, TESTRELIC_CLOUD_ENDPOINT, etc.)
|
|
525
|
+
* 2. CLI options
|
|
526
|
+
* 3. .testrelic/testrelic-config.json config file
|
|
527
|
+
* 4. Built-in defaults
|
|
528
|
+
*/
|
|
529
|
+
|
|
530
|
+
declare const DEFAULT_CLOUD_CONFIG: CloudConfig;
|
|
531
|
+
declare function discoverConfigFile(startDir: string): string | null;
|
|
532
|
+
declare function parseConfigFile(filePath: string): Record<string, unknown> | null;
|
|
533
|
+
declare function resolveEnvVar(value: string): string | null;
|
|
534
|
+
declare function resolveEnvVars(obj: Record<string, unknown>): Record<string, unknown>;
|
|
535
|
+
declare function parseDuration(value: string): number | null;
|
|
536
|
+
declare function mergeCloudConfig(fileConfig: Record<string, unknown> | null, reporterOptions: CloudReporterOptions | undefined): CloudConfig;
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Git metadata collection and project ID normalization.
|
|
540
|
+
*
|
|
541
|
+
* Collects branch, commit, message, and remote URL using git CLI.
|
|
542
|
+
* Each field fails independently.
|
|
543
|
+
*/
|
|
544
|
+
|
|
545
|
+
declare function collectGitMetadata(cwd?: string): GitMetadata;
|
|
546
|
+
declare function normalizeGitRemoteUrl(url: string): string;
|
|
547
|
+
declare function deriveRepoDisplayName(normalizedUrl: string): string;
|
|
548
|
+
declare function readPackageJsonName(dirPath: string): string | null;
|
|
549
|
+
declare function deriveNonGitProjectId(dirPath: string): string;
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* CI provider auto-detection via environment variables.
|
|
553
|
+
* Strategy pattern: check providers in priority order, first match wins.
|
|
554
|
+
*/
|
|
555
|
+
|
|
556
|
+
declare function detectCI(env?: Record<string, string | undefined>): CIMetadata | null;
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Cloud queue — offline storage and retry for failed uploads.
|
|
560
|
+
*/
|
|
561
|
+
declare function writeToQueue(queueDirectory: string, runId: string, type: string, reason: string, targetEndpoint: string, method: string, payload: Record<string, unknown>, headers: Record<string, string>): void;
|
|
562
|
+
declare function flushQueue(queueDirectory: string, endpoint: string, accessToken: string): Promise<void>;
|
|
563
|
+
declare function cleanupExpiredQueue(queueDirectory: string, maxAge: number): void;
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Cloud artifact upload — binary file upload via presigned S3 URLs.
|
|
567
|
+
*/
|
|
568
|
+
interface ArtifactUploadRequest {
|
|
569
|
+
readonly filePath: string;
|
|
570
|
+
readonly runId: string;
|
|
571
|
+
readonly testId: string;
|
|
572
|
+
readonly type: 'screenshot' | 'video' | 'trace' | 'other';
|
|
573
|
+
}
|
|
574
|
+
interface ArtifactUploadResult {
|
|
575
|
+
readonly success: boolean;
|
|
576
|
+
readonly storageKey: string | null;
|
|
577
|
+
readonly artifactId: string | null;
|
|
578
|
+
readonly error: string | null;
|
|
579
|
+
}
|
|
580
|
+
declare function uploadArtifact(endpoint: string, accessToken: string, request: ArtifactUploadRequest, maxSizeMb: number): Promise<ArtifactUploadResult>;
|
|
581
|
+
declare function uploadArtifacts(endpoint: string, accessToken: string, requests: readonly ArtifactUploadRequest[], maxSizeMb: number): Promise<Map<string, ArtifactUploadResult>>;
|
|
582
|
+
|
|
583
|
+
export { type AIAnalysisReport, type AIDefect, type AIDefectSeverity, type ArtifactUploadRequest, type ArtifactUploadResult, type AuthError, CloudClient, type CollectedArtifacts, DEFAULT_CLOUD_CONFIG, type JUnitProperty, type JUnitReport, type JUnitTestCase, type JUnitTestSuite, type MaestroCommandCategory, type MaestroCommandStep, type MaestroFlowMetadata, type MaestroFlowResult, type MaestroLogEntry, type MaestroPlatform, type MaestroReportOptions, type MaestroReporterConfig, type MaestroRunResult, type MaestroTestOptions, type OrchestratorInput, type OrchestratorResult, type PerTestArtifact, type RealtimeInitResult, type RepoResolveResult, type ResolvedMaestroConfig, type RunUploadPayload, type TestResultForUpload, type TokenExchangeResult, type TokenRefreshResult, type UploadFailure, type UploadResult, buildMaestroArgs, buildSummary, buildTimeline, buildTimelineEntry, buildUploadPayload, categorizeCommand, cleanupExpiredQueue, collectArtifacts, collectGitMetadata, deriveNonGitProjectId, deriveRepoDisplayName, detectCI, detectPlatformFromLogs, discoverAiReports, discoverCommandFiles, discoverConfigFile, discoverFlowFiles, discoverLogFiles, enforceHttps, exchangeToken, finalizeAndUpload, finalizeRun, flushQueue, generateHtmlReport, getArtifactStats, healthCheck, initRealtimeRun, isAuthError, mergeCloudConfig, normalizeGitRemoteUrl, openInBrowser, orchestrateReport, parseAiReportFile, parseAiReportHtml, parseCommandsFile, parseCommandsJson, parseConfigFile, parseDuration, parseFlowFile, parseFlowYaml, parseJUnitFile, parseJUnitXml, parseLogContent, parseLogFile, printConsoleSummary, readPackageJsonName, refreshAccessToken, renderHtmlDocument, resolveConfig, resolveEnvVar, resolveEnvVars, resolveRepo, runMaestro, uploadArtifact, uploadArtifacts, uploadBatchRun, writeToQueue };
|