testblocks 0.1.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/LICENSE +21 -0
- package/README.md +333 -0
- package/dist/cli/executor.d.ts +32 -0
- package/dist/cli/executor.js +517 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +411 -0
- package/dist/cli/reporters.d.ts +62 -0
- package/dist/cli/reporters.js +451 -0
- package/dist/client/assets/index-4hbFPUhP.js +2087 -0
- package/dist/client/assets/index-4hbFPUhP.js.map +1 -0
- package/dist/client/assets/index-Dnk1ti7l.css +1 -0
- package/dist/client/index.html +25 -0
- package/dist/core/blocks/api.d.ts +2 -0
- package/dist/core/blocks/api.js +610 -0
- package/dist/core/blocks/data-driven.d.ts +2 -0
- package/dist/core/blocks/data-driven.js +245 -0
- package/dist/core/blocks/index.d.ts +15 -0
- package/dist/core/blocks/index.js +71 -0
- package/dist/core/blocks/lifecycle.d.ts +2 -0
- package/dist/core/blocks/lifecycle.js +199 -0
- package/dist/core/blocks/logic.d.ts +2 -0
- package/dist/core/blocks/logic.js +357 -0
- package/dist/core/blocks/playwright.d.ts +2 -0
- package/dist/core/blocks/playwright.js +764 -0
- package/dist/core/blocks/procedures.d.ts +5 -0
- package/dist/core/blocks/procedures.js +321 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +44 -0
- package/dist/core/plugins.d.ts +66 -0
- package/dist/core/plugins.js +118 -0
- package/dist/core/types.d.ts +153 -0
- package/dist/core/types.js +2 -0
- package/dist/server/codegenManager.d.ts +54 -0
- package/dist/server/codegenManager.js +259 -0
- package/dist/server/codegenParser.d.ts +17 -0
- package/dist/server/codegenParser.js +598 -0
- package/dist/server/executor.d.ts +37 -0
- package/dist/server/executor.js +672 -0
- package/dist/server/globals.d.ts +85 -0
- package/dist/server/globals.js +273 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +361 -0
- package/dist/server/plugins.d.ts +55 -0
- package/dist/server/plugins.js +206 -0
- package/package.json +103 -0
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const commander_1 = require("commander");
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const glob_1 = require("glob");
|
|
41
|
+
const executor_1 = require("./executor");
|
|
42
|
+
const reporters_1 = require("./reporters");
|
|
43
|
+
const program = new commander_1.Command();
|
|
44
|
+
program
|
|
45
|
+
.name('testblocks')
|
|
46
|
+
.description('CLI runner for TestBlocks visual test automation')
|
|
47
|
+
.version('1.0.0');
|
|
48
|
+
program
|
|
49
|
+
.command('run')
|
|
50
|
+
.description('Run test files')
|
|
51
|
+
.argument('<patterns...>', 'Test file patterns (glob supported)')
|
|
52
|
+
.option('-H, --headed', 'Run tests in headed mode (show browser)', false)
|
|
53
|
+
.option('-t, --timeout <ms>', 'Test timeout in milliseconds', '30000')
|
|
54
|
+
.option('-r, --reporter <type>', 'Reporter type: console, json, junit, html', 'console')
|
|
55
|
+
.option('-o, --output <dir>', 'Output directory for reports', './testblocks-results')
|
|
56
|
+
.option('-b, --base-url <url>', 'Base URL for relative URLs')
|
|
57
|
+
.option('-v, --var <vars...>', 'Variables in key=value format')
|
|
58
|
+
.option('--fail-fast', 'Stop on first test failure', false)
|
|
59
|
+
.option('-p, --parallel <count>', 'Number of parallel workers', '1')
|
|
60
|
+
.option('--filter <pattern>', 'Only run tests matching pattern')
|
|
61
|
+
.action(async (patterns, options) => {
|
|
62
|
+
try {
|
|
63
|
+
// Find test files
|
|
64
|
+
const files = [];
|
|
65
|
+
for (const pattern of patterns) {
|
|
66
|
+
const matches = await (0, glob_1.glob)(pattern, { absolute: true });
|
|
67
|
+
files.push(...matches);
|
|
68
|
+
}
|
|
69
|
+
if (files.length === 0) {
|
|
70
|
+
console.error('No test files found matching patterns:', patterns);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
console.log(`Found ${files.length} test file(s)\n`);
|
|
74
|
+
// Parse variables
|
|
75
|
+
const variables = {};
|
|
76
|
+
if (options.var) {
|
|
77
|
+
for (const v of options.var) {
|
|
78
|
+
const [key, ...valueParts] = v.split('=');
|
|
79
|
+
const value = valueParts.join('=');
|
|
80
|
+
// Try to parse as JSON, otherwise use as string
|
|
81
|
+
try {
|
|
82
|
+
variables[key] = JSON.parse(value);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
variables[key] = value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Create executor options
|
|
90
|
+
const executorOptions = {
|
|
91
|
+
headless: !options.headed,
|
|
92
|
+
timeout: parseInt(options.timeout, 10),
|
|
93
|
+
baseUrl: options.baseUrl,
|
|
94
|
+
variables,
|
|
95
|
+
};
|
|
96
|
+
// Create reporter
|
|
97
|
+
const reporter = createReporter(options.reporter, options.output);
|
|
98
|
+
// Run tests
|
|
99
|
+
const allResults = [];
|
|
100
|
+
let hasFailures = false;
|
|
101
|
+
for (const file of files) {
|
|
102
|
+
console.log(`Running: ${path.basename(file)}`);
|
|
103
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
104
|
+
const testFile = JSON.parse(content);
|
|
105
|
+
// Apply filter if specified
|
|
106
|
+
if (options.filter) {
|
|
107
|
+
const filterRegex = new RegExp(options.filter, 'i');
|
|
108
|
+
testFile.tests = testFile.tests.filter(t => filterRegex.test(t.name));
|
|
109
|
+
}
|
|
110
|
+
if (testFile.tests.length === 0) {
|
|
111
|
+
console.log(' (no tests match filter)\n');
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const executor = new executor_1.TestExecutor(executorOptions);
|
|
115
|
+
const results = await executor.runTestFile(testFile);
|
|
116
|
+
allResults.push({ file, results });
|
|
117
|
+
// Report results
|
|
118
|
+
reporter.onTestFileComplete(file, testFile, results);
|
|
119
|
+
// Check for failures
|
|
120
|
+
const failed = results.some(r => r.status !== 'passed');
|
|
121
|
+
if (failed) {
|
|
122
|
+
hasFailures = true;
|
|
123
|
+
if (options.failFast) {
|
|
124
|
+
console.log('\nStopping due to --fail-fast\n');
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Generate final report
|
|
130
|
+
reporter.onComplete(allResults);
|
|
131
|
+
// Exit with appropriate code
|
|
132
|
+
process.exit(hasFailures ? 1 : 0);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error('Error:', error.message);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
program
|
|
140
|
+
.command('validate')
|
|
141
|
+
.description('Validate test files without running them')
|
|
142
|
+
.argument('<patterns...>', 'Test file patterns (glob supported)')
|
|
143
|
+
.action(async (patterns) => {
|
|
144
|
+
try {
|
|
145
|
+
const files = [];
|
|
146
|
+
for (const pattern of patterns) {
|
|
147
|
+
const matches = await (0, glob_1.glob)(pattern, { absolute: true });
|
|
148
|
+
files.push(...matches);
|
|
149
|
+
}
|
|
150
|
+
if (files.length === 0) {
|
|
151
|
+
console.error('No test files found matching patterns:', patterns);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
let hasErrors = false;
|
|
155
|
+
for (const file of files) {
|
|
156
|
+
console.log(`Validating: ${path.basename(file)}`);
|
|
157
|
+
try {
|
|
158
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
159
|
+
const testFile = JSON.parse(content);
|
|
160
|
+
const errors = validateTestFile(testFile);
|
|
161
|
+
if (errors.length > 0) {
|
|
162
|
+
hasErrors = true;
|
|
163
|
+
console.log(' ✗ Invalid');
|
|
164
|
+
errors.forEach(err => console.log(` - ${err}`));
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
console.log(` ✓ Valid (${testFile.tests.length} tests)`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
hasErrors = true;
|
|
172
|
+
console.log(` ✗ Parse error: ${error.message}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
process.exit(hasErrors ? 1 : 0);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
console.error('Error:', error.message);
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
program
|
|
183
|
+
.command('init')
|
|
184
|
+
.description('Initialize a new TestBlocks project')
|
|
185
|
+
.argument('[directory]', 'Directory to initialize (default: current directory)', '.')
|
|
186
|
+
.option('--name <name>', 'Project name', 'my-testblocks-project')
|
|
187
|
+
.action((directory, options) => {
|
|
188
|
+
const projectDir = path.resolve(directory);
|
|
189
|
+
const projectName = options.name;
|
|
190
|
+
console.log(`\nInitializing TestBlocks project in ${projectDir}...\n`);
|
|
191
|
+
// Create directories
|
|
192
|
+
const dirs = ['tests', 'snippets', 'plugins', 'reports'];
|
|
193
|
+
dirs.forEach(dir => {
|
|
194
|
+
const dirPath = path.join(projectDir, dir);
|
|
195
|
+
if (!fs.existsSync(dirPath)) {
|
|
196
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
197
|
+
console.log(` Created: ${dir}/`);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
// Create globals.json
|
|
201
|
+
const globalsPath = path.join(projectDir, 'globals.json');
|
|
202
|
+
if (!fs.existsSync(globalsPath)) {
|
|
203
|
+
const globals = {
|
|
204
|
+
variables: {
|
|
205
|
+
baseUrl: 'https://example.com',
|
|
206
|
+
credentials: {
|
|
207
|
+
validUser: {
|
|
208
|
+
email: 'test@example.com',
|
|
209
|
+
password: 'password123',
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
testIdAttribute: 'data-testid',
|
|
214
|
+
};
|
|
215
|
+
fs.writeFileSync(globalsPath, JSON.stringify(globals, null, 2));
|
|
216
|
+
console.log(' Created: globals.json');
|
|
217
|
+
}
|
|
218
|
+
// Create package.json
|
|
219
|
+
const packagePath = path.join(projectDir, 'package.json');
|
|
220
|
+
if (!fs.existsSync(packagePath)) {
|
|
221
|
+
const packageJson = {
|
|
222
|
+
name: projectName,
|
|
223
|
+
version: '1.0.0',
|
|
224
|
+
description: 'TestBlocks test automation project',
|
|
225
|
+
scripts: {
|
|
226
|
+
test: 'testblocks run tests/**/*.testblocks.json',
|
|
227
|
+
'test:headed': 'testblocks run tests/**/*.testblocks.json --headed',
|
|
228
|
+
'test:html': 'testblocks run tests/**/*.testblocks.json -r html -o reports',
|
|
229
|
+
'test:junit': 'testblocks run tests/**/*.testblocks.json -r junit -o reports',
|
|
230
|
+
},
|
|
231
|
+
devDependencies: {
|
|
232
|
+
testblocks: '^1.0.0',
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2));
|
|
236
|
+
console.log(' Created: package.json');
|
|
237
|
+
}
|
|
238
|
+
// Create example test file
|
|
239
|
+
const exampleTestPath = path.join(projectDir, 'tests', 'example.testblocks.json');
|
|
240
|
+
if (!fs.existsSync(exampleTestPath)) {
|
|
241
|
+
const exampleTest = {
|
|
242
|
+
version: '1.0.0',
|
|
243
|
+
name: 'Example Test Suite',
|
|
244
|
+
description: 'Sample tests demonstrating TestBlocks features',
|
|
245
|
+
variables: {},
|
|
246
|
+
tests: [
|
|
247
|
+
{
|
|
248
|
+
id: 'test-web-1',
|
|
249
|
+
name: 'Example Web Test',
|
|
250
|
+
description: 'Navigate to a page and verify content',
|
|
251
|
+
steps: [
|
|
252
|
+
{
|
|
253
|
+
id: 'step-1',
|
|
254
|
+
type: 'web_navigate',
|
|
255
|
+
params: { URL: '${baseUrl}' },
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
id: 'step-2',
|
|
259
|
+
type: 'web_expect_title',
|
|
260
|
+
params: { EXPECTED: 'Example Domain' },
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
tags: ['web', 'smoke'],
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
};
|
|
267
|
+
fs.writeFileSync(exampleTestPath, JSON.stringify(exampleTest, null, 2));
|
|
268
|
+
console.log(' Created: tests/example.testblocks.json');
|
|
269
|
+
}
|
|
270
|
+
// Create data-driven example
|
|
271
|
+
const dataDrivenPath = path.join(projectDir, 'tests', 'login-data-driven.testblocks.json');
|
|
272
|
+
if (!fs.existsSync(dataDrivenPath)) {
|
|
273
|
+
const dataDrivenTest = {
|
|
274
|
+
version: '1.0.0',
|
|
275
|
+
name: 'Login Tests (Data-Driven)',
|
|
276
|
+
description: 'Data-driven login tests with multiple user credentials',
|
|
277
|
+
variables: {},
|
|
278
|
+
tests: [
|
|
279
|
+
{
|
|
280
|
+
id: 'test-login-dd',
|
|
281
|
+
name: 'Login with credentials',
|
|
282
|
+
description: 'Tests login with different user types',
|
|
283
|
+
data: [
|
|
284
|
+
{ name: 'Valid Admin', values: { username: 'admin@example.com', password: 'admin123', shouldSucceed: true } },
|
|
285
|
+
{ name: 'Valid User', values: { username: 'user@example.com', password: 'user123', shouldSucceed: true } },
|
|
286
|
+
{ name: 'Invalid Password', values: { username: 'user@example.com', password: 'wrong', shouldSucceed: false } },
|
|
287
|
+
{ name: 'Invalid User', values: { username: 'nobody@example.com', password: 'test', shouldSucceed: false } },
|
|
288
|
+
],
|
|
289
|
+
steps: [
|
|
290
|
+
{
|
|
291
|
+
id: 'step-1',
|
|
292
|
+
type: 'web_navigate',
|
|
293
|
+
params: { URL: '${baseUrl}/login' },
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
id: 'step-2',
|
|
297
|
+
type: 'web_fill',
|
|
298
|
+
params: { SELECTOR: '#email', VALUE: '${username}' },
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
id: 'step-3',
|
|
302
|
+
type: 'web_fill',
|
|
303
|
+
params: { SELECTOR: '#password', VALUE: '${password}' },
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
id: 'step-4',
|
|
307
|
+
type: 'web_click',
|
|
308
|
+
params: { SELECTOR: 'button[type="submit"]' },
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
tags: ['web', 'login', 'data-driven'],
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
};
|
|
315
|
+
fs.writeFileSync(dataDrivenPath, JSON.stringify(dataDrivenTest, null, 2));
|
|
316
|
+
console.log(' Created: tests/login-data-driven.testblocks.json');
|
|
317
|
+
}
|
|
318
|
+
// Create .gitignore
|
|
319
|
+
const gitignorePath = path.join(projectDir, '.gitignore');
|
|
320
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
321
|
+
const gitignore = `# Dependencies
|
|
322
|
+
node_modules/
|
|
323
|
+
|
|
324
|
+
# Reports
|
|
325
|
+
reports/
|
|
326
|
+
|
|
327
|
+
# IDE
|
|
328
|
+
.idea/
|
|
329
|
+
.vscode/
|
|
330
|
+
|
|
331
|
+
# OS
|
|
332
|
+
.DS_Store
|
|
333
|
+
Thumbs.db
|
|
334
|
+
`;
|
|
335
|
+
fs.writeFileSync(gitignorePath, gitignore);
|
|
336
|
+
console.log(' Created: .gitignore');
|
|
337
|
+
}
|
|
338
|
+
console.log('\n✓ Project initialized successfully!\n');
|
|
339
|
+
console.log('Next steps:');
|
|
340
|
+
console.log(' 1. cd ' + (directory === '.' ? '' : directory));
|
|
341
|
+
console.log(' 2. npm install');
|
|
342
|
+
console.log(' 3. npm test\n');
|
|
343
|
+
console.log('Or open the folder in TestBlocks web editor to create tests visually.\n');
|
|
344
|
+
});
|
|
345
|
+
program
|
|
346
|
+
.command('list')
|
|
347
|
+
.description('List tests in test files')
|
|
348
|
+
.argument('<patterns...>', 'Test file patterns (glob supported)')
|
|
349
|
+
.action(async (patterns) => {
|
|
350
|
+
try {
|
|
351
|
+
const files = [];
|
|
352
|
+
for (const pattern of patterns) {
|
|
353
|
+
const matches = await (0, glob_1.glob)(pattern, { absolute: true });
|
|
354
|
+
files.push(...matches);
|
|
355
|
+
}
|
|
356
|
+
if (files.length === 0) {
|
|
357
|
+
console.error('No test files found matching patterns:', patterns);
|
|
358
|
+
process.exit(1);
|
|
359
|
+
}
|
|
360
|
+
for (const file of files) {
|
|
361
|
+
console.log(`\n${path.basename(file)}:`);
|
|
362
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
363
|
+
const testFile = JSON.parse(content);
|
|
364
|
+
testFile.tests.forEach((test, index) => {
|
|
365
|
+
const tags = test.tags?.length ? ` [${test.tags.join(', ')}]` : '';
|
|
366
|
+
console.log(` ${index + 1}. ${test.name}${tags}`);
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
console.error('Error:', error.message);
|
|
372
|
+
process.exit(1);
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
function createReporter(type, outputDir) {
|
|
376
|
+
switch (type) {
|
|
377
|
+
case 'json':
|
|
378
|
+
return new reporters_1.JSONReporter(outputDir);
|
|
379
|
+
case 'junit':
|
|
380
|
+
return new reporters_1.JUnitReporter(outputDir);
|
|
381
|
+
case 'html':
|
|
382
|
+
return new reporters_1.HTMLReporter(outputDir);
|
|
383
|
+
case 'console':
|
|
384
|
+
default:
|
|
385
|
+
return new reporters_1.ConsoleReporter();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function validateTestFile(testFile) {
|
|
389
|
+
const errors = [];
|
|
390
|
+
if (!testFile.version) {
|
|
391
|
+
errors.push('Missing version field');
|
|
392
|
+
}
|
|
393
|
+
if (!testFile.name) {
|
|
394
|
+
errors.push('Missing name field');
|
|
395
|
+
}
|
|
396
|
+
if (!testFile.tests || !Array.isArray(testFile.tests)) {
|
|
397
|
+
errors.push('Missing or invalid tests array');
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
testFile.tests.forEach((test, index) => {
|
|
401
|
+
if (!test.id) {
|
|
402
|
+
errors.push(`Test at index ${index} is missing an id`);
|
|
403
|
+
}
|
|
404
|
+
if (!test.name) {
|
|
405
|
+
errors.push(`Test at index ${index} is missing a name`);
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
return errors;
|
|
410
|
+
}
|
|
411
|
+
program.parse();
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { TestFile, TestResult } from '../core';
|
|
2
|
+
export interface Reporter {
|
|
3
|
+
onTestFileComplete(file: string, testFile: TestFile, results: TestResult[]): void;
|
|
4
|
+
onComplete(allResults: {
|
|
5
|
+
file: string;
|
|
6
|
+
results: TestResult[];
|
|
7
|
+
}[]): void;
|
|
8
|
+
}
|
|
9
|
+
export declare function getTimestamp(): string;
|
|
10
|
+
export declare class ConsoleReporter implements Reporter {
|
|
11
|
+
onTestFileComplete(file: string, testFile: TestFile, results: TestResult[]): void;
|
|
12
|
+
onComplete(allResults: {
|
|
13
|
+
file: string;
|
|
14
|
+
results: TestResult[];
|
|
15
|
+
}[]): void;
|
|
16
|
+
}
|
|
17
|
+
export declare class JSONReporter implements Reporter {
|
|
18
|
+
private outputDir;
|
|
19
|
+
private allResults;
|
|
20
|
+
constructor(outputDir: string);
|
|
21
|
+
onTestFileComplete(file: string, testFile: TestFile, results: TestResult[]): void;
|
|
22
|
+
onComplete(allResults: {
|
|
23
|
+
file: string;
|
|
24
|
+
results: TestResult[];
|
|
25
|
+
}[]): void;
|
|
26
|
+
}
|
|
27
|
+
export declare class JUnitReporter implements Reporter {
|
|
28
|
+
private outputDir;
|
|
29
|
+
private allResults;
|
|
30
|
+
constructor(outputDir: string);
|
|
31
|
+
onTestFileComplete(file: string, testFile: TestFile, results: TestResult[]): void;
|
|
32
|
+
onComplete(allResults: {
|
|
33
|
+
file: string;
|
|
34
|
+
results: TestResult[];
|
|
35
|
+
}[]): void;
|
|
36
|
+
}
|
|
37
|
+
export declare class HTMLReporter implements Reporter {
|
|
38
|
+
private outputDir;
|
|
39
|
+
private allResults;
|
|
40
|
+
constructor(outputDir: string);
|
|
41
|
+
onTestFileComplete(file: string, testFile: TestFile, results: TestResult[]): void;
|
|
42
|
+
onComplete(allResults: {
|
|
43
|
+
file: string;
|
|
44
|
+
results: TestResult[];
|
|
45
|
+
}[]): void;
|
|
46
|
+
}
|
|
47
|
+
export interface ReportData {
|
|
48
|
+
timestamp: string;
|
|
49
|
+
summary: {
|
|
50
|
+
totalTests: number;
|
|
51
|
+
passed: number;
|
|
52
|
+
failed: number;
|
|
53
|
+
duration: number;
|
|
54
|
+
};
|
|
55
|
+
testFiles: {
|
|
56
|
+
file: string;
|
|
57
|
+
testFile: TestFile;
|
|
58
|
+
results: TestResult[];
|
|
59
|
+
}[];
|
|
60
|
+
}
|
|
61
|
+
export declare function generateHTMLReport(data: ReportData): string;
|
|
62
|
+
export declare function generateJUnitXML(data: ReportData): string;
|