@lokalise/playwright-reporters 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,3 +102,4 @@ When performing a release, make sure to follow our conventional commit approach,
102
102
  ## License
103
103
 
104
104
  This project is APACHE, VERSION 2.0 licensed, see LICENSE.md for details.
105
+
@@ -4,6 +4,13 @@ exports.Elastic = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const logger_1 = require("./logger");
6
6
  class Elastic {
7
+ request;
8
+ flakyTestIndex;
9
+ failedTestIndex;
10
+ testRunIndex;
11
+ browserUsageIndex;
12
+ elasticUrl;
13
+ elasticToken;
7
14
  constructor(analyticsConfig) {
8
15
  this.flakyTestIndex = analyticsConfig.flakyTestIndex;
9
16
  this.failedTestIndex = analyticsConfig.failedTestIndex;
@@ -1,5 +1,20 @@
1
1
  import { type TestStatus } from '@playwright/test/reporter';
2
2
  import type { ElasticConfig } from './elastic';
3
+ /**
4
+ * CI/CD context information for test runs
5
+ */
6
+ export interface CIContext {
7
+ /** Git branch name */
8
+ branchName?: string;
9
+ /** Git commit SHA */
10
+ commitSha?: string;
11
+ /** Pull request number */
12
+ prNumber?: string;
13
+ /** CI job identifier */
14
+ ciJobId?: string;
15
+ /** What triggered the run (push, pr, schedule, manual) */
16
+ triggeredBy?: string;
17
+ }
3
18
  export interface TestAnalyticsData {
4
19
  timestamp: number;
5
20
  name: string;
@@ -8,6 +8,20 @@ const helpers_1 = require("./helpers");
8
8
  const transform_1 = require("./transform");
9
9
  // eslint-disable-next-line import/no-default-export
10
10
  class AnalyticsReporter {
11
+ listOfNonPassingTests;
12
+ listOfFlakyTests;
13
+ browserCreationTimes;
14
+ browserUsage;
15
+ elastic;
16
+ runStartTime;
17
+ runEndTime;
18
+ numberOfTests;
19
+ testRunId;
20
+ projectNames;
21
+ testOwnerCount;
22
+ options;
23
+ isMainPREnv;
24
+ workerCount;
11
25
  constructor(options) {
12
26
  this.options = options;
13
27
  this.listOfNonPassingTests = [];
@@ -7,6 +7,7 @@ export declare const calculateHooksDuration: (steps: TestStep[], hook: "before"
7
7
  export declare const getTeamNames: (test: TestCase) => {
8
8
  type: string;
9
9
  description?: string;
10
+ location?: import("playwright/types/test").Location;
10
11
  }[];
11
12
  export declare const formFailedTestData: (test: TestCase, result: TestResult, testRunId: string, prenvId?: string) => {
12
13
  prenvId?: string | undefined;
@@ -0,0 +1,25 @@
1
+ import type { DatadogMetricsPayload, DatadogReporterOptions } from './report.types';
2
+ /**
3
+ * Datadog API client for submitting metrics
4
+ */
5
+ export declare class Datadog {
6
+ private request;
7
+ private readonly apiKey;
8
+ private readonly site;
9
+ private readonly debug;
10
+ constructor(options: Pick<DatadogReporterOptions, 'apiKey' | 'site' | 'debug'>);
11
+ private log;
12
+ /**
13
+ * Initialize the Playwright request context for API calls
14
+ */
15
+ setNativeRequestContext(): Promise<void>;
16
+ /**
17
+ * Submit metrics to Datadog Metrics API v2
18
+ * @see https://docs.datadoghq.com/api/latest/metrics/#submit-metrics
19
+ */
20
+ submitMetrics(payload: DatadogMetricsPayload): Promise<boolean>;
21
+ /**
22
+ * Close the request context
23
+ */
24
+ dispose(): Promise<void>;
25
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Datadog = void 0;
4
+ const test_1 = require("@playwright/test");
5
+ /**
6
+ * Returns the Datadog API endpoint for the given site
7
+ */
8
+ const getApiEndpoint = (site) => {
9
+ const endpoints = {
10
+ 'datadoghq.com': 'https://api.datadoghq.com',
11
+ 'datadoghq.eu': 'https://api.datadoghq.eu',
12
+ 'us3.datadoghq.com': 'https://api.us3.datadoghq.com',
13
+ 'us5.datadoghq.com': 'https://api.us5.datadoghq.com',
14
+ 'ap1.datadoghq.com': 'https://api.ap1.datadoghq.com',
15
+ 'ddog-gov.com': 'https://api.ddog-gov.com',
16
+ };
17
+ return endpoints[site];
18
+ };
19
+ /**
20
+ * Datadog API client for submitting metrics
21
+ */
22
+ class Datadog {
23
+ request;
24
+ apiKey;
25
+ site;
26
+ debug;
27
+ constructor(options) {
28
+ this.apiKey = options.apiKey;
29
+ this.site = options.site ?? 'datadoghq.eu';
30
+ this.debug = options.debug ?? false;
31
+ }
32
+ log(message, data) {
33
+ if (this.debug) {
34
+ // eslint-disable-next-line no-console
35
+ console.log(message, data !== undefined ? JSON.stringify(data, null, 2) : '');
36
+ }
37
+ }
38
+ /**
39
+ * Initialize the Playwright request context for API calls
40
+ */
41
+ async setNativeRequestContext() {
42
+ this.request = await test_1.request.newContext({
43
+ baseURL: getApiEndpoint(this.site),
44
+ extraHTTPHeaders: {
45
+ 'DD-API-KEY': this.apiKey,
46
+ 'Content-Type': 'application/json',
47
+ },
48
+ });
49
+ }
50
+ /**
51
+ * Submit metrics to Datadog Metrics API v2
52
+ * @see https://docs.datadoghq.com/api/latest/metrics/#submit-metrics
53
+ */
54
+ async submitMetrics(payload) {
55
+ try {
56
+ if (!this.request) {
57
+ // eslint-disable-next-line no-console
58
+ console.error('[Datadog] Request context not initialized. Call setNativeRequestContext first.');
59
+ return false;
60
+ }
61
+ this.log('[Datadog] Submitting metrics:', payload);
62
+ const response = await this.request.post('/api/v2/series', { data: payload });
63
+ if (!response.ok()) {
64
+ // eslint-disable-next-line no-console
65
+ console.error(`[Datadog] Failed to submit metrics: ${response.status()} - ${await response.text()}`);
66
+ return false;
67
+ }
68
+ this.log(`[Datadog] Successfully submitted ${payload.series.length} metric series`);
69
+ return true;
70
+ }
71
+ catch (error) {
72
+ // eslint-disable-next-line no-console
73
+ console.error('[Datadog] Error submitting metrics:', error);
74
+ return false;
75
+ }
76
+ }
77
+ /**
78
+ * Close the request context
79
+ */
80
+ async dispose() {
81
+ if (this.request) {
82
+ await this.request.dispose();
83
+ }
84
+ }
85
+ }
86
+ exports.Datadog = Datadog;
@@ -0,0 +1,2 @@
1
+ export { default as DatadogReporter, defineDatadogReporterConfig } from './reporter';
2
+ export type { DatadogReporterOptions, DatadogSite, MetricTags, TestRunMetrics, TestMetrics, } from './report.types';
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.defineDatadogReporterConfig = exports.DatadogReporter = void 0;
7
+ var reporter_1 = require("./reporter");
8
+ Object.defineProperty(exports, "DatadogReporter", { enumerable: true, get: function () { return __importDefault(reporter_1).default; } });
9
+ Object.defineProperty(exports, "defineDatadogReporterConfig", { enumerable: true, get: function () { return reporter_1.defineDatadogReporterConfig; } });
@@ -0,0 +1,175 @@
1
+ import type { CIContext } from '../analytics/report.types';
2
+ /**
3
+ * Datadog site endpoints for different regions
4
+ */
5
+ export type DatadogSite = 'datadoghq.com' | 'datadoghq.eu' | 'us3.datadoghq.com' | 'us5.datadoghq.com' | 'ap1.datadoghq.com' | 'ddog-gov.com';
6
+ /**
7
+ * Configuration options for the Datadog reporter
8
+ */
9
+ export type DatadogReporterOptions = {
10
+ /**
11
+ * Datadog API key for authentication.
12
+ * Can also be set via DD_API_KEY environment variable.
13
+ */
14
+ apiKey: string;
15
+ /**
16
+ * Datadog site/region endpoint.
17
+ * @default 'datadoghq.eu'
18
+ */
19
+ site?: DatadogSite;
20
+ /**
21
+ * Service name for metric namespace.
22
+ * @default 'playwright-tests'
23
+ */
24
+ service?: string;
25
+ /**
26
+ * Environment tag (e.g., 'ci', 'local', 'staging').
27
+ */
28
+ env?: string;
29
+ /**
30
+ * Product identifier for filtering metrics.
31
+ */
32
+ product?: string;
33
+ /**
34
+ * PR environment identifier.
35
+ */
36
+ prenvId?: string;
37
+ /**
38
+ * Enable debug logging.
39
+ * @default false
40
+ */
41
+ debug?: boolean;
42
+ /**
43
+ * Skip sending data to Datadog (for testing).
44
+ * @default false
45
+ */
46
+ dryRun?: boolean;
47
+ /**
48
+ * CI/CD context information.
49
+ */
50
+ ci?: CIContext;
51
+ };
52
+ /**
53
+ * Datadog metric types for API v2
54
+ * @see https://docs.datadoghq.com/api/latest/metrics/#submit-metrics
55
+ * 0 = unspecified, 1 = count, 2 = rate, 3 = gauge
56
+ */
57
+ export type MetricType = 0 | 1 | 2 | 3;
58
+ export declare const MetricTypes: {
59
+ UNSPECIFIED: 0;
60
+ COUNT: 1;
61
+ RATE: 2;
62
+ GAUGE: 3;
63
+ };
64
+ /**
65
+ * A single metric point with timestamp and value
66
+ */
67
+ export interface MetricPoint {
68
+ /** Unix timestamp in seconds */
69
+ timestamp: number;
70
+ /** Metric value */
71
+ value: number;
72
+ }
73
+ /**
74
+ * A metric series to submit to Datadog
75
+ */
76
+ export interface MetricSeries {
77
+ /** Metric name (e.g., 'playwright.test_run.uptime') */
78
+ metric: string;
79
+ /** Metric type */
80
+ type: MetricType;
81
+ /** Metric points (timestamp + value pairs) */
82
+ points: MetricPoint[];
83
+ /** Tags for filtering and grouping */
84
+ tags?: string[];
85
+ /** Unit of the metric (optional) */
86
+ unit?: string;
87
+ }
88
+ /**
89
+ * Datadog Metrics API v2 request body
90
+ * @see https://docs.datadoghq.com/api/latest/metrics/#submit-metrics
91
+ */
92
+ export interface DatadogMetricsPayload {
93
+ series: MetricSeries[];
94
+ }
95
+ /**
96
+ * Aggregated test run data for metrics generation
97
+ */
98
+ export interface TestRunMetrics {
99
+ /** Test run unique identifier */
100
+ testRunId: string;
101
+ /** Unix timestamp when run started (seconds) */
102
+ timestamp: number;
103
+ /** Total number of tests */
104
+ totalTests: number;
105
+ /** Number of passed tests (including flaky that eventually passed) */
106
+ passedTests: number;
107
+ /** Number of failed tests (permanently failed) */
108
+ failedTests: number;
109
+ /** Number of flaky tests (passed after retry) */
110
+ flakyTests: number;
111
+ /** Number of skipped tests */
112
+ skippedTests: number;
113
+ /** Number of tests that timed out */
114
+ timedOutTests: number;
115
+ /** Total run duration in milliseconds */
116
+ durationMs: number;
117
+ /** Total time spent on browser creation in milliseconds */
118
+ browserCreationMs: number;
119
+ /** Total time spent on retries in milliseconds */
120
+ retryTimeMs: number;
121
+ /** Total time spent on page navigations in milliseconds */
122
+ navigationMs: number;
123
+ /** Whether all tests passed (uptime = 1) */
124
+ allPassed: boolean;
125
+ /** Pass rate as percentage (0-100) */
126
+ passRate: number;
127
+ /** Flaky rate as percentage (0-100) */
128
+ flakyRate: number;
129
+ /** Number of parallel workers */
130
+ workerCount: number;
131
+ /** Average test duration in milliseconds */
132
+ avgTestDurationMs: number;
133
+ }
134
+ /**
135
+ * Individual test metrics
136
+ */
137
+ export interface TestMetrics {
138
+ /** Test name/title */
139
+ name: string;
140
+ /** Test stable ID */
141
+ testId: string;
142
+ /** Test duration in milliseconds */
143
+ durationMs: number;
144
+ /** Number of retries */
145
+ retryCount: number;
146
+ /** Whether this test was flaky */
147
+ isFlaky: boolean;
148
+ /** Whether this test timed out */
149
+ isTimedOut: boolean;
150
+ /** Team that owns this test */
151
+ team?: string;
152
+ /** Project name */
153
+ project?: string;
154
+ /** Navigation time in milliseconds */
155
+ navigationMs: number;
156
+ }
157
+ /**
158
+ * Tags to apply to all metrics
159
+ */
160
+ export interface MetricTags {
161
+ /** Git branch name */
162
+ branch?: string;
163
+ /** Project name(s) */
164
+ project?: string[];
165
+ /** PR environment identifier */
166
+ prenvId?: string;
167
+ /** What triggered the run */
168
+ triggeredBy?: string;
169
+ /** Environment (ci, local, etc.) */
170
+ env?: string;
171
+ /** Service name */
172
+ service?: string;
173
+ /** Product identifier */
174
+ product?: string;
175
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MetricTypes = void 0;
4
+ exports.MetricTypes = {
5
+ UNSPECIFIED: 0,
6
+ COUNT: 1,
7
+ RATE: 2,
8
+ GAUGE: 3,
9
+ };
@@ -0,0 +1,35 @@
1
+ import { type FullConfig, type FullResult, type Reporter, type Suite, type TestCase, type TestResult, type TestStep } from '@playwright/test/reporter';
2
+ import type { DatadogReporterOptions } from './report.types';
3
+ /**
4
+ * Playwright reporter that sends test execution metrics to Datadog
5
+ */
6
+ export default class DatadogReporter implements Reporter {
7
+ private readonly options;
8
+ private readonly datadog;
9
+ private readonly testRunId;
10
+ private runStartTime;
11
+ private runEndTime;
12
+ private totalTests;
13
+ private passedTests;
14
+ private failedTests;
15
+ private flakyTests;
16
+ private skippedTests;
17
+ private timedOutTests;
18
+ private browserCreationMs;
19
+ private retryTimeMs;
20
+ private navigationMs;
21
+ private workerCount;
22
+ private readonly testDurations;
23
+ private readonly testMetrics;
24
+ private projectNames;
25
+ private readonly currentTestNavigationMs;
26
+ constructor(options: DatadogReporterOptions);
27
+ onBegin(config: FullConfig, suite: Suite): Promise<void>;
28
+ onStepEnd(test: TestCase, result: TestResult, step: TestStep): void;
29
+ onTestEnd(test: TestCase, result: TestResult): void;
30
+ onEnd(result: FullResult): Promise<void>;
31
+ }
32
+ /**
33
+ * Helper function for type-safe configuration
34
+ */
35
+ export declare const defineDatadogReporterConfig: (options: ConstructorParameters<typeof DatadogReporter>[0]) => DatadogReporterOptions;