@git.zone/tstest 3.1.1 → 3.1.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.
Files changed (34) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts_tapbundle/webhelpers.js +12 -2
  3. package/npmextra.json +11 -5
  4. package/package.json +13 -12
  5. package/readme.md +19 -0
  6. package/ts/00_commitinfo_data.ts +1 -1
  7. package/dist_ts/tstest.classes.tap.parser.old.d.ts +0 -50
  8. package/dist_ts/tstest.classes.tap.parser.old.js +0 -332
  9. package/dist_ts_tapbundle/tapbundle.protocols.d.ts +0 -88
  10. package/dist_ts_tapbundle/tapbundle.protocols.js +0 -168
  11. package/dist_ts_tapbundle/ts_tapbundle/00_commitinfo_data.d.ts +0 -8
  12. package/dist_ts_tapbundle/ts_tapbundle/00_commitinfo_data.js +0 -9
  13. package/dist_ts_tapbundle/ts_tapbundle/index.d.ts +0 -6
  14. package/dist_ts_tapbundle/ts_tapbundle/index.js +0 -7
  15. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.pretask.d.ts +0 -10
  16. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.pretask.js +0 -13
  17. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.tap.d.ts +0 -104
  18. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.tap.js +0 -401
  19. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.taptest.d.ts +0 -38
  20. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.taptest.js +0 -110
  21. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.taptools.d.ts +0 -109
  22. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.taptools.js +0 -241
  23. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.tapwrap.d.ts +0 -8
  24. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.classes.tapwrap.js +0 -7
  25. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.plugins.d.ts +0 -8
  26. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.plugins.js +0 -10
  27. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.tapcreator.d.ts +0 -3
  28. package/dist_ts_tapbundle/ts_tapbundle/tapbundle.tapcreator.js +0 -5
  29. package/dist_ts_tapbundle/ts_tapbundle/webhelpers.d.ts +0 -7
  30. package/dist_ts_tapbundle/ts_tapbundle/webhelpers.js +0 -35
  31. package/dist_ts_tapbundle/ts_tapbundle_node/classes.pathinject.d.ts +0 -5
  32. package/dist_ts_tapbundle/ts_tapbundle_node/classes.pathinject.js +0 -13
  33. package/dist_ts_tapbundle/ts_tapbundle_node/plugins.d.ts +0 -11
  34. package/dist_ts_tapbundle/ts_tapbundle_node/plugins.js +0 -14
@@ -1,401 +0,0 @@
1
- import * as plugins from './tapbundle.plugins.js';
2
- import { PreTask } from './tapbundle.classes.pretask.js';
3
- import { TapTest } from './tapbundle.classes.taptest.js';
4
- class TestBuilder {
5
- constructor(tap) {
6
- this._tags = [];
7
- this._priority = 'medium';
8
- this._tap = tap;
9
- }
10
- tags(...tags) {
11
- this._tags = tags;
12
- return this;
13
- }
14
- priority(level) {
15
- this._priority = level;
16
- return this;
17
- }
18
- retry(count) {
19
- this._retryCount = count;
20
- return this;
21
- }
22
- timeout(ms) {
23
- this._timeoutMs = ms;
24
- return this;
25
- }
26
- test(description, testFunction) {
27
- const test = this._tap.test(description, testFunction, 'normal');
28
- // Apply settings to the test
29
- if (this._tags.length > 0) {
30
- test.tags = this._tags;
31
- }
32
- test.priority = this._priority;
33
- if (this._retryCount !== undefined) {
34
- test.tapTools.retry(this._retryCount);
35
- }
36
- if (this._timeoutMs !== undefined) {
37
- test.timeoutMs = this._timeoutMs;
38
- }
39
- return test;
40
- }
41
- testOnly(description, testFunction) {
42
- const test = this._tap.test(description, testFunction, 'only');
43
- // Apply settings to the test
44
- if (this._tags.length > 0) {
45
- test.tags = this._tags;
46
- }
47
- test.priority = this._priority;
48
- if (this._retryCount !== undefined) {
49
- test.tapTools.retry(this._retryCount);
50
- }
51
- if (this._timeoutMs !== undefined) {
52
- test.timeoutMs = this._timeoutMs;
53
- }
54
- return test;
55
- }
56
- testSkip(description, testFunction) {
57
- const test = this._tap.test(description, testFunction, 'skip');
58
- // Apply settings to the test
59
- if (this._tags.length > 0) {
60
- test.tags = this._tags;
61
- }
62
- test.priority = this._priority;
63
- if (this._retryCount !== undefined) {
64
- test.tapTools.retry(this._retryCount);
65
- }
66
- if (this._timeoutMs !== undefined) {
67
- test.timeoutMs = this._timeoutMs;
68
- }
69
- return test;
70
- }
71
- }
72
- export class Tap {
73
- constructor() {
74
- this._skipCount = 0;
75
- this._filterTags = [];
76
- /**
77
- * skips a test
78
- * tests marked with tap.skip.test() are never executed
79
- */
80
- this.skip = {
81
- test: (descriptionArg, functionArg) => {
82
- console.log(`skipped test: ${descriptionArg}`);
83
- this._skipCount++;
84
- },
85
- testParallel: (descriptionArg, functionArg) => {
86
- console.log(`skipped test: ${descriptionArg}`);
87
- this._skipCount++;
88
- },
89
- };
90
- /**
91
- * only executes tests marked as ONLY
92
- */
93
- this.only = {
94
- test: (descriptionArg, testFunctionArg) => {
95
- this.test(descriptionArg, testFunctionArg, 'only');
96
- },
97
- };
98
- this._tapPreTasks = [];
99
- this._tapTests = [];
100
- this._tapTestsOnly = [];
101
- this._currentSuite = null;
102
- this._rootSuites = [];
103
- // Get filter tags from environment
104
- if (process.env.TSTEST_FILTER_TAGS) {
105
- this._filterTags = process.env.TSTEST_FILTER_TAGS.split(',');
106
- }
107
- }
108
- // Fluent test builder
109
- tags(...tags) {
110
- const builder = new TestBuilder(this);
111
- return builder.tags(...tags);
112
- }
113
- priority(level) {
114
- const builder = new TestBuilder(this);
115
- return builder.priority(level);
116
- }
117
- retry(count) {
118
- const builder = new TestBuilder(this);
119
- return builder.retry(count);
120
- }
121
- timeout(ms) {
122
- const builder = new TestBuilder(this);
123
- return builder.timeout(ms);
124
- }
125
- /**
126
- * Normal test function, will run one by one
127
- * @param testDescription - A description of what the test does
128
- * @param testFunction - A Function that returns a Promise and resolves or rejects
129
- */
130
- test(testDescription, testFunction, modeArg = 'normal') {
131
- const localTest = new TapTest({
132
- description: testDescription,
133
- testFunction,
134
- parallel: false,
135
- });
136
- // No options applied here - use the fluent builder syntax instead
137
- // If we're in a suite, add test to the suite
138
- if (this._currentSuite) {
139
- this._currentSuite.tests.push(localTest);
140
- }
141
- else {
142
- // Otherwise add to global test list
143
- if (modeArg === 'normal') {
144
- this._tapTests.push(localTest);
145
- }
146
- else if (modeArg === 'only') {
147
- this._tapTestsOnly.push(localTest);
148
- }
149
- }
150
- return localTest;
151
- }
152
- preTask(descriptionArg, functionArg) {
153
- this._tapPreTasks.push(new PreTask(descriptionArg, functionArg));
154
- }
155
- /**
156
- * A parallel test that will not be waited for before the next starts.
157
- * @param testDescription - A description of what the test does
158
- * @param testFunction - A Function that returns a Promise and resolves or rejects
159
- */
160
- testParallel(testDescription, testFunction) {
161
- const localTest = new TapTest({
162
- description: testDescription,
163
- testFunction,
164
- parallel: true,
165
- });
166
- if (this._currentSuite) {
167
- this._currentSuite.tests.push(localTest);
168
- }
169
- else {
170
- this._tapTests.push(localTest);
171
- }
172
- }
173
- /**
174
- * Create a test suite for grouping related tests
175
- */
176
- describe(description, suiteFunction) {
177
- const suite = {
178
- description,
179
- tests: [],
180
- children: [],
181
- parent: this._currentSuite,
182
- };
183
- // Add to parent or root
184
- if (this._currentSuite) {
185
- this._currentSuite.children.push(suite);
186
- }
187
- else {
188
- this._rootSuites.push(suite);
189
- }
190
- // Execute suite function in context
191
- const previousSuite = this._currentSuite;
192
- this._currentSuite = suite;
193
- try {
194
- suiteFunction();
195
- }
196
- finally {
197
- this._currentSuite = previousSuite;
198
- }
199
- }
200
- /**
201
- * Set up a function to run before each test in the current suite
202
- */
203
- beforeEach(setupFunction) {
204
- if (this._currentSuite) {
205
- this._currentSuite.beforeEach = setupFunction;
206
- }
207
- else {
208
- throw new Error('beforeEach can only be used inside a describe block');
209
- }
210
- }
211
- /**
212
- * Set up a function to run after each test in the current suite
213
- */
214
- afterEach(teardownFunction) {
215
- if (this._currentSuite) {
216
- this._currentSuite.afterEach = teardownFunction;
217
- }
218
- else {
219
- throw new Error('afterEach can only be used inside a describe block');
220
- }
221
- }
222
- /**
223
- * collect all tests from suites
224
- */
225
- _collectTests(suite, tests = []) {
226
- tests.push(...suite.tests);
227
- for (const childSuite of suite.children) {
228
- this._collectTests(childSuite, tests);
229
- }
230
- return tests;
231
- }
232
- /**
233
- * starts the test evaluation
234
- */
235
- async start(optionsArg) {
236
- // lets set the tapbundle promise
237
- const smartenvInstance = new plugins.smartenv.Smartenv();
238
- smartenvInstance.isBrowser
239
- ? (globalThis.tapbundleDeferred = plugins.smartpromise.defer())
240
- : null;
241
- // Initialize path helpers for Node.js environment
242
- if (!smartenvInstance.isBrowser) {
243
- try {
244
- const { initializePathHelpers } = await import('../ts_tapbundle_node/classes.pathinject.js');
245
- initializePathHelpers();
246
- }
247
- catch (error) {
248
- // tapbundle_node not available in browser environment
249
- }
250
- }
251
- // lets continue with running the tests
252
- const promiseArray = [];
253
- // Collect all tests including those in suites
254
- let allTests = [...this._tapTests];
255
- for (const suite of this._rootSuites) {
256
- this._collectTests(suite, allTests);
257
- }
258
- // safeguard against empty test array
259
- if (allTests.length === 0 && this._tapTestsOnly.length === 0) {
260
- console.log('no tests specified. Ending here!');
261
- return;
262
- }
263
- // determine which tests to run
264
- let concerningTests;
265
- if (this._tapTestsOnly.length > 0) {
266
- concerningTests = this._tapTestsOnly;
267
- }
268
- else {
269
- concerningTests = allTests;
270
- }
271
- // Filter tests by tags if specified
272
- if (this._filterTags.length > 0) {
273
- concerningTests = concerningTests.filter(test => {
274
- // Skip tests without tags when filtering is active
275
- if (!test.tags || test.tags.length === 0) {
276
- return false;
277
- }
278
- // Check if test has any of the filter tags
279
- return test.tags.some(tag => this._filterTags.includes(tag));
280
- });
281
- }
282
- // lets run the pretasks
283
- for (const preTask of this._tapPreTasks) {
284
- await preTask.run();
285
- }
286
- // Count actual tests that will be run
287
- console.log(`1..${concerningTests.length}`);
288
- // Run tests from suites with lifecycle hooks
289
- let testKey = 0;
290
- // Run all concerning tests (filtered by tags if applicable)
291
- for (const currentTest of concerningTests) {
292
- const testPromise = currentTest.run(testKey++);
293
- if (currentTest.parallel) {
294
- promiseArray.push(testPromise);
295
- }
296
- else {
297
- await testPromise;
298
- }
299
- }
300
- await Promise.all(promiseArray);
301
- // when tests have been run and all promises are fullfilled
302
- const failReasons = [];
303
- const executionNotes = [];
304
- // collect failed tests
305
- for (const tapTest of concerningTests) {
306
- if (tapTest.status !== 'success' && tapTest.status !== 'skipped') {
307
- failReasons.push(`Test ${tapTest.testKey + 1} failed with status ${tapTest.status}:\n` +
308
- `|| ${tapTest.description}\n` +
309
- `|| for more information please take a look the logs above`);
310
- }
311
- }
312
- // render fail Reasons
313
- for (const failReason of failReasons) {
314
- console.log(failReason);
315
- }
316
- if (optionsArg && optionsArg.throwOnError && failReasons.length > 0) {
317
- if (!smartenvInstance.isBrowser)
318
- process.exit(1);
319
- }
320
- if (smartenvInstance.isBrowser) {
321
- globalThis.tapbundleDeferred.resolve();
322
- }
323
- }
324
- /**
325
- * Run tests in a suite with lifecycle hooks
326
- */
327
- async _runSuite(parentSuite, suites, promiseArray, context) {
328
- for (const suite of suites) {
329
- // Run beforeEach from parent suites
330
- const beforeEachFunctions = [];
331
- let currentSuite = suite;
332
- while (currentSuite) {
333
- if (currentSuite.beforeEach) {
334
- beforeEachFunctions.unshift(currentSuite.beforeEach);
335
- }
336
- currentSuite = currentSuite.parent || null;
337
- }
338
- // Run tests in this suite
339
- for (const test of suite.tests) {
340
- // Create wrapper test function that includes lifecycle hooks
341
- const originalFunction = test.testFunction;
342
- test.testFunction = async (tapTools) => {
343
- // Run all beforeEach hooks
344
- for (const beforeEach of beforeEachFunctions) {
345
- await beforeEach(tapTools);
346
- }
347
- // Run the actual test
348
- const result = await originalFunction(tapTools);
349
- // Run afterEach hooks in reverse order
350
- const afterEachFunctions = [];
351
- currentSuite = suite;
352
- while (currentSuite) {
353
- if (currentSuite.afterEach) {
354
- afterEachFunctions.push(currentSuite.afterEach);
355
- }
356
- currentSuite = currentSuite.parent || null;
357
- }
358
- for (const afterEach of afterEachFunctions) {
359
- await afterEach(tapTools);
360
- }
361
- return result;
362
- };
363
- const testPromise = test.run(context.testKey++);
364
- if (test.parallel) {
365
- promiseArray.push(testPromise);
366
- }
367
- else {
368
- await testPromise;
369
- }
370
- }
371
- // Recursively run child suites
372
- await this._runSuite(suite, suite.children, promiseArray, context);
373
- }
374
- }
375
- async stopForcefully(codeArg = 0, directArg = false) {
376
- console.log(`tap stopping forcefully! Code: ${codeArg} / Direct: ${directArg}`);
377
- if (directArg) {
378
- process.exit(codeArg);
379
- }
380
- else {
381
- setTimeout(() => {
382
- process.exit(codeArg);
383
- }, 10);
384
- }
385
- }
386
- /**
387
- * handle errors
388
- */
389
- threw(err) {
390
- console.log(err);
391
- }
392
- /**
393
- * Explicitly fail the current test with a custom message
394
- * @param message - The failure message to display
395
- */
396
- fail(message = 'Test failed') {
397
- throw new Error(message);
398
- }
399
- }
400
- export const tap = new Tap();
401
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFwYnVuZGxlLmNsYXNzZXMudGFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfdGFwYnVuZGxlL3RhcGJ1bmRsZS5jbGFzc2VzLnRhcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHdCQUF3QixDQUFDO0FBRWxELE9BQU8sRUFBeUIsT0FBTyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDaEYsT0FBTyxFQUFFLE9BQU8sRUFBc0IsTUFBTSxnQ0FBZ0MsQ0FBQztBQVc3RSxNQUFNLFdBQVc7SUFPZixZQUFZLEdBQVc7UUFMZixVQUFLLEdBQWEsRUFBRSxDQUFDO1FBQ3JCLGNBQVMsR0FBOEIsUUFBUSxDQUFDO1FBS3RELElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2xCLENBQUM7SUFFRCxJQUFJLENBQUMsR0FBRyxJQUFjO1FBQ3BCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELFFBQVEsQ0FBQyxLQUFnQztRQUN2QyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN2QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxLQUFLLENBQUMsS0FBYTtRQUNqQixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztRQUN6QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLENBQUMsRUFBVTtRQUNoQixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNyQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUFJLENBQUMsV0FBbUIsRUFBRSxZQUE4QjtRQUN0RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBRWpFLDZCQUE2QjtRQUM3QixJQUFJLElBQUks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
@@ -1,38 +0,0 @@
1
- import { TapTools } from './tapbundle.classes.taptools.js';
2
- import { HrtMeasurement } from '@push.rocks/smarttime';
3
- export type TTestStatus = 'success' | 'error' | 'pending' | 'errorAfterSuccess' | 'timeout' | 'skipped';
4
- export interface ITestFunction<T> {
5
- (tapTools?: TapTools): Promise<T>;
6
- }
7
- export declare class TapTest<T = unknown> {
8
- description: string;
9
- failureAllowed: boolean;
10
- hrtMeasurement: HrtMeasurement;
11
- parallel: boolean;
12
- status: TTestStatus;
13
- tapTools: TapTools;
14
- testFunction: ITestFunction<T>;
15
- testKey: number;
16
- timeoutMs?: number;
17
- isTodo: boolean;
18
- todoReason?: string;
19
- tags: string[];
20
- priority: 'high' | 'medium' | 'low';
21
- fileName?: string;
22
- private testDeferred;
23
- testPromise: Promise<TapTest<T>>;
24
- private testResultDeferred;
25
- testResultPromise: Promise<T>;
26
- /**
27
- * constructor
28
- */
29
- constructor(optionsArg: {
30
- description: string;
31
- testFunction: ITestFunction<T>;
32
- parallel: boolean;
33
- });
34
- /**
35
- * run the test
36
- */
37
- run(testKeyArg: number): Promise<void>;
38
- }
@@ -1,110 +0,0 @@
1
- import * as plugins from './tapbundle.plugins.js';
2
- import { tapCreator } from './tapbundle.tapcreator.js';
3
- import { TapTools, SkipError } from './tapbundle.classes.taptools.js';
4
- // imported interfaces
5
- import { Deferred } from '@push.rocks/smartpromise';
6
- import { HrtMeasurement } from '@push.rocks/smarttime';
7
- export class TapTest {
8
- /**
9
- * constructor
10
- */
11
- constructor(optionsArg) {
12
- this.isTodo = false;
13
- this.tags = [];
14
- this.priority = 'medium';
15
- this.testDeferred = plugins.smartpromise.defer();
16
- this.testPromise = this.testDeferred.promise;
17
- this.testResultDeferred = plugins.smartpromise.defer();
18
- this.testResultPromise = this.testResultDeferred.promise;
19
- this.description = optionsArg.description;
20
- this.hrtMeasurement = new HrtMeasurement();
21
- this.parallel = optionsArg.parallel;
22
- this.status = 'pending';
23
- this.tapTools = new TapTools(this);
24
- this.testFunction = optionsArg.testFunction;
25
- }
26
- /**
27
- * run the test
28
- */
29
- async run(testKeyArg) {
30
- this.testKey = testKeyArg;
31
- const testNumber = testKeyArg + 1;
32
- // Handle todo tests
33
- if (this.isTodo) {
34
- const todoText = this.todoReason ? `# TODO ${this.todoReason}` : '# TODO';
35
- console.log(`ok ${testNumber} - ${this.description} ${todoText}`);
36
- this.status = 'success';
37
- this.testDeferred.resolve(this);
38
- return;
39
- }
40
- // Run test with retries
41
- let lastError;
42
- const maxRetries = this.tapTools.maxRetries;
43
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
44
- this.hrtMeasurement.start();
45
- try {
46
- // Set up timeout if specified
47
- let timeoutHandle;
48
- let timeoutPromise = null;
49
- if (this.timeoutMs) {
50
- timeoutPromise = new Promise((_, reject) => {
51
- timeoutHandle = setTimeout(() => {
52
- this.status = 'timeout';
53
- reject(new Error(`Test timed out after ${this.timeoutMs}ms`));
54
- }, this.timeoutMs);
55
- });
56
- }
57
- // Run the test function with potential timeout
58
- const testPromise = this.testFunction(this.tapTools);
59
- const testReturnValue = timeoutPromise
60
- ? await Promise.race([testPromise, timeoutPromise])
61
- : await testPromise;
62
- // Clear timeout if test completed
63
- if (timeoutHandle) {
64
- clearTimeout(timeoutHandle);
65
- }
66
- this.hrtMeasurement.stop();
67
- console.log(`ok ${testNumber} - ${this.description} # time=${this.hrtMeasurement.milliSeconds}ms`);
68
- this.status = 'success';
69
- this.testDeferred.resolve(this);
70
- this.testResultDeferred.resolve(testReturnValue);
71
- return; // Success, exit retry loop
72
- }
73
- catch (err) {
74
- this.hrtMeasurement.stop();
75
- // Handle skip
76
- if (err instanceof SkipError || err.name === 'SkipError') {
77
- console.log(`ok ${testNumber} - ${this.description} # SKIP ${err.message.replace('Skipped: ', '')}`);
78
- this.status = 'skipped';
79
- this.testDeferred.resolve(this);
80
- return;
81
- }
82
- lastError = err;
83
- // If we have retries left, try again
84
- if (attempt < maxRetries) {
85
- console.log(`# Retry ${attempt + 1}/${maxRetries} for test: ${this.description}`);
86
- this.tapTools._incrementRetryCount();
87
- continue;
88
- }
89
- // Final failure
90
- console.log(`not ok ${testNumber} - ${this.description} # time=${this.hrtMeasurement.milliSeconds}ms`);
91
- this.testDeferred.resolve(this);
92
- this.testResultDeferred.resolve(err);
93
- // if the test has already succeeded before
94
- if (this.status === 'success') {
95
- this.status = 'errorAfterSuccess';
96
- console.log('!!! ALERT !!!: weird behaviour, since test has been already successfull');
97
- }
98
- else {
99
- this.status = 'error';
100
- }
101
- // if the test is allowed to fail
102
- if (this.failureAllowed) {
103
- console.log(`please note: failure allowed!`);
104
- }
105
- console.log(err);
106
- }
107
- }
108
- }
109
- }
110
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFwYnVuZGxlLmNsYXNzZXMudGFwdGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3RhcGJ1bmRsZS90YXBidW5kbGUuY2xhc3Nlcy50YXB0ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sd0JBQXdCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFdEUsc0JBQXNCO0FBQ3RCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFTdkQsTUFBTSxPQUFPLE9BQU87SUFtQmxCOztPQUVHO0lBQ0gsWUFBWSxVQUlYO1FBaEJNLFdBQU0sR0FBWSxLQUFLLENBQUM7UUFFeEIsU0FBSSxHQUFhLEVBQUUsQ0FBQztRQUNwQixhQUFRLEdBQThCLFFBQVEsQ0FBQztRQUU5QyxpQkFBWSxHQUF5QixPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25FLGdCQUFXLEdBQXdCLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDO1FBQzVELHVCQUFrQixHQUFnQixPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2hFLHNCQUFpQixHQUFlLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUM7UUFTckUsSUFBSSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDO1FBQzFDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztRQUMzQyxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUM7UUFDcEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7UUFDeEIsSUFB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