playwright-ai-reporter 0.0.4
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/LICENSE +21 -0
- package/README.md +1183 -0
- package/dist/colors.d.ts +54 -0
- package/dist/colors.js +57 -0
- package/dist/examples/ReporterWorkflow.d.ts +54 -0
- package/dist/examples/ReporterWorkflow.js +307 -0
- package/dist/providers/ProviderRegistry.d.ts +79 -0
- package/dist/providers/ProviderRegistry.js +195 -0
- package/dist/providers/ai/AIProviderFactory.d.ts +33 -0
- package/dist/providers/ai/AIProviderFactory.js +82 -0
- package/dist/providers/ai/AnthropicProvider.d.ts +15 -0
- package/dist/providers/ai/AnthropicProvider.js +128 -0
- package/dist/providers/ai/AzureOpenAIProvider.d.ts +20 -0
- package/dist/providers/ai/AzureOpenAIProvider.js +158 -0
- package/dist/providers/ai/GoogleAIProvider.d.ts +17 -0
- package/dist/providers/ai/GoogleAIProvider.js +154 -0
- package/dist/providers/ai/MistralProvider.d.ts +16 -0
- package/dist/providers/ai/MistralProvider.js +137 -0
- package/dist/providers/ai/OpenAIProvider.d.ts +16 -0
- package/dist/providers/ai/OpenAIProvider.js +141 -0
- package/dist/providers/bugTrackers/AzureDevOpsBugTracker.d.ts +32 -0
- package/dist/providers/bugTrackers/AzureDevOpsBugTracker.js +295 -0
- package/dist/providers/bugTrackers/GitHubBugTracker.d.ts +28 -0
- package/dist/providers/bugTrackers/GitHubBugTracker.js +241 -0
- package/dist/providers/bugTrackers/JiraBugTracker.d.ts +29 -0
- package/dist/providers/bugTrackers/JiraBugTracker.js +279 -0
- package/dist/providers/databases/MySQLProvider.d.ts +32 -0
- package/dist/providers/databases/MySQLProvider.js +274 -0
- package/dist/providers/databases/SQLiteProvider.d.ts +28 -0
- package/dist/providers/databases/SQLiteProvider.js +272 -0
- package/dist/providers/factories/BugTrackerFactory.d.ts +20 -0
- package/dist/providers/factories/BugTrackerFactory.js +50 -0
- package/dist/providers/factories/DatabaseFactory.d.ts +28 -0
- package/dist/providers/factories/DatabaseFactory.js +71 -0
- package/dist/providers/factories/NotificationFactory.d.ts +24 -0
- package/dist/providers/factories/NotificationFactory.js +64 -0
- package/dist/providers/factories/PRProviderFactory.d.ts +20 -0
- package/dist/providers/factories/PRProviderFactory.js +45 -0
- package/dist/providers/index.d.ts +28 -0
- package/dist/providers/index.js +55 -0
- package/dist/providers/interfaces/IAIProvider.d.ts +59 -0
- package/dist/providers/interfaces/IAIProvider.js +5 -0
- package/dist/providers/interfaces/IBugTrackerProvider.d.ts +70 -0
- package/dist/providers/interfaces/IBugTrackerProvider.js +20 -0
- package/dist/providers/interfaces/IDatabaseProvider.d.ts +90 -0
- package/dist/providers/interfaces/IDatabaseProvider.js +5 -0
- package/dist/providers/interfaces/INotificationProvider.d.ts +59 -0
- package/dist/providers/interfaces/INotificationProvider.js +13 -0
- package/dist/providers/interfaces/IPRProvider.d.ts +82 -0
- package/dist/providers/interfaces/IPRProvider.js +5 -0
- package/dist/providers/notifications/EmailNotificationProvider.d.ts +29 -0
- package/dist/providers/notifications/EmailNotificationProvider.js +290 -0
- package/dist/providers/pr/AzureDevOpsPRProvider.d.ts +30 -0
- package/dist/providers/pr/AzureDevOpsPRProvider.js +263 -0
- package/dist/providers/pr/GitHubPRProvider.d.ts +29 -0
- package/dist/providers/pr/GitHubPRProvider.js +320 -0
- package/dist/reporter.d.ts +138 -0
- package/dist/reporter.js +787 -0
- package/dist/types/index.d.ts +168 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/buildInfoUtils.d.ts +26 -0
- package/dist/utils/buildInfoUtils.js +125 -0
- package/dist/utils/configValidator.d.ts +67 -0
- package/dist/utils/configValidator.js +454 -0
- package/dist/utils/fileHandlerUtils.d.ts +42 -0
- package/dist/utils/fileHandlerUtils.js +136 -0
- package/dist/utils/genaiUtils.d.ts +38 -0
- package/dist/utils/genaiUtils.js +178 -0
- package/dist/utils/historyUtils.d.ts +49 -0
- package/dist/utils/historyUtils.js +118 -0
- package/dist/utils/utils.d.ts +104 -0
- package/dist/utils/utils.js +371 -0
- package/docs/API.md +591 -0
- package/docs/ENV_CONFIG_GUIDE.md +444 -0
- package/docs/IMPLEMENTATION_SUMMARY.md +285 -0
- package/docs/PROVIDERS.md +261 -0
- package/docs/QUICKSTART.md +350 -0
- package/docs/README.md +253 -0
- package/docs/TROUBLESHOOTING.md +577 -0
- package/docs/design.md +384 -0
- package/docs/logo.png +0 -0
- package/examples/README.md +326 -0
- package/examples/VALIDATION.md +68 -0
- package/examples/env-configs/.env.anthropic-minimal +40 -0
- package/examples/env-configs/.env.azure-stack +71 -0
- package/examples/env-configs/.env.example +32 -0
- package/examples/env-configs/.env.github-stack +57 -0
- package/examples/env-configs/.env.google-mysql +61 -0
- package/examples/env-configs/.env.ms-auth-examples +56 -0
- package/examples/env-configs/.env.openai-jira +64 -0
- package/examples/package.json +22 -0
- package/package.json +70 -0
- package/playwright-ai-reporter-0.0.4.tgz +0 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GitHub Pull Request Provider
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.GitHubPRProvider = void 0;
|
|
40
|
+
class GitHubPRProvider {
|
|
41
|
+
constructor(config) {
|
|
42
|
+
this.config = config;
|
|
43
|
+
this.initialized = this.initialize();
|
|
44
|
+
}
|
|
45
|
+
async initialize() {
|
|
46
|
+
const { Octokit } = await Promise.resolve().then(() => __importStar(require('@octokit/rest')));
|
|
47
|
+
this.octokit = new Octokit({ auth: this.config.token });
|
|
48
|
+
}
|
|
49
|
+
async createBranch(branchName, baseBranch) {
|
|
50
|
+
await this.initialized;
|
|
51
|
+
try {
|
|
52
|
+
// Get the reference of the base branch
|
|
53
|
+
const baseRef = await this.octokit.git.getRef({
|
|
54
|
+
owner: this.config.owner,
|
|
55
|
+
repo: this.config.repo,
|
|
56
|
+
ref: `heads/${baseBranch}`,
|
|
57
|
+
});
|
|
58
|
+
// Create new branch from base
|
|
59
|
+
await this.octokit.git.createRef({
|
|
60
|
+
owner: this.config.owner,
|
|
61
|
+
repo: this.config.repo,
|
|
62
|
+
ref: `refs/heads/${branchName}`,
|
|
63
|
+
sha: baseRef.data.object.sha,
|
|
64
|
+
});
|
|
65
|
+
console.log(`Created branch: ${branchName} from ${baseBranch}`);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error('Error creating branch:', error.message);
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async commitChanges(branchName, changes, commitMessage) {
|
|
74
|
+
await this.initialized;
|
|
75
|
+
try {
|
|
76
|
+
// Get the current commit SHA of the branch
|
|
77
|
+
const branchRef = await this.octokit.git.getRef({
|
|
78
|
+
owner: this.config.owner,
|
|
79
|
+
repo: this.config.repo,
|
|
80
|
+
ref: `heads/${branchName}`,
|
|
81
|
+
});
|
|
82
|
+
const currentCommitSha = branchRef.data.object.sha;
|
|
83
|
+
// Get the tree of the current commit
|
|
84
|
+
const currentCommit = await this.octokit.git.getCommit({
|
|
85
|
+
owner: this.config.owner,
|
|
86
|
+
repo: this.config.repo,
|
|
87
|
+
commit_sha: currentCommitSha,
|
|
88
|
+
});
|
|
89
|
+
const baseTreeSha = currentCommit.data.tree.sha;
|
|
90
|
+
// Create blobs for each file change
|
|
91
|
+
const tree = [];
|
|
92
|
+
for (const change of changes) {
|
|
93
|
+
if (change.action === 'delete') {
|
|
94
|
+
tree.push({
|
|
95
|
+
path: change.path,
|
|
96
|
+
mode: '100644',
|
|
97
|
+
type: 'blob',
|
|
98
|
+
sha: null,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const blob = await this.octokit.git.createBlob({
|
|
103
|
+
owner: this.config.owner,
|
|
104
|
+
repo: this.config.repo,
|
|
105
|
+
content: Buffer.from(change.content).toString('base64'),
|
|
106
|
+
encoding: 'base64',
|
|
107
|
+
});
|
|
108
|
+
tree.push({
|
|
109
|
+
path: change.path,
|
|
110
|
+
mode: '100644',
|
|
111
|
+
type: 'blob',
|
|
112
|
+
sha: blob.data.sha,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Create a new tree
|
|
117
|
+
const newTree = await this.octokit.git.createTree({
|
|
118
|
+
owner: this.config.owner,
|
|
119
|
+
repo: this.config.repo,
|
|
120
|
+
base_tree: baseTreeSha,
|
|
121
|
+
tree,
|
|
122
|
+
});
|
|
123
|
+
// Create a new commit
|
|
124
|
+
const newCommit = await this.octokit.git.createCommit({
|
|
125
|
+
owner: this.config.owner,
|
|
126
|
+
repo: this.config.repo,
|
|
127
|
+
message: commitMessage,
|
|
128
|
+
tree: newTree.data.sha,
|
|
129
|
+
parents: [currentCommitSha],
|
|
130
|
+
});
|
|
131
|
+
// Update the branch reference
|
|
132
|
+
await this.octokit.git.updateRef({
|
|
133
|
+
owner: this.config.owner,
|
|
134
|
+
repo: this.config.repo,
|
|
135
|
+
ref: `heads/${branchName}`,
|
|
136
|
+
sha: newCommit.data.sha,
|
|
137
|
+
});
|
|
138
|
+
console.log(`Committed changes to ${branchName}: ${newCommit.data.sha}`);
|
|
139
|
+
return newCommit.data.sha;
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
console.error('Error committing changes:', error.message);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async createPullRequest(options) {
|
|
147
|
+
await this.initialized;
|
|
148
|
+
try {
|
|
149
|
+
const pr = await this.octokit.pulls.create({
|
|
150
|
+
owner: this.config.owner,
|
|
151
|
+
repo: this.config.repo,
|
|
152
|
+
title: options.title,
|
|
153
|
+
body: options.description,
|
|
154
|
+
head: options.sourceBranch,
|
|
155
|
+
base: options.targetBranch,
|
|
156
|
+
draft: options.draft,
|
|
157
|
+
});
|
|
158
|
+
// Add reviewers if specified
|
|
159
|
+
if (options.reviewers && options.reviewers.length > 0) {
|
|
160
|
+
await this.octokit.pulls.requestReviewers({
|
|
161
|
+
owner: this.config.owner,
|
|
162
|
+
repo: this.config.repo,
|
|
163
|
+
pull_number: pr.data.number,
|
|
164
|
+
reviewers: options.reviewers,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// Add labels if specified
|
|
168
|
+
if (options.labels && options.labels.length > 0) {
|
|
169
|
+
await this.octokit.issues.addLabels({
|
|
170
|
+
owner: this.config.owner,
|
|
171
|
+
repo: this.config.repo,
|
|
172
|
+
issue_number: pr.data.number,
|
|
173
|
+
labels: options.labels,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
console.log(`Created pull request: #${pr.data.number}`);
|
|
177
|
+
return {
|
|
178
|
+
id: pr.data.id.toString(),
|
|
179
|
+
number: pr.data.number,
|
|
180
|
+
url: pr.data.html_url,
|
|
181
|
+
status: 'open',
|
|
182
|
+
sourceBranch: options.sourceBranch,
|
|
183
|
+
targetBranch: options.targetBranch,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
console.error('Error creating pull request:', error.message);
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async updatePullRequest(prId, updates) {
|
|
192
|
+
await this.initialized;
|
|
193
|
+
try {
|
|
194
|
+
const prNumber = parseInt(prId);
|
|
195
|
+
const updateData = {};
|
|
196
|
+
if (updates.title)
|
|
197
|
+
updateData.title = updates.title;
|
|
198
|
+
if (updates.description)
|
|
199
|
+
updateData.body = updates.description;
|
|
200
|
+
const pr = await this.octokit.pulls.update({
|
|
201
|
+
owner: this.config.owner,
|
|
202
|
+
repo: this.config.repo,
|
|
203
|
+
pull_number: prNumber,
|
|
204
|
+
...updateData,
|
|
205
|
+
});
|
|
206
|
+
return {
|
|
207
|
+
id: pr.data.id.toString(),
|
|
208
|
+
number: pr.data.number,
|
|
209
|
+
url: pr.data.html_url,
|
|
210
|
+
status: pr.data.state === 'closed' ? (pr.data.merged ? 'merged' : 'closed') : 'open',
|
|
211
|
+
sourceBranch: pr.data.head.ref,
|
|
212
|
+
targetBranch: pr.data.base.ref,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
console.error('Error updating pull request:', error.message);
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async addComment(prId, comment) {
|
|
221
|
+
await this.initialized;
|
|
222
|
+
try {
|
|
223
|
+
const prNumber = parseInt(prId);
|
|
224
|
+
await this.octokit.issues.createComment({
|
|
225
|
+
owner: this.config.owner,
|
|
226
|
+
repo: this.config.repo,
|
|
227
|
+
issue_number: prNumber,
|
|
228
|
+
body: comment,
|
|
229
|
+
});
|
|
230
|
+
console.log(`Added comment to PR #${prNumber}`);
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
console.error('Error adding comment to pull request:', error.message);
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async closePullRequest(prId, comment) {
|
|
239
|
+
await this.initialized;
|
|
240
|
+
try {
|
|
241
|
+
const prNumber = parseInt(prId);
|
|
242
|
+
if (comment) {
|
|
243
|
+
await this.addComment(prId, comment);
|
|
244
|
+
}
|
|
245
|
+
await this.octokit.pulls.update({
|
|
246
|
+
owner: this.config.owner,
|
|
247
|
+
repo: this.config.repo,
|
|
248
|
+
pull_number: prNumber,
|
|
249
|
+
state: 'closed',
|
|
250
|
+
});
|
|
251
|
+
console.log(`Closed PR #${prNumber}`);
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
console.error('Error closing pull request:', error.message);
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
async createAutoFixPR(failures, baseBranch) {
|
|
260
|
+
await this.initialized;
|
|
261
|
+
try {
|
|
262
|
+
const branchName = `autofix/test-failures-${Date.now()}`;
|
|
263
|
+
// Create branch
|
|
264
|
+
const branchCreated = await this.createBranch(branchName, baseBranch);
|
|
265
|
+
if (!branchCreated) {
|
|
266
|
+
throw new Error('Failed to create branch');
|
|
267
|
+
}
|
|
268
|
+
// Prepare file changes
|
|
269
|
+
const changes = failures.map(({ filePath, fixContent }) => ({
|
|
270
|
+
path: filePath,
|
|
271
|
+
content: fixContent,
|
|
272
|
+
action: 'modify',
|
|
273
|
+
}));
|
|
274
|
+
// Commit changes
|
|
275
|
+
const commitSha = await this.commitChanges(branchName, changes, `fix: Auto-fix for ${failures.length} failing test(s)`);
|
|
276
|
+
if (!commitSha) {
|
|
277
|
+
throw new Error('Failed to commit changes');
|
|
278
|
+
}
|
|
279
|
+
// Create PR description
|
|
280
|
+
const description = this.generateAutoFixPRDescription(failures);
|
|
281
|
+
// Create pull request
|
|
282
|
+
const pr = await this.createPullRequest({
|
|
283
|
+
sourceBranch: branchName,
|
|
284
|
+
targetBranch: baseBranch,
|
|
285
|
+
title: `🤖 Auto-fix: ${failures.length} failing test(s)`,
|
|
286
|
+
description,
|
|
287
|
+
labels: ['auto-fix', 'test-failure'],
|
|
288
|
+
draft: true, // Create as draft by default for review
|
|
289
|
+
});
|
|
290
|
+
return pr;
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
console.error('Error creating auto-fix PR:', error.message);
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
generateAutoFixPRDescription(failures) {
|
|
298
|
+
let description = `## 🤖 Auto-generated Fix for Test Failures\n\n`;
|
|
299
|
+
description += `This PR contains AI-generated fixes for ${failures.length} failing test(s).\n\n`;
|
|
300
|
+
description += `⚠️ **Please review carefully before merging!**\n\n`;
|
|
301
|
+
description += `### Failed Tests\n\n`;
|
|
302
|
+
failures.forEach(({ failure }, index) => {
|
|
303
|
+
description += `${index + 1}. **${failure.testTitle}**\n`;
|
|
304
|
+
description += ` - Suite: ${failure.suiteTitle}\n`;
|
|
305
|
+
if (failure.testFile) {
|
|
306
|
+
description += ` - File: \`${failure.testFile}\`\n`;
|
|
307
|
+
}
|
|
308
|
+
description += ` - Error: ${failure.errorCategory}\n\n`;
|
|
309
|
+
});
|
|
310
|
+
description += `### Modified Files\n\n`;
|
|
311
|
+
const uniqueFiles = [...new Set(failures.map((f) => f.filePath))];
|
|
312
|
+
uniqueFiles.forEach((file) => {
|
|
313
|
+
description += `- \`${file}\`\n`;
|
|
314
|
+
});
|
|
315
|
+
description += `\n---\n`;
|
|
316
|
+
description += `_This PR was automatically created by the Playwright AI Test Reporter_`;
|
|
317
|
+
return description;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
exports.GitHubPRProvider = GitHubPRProvider;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Reporter, TestCase, TestResult, FullConfig, Suite } from '@playwright/test/reporter';
|
|
2
|
+
import { ReporterConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* PlaywrightTestReporter is a modern, maintainable reporter for Playwright tests.
|
|
5
|
+
* It provides detailed, colorized output of test results with comprehensive metrics
|
|
6
|
+
* and configurable options for better visibility into test execution.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Colorized output for different test states (passed, failed, skipped, retried)
|
|
10
|
+
* - Detailed metrics including test duration and slow test identification
|
|
11
|
+
* - Configurable thresholds for slow tests and timeouts
|
|
12
|
+
* - Comprehensive error reporting with stack traces
|
|
13
|
+
* - Support for test retries with clear status indication
|
|
14
|
+
* - Complete monitoring of all error types including setup/teardown errors
|
|
15
|
+
* - JSON output files for CI integration and historical tracking
|
|
16
|
+
*/
|
|
17
|
+
export default class PlaywrightTestReporter implements Reporter {
|
|
18
|
+
private suite;
|
|
19
|
+
private outputDir;
|
|
20
|
+
private readonly _testRecords;
|
|
21
|
+
private _startTime;
|
|
22
|
+
private readonly _config;
|
|
23
|
+
private _nonTestErrors;
|
|
24
|
+
private _hasInterruptedTests;
|
|
25
|
+
private _fileHandler;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new instance of the PlaywrightTestReporter.
|
|
28
|
+
*
|
|
29
|
+
* @param config - Optional configuration object to customize reporter behavior
|
|
30
|
+
*/
|
|
31
|
+
constructor(config?: ReporterConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Called when the test run begins.
|
|
34
|
+
* Initializes the start time and displays a start message.
|
|
35
|
+
*
|
|
36
|
+
* @param config - The full Playwright configuration
|
|
37
|
+
* @param suite - The root test suite
|
|
38
|
+
*/
|
|
39
|
+
onBegin(config: FullConfig, suite: Suite): void;
|
|
40
|
+
/**
|
|
41
|
+
* Recursively counts the total number of tests in a suite and its children
|
|
42
|
+
*
|
|
43
|
+
* @param suite - The test suite to count tests from
|
|
44
|
+
* @returns The total number of tests
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
private _countTests;
|
|
48
|
+
/**
|
|
49
|
+
* Called when an error occurs during test setup or teardown.
|
|
50
|
+
* Logs the error with optional stack trace based on configuration.
|
|
51
|
+
* Now tracks errors to ensure they affect final exit code.
|
|
52
|
+
*
|
|
53
|
+
* @param error - The error that occurred
|
|
54
|
+
*/
|
|
55
|
+
onError(error: Error): void;
|
|
56
|
+
/**
|
|
57
|
+
* Called when a test completes (whether passed, failed, or skipped).
|
|
58
|
+
* Records the test result and logs appropriate output based on the test status.
|
|
59
|
+
* Now tracks all test statuses including interrupted ones.
|
|
60
|
+
*
|
|
61
|
+
* @param test - The test case that completed
|
|
62
|
+
* @param result - The result of the test execution
|
|
63
|
+
*/
|
|
64
|
+
onTestEnd(test: TestCase, result: TestResult): void;
|
|
65
|
+
/**
|
|
66
|
+
* Called when all tests have completed.
|
|
67
|
+
* Processes results, displays summary statistics, and sets appropriate exit code.
|
|
68
|
+
* Now properly handles all error conditions including non-test errors.
|
|
69
|
+
*/
|
|
70
|
+
onEnd(): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Exits the process with a success code.
|
|
73
|
+
* Extracted to a method to make the flow clearer and more maintainable.
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
private _exitWithSuccess;
|
|
77
|
+
/**
|
|
78
|
+
* Exits the process with an error code.
|
|
79
|
+
* Extracted to a method to make the flow clearer and more maintainable.
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
private _exitWithError;
|
|
83
|
+
/**
|
|
84
|
+
* Formats and logs the outcome of a single test with appropriate coloring.
|
|
85
|
+
* Handles different test states (passed, failed, skipped) and retry attempts.
|
|
86
|
+
* Now includes handling for interrupted tests and other unexpected statuses.
|
|
87
|
+
*
|
|
88
|
+
* @param title - The title of the test
|
|
89
|
+
* @param result - The result of the test execution
|
|
90
|
+
* @param timeTakenSec - The time taken by the test in seconds
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
private _logTestOutcome;
|
|
94
|
+
/**
|
|
95
|
+
* Records the status of the last test run in a JSON file
|
|
96
|
+
* @param hasFailed - Whether any tests failed
|
|
97
|
+
*/
|
|
98
|
+
private saveLastRunStatus;
|
|
99
|
+
/**
|
|
100
|
+
* Generates AI-powered fix suggestions for test failures
|
|
101
|
+
*
|
|
102
|
+
* @param failures - Array of test failures
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
private _generateFixSuggestions;
|
|
106
|
+
/**
|
|
107
|
+
* Generates a pull request with the AI-generated fix
|
|
108
|
+
*
|
|
109
|
+
* @param failure - The test failure information
|
|
110
|
+
* @param fixResult - The result from GenAIUtils containing prompt and fix paths
|
|
111
|
+
* @private
|
|
112
|
+
*/
|
|
113
|
+
private _generatePullRequest;
|
|
114
|
+
/**
|
|
115
|
+
* Creates bugs in the configured bug tracker for test failures
|
|
116
|
+
*
|
|
117
|
+
* @param failures - Array of test failures
|
|
118
|
+
* @private
|
|
119
|
+
*/
|
|
120
|
+
private _createBugsForFailures;
|
|
121
|
+
/**
|
|
122
|
+
* Publishes test results to database
|
|
123
|
+
*
|
|
124
|
+
* @param summary - Test run summary
|
|
125
|
+
* @param allTestCases - All test cases details
|
|
126
|
+
* @param failures - Test failures
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
private _publishToDatabase;
|
|
130
|
+
/**
|
|
131
|
+
* Sends email notification with test results
|
|
132
|
+
*
|
|
133
|
+
* @param summary - Test run summary
|
|
134
|
+
* @param failures - Test failures
|
|
135
|
+
* @private
|
|
136
|
+
*/
|
|
137
|
+
private _sendEmailNotification;
|
|
138
|
+
}
|