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,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.GenAIUtils = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const dotenv = __importStar(require("dotenv"));
|
|
40
|
+
const ProviderRegistry_1 = require("../providers/ProviderRegistry");
|
|
41
|
+
// Load environment variables from .env file
|
|
42
|
+
dotenv.config({ path: path.resolve(process.cwd(), '.env') });
|
|
43
|
+
/**
|
|
44
|
+
* Utility for generating AI-powered suggestions for test failures
|
|
45
|
+
*/
|
|
46
|
+
class GenAIUtils {
|
|
47
|
+
/**
|
|
48
|
+
* Calls the configured AI provider to get a suggestion for fixing a failed test
|
|
49
|
+
*
|
|
50
|
+
* @param prompt - The prompt to send to the AI
|
|
51
|
+
* @returns AI's suggested fix
|
|
52
|
+
*/
|
|
53
|
+
static async callGenAISuggestion(prompt) {
|
|
54
|
+
try {
|
|
55
|
+
const provider = await ProviderRegistry_1.ProviderRegistry.getAIProvider();
|
|
56
|
+
console.log(`[GenAI] Using AI provider: ${provider.getName()}`);
|
|
57
|
+
const messages = [
|
|
58
|
+
{
|
|
59
|
+
role: 'system',
|
|
60
|
+
content: 'You are a test engineer helping debug flaky Playwright tests.',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
role: 'user',
|
|
64
|
+
content: prompt,
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
const response = await provider.generateCompletion(messages, {
|
|
68
|
+
maxTokens: 1000,
|
|
69
|
+
temperature: 0.7,
|
|
70
|
+
});
|
|
71
|
+
return response.content;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('[GenAI] Error calling AI provider:', error);
|
|
75
|
+
return `Error retrieving suggestion from AI provider: ${error instanceof Error ? error.message : 'Unknown error'}`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Generates a fix suggestion for a failed test
|
|
80
|
+
*
|
|
81
|
+
* @param failure - The test failure information
|
|
82
|
+
* @param sourceCode - Map of source code files for context
|
|
83
|
+
* @returns The path to the saved suggestion file
|
|
84
|
+
*/
|
|
85
|
+
static async generateFixSuggestion(failure, sourceCode) {
|
|
86
|
+
if (!failure.testFile) {
|
|
87
|
+
console.warn(`[GenAI] Cannot generate fix for test without file path: ${failure.testTitle}`);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
// Ensure the prompt and fixes directories exist
|
|
92
|
+
const promptDir = path.join(process.cwd(), 'test-results', 'prompts');
|
|
93
|
+
const fixesDir = path.join(process.cwd(), 'test-results', 'fixes');
|
|
94
|
+
fs.mkdirSync(promptDir, { recursive: true });
|
|
95
|
+
fs.mkdirSync(fixesDir, { recursive: true });
|
|
96
|
+
// Read the source file content if not already in cache
|
|
97
|
+
let source = sourceCode.get(failure.testFile);
|
|
98
|
+
if (!source) {
|
|
99
|
+
source = fs.readFileSync(failure.testFile, 'utf8');
|
|
100
|
+
sourceCode.set(failure.testFile, source);
|
|
101
|
+
}
|
|
102
|
+
// Create the prompt
|
|
103
|
+
const promptContent = [
|
|
104
|
+
`# Instructions`,
|
|
105
|
+
'',
|
|
106
|
+
`- The following Playwright test failed.`,
|
|
107
|
+
`- Explain why it failed and suggest a fix, respecting Playwright best practices.`,
|
|
108
|
+
`- Be concise and provide a code snippet with the fix.`,
|
|
109
|
+
'',
|
|
110
|
+
`# Test info`,
|
|
111
|
+
'',
|
|
112
|
+
`- Name: ${failure.testTitle}`,
|
|
113
|
+
`- File: ${failure.testFile}`,
|
|
114
|
+
`- Line: ${failure.location?.line || 'unknown'}`,
|
|
115
|
+
`- Column: ${failure.location?.column || 'unknown'}`,
|
|
116
|
+
'',
|
|
117
|
+
'# Error details',
|
|
118
|
+
'',
|
|
119
|
+
'```',
|
|
120
|
+
failure.errorMessage,
|
|
121
|
+
'```',
|
|
122
|
+
'',
|
|
123
|
+
'# Stack trace',
|
|
124
|
+
'',
|
|
125
|
+
'```',
|
|
126
|
+
this.truncateStackTrace(failure.errorStack),
|
|
127
|
+
'```',
|
|
128
|
+
'',
|
|
129
|
+
'# Test source',
|
|
130
|
+
'',
|
|
131
|
+
'```ts',
|
|
132
|
+
source,
|
|
133
|
+
'```',
|
|
134
|
+
].join('\n');
|
|
135
|
+
// Generate a clean filename for the test
|
|
136
|
+
const safeFilename = this.sanitizeFilename(failure.testId ? `${failure.testId}` : `${path.basename(failure.testFile, '.ts')}-${failure.testTitle}`);
|
|
137
|
+
// Save the prompt
|
|
138
|
+
const promptPath = path.join(promptDir, `${safeFilename}.md`);
|
|
139
|
+
fs.writeFileSync(promptPath, promptContent, 'utf8');
|
|
140
|
+
// Call AI for the fix suggestion
|
|
141
|
+
const suggestion = await this.callGenAISuggestion(promptContent);
|
|
142
|
+
// Save the suggestion
|
|
143
|
+
const fixPath = path.join(fixesDir, `fix-${safeFilename}.md`);
|
|
144
|
+
fs.writeFileSync(fixPath, suggestion, 'utf8');
|
|
145
|
+
return { promptPath, fixPath };
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
console.error('[GenAI] Error generating fix suggestion:', error);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Truncates a stack trace to a reasonable length
|
|
154
|
+
*
|
|
155
|
+
* @param stack - The full stack trace
|
|
156
|
+
* @returns Truncated stack trace
|
|
157
|
+
*/
|
|
158
|
+
static truncateStackTrace(stack) {
|
|
159
|
+
if (!stack)
|
|
160
|
+
return '';
|
|
161
|
+
const lines = stack.split('\n');
|
|
162
|
+
// Return first 15 lines max to keep the context reasonable
|
|
163
|
+
return lines.slice(0, 15).join('\n') + (lines.length > 15 ? '\n... (truncated)' : '');
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Sanitizes a filename to be used in a file path
|
|
167
|
+
*
|
|
168
|
+
* @param filename - The filename to sanitize
|
|
169
|
+
* @returns Sanitized filename
|
|
170
|
+
*/
|
|
171
|
+
static sanitizeFilename(filename) {
|
|
172
|
+
return filename
|
|
173
|
+
.replace(/[\\/:*?"<>|]/g, '_')
|
|
174
|
+
.replace(/\s+/g, '-')
|
|
175
|
+
.substring(0, 100); // Limit length
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.GenAIUtils = GenAIUtils;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { TestFailure } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for the last run information
|
|
4
|
+
*/
|
|
5
|
+
interface LastRunInfo {
|
|
6
|
+
status: string;
|
|
7
|
+
failedTests: string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Interface for test failure history item
|
|
11
|
+
*/
|
|
12
|
+
interface TestFailureHistory extends TestFailure {
|
|
13
|
+
timestamp?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Utility functions for working with test history
|
|
17
|
+
*/
|
|
18
|
+
export declare class HistoryUtils {
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves information about the last test run
|
|
21
|
+
* @param outputDir - Directory where test results are stored
|
|
22
|
+
* @returns Information about the last test run, or null if not available
|
|
23
|
+
*/
|
|
24
|
+
static getLastRunInfo(outputDir?: string): LastRunInfo | null;
|
|
25
|
+
/**
|
|
26
|
+
* Checks if a particular test was failing in the previous run
|
|
27
|
+
* @param testId - ID of the test to check
|
|
28
|
+
* @param outputDir - Directory where test results are stored
|
|
29
|
+
* @returns True if the test was failing in the previous run, false otherwise
|
|
30
|
+
*/
|
|
31
|
+
static wasTestFailingPreviously(testId: string, outputDir?: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Compares current test failures with previous run failures to identify new and fixed tests
|
|
34
|
+
* @param currentFailures - List of currently failed test IDs
|
|
35
|
+
* @param outputDir - Directory where test results are stored
|
|
36
|
+
* @returns Object with lists of newly failing and fixed tests
|
|
37
|
+
*/
|
|
38
|
+
static compareWithPreviousRun(currentFailures: string[], outputDir?: string): {
|
|
39
|
+
newlyFailing: string[];
|
|
40
|
+
fixed: string[];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Gets the full test failure history
|
|
44
|
+
* @param outputDir - Directory where test results are stored
|
|
45
|
+
* @returns Array of test failures with timestamps
|
|
46
|
+
*/
|
|
47
|
+
static getTestFailureHistory(outputDir?: string): TestFailureHistory[];
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.HistoryUtils = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
/**
|
|
40
|
+
* Utility functions for working with test history
|
|
41
|
+
*/
|
|
42
|
+
class HistoryUtils {
|
|
43
|
+
/**
|
|
44
|
+
* Retrieves information about the last test run
|
|
45
|
+
* @param outputDir - Directory where test results are stored
|
|
46
|
+
* @returns Information about the last test run, or null if not available
|
|
47
|
+
*/
|
|
48
|
+
static getLastRunInfo(outputDir = './test-results') {
|
|
49
|
+
try {
|
|
50
|
+
const lastRunFilePath = path.join(outputDir, '.last-run.json');
|
|
51
|
+
if (!fs.existsSync(lastRunFilePath)) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const content = fs.readFileSync(lastRunFilePath, 'utf8');
|
|
55
|
+
return JSON.parse(content);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('Error reading last run information:', error);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Checks if a particular test was failing in the previous run
|
|
64
|
+
* @param testId - ID of the test to check
|
|
65
|
+
* @param outputDir - Directory where test results are stored
|
|
66
|
+
* @returns True if the test was failing in the previous run, false otherwise
|
|
67
|
+
*/
|
|
68
|
+
static wasTestFailingPreviously(testId, outputDir = './test-results') {
|
|
69
|
+
const lastRunInfo = this.getLastRunInfo(outputDir);
|
|
70
|
+
if (!lastRunInfo) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return lastRunInfo.failedTests.includes(testId);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Compares current test failures with previous run failures to identify new and fixed tests
|
|
77
|
+
* @param currentFailures - List of currently failed test IDs
|
|
78
|
+
* @param outputDir - Directory where test results are stored
|
|
79
|
+
* @returns Object with lists of newly failing and fixed tests
|
|
80
|
+
*/
|
|
81
|
+
static compareWithPreviousRun(currentFailures, outputDir = './test-results') {
|
|
82
|
+
const lastRunInfo = this.getLastRunInfo(outputDir);
|
|
83
|
+
if (!lastRunInfo) {
|
|
84
|
+
// No previous run data available, all current failures are new
|
|
85
|
+
return {
|
|
86
|
+
newlyFailing: currentFailures,
|
|
87
|
+
fixed: [],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const previousFailures = lastRunInfo.failedTests || [];
|
|
91
|
+
return {
|
|
92
|
+
// Tests failing now but not in previous run
|
|
93
|
+
newlyFailing: currentFailures.filter((id) => !previousFailures.includes(id)),
|
|
94
|
+
// Tests that were failing before but now passing
|
|
95
|
+
fixed: previousFailures.filter((id) => !currentFailures.includes(id)),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Gets the full test failure history
|
|
100
|
+
* @param outputDir - Directory where test results are stored
|
|
101
|
+
* @returns Array of test failures with timestamps
|
|
102
|
+
*/
|
|
103
|
+
static getTestFailureHistory(outputDir = './test-results') {
|
|
104
|
+
try {
|
|
105
|
+
const failuresFilePath = path.join(outputDir, 'testFailures.json');
|
|
106
|
+
if (!fs.existsSync(failuresFilePath)) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
const content = fs.readFileSync(failuresFilePath, 'utf8');
|
|
110
|
+
return JSON.parse(content);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error('Error reading test failure history:', error);
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.HistoryUtils = HistoryUtils;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { TestRecord, TestSummary, SlowTest, TestFailure, BuildInfo } from '../types';
|
|
2
|
+
import { TestCase } from '@playwright/test/reporter';
|
|
3
|
+
/**
|
|
4
|
+
* Utility class containing static methods for test result processing and calculations.
|
|
5
|
+
* Provides functionality for formatting time, calculating statistics, and processing test results.
|
|
6
|
+
*/
|
|
7
|
+
export declare class TestUtils {
|
|
8
|
+
/**
|
|
9
|
+
* Formats a time duration from seconds into a human-readable string.
|
|
10
|
+
* Converts to minutes if the duration is longer than 60 seconds.
|
|
11
|
+
*
|
|
12
|
+
* @param timeInSeconds - The time duration to format in seconds
|
|
13
|
+
* @returns A formatted string with appropriate units (e.g., "1.23s" or "2.50min")
|
|
14
|
+
*/
|
|
15
|
+
static formatTime(timeInSeconds: number): string;
|
|
16
|
+
/**
|
|
17
|
+
* Calculates the average duration from an array of time measurements.
|
|
18
|
+
*
|
|
19
|
+
* @param durations - Array of durations in seconds
|
|
20
|
+
* @returns The average duration in seconds, or 0 if the array is empty
|
|
21
|
+
*/
|
|
22
|
+
static calculateAverageTime(durations: number[]): number;
|
|
23
|
+
/**
|
|
24
|
+
* Finds the slowest tests from all test records.
|
|
25
|
+
* Only considers passed tests when calculating the slowest ones.
|
|
26
|
+
*
|
|
27
|
+
* @param testRecords - Map of all test records
|
|
28
|
+
* @param limit - Maximum number of slow tests to return
|
|
29
|
+
* @returns Array of the slowest tests, sorted by duration
|
|
30
|
+
*/
|
|
31
|
+
static findSlowestTests(testRecords: Map<string, TestRecord>, limit: number): SlowTest[];
|
|
32
|
+
/**
|
|
33
|
+
* Categorizes the error message into predefined types
|
|
34
|
+
* @param message - Error message
|
|
35
|
+
* @returns Error category
|
|
36
|
+
*/
|
|
37
|
+
static categorizeError(message: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Convert test outcome to status
|
|
40
|
+
* @param outcome - Test outcome
|
|
41
|
+
* @returns Standardized status
|
|
42
|
+
*/
|
|
43
|
+
static outcomeToStatus(outcome: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Determines the team that owns a test based on test name and annotations
|
|
46
|
+
* @param test - Test case to analyze
|
|
47
|
+
* @returns Name of the team that owns the test
|
|
48
|
+
*/
|
|
49
|
+
static getOwningTeam(test: TestCase): string;
|
|
50
|
+
/**
|
|
51
|
+
* Helper method to wrap a string for team name matching
|
|
52
|
+
* @param text - Text to wrap
|
|
53
|
+
* @returns Wrapped text
|
|
54
|
+
*/
|
|
55
|
+
private static wrap;
|
|
56
|
+
/**
|
|
57
|
+
* Processes all test records to generate comprehensive test results.
|
|
58
|
+
* Calculates passed, failed, and skipped test counts, and collects timing information.
|
|
59
|
+
*
|
|
60
|
+
* @param testRecords - Map of all test records
|
|
61
|
+
* @returns Object containing test counts, failures, and timing information
|
|
62
|
+
*/
|
|
63
|
+
static processTestResults(testRecords: Map<string, TestRecord>): {
|
|
64
|
+
passedCount: number;
|
|
65
|
+
testCount: number;
|
|
66
|
+
skippedCount: number;
|
|
67
|
+
failedCount: number;
|
|
68
|
+
failures: TestFailure[];
|
|
69
|
+
passedDurations: number[];
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Logger class responsible for formatting and outputting test results.
|
|
74
|
+
* Provides methods for logging test summaries, metrics, and failures with appropriate formatting.
|
|
75
|
+
*/
|
|
76
|
+
export declare class Logger {
|
|
77
|
+
/**
|
|
78
|
+
* Logs the overall test run summary with appropriate coloring.
|
|
79
|
+
* Includes total tests, passed tests, skipped tests, and total time.
|
|
80
|
+
*
|
|
81
|
+
* @param summary - The test summary to log
|
|
82
|
+
*/
|
|
83
|
+
static logSummary(summary: TestSummary): void;
|
|
84
|
+
/**
|
|
85
|
+
* Logs build information if available
|
|
86
|
+
*
|
|
87
|
+
* @param buildInfo - The build information to log
|
|
88
|
+
*/
|
|
89
|
+
static logBuildInfo(buildInfo: BuildInfo): void;
|
|
90
|
+
/**
|
|
91
|
+
* Logs detailed metrics about the test run.
|
|
92
|
+
* Includes average test time and information about slow tests.
|
|
93
|
+
*
|
|
94
|
+
* @param summary - The test summary containing metrics to log
|
|
95
|
+
*/
|
|
96
|
+
static logMetrics(summary: TestSummary): void;
|
|
97
|
+
/**
|
|
98
|
+
* Logs detailed information about test failures.
|
|
99
|
+
* Includes test title, stack trace, and timeout information.
|
|
100
|
+
*
|
|
101
|
+
* @param failures - Array of test failures to log
|
|
102
|
+
*/
|
|
103
|
+
static logFailures(failures: TestFailure[]): void;
|
|
104
|
+
}
|