@checkly/playwright-reporter 0.1.10 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +266 -0
  2. package/dist/index.d.ts +343 -267
  3. package/dist/index.js +1597 -789
  4. package/package.json +16 -14
package/dist/index.d.ts CHANGED
@@ -1,308 +1,384 @@
1
- export { Asset, AssetCollector, ZipEntry, ZipResult, Zipper, ZipperOptions } from '@checkly/reporter-utils';
2
- import { FullConfig, Suite, JSONReport as JSONReport$1, JSONReportSuite as JSONReportSuite$1, JSONReportSpec as JSONReportSpec$1, JSONReportTest as JSONReportTest$1, JSONReportTestResult as JSONReportTestResult$1, Reporter, TestCase, TestResult, TestError } from '@playwright/test/reporter';
1
+ import { Reporter, FullConfig, Suite as Suite$1, TestCase, TestResult as TestResult$1, TestStep as TestStep$1, TestError as TestError$1, FullResult } from '@playwright/test/reporter';
3
2
 
4
3
  /**
5
- * Checkly environment for API endpoints
6
- */
7
- type ChecklyEnvironment = 'local' | 'development' | 'staging' | 'production';
8
- /**
9
- * Context passed to sessionName callback function
4
+ * Output Contract Schema
5
+ *
6
+ * This defines the JSON structure that our reporter MUST produce.
7
+ * It is designed to be compatible with Playwright 1.40 through 1.57+.
8
+ *
9
+ * Fields are categorized as:
10
+ * - REQUIRED: Must always be present (exist in all versions 1.40+)
11
+ * - OPTIONAL: May be present (added in newer versions, older consumers ignore them)
10
12
  */
11
- interface SessionNameContext {
12
- /**
13
- * The directory name where tests are running
14
- */
15
- directoryName: string;
16
- /**
17
- * Playwright's full configuration object
18
- */
19
- config: FullConfig;
20
- /**
21
- * The root test suite containing all tests
22
- */
23
- suite: Suite;
24
- }
25
13
  /**
26
- * Session name can be a static string or a function that returns a string
14
+ * Individual test run status
27
15
  */
28
- type SessionNameOption = string | ((context: SessionNameContext) => string);
16
+ type TestStatus = 'passed' | 'failed' | 'skipped' | 'timedOut' | 'interrupted';
29
17
  /**
30
- * Configuration options for ChecklyReporter
18
+ * Overall test outcome (aggregated across retries)
31
19
  */
32
- interface ChecklyReporterOptions {
33
- /**
34
- * Checkly account ID for uploading test results
35
- * Required for Phase 2 (upload functionality)
36
- */
37
- accountId?: string;
38
- /**
39
- * Checkly API key for authentication
40
- * Required for Phase 2 (upload functionality)
41
- */
42
- apiKey?: string;
43
- /**
44
- * Checkly environment to use
45
- * Can also be set via CHECKLY_ENV environment variable
46
- * @default 'production'
47
- */
48
- environment?: ChecklyEnvironment;
49
- /**
50
- * Output path for the generated ZIP file (for testing/debugging)
51
- * @default 'checkly-report.zip'
52
- * @internal
53
- */
54
- outputPath?: string;
55
- /**
56
- * Path to the JSON report file generated by Playwright's json reporter
57
- * @default 'test-results/playwright-test-report.json'
58
- * @internal
59
- */
60
- jsonReportPath?: string;
61
- /**
62
- * Directory containing test results and assets
63
- * @default 'test-results'
64
- * @internal
65
- */
66
- testResultsDir?: string;
67
- /**
68
- * Dry run mode - skips API calls and only creates local ZIP file
69
- * @default false
70
- */
71
- dryRun?: boolean;
72
- /**
73
- * Custom name for the test session
74
- * Can be a string or a callback function for dynamic names
75
- * @default 'Playwright Test Session: {directoryName}'
76
- * @example
77
- * // Static string
78
- * sessionName: 'My E2E Tests'
79
- *
80
- * // Dynamic with callback
81
- * sessionName: ({ directoryName, config }) => `E2E: ${directoryName} (${config.projects.length} projects)`
82
- */
83
- sessionName?: SessionNameOption;
84
- /**
85
- * Enable verbose logging for debugging
86
- * Logs detailed information about each phase of report generation
87
- * Can also be enabled via CHECKLY_REPORTER_VERBOSE=true environment variable
88
- * @default false
89
- */
90
- verbose?: boolean;
20
+ type TestOutcome = 'expected' | 'unexpected' | 'skipped' | 'flaky';
21
+ interface Location {
22
+ file: string;
23
+ line: number;
24
+ column: number;
91
25
  }
92
- /**
93
- * Warning types that can be attached to test results
94
- */
95
- type ChecklyWarningType = 'trace-off' | 'trace-retained-on-failure' | 'trace-first-retry-only' | 'trace-retries-only' | 'trace-retained-on-first-failure' | 'trace-missing';
96
- /**
97
- * A warning attached to a test result
98
- */
99
- interface ChecklyWarning {
100
- /**
101
- * Type of warning for programmatic handling
102
- */
103
- type: ChecklyWarningType;
104
- /**
105
- * Human-readable warning message
106
- */
107
- message: string;
26
+ interface TestError {
27
+ message?: string;
28
+ stack?: string;
29
+ location?: Location;
30
+ snippet?: string;
31
+ value?: string;
32
+ matcherResult?: unknown;
33
+ }
34
+ interface Attachment {
35
+ name: string;
36
+ contentType: string;
37
+ path?: string;
38
+ body?: string;
39
+ }
40
+ interface TestStep {
41
+ title: string;
42
+ duration: number;
43
+ error?: TestError;
44
+ steps?: TestStep[];
45
+ }
46
+ interface Annotation {
47
+ type: string;
48
+ description?: string;
49
+ location?: {
50
+ file: string;
51
+ line: number;
52
+ column: number;
53
+ };
54
+ }
55
+ interface TestResult {
56
+ workerIndex: number;
57
+ parallelIndex: number;
58
+ status: TestStatus;
59
+ duration: number;
60
+ startTime: string;
61
+ retry: number;
62
+ errors: TestError[];
63
+ error?: TestError;
64
+ errorLocation?: Location;
65
+ stdout: Array<{
66
+ text: string;
67
+ } | {
68
+ buffer: string;
69
+ }>;
70
+ stderr: Array<{
71
+ text: string;
72
+ } | {
73
+ buffer: string;
74
+ }>;
75
+ attachments: Attachment[];
76
+ steps?: TestStep[];
77
+ annotations: Annotation[];
78
+ }
79
+ interface Test {
80
+ projectId: string;
81
+ projectName: string;
82
+ timeout: number;
83
+ expectedStatus: TestStatus;
84
+ annotations: Annotation[];
85
+ results: TestResult[];
86
+ status: TestOutcome;
87
+ }
88
+ interface Spec {
89
+ id: string;
90
+ title: string;
91
+ file: string;
92
+ line: number;
93
+ column: number;
94
+ tags: string[];
95
+ ok: boolean;
96
+ tests: Test[];
97
+ }
98
+ interface Suite {
99
+ title: string;
100
+ file: string;
101
+ line: number;
102
+ column: number;
103
+ specs: Spec[];
104
+ suites?: Suite[];
105
+ }
106
+ interface ProjectConfig {
107
+ id: string;
108
+ name: string;
109
+ testDir: string;
110
+ outputDir: string;
111
+ timeout: number;
112
+ retries: number;
113
+ repeatEach: number;
114
+ metadata: Record<string, unknown>;
115
+ testMatch: string[];
116
+ testIgnore: string[];
117
+ }
118
+ interface ReportConfig {
119
+ rootDir: string;
120
+ configFile?: string;
121
+ version: string;
122
+ workers: number;
123
+ fullyParallel: boolean;
124
+ forbidOnly: boolean;
125
+ globalTimeout: number;
126
+ maxFailures: number;
127
+ projects: ProjectConfig[];
128
+ shard?: {
129
+ current: number;
130
+ total: number;
131
+ } | null;
132
+ metadata: Record<string, unknown>;
133
+ tags?: string[];
134
+ updateSourceMethod?: string;
135
+ preserveOutput?: string;
136
+ quiet?: boolean;
137
+ reportSlowTests?: {
138
+ max: number;
139
+ threshold: number;
140
+ } | null;
141
+ webServer?: unknown;
142
+ globalSetup?: string | null;
143
+ globalTeardown?: string | null;
144
+ grep?: unknown;
145
+ grepInvert?: unknown;
146
+ reporter?: unknown;
147
+ updateSnapshots?: string;
148
+ }
149
+ interface Stats {
150
+ startTime: string;
151
+ duration: number;
152
+ expected: number;
153
+ unexpected: number;
154
+ flaky: number;
155
+ skipped: number;
156
+ }
157
+ interface JSONReport {
158
+ config: ReportConfig;
159
+ suites: Suite[];
160
+ errors: TestError[];
161
+ stats: Stats;
108
162
  }
109
163
  /**
110
- * Console message type matching the webapp's CheckRunNavigationTracePage.console type
164
+ * Type guard to check if an object is a valid JSONReport
111
165
  */
112
- type ConsoleMessageType = 'debug' | 'error' | 'info' | 'log' | 'warning';
166
+ declare function isValidJSONReport(obj: unknown): obj is JSONReport;
113
167
  /**
114
- * Location of a console message in source code
168
+ * Type guard to check if stats are valid
115
169
  */
116
- interface ConsoleMessageLocation {
117
- url: string;
118
- columnNumber: number;
119
- lineNumber: number;
120
- }
170
+ declare function isValidStats(obj: unknown): obj is Stats;
121
171
  /**
122
- * Console message extracted from Playwright trace
123
- * Matches the webapp's CheckRunNavigationTracePage.console array item type
172
+ * Type guard to check if a test result is valid
124
173
  */
125
- interface ConsoleMessage {
126
- /**
127
- * Unique identifier for the console message
128
- */
129
- id: string;
130
- /**
131
- * Source location where the console message was triggered
132
- */
133
- location: ConsoleMessageLocation;
134
- /**
135
- * The text content of the console message
136
- */
137
- text: string;
174
+ declare function isValidTestResult(obj: unknown): obj is TestResult;
175
+
176
+ interface BaseReporterOptions {
138
177
  /**
139
- * Timestamp when the message was logged (milliseconds)
178
+ * Directory for output files. JSON report is written to `{outputDir}/checkly-report.json`.
140
179
  */
141
- timestamp: number;
180
+ outputDir?: string;
142
181
  /**
143
- * Type of console message
182
+ * @deprecated Use `outputDir` instead. Will be removed in next major version.
144
183
  */
145
- type: ConsoleMessageType;
184
+ outputFile?: string;
185
+ verbose?: boolean;
146
186
  }
147
- /**
148
- * Network request extracted from Playwright trace
149
- * Matches the webapp's CheckRunNavigationTraceNetworkEntry type
150
- */
151
- interface NetworkRequest {
152
- id: string;
153
- url: string;
154
- domain: string;
155
- method: string;
156
- resourceType: string;
157
- statusCode: number;
158
- statusText: string;
159
- start: number;
160
- startedAt: number;
161
- finishedAt: number;
162
- time: number;
163
- hasFinished: boolean;
164
- hasSucceeded: boolean;
165
- requestHeaders: Record<string, string>;
166
- responseHeaders: Record<string, string>;
167
- transferBytes?: number;
168
- resourceBytes?: number;
187
+ type LogFn = (message: string, data?: Record<string, unknown>) => void;
188
+ interface ExtensionContext$1 {
189
+ log: LogFn;
169
190
  }
170
- /**
171
- * Checkly-specific extensions added to JSONReportTestResult
172
- */
173
- interface ChecklyTestResultExtensions {
191
+ interface Extension$1 {
192
+ name: string;
193
+ onBegin?(ctx: ExtensionContext$1 & {
194
+ config: FullConfig;
195
+ suite: Suite$1;
196
+ }): void | Promise<void>;
197
+ onTestBegin?(ctx: ExtensionContext$1 & {
198
+ test: TestCase;
199
+ result: TestResult$1;
200
+ }): void | Promise<void>;
201
+ onStepBegin?(ctx: ExtensionContext$1 & {
202
+ test: TestCase;
203
+ result: TestResult$1;
204
+ step: TestStep$1;
205
+ }): void | Promise<void>;
206
+ onStepEnd?(ctx: ExtensionContext$1 & {
207
+ test: TestCase;
208
+ result: TestResult$1;
209
+ step: TestStep$1;
210
+ }): void | Promise<void>;
211
+ onTestEnd?(ctx: ExtensionContext$1 & {
212
+ test: TestCase;
213
+ result: TestResult$1;
214
+ }): void | Promise<void>;
215
+ onStdOut?(ctx: ExtensionContext$1 & {
216
+ chunk: string | Buffer;
217
+ test?: TestCase;
218
+ result?: TestResult$1;
219
+ }): void | Promise<void>;
220
+ onStdErr?(ctx: ExtensionContext$1 & {
221
+ chunk: string | Buffer;
222
+ test?: TestCase;
223
+ result?: TestResult$1;
224
+ }): void | Promise<void>;
225
+ onError?(ctx: ExtensionContext$1 & {
226
+ error: TestError$1;
227
+ }): void | Promise<void>;
228
+ onEnd?(ctx: ExtensionContext$1 & {
229
+ result: FullResult;
230
+ report: JSONReport;
231
+ addSummaryLine: (line: string) => void;
232
+ }): void | Promise<void>;
233
+ onExit?(ctx: ExtensionContext$1): void | Promise<void>;
234
+ }
235
+ declare class BaseReporter implements Reporter {
236
+ private config;
237
+ private suite;
238
+ private startTime;
239
+ private options;
240
+ private verbose;
241
+ private globalErrors;
242
+ private tests;
243
+ private expectedCount;
244
+ private unexpectedCount;
245
+ private flakyCount;
246
+ private skippedCount;
247
+ private _report;
248
+ private extensions;
249
+ private summaryLines;
250
+ constructor(options?: BaseReporterOptions);
251
+ protected use(extension: Extension$1): this;
252
+ private log;
253
+ private createExtensionLogger;
254
+ onBegin(config: FullConfig, suite: Suite$1): void;
255
+ onTestBegin(test: TestCase, result: TestResult$1): void;
256
+ onStepBegin(test: TestCase, result: TestResult$1, step: TestStep$1): void;
257
+ onStepEnd(test: TestCase, result: TestResult$1, step: TestStep$1): void;
258
+ onTestEnd(test: TestCase, result: TestResult$1): void;
259
+ onStdOut(chunk: string | Buffer, test?: TestCase, result?: TestResult$1): void;
260
+ onStdErr(chunk: string | Buffer, test?: TestCase, result?: TestResult$1): void;
261
+ onError(error: TestError$1): void;
262
+ onEnd(result: FullResult): Promise<void>;
263
+ onExit(): Promise<void>;
264
+ printsToStdio(): boolean;
265
+ getReport(): JSONReport;
266
+ private buildReport;
267
+ private serializeConfig;
268
+ private serializeProject;
269
+ /**
270
+ * Serialize suites following the same order as native Playwright JSON reporter.
271
+ * Iterates through suite tree structure (discovery order) rather than test completion order.
272
+ */
273
+ private serializeSuites;
274
+ /**
275
+ * Recursively serialize a suite and its children.
276
+ * Returns null if the suite has no tests.
277
+ */
278
+ private serializeSuite;
279
+ /**
280
+ * Merge tests from 'from' suite into 'to' suite (for multi-project scenarios).
281
+ * Matches native Playwright JSON reporter behavior - specs are NOT merged,
282
+ * each project gets its own spec even for the same test.
283
+ */
284
+ private mergeSuites;
285
+ private serializeSpec;
286
+ /**
287
+ * Extract tags from test case - uses testCase.tags (1.42+) or extracts @tags from title
288
+ * Tags are returned without @ prefix to match native Playwright JSON reporter
289
+ */
290
+ private extractTags;
291
+ private serializeTest;
292
+ private serializeTestResult;
293
+ private serializeStep;
294
+ private serializeError;
295
+ private serializeAnnotations;
296
+ private countTests;
297
+ private getFileName;
298
+ private mapOutcome;
299
+ private printSummary;
300
+ }
301
+
302
+ type ChecklyEnvironment = 'local' | 'development' | 'staging' | 'production';
303
+ interface SessionNameContext {
304
+ directoryName: string;
305
+ config: FullConfig;
306
+ suite: Suite$1;
307
+ }
308
+ type SessionNameOption = string | ((context: SessionNameContext) => string);
309
+ interface ChecklyUploadOptions {
310
+ apiKey?: string;
311
+ accountId?: string;
312
+ environment?: ChecklyEnvironment;
313
+ sessionName?: SessionNameOption;
314
+ dryRun?: boolean;
174
315
  /**
175
- * Warnings about the test result (e.g., missing traces)
316
+ * Directory for assets and ZIP output. Defaults to Playwright's outputDir.
317
+ * - Assets (screenshots, videos, traces) are read from here
318
+ * - ZIP is written to `{outputDir}/checkly-report.zip`
176
319
  */
177
- warnings?: ChecklyWarning[];
320
+ outputDir?: string;
178
321
  /**
179
- * Console messages extracted from the Playwright trace
322
+ * @deprecated Use `outputDir` instead. Will be removed in next major version.
180
323
  */
181
- console?: ConsoleMessage[];
324
+ testResultsDir?: string;
182
325
  /**
183
- * Network requests extracted from the Playwright trace
326
+ * @deprecated ZIP is now written to `{outputDir}/checkly-report.zip`. Will be removed in next major version.
184
327
  */
185
- network?: NetworkRequest[];
328
+ outputPath?: string;
186
329
  }
330
+ interface ExtensionContext {
331
+ log: LogFn;
332
+ }
333
+ interface Extension {
334
+ name: string;
335
+ onBegin?(ctx: ExtensionContext & {
336
+ config: FullConfig;
337
+ suite: Suite$1;
338
+ }): void | Promise<void>;
339
+ onTestEnd?(ctx: ExtensionContext & {
340
+ test: TestCase;
341
+ result: TestResult$1;
342
+ }): void | Promise<void>;
343
+ onEnd?(ctx: ExtensionContext & {
344
+ result: unknown;
345
+ report: JSONReport;
346
+ addSummaryLine: (line: string) => void;
347
+ }): void | Promise<void>;
348
+ }
349
+ declare function checklyUpload(options?: ChecklyUploadOptions): Extension;
350
+
187
351
  /**
188
- * Extended JSONReportTestResult with Checkly-specific data
189
- */
190
- type JSONReportTestResult = JSONReportTestResult$1 & {
191
- _checkly?: ChecklyTestResultExtensions;
192
- };
193
- /**
194
- * Extended JSONReportTest with Checkly-extended results
195
- */
196
- type JSONReportTest = Omit<JSONReportTest$1, 'results'> & {
197
- results: JSONReportTestResult[];
198
- };
199
- /**
200
- * Extended JSONReportSpec with Checkly-extended tests
201
- */
202
- type JSONReportSpec = Omit<JSONReportSpec$1, 'tests'> & {
203
- tests: JSONReportTest[];
204
- };
205
- /**
206
- * Extended JSONReportSuite with Checkly-extended specs and nested suites
352
+ * @checkly/playwright-reporter-next
353
+ *
354
+ * Standalone Playwright reporter for Checkly
355
+ * Compatible with Playwright 1.40 through 1.57+
207
356
  */
208
- type JSONReportSuite = Omit<JSONReportSuite$1, 'suites' | 'specs'> & {
209
- suites?: JSONReportSuite[];
210
- specs: JSONReportSpec[];
211
- };
357
+
358
+ interface ChecklyReporterOptions extends BaseReporterOptions, ChecklyUploadOptions {
359
+ }
212
360
  /**
213
- * Extended JSONReport with Checkly-extended suites
361
+ * Full-featured reporter with all Checkly functionality.
362
+ * This is what Playwright loads when using the package.
214
363
  */
215
- type JSONReport = Omit<JSONReport$1, 'suites'> & {
216
- suites: JSONReportSuite[];
217
- };
364
+ declare class ChecklyReporter extends BaseReporter {
365
+ constructor(options?: ChecklyReporterOptions);
366
+ }
218
367
 
219
368
  /**
220
- * Checkly Playwright Reporter
369
+ * Create a Checkly reporter configuration with full intellisense support.
221
370
  *
222
- * Creates a ZIP archive containing the JSON report and all test assets.
223
- * Designed to work alongside Playwright's built-in JSONReporter.
371
+ * Use this instead of the array-based syntax for better IDE experience.
224
372
  *
225
373
  * @example
226
- * // playwright.config.ts
374
+ * import { createChecklyReporter } from '@checkly/playwright-reporter'
375
+ *
227
376
  * export default defineConfig({
228
377
  * reporter: [
229
- * ['json', { outputFile: 'test-results/playwright-test-report.json' }],
230
- * ['@checkly/playwright-reporter', {
231
- * apiKey: process.env.CHECKLY_API_KEY,
232
- * accountId: process.env.CHECKLY_ACCOUNT_ID,
233
- * }]
234
- * ]
235
- * });
378
+ * createChecklyReporter({ outputDir: 'test-results' }),
379
+ * ],
380
+ * })
236
381
  */
237
- declare class ChecklyReporter implements Reporter {
238
- private options;
239
- private assetCollector;
240
- private zipper;
241
- private testResults?;
242
- private testSession?;
243
- private startTime?;
244
- private testCounts;
245
- private stepsMap;
246
- private warningsMap;
247
- private tracePathsMap;
248
- private consoleMessagesMap;
249
- private networkRequestsMap;
250
- /**
251
- * Log a message if verbose mode is enabled
252
- */
253
- private log;
254
- constructor(options?: ChecklyReporterOptions);
255
- /**
256
- * Resolves the session name from options
257
- * Supports string, callback function, or falls back to default
258
- */
259
- private resolveSessionName;
260
- /**
261
- * Checks if test result has a trace attachment and adds context-aware warning if missing
262
- * Also captures trace file path for later console message extraction
263
- * The warning type depends on the trace configuration and test result state
264
- */
265
- private checkTraceAttachment;
266
- /**
267
- * Called once before running tests
268
- * Creates test session in Checkly if credentials provided
269
- */
270
- onBegin(config: FullConfig, suite: Suite): void;
271
- /**
272
- * Called for each test when it completes
273
- * Captures steps and warnings, tracks test results for final status calculation
274
- */
275
- onTestEnd(test: TestCase, result: TestResult): void;
276
- /**
277
- * Called after all tests have completed
278
- * This is where we create the ZIP archive and upload results
279
- */
280
- onEnd(): Promise<void>;
281
- private printSummary;
282
- /**
283
- * Extracts console messages and network requests from all captured traces
284
- * Called before injecting data into the report
285
- */
286
- private extractDataFromTraces;
287
- /**
288
- * Injects captured steps, warnings, console messages, and network requests into the JSON report
289
- * Traverses the report structure and matches by test ID + retry
290
- */
291
- private injectDataIntoReport;
292
- /**
293
- * Reconstructs config.projects and test.projectId from test data
294
- * This is necessary for blob merge scenarios where Playwright's JSON reporter
295
- * doesn't populate projects array or projectId fields
296
- */
297
- private reconstructProjectsFromTests;
298
- /**
299
- * Uploads test results to Checkly API
300
- */
301
- private uploadResults;
302
- /**
303
- * Called when a global error occurs
304
- */
305
- onError(error: TestError): void;
306
- }
382
+ declare function createChecklyReporter(options?: ChecklyReporterOptions): ['@checkly/playwright-reporter', ChecklyReporterOptions];
307
383
 
308
- export { ChecklyReporter, type ChecklyReporterOptions, type ChecklyTestResultExtensions, type ChecklyWarning, type ChecklyWarningType, type ConsoleMessage, type ConsoleMessageLocation, type ConsoleMessageType, type JSONReport, type JSONReportSpec, type JSONReportSuite, type JSONReportTest, type JSONReportTestResult, type NetworkRequest, ChecklyReporter as default };
384
+ export { type Annotation, type Attachment, BaseReporter, type BaseReporterOptions, ChecklyReporter, type ChecklyReporterOptions, type ChecklyUploadOptions, type JSONReport, type Location, type LogFn, type ProjectConfig, type ReportConfig, type Spec, type Stats, type Suite, type Test, type TestError, type TestOutcome, type TestResult, type TestStatus, type TestStep, checklyUpload, createChecklyReporter, ChecklyReporter as default, isValidJSONReport, isValidStats, isValidTestResult };