slapify 0.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.
- package/README.md +452 -0
- package/bin/slapify.js +2 -0
- package/dist/ai/interpreter.d.ts +54 -0
- package/dist/ai/interpreter.d.ts.map +1 -0
- package/dist/ai/interpreter.js +293 -0
- package/dist/ai/interpreter.js.map +1 -0
- package/dist/browser/agent.d.ts +137 -0
- package/dist/browser/agent.d.ts.map +1 -0
- package/dist/browser/agent.js +362 -0
- package/dist/browser/agent.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1181 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/loader.d.ts +35 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +278 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/index.d.ts +155 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +260 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/flow.d.ts +27 -0
- package/dist/parser/flow.d.ts.map +1 -0
- package/dist/parser/flow.js +117 -0
- package/dist/parser/flow.js.map +1 -0
- package/dist/report/generator.d.ts +61 -0
- package/dist/report/generator.d.ts.map +1 -0
- package/dist/report/generator.js +549 -0
- package/dist/report/generator.js.map +1 -0
- package/dist/runner/index.d.ts +44 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +403 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/types.d.ts +105 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
/**
|
|
4
|
+
* Generate test reports in various formats
|
|
5
|
+
*/
|
|
6
|
+
export class ReportGenerator {
|
|
7
|
+
config;
|
|
8
|
+
constructor(config = {}) {
|
|
9
|
+
this.config = {
|
|
10
|
+
format: "html",
|
|
11
|
+
screenshots: true,
|
|
12
|
+
output_dir: "./test-reports",
|
|
13
|
+
...config,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate a report from test results
|
|
18
|
+
*/
|
|
19
|
+
generate(result) {
|
|
20
|
+
switch (this.config.format) {
|
|
21
|
+
case "markdown":
|
|
22
|
+
return this.generateMarkdown(result);
|
|
23
|
+
case "html":
|
|
24
|
+
return this.generateHTML(result);
|
|
25
|
+
case "json":
|
|
26
|
+
return JSON.stringify(result, null, 2);
|
|
27
|
+
default:
|
|
28
|
+
return this.generateHTML(result);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generate a suite report from multiple test results
|
|
33
|
+
*/
|
|
34
|
+
generateSuiteReport(results) {
|
|
35
|
+
return this.generateSuiteHTML(results);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Save report to file
|
|
39
|
+
*/
|
|
40
|
+
save(result, filename) {
|
|
41
|
+
const report = this.generate(result);
|
|
42
|
+
// Ensure output directory exists
|
|
43
|
+
const outputDir = this.config.output_dir || "./test-reports";
|
|
44
|
+
if (!fs.existsSync(outputDir)) {
|
|
45
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
// Generate filename
|
|
48
|
+
const ext = this.config.format === "html"
|
|
49
|
+
? "html"
|
|
50
|
+
: this.config.format === "json"
|
|
51
|
+
? "json"
|
|
52
|
+
: "md";
|
|
53
|
+
const defaultName = `${path.basename(result.flowFile, ".flow")}-${Date.now()}.${ext}`;
|
|
54
|
+
const outputPath = path.join(outputDir, filename || defaultName);
|
|
55
|
+
fs.writeFileSync(outputPath, report);
|
|
56
|
+
return outputPath;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Save report as a folder with embedded images
|
|
60
|
+
*/
|
|
61
|
+
saveAsFolder(result) {
|
|
62
|
+
const outputDir = this.config.output_dir || "./test-reports";
|
|
63
|
+
const folderName = `${path.basename(result.flowFile, ".flow")}-${Date.now()}`;
|
|
64
|
+
const reportFolder = path.join(outputDir, folderName);
|
|
65
|
+
// Create report folder
|
|
66
|
+
fs.mkdirSync(reportFolder, { recursive: true });
|
|
67
|
+
// Copy screenshots to folder and build map
|
|
68
|
+
const screenshotMap = {};
|
|
69
|
+
for (const step of result.steps) {
|
|
70
|
+
if (step.screenshot && fs.existsSync(step.screenshot)) {
|
|
71
|
+
const screenshotName = path.basename(step.screenshot);
|
|
72
|
+
const destPath = path.join(reportFolder, screenshotName);
|
|
73
|
+
fs.copyFileSync(step.screenshot, destPath);
|
|
74
|
+
screenshotMap[step.screenshot] = screenshotName;
|
|
75
|
+
// Clean up original screenshot
|
|
76
|
+
try {
|
|
77
|
+
fs.unlinkSync(step.screenshot);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Ignore cleanup errors
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Update result with relative paths
|
|
85
|
+
const updatedResult = {
|
|
86
|
+
...result,
|
|
87
|
+
steps: result.steps.map((step) => ({
|
|
88
|
+
...step,
|
|
89
|
+
screenshot: step.screenshot
|
|
90
|
+
? screenshotMap[step.screenshot] || step.screenshot
|
|
91
|
+
: undefined,
|
|
92
|
+
})),
|
|
93
|
+
};
|
|
94
|
+
// Generate report
|
|
95
|
+
const report = this.generateHTML(updatedResult);
|
|
96
|
+
const reportPath = path.join(reportFolder, "report.html");
|
|
97
|
+
fs.writeFileSync(reportPath, report);
|
|
98
|
+
return reportFolder;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Save suite report as a folder
|
|
102
|
+
*/
|
|
103
|
+
saveSuiteAsFolder(results) {
|
|
104
|
+
const outputDir = this.config.output_dir || "./test-reports";
|
|
105
|
+
const folderName = `test-suite-${Date.now()}`;
|
|
106
|
+
const reportFolder = path.join(outputDir, folderName);
|
|
107
|
+
// Create report folder
|
|
108
|
+
fs.mkdirSync(reportFolder, { recursive: true });
|
|
109
|
+
// Copy all screenshots and update paths
|
|
110
|
+
const updatedResults = results.map((result) => {
|
|
111
|
+
const screenshotMap = {};
|
|
112
|
+
for (const step of result.steps) {
|
|
113
|
+
if (step.screenshot && fs.existsSync(step.screenshot)) {
|
|
114
|
+
const screenshotName = `${path.basename(result.flowFile, ".flow")}-${path.basename(step.screenshot)}`;
|
|
115
|
+
const destPath = path.join(reportFolder, screenshotName);
|
|
116
|
+
fs.copyFileSync(step.screenshot, destPath);
|
|
117
|
+
screenshotMap[step.screenshot] = screenshotName;
|
|
118
|
+
try {
|
|
119
|
+
fs.unlinkSync(step.screenshot);
|
|
120
|
+
}
|
|
121
|
+
catch { }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
...result,
|
|
126
|
+
steps: result.steps.map((step) => ({
|
|
127
|
+
...step,
|
|
128
|
+
screenshot: step.screenshot
|
|
129
|
+
? screenshotMap[step.screenshot] || step.screenshot
|
|
130
|
+
: undefined,
|
|
131
|
+
})),
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
// Generate suite report
|
|
135
|
+
const report = this.generateSuiteHTML(updatedResults);
|
|
136
|
+
const reportPath = path.join(reportFolder, "report.html");
|
|
137
|
+
fs.writeFileSync(reportPath, report);
|
|
138
|
+
return reportFolder;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Generate Markdown report
|
|
142
|
+
*/
|
|
143
|
+
generateMarkdown(result) {
|
|
144
|
+
const lines = [];
|
|
145
|
+
const statusEmoji = result.status === "passed" ? "â
" : "â";
|
|
146
|
+
lines.push(`# ${path.basename(result.flowFile, ".flow")}`);
|
|
147
|
+
lines.push("");
|
|
148
|
+
lines.push(`**Status:** ${statusEmoji} ${result.status.toUpperCase()}`);
|
|
149
|
+
lines.push(`**Duration:** ${this.formatDuration(result.duration)}`);
|
|
150
|
+
lines.push(`**Started:** ${result.startTime.toISOString()}`);
|
|
151
|
+
lines.push("");
|
|
152
|
+
lines.push("## Summary");
|
|
153
|
+
lines.push("");
|
|
154
|
+
lines.push(`| Metric | Value |`);
|
|
155
|
+
lines.push(`|--------|-------|`);
|
|
156
|
+
lines.push(`| Total Steps | ${result.totalSteps} |`);
|
|
157
|
+
lines.push(`| Passed | ${result.passedSteps} |`);
|
|
158
|
+
lines.push(`| Failed | ${result.failedSteps} |`);
|
|
159
|
+
lines.push(`| Skipped | ${result.skippedSteps} |`);
|
|
160
|
+
lines.push("");
|
|
161
|
+
if (result.autoHandled.length > 0) {
|
|
162
|
+
lines.push("## Auto-Handled");
|
|
163
|
+
for (const handled of result.autoHandled) {
|
|
164
|
+
lines.push(`- ${handled}`);
|
|
165
|
+
}
|
|
166
|
+
lines.push("");
|
|
167
|
+
}
|
|
168
|
+
lines.push("## Steps");
|
|
169
|
+
lines.push("");
|
|
170
|
+
for (const stepResult of result.steps) {
|
|
171
|
+
const step = stepResult.step;
|
|
172
|
+
const statusIcon = stepResult.status === "passed"
|
|
173
|
+
? "â
"
|
|
174
|
+
: stepResult.status === "failed"
|
|
175
|
+
? "â"
|
|
176
|
+
: "âī¸";
|
|
177
|
+
const optional = step.optional ? " [Optional]" : "";
|
|
178
|
+
lines.push(`### ${statusIcon} ${step.text}${optional}`);
|
|
179
|
+
lines.push(`Duration: ${this.formatDuration(stepResult.duration)}`);
|
|
180
|
+
lines.push("");
|
|
181
|
+
if (stepResult.actions.length > 0) {
|
|
182
|
+
for (const action of stepResult.actions) {
|
|
183
|
+
lines.push(`- ${action.description}`);
|
|
184
|
+
}
|
|
185
|
+
lines.push("");
|
|
186
|
+
}
|
|
187
|
+
if (stepResult.error) {
|
|
188
|
+
lines.push(`**Error:** ${stepResult.error}`);
|
|
189
|
+
lines.push("");
|
|
190
|
+
}
|
|
191
|
+
if (stepResult.screenshot) {
|
|
192
|
+
lines.push(``);
|
|
193
|
+
lines.push("");
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return lines.join("\n");
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Generate HTML report with Tailwind CSS
|
|
200
|
+
*/
|
|
201
|
+
generateHTML(result) {
|
|
202
|
+
const statusIcon = result.status === "passed" ? "â" : "â";
|
|
203
|
+
return `<!DOCTYPE html>
|
|
204
|
+
<html lang="en">
|
|
205
|
+
<head>
|
|
206
|
+
<meta charset="UTF-8">
|
|
207
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
208
|
+
<title>${path.basename(result.flowFile, ".flow")} - Test Report</title>
|
|
209
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
210
|
+
<style>
|
|
211
|
+
.step-details { display: none; }
|
|
212
|
+
.step.expanded .step-details { display: block; }
|
|
213
|
+
.step.expanded .chevron { transform: rotate(180deg); }
|
|
214
|
+
.modal { display: none; }
|
|
215
|
+
.modal.active { display: flex; }
|
|
216
|
+
</style>
|
|
217
|
+
</head>
|
|
218
|
+
<body class="bg-gray-50 text-gray-900 min-h-screen">
|
|
219
|
+
<div class="max-w-4xl mx-auto p-6">
|
|
220
|
+
|
|
221
|
+
<!-- Header -->
|
|
222
|
+
<div class="bg-white rounded-xl shadow-sm p-6 mb-6">
|
|
223
|
+
<div class="flex items-center justify-between mb-4">
|
|
224
|
+
<h1 class="text-2xl font-bold">${path.basename(result.flowFile, ".flow")}</h1>
|
|
225
|
+
<span class="px-4 py-2 rounded-full font-semibold text-sm ${result.status === "passed"
|
|
226
|
+
? "bg-green-100 text-green-800"
|
|
227
|
+
: "bg-red-100 text-red-800"}">
|
|
228
|
+
${statusIcon} ${result.status.toUpperCase()}
|
|
229
|
+
</span>
|
|
230
|
+
</div>
|
|
231
|
+
<p class="text-gray-500 text-sm mb-6">Duration: ${this.formatDuration(result.duration)} ¡ ${result.startTime.toLocaleString()}</p>
|
|
232
|
+
|
|
233
|
+
<!-- Stats -->
|
|
234
|
+
<div class="grid grid-cols-4 gap-4">
|
|
235
|
+
<div class="bg-gray-100 rounded-lg p-4 text-center">
|
|
236
|
+
<div class="text-3xl font-bold">${result.totalSteps}</div>
|
|
237
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide">Total</div>
|
|
238
|
+
</div>
|
|
239
|
+
<div class="bg-gray-100 rounded-lg p-4 text-center">
|
|
240
|
+
<div class="text-3xl font-bold text-green-600">${result.passedSteps}</div>
|
|
241
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide">Passed</div>
|
|
242
|
+
</div>
|
|
243
|
+
<div class="bg-gray-100 rounded-lg p-4 text-center">
|
|
244
|
+
<div class="text-3xl font-bold text-red-600">${result.failedSteps}</div>
|
|
245
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide">Failed</div>
|
|
246
|
+
</div>
|
|
247
|
+
<div class="bg-gray-100 rounded-lg p-4 text-center">
|
|
248
|
+
<div class="text-3xl font-bold text-yellow-600">${result.skippedSteps}</div>
|
|
249
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide">Skipped</div>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
|
|
254
|
+
${result.autoHandled.length > 0
|
|
255
|
+
? `
|
|
256
|
+
<!-- Auto-handled -->
|
|
257
|
+
<div class="bg-blue-50 border border-blue-200 rounded-xl p-4 mb-6">
|
|
258
|
+
<div class="font-semibold text-blue-800 mb-2">âšī¸ Auto-Handled Interruptions</div>
|
|
259
|
+
${result.autoHandled
|
|
260
|
+
.map((h) => `<div class="text-blue-700 text-sm py-1">âĸ ${h}</div>`)
|
|
261
|
+
.join("")}
|
|
262
|
+
</div>
|
|
263
|
+
`
|
|
264
|
+
: ""}
|
|
265
|
+
|
|
266
|
+
<!-- Steps -->
|
|
267
|
+
<div class="bg-white rounded-xl shadow-sm overflow-hidden">
|
|
268
|
+
<div class="px-6 py-4 border-b border-gray-200 font-semibold">Steps</div>
|
|
269
|
+
${result.steps.map((s, i) => this.formatStepHTML(s, i)).join("")}
|
|
270
|
+
</div>
|
|
271
|
+
|
|
272
|
+
<!-- Footer -->
|
|
273
|
+
<div class="text-center text-gray-400 text-sm py-8">
|
|
274
|
+
Generated by Slapify ¡ ${new Date().toISOString()}
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
<!-- Modal -->
|
|
279
|
+
<div class="modal fixed inset-0 bg-black/90 z-50 items-center justify-center cursor-pointer" id="modal">
|
|
280
|
+
<img src="" alt="Screenshot" id="modal-img" class="max-w-[95%] max-h-[95%] rounded-lg">
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
<script>
|
|
284
|
+
document.querySelectorAll('.step-header').forEach(header => {
|
|
285
|
+
header.addEventListener('click', () => header.parentElement.classList.toggle('expanded'));
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const modal = document.getElementById('modal');
|
|
289
|
+
const modalImg = document.getElementById('modal-img');
|
|
290
|
+
|
|
291
|
+
document.querySelectorAll('.screenshot-img').forEach(img => {
|
|
292
|
+
img.addEventListener('click', (e) => {
|
|
293
|
+
e.stopPropagation();
|
|
294
|
+
modalImg.src = img.src;
|
|
295
|
+
modal.classList.add('active');
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
modal.addEventListener('click', () => modal.classList.remove('active'));
|
|
300
|
+
document.querySelectorAll('.step.failed').forEach(step => step.classList.add('expanded'));
|
|
301
|
+
</script>
|
|
302
|
+
</body>
|
|
303
|
+
</html>`;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Format a single step for HTML with Tailwind
|
|
307
|
+
*/
|
|
308
|
+
formatStepHTML(result, index) {
|
|
309
|
+
const step = result.step;
|
|
310
|
+
const statusIcon = result.status === "passed" ? "â" : result.status === "failed" ? "â" : "â";
|
|
311
|
+
const statusColors = {
|
|
312
|
+
passed: "bg-green-100 text-green-600",
|
|
313
|
+
failed: "bg-red-100 text-red-600",
|
|
314
|
+
skipped: "bg-yellow-100 text-yellow-600",
|
|
315
|
+
};
|
|
316
|
+
const hasScreenshot = !!result.screenshot;
|
|
317
|
+
const wasRetried = result.retried;
|
|
318
|
+
return `
|
|
319
|
+
<div class="step ${result.status} border-b border-gray-100 last:border-b-0">
|
|
320
|
+
<div class="step-header flex items-center px-6 py-4 cursor-pointer hover:bg-gray-50 transition-colors">
|
|
321
|
+
<div class="w-8 h-8 rounded-full flex items-center justify-center font-semibold text-sm mr-4 flex-shrink-0 ${statusColors[result.status]}">${statusIcon}</div>
|
|
322
|
+
<div class="flex-1 min-w-0">
|
|
323
|
+
<div class="font-medium flex items-center flex-wrap gap-2">
|
|
324
|
+
<span>${step.text}</span>
|
|
325
|
+
${step.optional
|
|
326
|
+
? '<span class="px-2 py-0.5 bg-gray-100 text-gray-500 text-xs rounded">Optional</span>'
|
|
327
|
+
: ""}
|
|
328
|
+
${wasRetried
|
|
329
|
+
? '<span class="px-2 py-0.5 bg-orange-100 text-orange-600 text-xs rounded">Retried</span>'
|
|
330
|
+
: ""}
|
|
331
|
+
</div>
|
|
332
|
+
${result.actions.length > 0
|
|
333
|
+
? `<div class="text-sm text-gray-500 mt-1 truncate">${result.actions[0]?.description || ""}</div>`
|
|
334
|
+
: ""}
|
|
335
|
+
</div>
|
|
336
|
+
<div class="flex items-center gap-3 ml-4">
|
|
337
|
+
${hasScreenshot ? '<span class="text-gray-400" title="Has screenshot">đˇ</span>' : ""}
|
|
338
|
+
<span class="text-gray-400 text-sm">${this.formatDuration(result.duration)}</span>
|
|
339
|
+
</div>
|
|
340
|
+
<div class="chevron ml-2 text-gray-400 transition-transform">âŧ</div>
|
|
341
|
+
</div>
|
|
342
|
+
<div class="step-details px-6 pb-6 pl-16">
|
|
343
|
+
${result.actions.length > 0
|
|
344
|
+
? `
|
|
345
|
+
<div class="bg-gray-50 rounded-lg p-4 mb-4">
|
|
346
|
+
${result.actions
|
|
347
|
+
.map((a) => `<div class="py-1 text-sm"><span class="mr-2">${this.getActionIcon(a.type)}</span>${a.description}</div>`)
|
|
348
|
+
.join("")}
|
|
349
|
+
</div>
|
|
350
|
+
`
|
|
351
|
+
: ""}
|
|
352
|
+
${result.assumptions && result.assumptions.length > 0
|
|
353
|
+
? `
|
|
354
|
+
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-4">
|
|
355
|
+
<div class="font-semibold text-yellow-800 mb-2">đĄ Assumptions</div>
|
|
356
|
+
${result.assumptions
|
|
357
|
+
.map((a) => `<div class="text-yellow-700 text-sm py-1">âĸ ${a}</div>`)
|
|
358
|
+
.join("")}
|
|
359
|
+
</div>
|
|
360
|
+
`
|
|
361
|
+
: ""}
|
|
362
|
+
${result.error
|
|
363
|
+
? `<div class="bg-red-50 border border-red-200 rounded-lg p-4 mb-4 font-mono text-sm text-red-700 whitespace-pre-wrap break-words">${result.error}</div>`
|
|
364
|
+
: ""}
|
|
365
|
+
${result.screenshot
|
|
366
|
+
? `
|
|
367
|
+
<div class="mt-4">
|
|
368
|
+
<img src="./${result.screenshot}" alt="Step ${index + 1}" loading="lazy" class="screenshot-img max-w-full rounded-lg border border-gray-200 cursor-pointer hover:shadow-lg transition-shadow">
|
|
369
|
+
</div>
|
|
370
|
+
`
|
|
371
|
+
: ""}
|
|
372
|
+
</div>
|
|
373
|
+
</div>`;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Generate suite report HTML with Tailwind
|
|
377
|
+
*/
|
|
378
|
+
generateSuiteHTML(results) {
|
|
379
|
+
const totalTests = results.length;
|
|
380
|
+
const passedTests = results.filter((r) => r.status === "passed").length;
|
|
381
|
+
const failedTests = results.filter((r) => r.status === "failed").length;
|
|
382
|
+
const totalSteps = results.reduce((sum, r) => sum + r.totalSteps, 0);
|
|
383
|
+
const totalDuration = results.reduce((sum, r) => sum + r.duration, 0);
|
|
384
|
+
const overallStatus = failedTests === 0 ? "passed" : "failed";
|
|
385
|
+
return `<!DOCTYPE html>
|
|
386
|
+
<html lang="en">
|
|
387
|
+
<head>
|
|
388
|
+
<meta charset="UTF-8">
|
|
389
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
390
|
+
<title>Test Suite Report</title>
|
|
391
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
392
|
+
<style>
|
|
393
|
+
.test-details { display: none; }
|
|
394
|
+
.test-item.expanded .test-details { display: block; }
|
|
395
|
+
.test-item.expanded .chevron { transform: rotate(180deg); }
|
|
396
|
+
</style>
|
|
397
|
+
</head>
|
|
398
|
+
<body class="bg-gray-50 text-gray-900 min-h-screen">
|
|
399
|
+
<div class="max-w-5xl mx-auto p-6">
|
|
400
|
+
|
|
401
|
+
<!-- Header -->
|
|
402
|
+
<div class="bg-white rounded-xl shadow-sm p-8 mb-6">
|
|
403
|
+
<div class="flex items-center justify-between mb-6">
|
|
404
|
+
<h1 class="text-3xl font-bold">Test Suite Report</h1>
|
|
405
|
+
<span class="px-6 py-3 rounded-full font-bold ${overallStatus === "passed"
|
|
406
|
+
? "bg-green-100 text-green-800"
|
|
407
|
+
: "bg-red-100 text-red-800"}">
|
|
408
|
+
${overallStatus === "passed" ? "â ALL PASSED" : "â FAILURES"}
|
|
409
|
+
</span>
|
|
410
|
+
</div>
|
|
411
|
+
|
|
412
|
+
<!-- Stats -->
|
|
413
|
+
<div class="grid grid-cols-5 gap-4">
|
|
414
|
+
<div class="bg-gray-100 rounded-lg p-5 text-center">
|
|
415
|
+
<div class="text-4xl font-bold">${totalTests}</div>
|
|
416
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide mt-1">Test Files</div>
|
|
417
|
+
</div>
|
|
418
|
+
<div class="bg-gray-100 rounded-lg p-5 text-center">
|
|
419
|
+
<div class="text-4xl font-bold text-green-600">${passedTests}</div>
|
|
420
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide mt-1">Passed</div>
|
|
421
|
+
</div>
|
|
422
|
+
<div class="bg-gray-100 rounded-lg p-5 text-center">
|
|
423
|
+
<div class="text-4xl font-bold text-red-600">${failedTests}</div>
|
|
424
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide mt-1">Failed</div>
|
|
425
|
+
</div>
|
|
426
|
+
<div class="bg-gray-100 rounded-lg p-5 text-center">
|
|
427
|
+
<div class="text-4xl font-bold">${totalSteps}</div>
|
|
428
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide mt-1">Total Steps</div>
|
|
429
|
+
</div>
|
|
430
|
+
<div class="bg-gray-100 rounded-lg p-5 text-center">
|
|
431
|
+
<div class="text-2xl font-bold">${this.formatDuration(totalDuration)}</div>
|
|
432
|
+
<div class="text-xs text-gray-500 uppercase tracking-wide mt-1">Duration</div>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
|
|
437
|
+
<!-- Test List -->
|
|
438
|
+
<div class="bg-white rounded-xl shadow-sm overflow-hidden">
|
|
439
|
+
<div class="px-6 py-4 border-b border-gray-200 font-semibold text-lg">Test Files (${totalTests})</div>
|
|
440
|
+
${results.map((r, i) => this.formatTestItemHTML(r, i)).join("")}
|
|
441
|
+
</div>
|
|
442
|
+
|
|
443
|
+
<!-- Footer -->
|
|
444
|
+
<div class="text-center text-gray-400 text-sm py-8">
|
|
445
|
+
Generated by Slapify ¡ ${new Date().toISOString()}
|
|
446
|
+
</div>
|
|
447
|
+
</div>
|
|
448
|
+
|
|
449
|
+
<script>
|
|
450
|
+
document.querySelectorAll('.test-header').forEach(header => {
|
|
451
|
+
header.addEventListener('click', () => header.parentElement.classList.toggle('expanded'));
|
|
452
|
+
});
|
|
453
|
+
document.querySelectorAll('.test-item.failed').forEach(item => item.classList.add('expanded'));
|
|
454
|
+
</script>
|
|
455
|
+
</body>
|
|
456
|
+
</html>`;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Format a test item for suite report with Tailwind
|
|
460
|
+
*/
|
|
461
|
+
formatTestItemHTML(result, index) {
|
|
462
|
+
const statusIcon = result.status === "passed" ? "â" : "â";
|
|
463
|
+
const statusColors = result.status === "passed"
|
|
464
|
+
? "bg-green-100 text-green-600"
|
|
465
|
+
: "bg-red-100 text-red-600";
|
|
466
|
+
return `
|
|
467
|
+
<div class="test-item ${result.status} border-b border-gray-100 last:border-b-0">
|
|
468
|
+
<div class="test-header flex items-center px-6 py-5 cursor-pointer hover:bg-gray-50 transition-colors">
|
|
469
|
+
<div class="w-10 h-10 rounded-full flex items-center justify-center font-bold mr-4 ${statusColors}">${statusIcon}</div>
|
|
470
|
+
<div class="flex-1">
|
|
471
|
+
<div class="font-semibold text-lg">${path.basename(result.flowFile, ".flow")}</div>
|
|
472
|
+
<div class="text-sm text-gray-500 mt-1">${result.totalSteps} steps ¡ ${this.formatDuration(result.duration)}</div>
|
|
473
|
+
</div>
|
|
474
|
+
<div class="flex gap-2 ml-4">
|
|
475
|
+
<span class="px-3 py-1 bg-green-100 text-green-700 rounded text-sm font-medium">${result.passedSteps} passed</span>
|
|
476
|
+
${result.failedSteps > 0
|
|
477
|
+
? `<span class="px-3 py-1 bg-red-100 text-red-700 rounded text-sm font-medium">${result.failedSteps} failed</span>`
|
|
478
|
+
: ""}
|
|
479
|
+
</div>
|
|
480
|
+
<div class="chevron ml-4 text-gray-400 transition-transform">âŧ</div>
|
|
481
|
+
</div>
|
|
482
|
+
<div class="test-details px-6 pb-6 bg-gray-50">
|
|
483
|
+
${result.steps
|
|
484
|
+
.map((s) => {
|
|
485
|
+
const stepColors = {
|
|
486
|
+
passed: "bg-green-100 text-green-600",
|
|
487
|
+
failed: "bg-red-100 text-red-600",
|
|
488
|
+
skipped: "bg-yellow-100 text-yellow-600",
|
|
489
|
+
};
|
|
490
|
+
const stepIcon = s.status === "passed" ? "â" : s.status === "failed" ? "â" : "â";
|
|
491
|
+
return `
|
|
492
|
+
<div class="flex items-center py-2 text-sm">
|
|
493
|
+
<div class="w-6 h-6 rounded-full flex items-center justify-center text-xs mr-3 ${stepColors[s.status]}">${stepIcon}</div>
|
|
494
|
+
<div class="flex-1">${s.step.text}</div>
|
|
495
|
+
<div class="text-gray-400">${this.formatDuration(s.duration)}</div>
|
|
496
|
+
</div>
|
|
497
|
+
${s.error
|
|
498
|
+
? `<div class="ml-9 p-2 bg-red-50 border border-red-200 rounded text-xs text-red-700 mb-2">${s.error}</div>`
|
|
499
|
+
: ""}
|
|
500
|
+
`;
|
|
501
|
+
})
|
|
502
|
+
.join("")}
|
|
503
|
+
</div>
|
|
504
|
+
</div>`;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Format duration in human-readable form
|
|
508
|
+
*/
|
|
509
|
+
formatDuration(ms) {
|
|
510
|
+
if (ms < 1000)
|
|
511
|
+
return `${ms}ms`;
|
|
512
|
+
if (ms < 60000)
|
|
513
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
514
|
+
const mins = Math.floor(ms / 60000);
|
|
515
|
+
const secs = Math.floor((ms % 60000) / 1000);
|
|
516
|
+
return `${mins}m ${secs}s`;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Get icon for action type
|
|
520
|
+
*/
|
|
521
|
+
getActionIcon(type) {
|
|
522
|
+
switch (type) {
|
|
523
|
+
case "navigate":
|
|
524
|
+
return "đ";
|
|
525
|
+
case "click":
|
|
526
|
+
return "đ";
|
|
527
|
+
case "fill":
|
|
528
|
+
return "âī¸";
|
|
529
|
+
case "verify":
|
|
530
|
+
return "â";
|
|
531
|
+
case "wait":
|
|
532
|
+
return "âŗ";
|
|
533
|
+
case "auto-handle":
|
|
534
|
+
return "âšī¸";
|
|
535
|
+
default:
|
|
536
|
+
return "âĸ";
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Print summary to console
|
|
541
|
+
*/
|
|
542
|
+
printSummary(result) {
|
|
543
|
+
const statusEmoji = result.status === "passed" ? "â
" : "â";
|
|
544
|
+
console.log("");
|
|
545
|
+
console.log(`${statusEmoji} ${path.basename(result.flowFile, ".flow")} - ${result.status.toUpperCase()}`);
|
|
546
|
+
console.log(` ${result.passedSteps}/${result.totalSteps} steps passed (${this.formatDuration(result.duration)})`);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/report/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { SlapifyConfig, CredentialsConfig, FlowFile, StepResult, TestResult } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Test runner that executes flow files
|
|
4
|
+
*/
|
|
5
|
+
export declare class TestRunner {
|
|
6
|
+
private config;
|
|
7
|
+
private credentials;
|
|
8
|
+
private browser;
|
|
9
|
+
private ai;
|
|
10
|
+
private autoHandled;
|
|
11
|
+
private allAssumptions;
|
|
12
|
+
constructor(config: SlapifyConfig, credentials: CredentialsConfig);
|
|
13
|
+
/**
|
|
14
|
+
* Run a flow file
|
|
15
|
+
* @param flow The flow file to run
|
|
16
|
+
* @param onStep Optional callback for real-time step progress
|
|
17
|
+
*/
|
|
18
|
+
runFlow(flow: FlowFile, onStep?: (result: StepResult) => void): Promise<TestResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Execute a single step
|
|
21
|
+
*/
|
|
22
|
+
private executeStep;
|
|
23
|
+
/**
|
|
24
|
+
* Execute a browser command
|
|
25
|
+
*/
|
|
26
|
+
private executeCommand;
|
|
27
|
+
/**
|
|
28
|
+
* Handle automatic dismissal of interruptions
|
|
29
|
+
*/
|
|
30
|
+
private handleInterruptions;
|
|
31
|
+
/**
|
|
32
|
+
* Handle login with credentials
|
|
33
|
+
*/
|
|
34
|
+
private handleLogin;
|
|
35
|
+
/**
|
|
36
|
+
* Generate TOTP code from secret
|
|
37
|
+
*/
|
|
38
|
+
private generateTOTP;
|
|
39
|
+
/**
|
|
40
|
+
* Get action type from command
|
|
41
|
+
*/
|
|
42
|
+
private getActionType;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,QAAQ,EAER,UAAU,EACV,UAAU,EAGX,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,cAAc,CAAgB;gBAE1B,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB;IAOjE;;;;OAIG;IACG,OAAO,CACX,IAAI,EAAE,QAAQ,EACd,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GACpC,OAAO,CAAC,UAAU,CAAC;IAqEtB;;OAEG;YACW,WAAW;IAqHzB;;OAEG;YACW,cAAc;IAmE5B;;OAEG;YACW,mBAAmB;IA8BjC;;OAEG;YACW,WAAW;IAyGzB;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;OAEG;IACH,OAAO,CAAC,aAAa;CAmBtB"}
|