@wdio/cli 9.0.0-alpha.9 → 9.0.1
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/build/commands/config.d.ts.map +1 -1
- package/build/commands/repl.d.ts.map +1 -1
- package/build/commands/run.d.ts +14 -13
- package/build/commands/run.d.ts.map +1 -1
- package/build/constants.d.ts +83 -10
- package/build/constants.d.ts.map +1 -1
- package/build/index.cjs +46 -0
- package/build/index.d.cts +2 -0
- package/build/index.d.cts.map +1 -0
- package/build/index.js +3233 -4
- package/build/interface.d.ts +0 -1
- package/build/interface.d.ts.map +1 -1
- package/build/launcher.d.ts.map +1 -1
- package/build/run.d.ts.map +1 -1
- package/build/types.d.ts +3 -4
- package/build/types.d.ts.map +1 -1
- package/build/utils.d.ts +7 -11
- package/build/utils.d.ts.map +1 -1
- package/build/watcher.d.ts.map +1 -1
- package/package.json +20 -25
- package/build/cjs/index.d.ts +0 -2
- package/build/cjs/index.d.ts.map +0 -1
- package/build/cjs/index.js +0 -26
- package/build/cjs/package.json +0 -5
- package/build/commands/config.js +0 -197
- package/build/commands/index.js +0 -5
- package/build/commands/install.js +0 -109
- package/build/commands/repl.js +0 -50
- package/build/commands/run.js +0 -262
- package/build/constants.js +0 -909
- package/build/install.js +0 -38
- package/build/interface.js +0 -285
- package/build/launcher.js +0 -513
- package/build/run.js +0 -75
- package/build/templates/EjsHelpers.js +0 -59
- package/build/templates/EjsHelpers.ts +0 -84
- package/build/templates/exampleFiles/browser/Component.css.ejs +0 -121
- package/build/templates/exampleFiles/browser/Component.lit.ejs +0 -154
- package/build/templates/exampleFiles/browser/Component.lit.test.ejs +0 -24
- package/build/templates/exampleFiles/browser/Component.preact.ejs +0 -28
- package/build/templates/exampleFiles/browser/Component.preact.test.ejs +0 -59
- package/build/templates/exampleFiles/browser/Component.react.ejs +0 -29
- package/build/templates/exampleFiles/browser/Component.react.test.ejs +0 -58
- package/build/templates/exampleFiles/browser/Component.solid.ejs +0 -28
- package/build/templates/exampleFiles/browser/Component.solid.test.ejs +0 -58
- package/build/templates/exampleFiles/browser/Component.stencil.ejs +0 -43
- package/build/templates/exampleFiles/browser/Component.stencil.test.ejs +0 -45
- package/build/templates/exampleFiles/browser/Component.svelte.ejs +0 -47
- package/build/templates/exampleFiles/browser/Component.svelte.test.ejs +0 -58
- package/build/templates/exampleFiles/browser/Component.vue.ejs +0 -34
- package/build/templates/exampleFiles/browser/Component.vue.test.ejs +0 -62
- package/build/templates/exampleFiles/browser/standalone.test.ejs +0 -13
- package/build/templates/exampleFiles/cucumber/features/login.feature +0 -12
- package/build/templates/exampleFiles/cucumber/step_definitions/steps.js.ejs +0 -55
- package/build/templates/exampleFiles/mochaJasmine/test.e2e.js.ejs +0 -11
- package/build/templates/exampleFiles/pageobjects/login.page.js.ejs +0 -45
- package/build/templates/exampleFiles/pageobjects/page.js.ejs +0 -17
- package/build/templates/exampleFiles/pageobjects/secure.page.js.ejs +0 -20
- package/build/templates/exampleFiles/serenity-js/common/config/serenity.properties.ejs +0 -1
- package/build/templates/exampleFiles/serenity-js/common/serenity/github-api/GitHubStatus.ts.ejs +0 -41
- package/build/templates/exampleFiles/serenity-js/common/serenity/todo-list-app/TodoList.ts.ejs +0 -100
- package/build/templates/exampleFiles/serenity-js/common/serenity/todo-list-app/TodoListItem.ts.ejs +0 -36
- package/build/templates/exampleFiles/serenity-js/cucumber/step-definitions/steps.ts.ejs +0 -37
- package/build/templates/exampleFiles/serenity-js/cucumber/support/parameter.config.ts.ejs +0 -18
- package/build/templates/exampleFiles/serenity-js/cucumber/todo-list/completing_items.feature.ejs +0 -23
- package/build/templates/exampleFiles/serenity-js/cucumber/todo-list/narrative.md.ejs +0 -17
- package/build/templates/exampleFiles/serenity-js/jasmine/example.spec.ts.ejs +0 -86
- package/build/templates/exampleFiles/serenity-js/mocha/example.spec.ts.ejs +0 -88
- package/build/templates/snippets/afterTest.ejs +0 -20
- package/build/templates/snippets/capabilities.ejs +0 -57
- package/build/templates/snippets/cucumber.ejs +0 -50
- package/build/templates/snippets/electronTest.js.ejs +0 -7
- package/build/templates/snippets/jasmine.ejs +0 -20
- package/build/templates/snippets/macosTest.js.ejs +0 -11
- package/build/templates/snippets/mocha.ejs +0 -14
- package/build/templates/snippets/reporters.ejs +0 -14
- package/build/templates/snippets/serenity.ejs +0 -18
- package/build/templates/snippets/services.ejs +0 -18
- package/build/templates/snippets/testWithPO.js.ejs +0 -22
- package/build/templates/snippets/testWithoutPO.js.ejs +0 -19
- package/build/templates/snippets/vscodeTest.js.ejs +0 -9
- package/build/templates/wdio.conf.tpl.ejs +0 -422
- package/build/types.js +0 -1
- package/build/utils.js +0 -930
- package/build/watcher.js +0 -156
- /package/{LICENSE-MIT → LICENSE} +0 -0
package/build/install.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { execa } from 'execa';
|
|
2
|
-
import { detectPackageManager } from './utils.js';
|
|
3
|
-
const installCommand = {
|
|
4
|
-
npm: 'install',
|
|
5
|
-
pnpm: 'add',
|
|
6
|
-
yarn: 'add',
|
|
7
|
-
bun: 'install'
|
|
8
|
-
};
|
|
9
|
-
const devFlag = {
|
|
10
|
-
npm: '--save-dev',
|
|
11
|
-
pnpm: '--save-dev',
|
|
12
|
-
yarn: '--dev',
|
|
13
|
-
bun: '--dev'
|
|
14
|
-
};
|
|
15
|
-
export async function installPackages(cwd, packages, dev) {
|
|
16
|
-
const pm = detectPackageManager();
|
|
17
|
-
const devParam = dev ? devFlag[pm] : '';
|
|
18
|
-
console.log('\n');
|
|
19
|
-
const p = execa(pm, [installCommand[pm], ...packages, devParam], {
|
|
20
|
-
cwd,
|
|
21
|
-
stdout: process.stdout,
|
|
22
|
-
stderr: process.stderr
|
|
23
|
-
});
|
|
24
|
-
const { stdout, stderr, exitCode } = await p;
|
|
25
|
-
if (exitCode !== 0) {
|
|
26
|
-
const cmd = getInstallCommand(pm, packages, dev);
|
|
27
|
-
const customError = ('⚠️ An unknown error happened! Please retry ' +
|
|
28
|
-
`installing dependencies via "${cmd}"\n\n` +
|
|
29
|
-
`Error: ${stderr || stdout || 'unknown'}`);
|
|
30
|
-
console.error(customError);
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
export function getInstallCommand(pm, packages, dev) {
|
|
36
|
-
const devParam = dev ? devFlag[pm] : '';
|
|
37
|
-
return `${pm} ${installCommand[pm]} ${packages.join(' ')} ${devParam}`;
|
|
38
|
-
}
|
package/build/interface.js
DELETED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from 'node:events';
|
|
2
|
-
import chalk, { supportsColor } from 'chalk';
|
|
3
|
-
import logger from '@wdio/logger';
|
|
4
|
-
import { SnapshotManager } from '@vitest/snapshot/manager';
|
|
5
|
-
import { HookError } from './utils.js';
|
|
6
|
-
import { getRunnerName } from './utils.js';
|
|
7
|
-
const log = logger('@wdio/cli');
|
|
8
|
-
const EVENT_FILTER = ['sessionStarted', 'sessionEnded', 'finishedCommand', 'ready', 'workerResponse', 'workerEvent'];
|
|
9
|
-
export default class WDIOCLInterface extends EventEmitter {
|
|
10
|
-
_config;
|
|
11
|
-
totalWorkerCnt;
|
|
12
|
-
_isWatchMode;
|
|
13
|
-
#snapshotManager = new SnapshotManager({
|
|
14
|
-
updateSnapshot: 'new' // ignored in this context
|
|
15
|
-
});
|
|
16
|
-
hasAnsiSupport;
|
|
17
|
-
result = {
|
|
18
|
-
finished: 0,
|
|
19
|
-
passed: 0,
|
|
20
|
-
retries: 0,
|
|
21
|
-
failed: 0
|
|
22
|
-
};
|
|
23
|
-
_jobs = new Map();
|
|
24
|
-
_specFileRetries;
|
|
25
|
-
_specFileRetriesDelay;
|
|
26
|
-
_skippedSpecs = 0;
|
|
27
|
-
_inDebugMode = false;
|
|
28
|
-
_start = new Date();
|
|
29
|
-
_messages = {
|
|
30
|
-
reporter: {},
|
|
31
|
-
debugger: {}
|
|
32
|
-
};
|
|
33
|
-
constructor(_config, totalWorkerCnt, _isWatchMode = false) {
|
|
34
|
-
super();
|
|
35
|
-
this._config = _config;
|
|
36
|
-
this.totalWorkerCnt = totalWorkerCnt;
|
|
37
|
-
this._isWatchMode = _isWatchMode;
|
|
38
|
-
/**
|
|
39
|
-
* Colors can be forcibly enabled/disabled with env variable `FORCE_COLOR`
|
|
40
|
-
* `FORCE_COLOR=1` - forcibly enable colors
|
|
41
|
-
* `FORCE_COLOR=0` - forcibly disable colors
|
|
42
|
-
*/
|
|
43
|
-
this.hasAnsiSupport = supportsColor && supportsColor.hasBasic;
|
|
44
|
-
this.totalWorkerCnt = totalWorkerCnt;
|
|
45
|
-
this._isWatchMode = _isWatchMode;
|
|
46
|
-
this._specFileRetries = _config.specFileRetries || 0;
|
|
47
|
-
this._specFileRetriesDelay = _config.specFileRetriesDelay || 0;
|
|
48
|
-
this.on('job:start', this.addJob.bind(this));
|
|
49
|
-
this.on('job:end', this.clearJob.bind(this));
|
|
50
|
-
this.setup();
|
|
51
|
-
this.onStart();
|
|
52
|
-
}
|
|
53
|
-
#hasShard() {
|
|
54
|
-
return this._config.shard && this._config.shard.total !== 1;
|
|
55
|
-
}
|
|
56
|
-
setup() {
|
|
57
|
-
this._jobs = new Map();
|
|
58
|
-
this._start = new Date();
|
|
59
|
-
/**
|
|
60
|
-
* The relationship between totalWorkerCnt and these counters are as follows:
|
|
61
|
-
* totalWorkerCnt - retries = finished = passed + failed
|
|
62
|
-
*/
|
|
63
|
-
this.result = {
|
|
64
|
-
finished: 0,
|
|
65
|
-
passed: 0,
|
|
66
|
-
retries: 0,
|
|
67
|
-
failed: 0
|
|
68
|
-
};
|
|
69
|
-
this._messages = {
|
|
70
|
-
reporter: {},
|
|
71
|
-
debugger: {}
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
onStart() {
|
|
75
|
-
const shardNote = this.#hasShard()
|
|
76
|
-
? ` (Shard ${this._config.shard.current} of ${this._config.shard.total})`
|
|
77
|
-
: '';
|
|
78
|
-
this.log(chalk.bold(`\nExecution of ${chalk.blue(this.totalWorkerCnt)} workers${shardNote} started at`), this._start.toISOString());
|
|
79
|
-
if (this._inDebugMode) {
|
|
80
|
-
this.log(chalk.bgYellow(chalk.black('DEBUG mode enabled!')));
|
|
81
|
-
}
|
|
82
|
-
if (this._isWatchMode) {
|
|
83
|
-
this.log(chalk.bgYellow(chalk.black('WATCH mode enabled!')));
|
|
84
|
-
}
|
|
85
|
-
this.log('');
|
|
86
|
-
}
|
|
87
|
-
onSpecRunning(rid) {
|
|
88
|
-
this.onJobComplete(rid, this._jobs.get(rid), 0, chalk.bold(chalk.cyan('RUNNING')));
|
|
89
|
-
}
|
|
90
|
-
onSpecRetry(rid, job, retries = 0) {
|
|
91
|
-
const delayMsg = this._specFileRetriesDelay > 0 ? ` after ${this._specFileRetriesDelay}s` : '';
|
|
92
|
-
this.onJobComplete(rid, job, retries, chalk.bold(chalk.yellow('RETRYING') + delayMsg));
|
|
93
|
-
}
|
|
94
|
-
onSpecPass(rid, job, retries = 0) {
|
|
95
|
-
this.onJobComplete(rid, job, retries, chalk.bold(chalk.green('PASSED')));
|
|
96
|
-
}
|
|
97
|
-
onSpecFailure(rid, job, retries = 0) {
|
|
98
|
-
this.onJobComplete(rid, job, retries, chalk.bold(chalk.red('FAILED')));
|
|
99
|
-
}
|
|
100
|
-
onSpecSkip(rid, job) {
|
|
101
|
-
this.onJobComplete(rid, job, 0, 'SKIPPED', log.info);
|
|
102
|
-
}
|
|
103
|
-
onJobComplete(cid, job, retries = 0, message = '', _logger = this.log) {
|
|
104
|
-
const details = [`[${cid}]`, message];
|
|
105
|
-
if (job) {
|
|
106
|
-
details.push('in', getRunnerName(job.caps), this.getFilenames(job.specs));
|
|
107
|
-
}
|
|
108
|
-
if (retries > 0) {
|
|
109
|
-
details.push(`(${retries} retries)`);
|
|
110
|
-
}
|
|
111
|
-
return _logger(...details);
|
|
112
|
-
}
|
|
113
|
-
onTestError(payload) {
|
|
114
|
-
const error = {
|
|
115
|
-
type: payload.error?.type || 'Error',
|
|
116
|
-
message: payload.error?.message || (typeof payload.error === 'string' ? payload.error : 'Unknown error.'),
|
|
117
|
-
stack: payload.error?.stack
|
|
118
|
-
};
|
|
119
|
-
return this.log(`[${payload.cid}]`, `${chalk.red(error.type)} in "${payload.fullTitle}"\n${chalk.red(error.stack || error.message)}`);
|
|
120
|
-
}
|
|
121
|
-
getFilenames(specs = []) {
|
|
122
|
-
if (specs.length > 0) {
|
|
123
|
-
return '- ' + specs.join(', ').replace(new RegExp(`${process.cwd()}`, 'g'), '');
|
|
124
|
-
}
|
|
125
|
-
return '';
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* add job to interface
|
|
129
|
-
*/
|
|
130
|
-
addJob({ cid, caps, specs, hasTests }) {
|
|
131
|
-
this._jobs.set(cid, { caps, specs, hasTests });
|
|
132
|
-
if (hasTests) {
|
|
133
|
-
this.onSpecRunning(cid);
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
this._skippedSpecs++;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* clear job from interface
|
|
141
|
-
*/
|
|
142
|
-
clearJob({ cid, passed, retries }) {
|
|
143
|
-
const job = this._jobs.get(cid);
|
|
144
|
-
this._jobs.delete(cid);
|
|
145
|
-
const retryAttempts = this._specFileRetries - retries;
|
|
146
|
-
const retry = !passed && retries > 0;
|
|
147
|
-
if (!retry) {
|
|
148
|
-
this.result.finished++;
|
|
149
|
-
}
|
|
150
|
-
if (job && job.hasTests === false) {
|
|
151
|
-
return this.onSpecSkip(cid, job);
|
|
152
|
-
}
|
|
153
|
-
if (passed) {
|
|
154
|
-
this.result.passed++;
|
|
155
|
-
this.onSpecPass(cid, job, retryAttempts);
|
|
156
|
-
}
|
|
157
|
-
else if (retry) {
|
|
158
|
-
this.totalWorkerCnt++;
|
|
159
|
-
this.result.retries++;
|
|
160
|
-
this.onSpecRetry(cid, job, retryAttempts);
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
this.result.failed++;
|
|
164
|
-
this.onSpecFailure(cid, job, retryAttempts);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* for testing purposes call console log in a static method
|
|
169
|
-
*/
|
|
170
|
-
log(...args) {
|
|
171
|
-
// eslint-disable-next-line no-console
|
|
172
|
-
console.log(...args);
|
|
173
|
-
return args;
|
|
174
|
-
}
|
|
175
|
-
logHookError(error) {
|
|
176
|
-
if (error instanceof HookError) {
|
|
177
|
-
return this.log(`${chalk.red(error.name)} in "${error.origin}"\n${chalk.red(error.stack || error.message)}`);
|
|
178
|
-
}
|
|
179
|
-
return this.log(`${chalk.red(error.name)}: ${chalk.red(error.stack || error.message)}`);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* event handler that is triggered when runner sends up events
|
|
183
|
-
*/
|
|
184
|
-
onMessage(event) {
|
|
185
|
-
if (event.name === 'reporterRealTime') {
|
|
186
|
-
this.log(event.content);
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
if (event.origin === 'debugger' && event.name === 'start') {
|
|
190
|
-
this.log(chalk.yellow(event.params.introMessage));
|
|
191
|
-
this._inDebugMode = true;
|
|
192
|
-
return this._inDebugMode;
|
|
193
|
-
}
|
|
194
|
-
if (event.origin === 'debugger' && event.name === 'stop') {
|
|
195
|
-
this._inDebugMode = false;
|
|
196
|
-
return this._inDebugMode;
|
|
197
|
-
}
|
|
198
|
-
if (event.name === 'testFrameworkInit') {
|
|
199
|
-
return this.emit('job:start', event.content);
|
|
200
|
-
}
|
|
201
|
-
if (event.name === 'snapshot') {
|
|
202
|
-
const snapshotResults = event.content;
|
|
203
|
-
return snapshotResults.forEach((snapshotResult) => {
|
|
204
|
-
this.#snapshotManager.add(snapshotResult);
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
if (event.name === 'error') {
|
|
208
|
-
return this.log(`[${event.cid}]`, chalk.white(chalk.bgRed(chalk.bold(' Error: '))), event.content ? (event.content.message || event.content.stack || event.content) : '');
|
|
209
|
-
}
|
|
210
|
-
if (event.origin !== 'reporter' && event.origin !== 'debugger') {
|
|
211
|
-
/**
|
|
212
|
-
* filter certain events though
|
|
213
|
-
*/
|
|
214
|
-
if (EVENT_FILTER.includes(event.name)) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
return this.log(event.cid, event.origin, event.name, event.content);
|
|
218
|
-
}
|
|
219
|
-
if (event.name === 'printFailureMessage') {
|
|
220
|
-
return this.onTestError(event.content);
|
|
221
|
-
}
|
|
222
|
-
if (!this._messages[event.origin][event.name]) {
|
|
223
|
-
this._messages[event.origin][event.name] = [];
|
|
224
|
-
}
|
|
225
|
-
this._messages[event.origin][event.name].push(event.content);
|
|
226
|
-
}
|
|
227
|
-
sigintTrigger() {
|
|
228
|
-
/**
|
|
229
|
-
* allow to exit repl mode via Ctrl+C
|
|
230
|
-
*/
|
|
231
|
-
if (this._inDebugMode) {
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
const isRunning = this._jobs.size !== 0 || this._isWatchMode;
|
|
235
|
-
const shutdownMessage = isRunning
|
|
236
|
-
? 'Ending WebDriver sessions gracefully ...\n' +
|
|
237
|
-
'(press ctrl+c again to hard kill the runner)'
|
|
238
|
-
: 'Ended WebDriver sessions gracefully after a SIGINT signal was received!';
|
|
239
|
-
return this.log('\n\n' + shutdownMessage);
|
|
240
|
-
}
|
|
241
|
-
printReporters() {
|
|
242
|
-
/**
|
|
243
|
-
* print reporter output
|
|
244
|
-
*/
|
|
245
|
-
const reporter = this._messages.reporter;
|
|
246
|
-
this._messages.reporter = {};
|
|
247
|
-
for (const [reporterName, messages] of Object.entries(reporter)) {
|
|
248
|
-
this.log('\n', chalk.bold(chalk.magenta(`"${reporterName}" Reporter:`)));
|
|
249
|
-
this.log(messages.join(''));
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
printSummary() {
|
|
253
|
-
const totalJobs = this.totalWorkerCnt - this.result.retries;
|
|
254
|
-
const elapsed = (new Date(Date.now() - this._start.getTime())).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
|
|
255
|
-
const retries = this.result.retries ? chalk.yellow(this.result.retries, 'retries') + ', ' : '';
|
|
256
|
-
const failed = this.result.failed ? chalk.red(this.result.failed, 'failed') + ', ' : '';
|
|
257
|
-
const skipped = this._skippedSpecs > 0 ? chalk.gray(this._skippedSpecs, 'skipped') + ', ' : '';
|
|
258
|
-
const percentCompleted = totalJobs ? Math.round(this.result.finished / totalJobs * 100) : 0;
|
|
259
|
-
const snapshotSummary = this.#snapshotManager.summary;
|
|
260
|
-
const snapshotNotes = [];
|
|
261
|
-
if (snapshotSummary.added > 0) {
|
|
262
|
-
snapshotNotes.push(chalk.green(`${snapshotSummary.added} snapshot(s) added.`));
|
|
263
|
-
}
|
|
264
|
-
if (snapshotSummary.updated > 0) {
|
|
265
|
-
snapshotNotes.push(chalk.yellow(`${snapshotSummary.updated} snapshot(s) updated.`));
|
|
266
|
-
}
|
|
267
|
-
if (snapshotSummary.unmatched > 0) {
|
|
268
|
-
snapshotNotes.push(chalk.red(`${snapshotSummary.unmatched} snapshot(s) unmatched.`));
|
|
269
|
-
}
|
|
270
|
-
if (snapshotSummary.unchecked > 0) {
|
|
271
|
-
snapshotNotes.push(chalk.gray(`${snapshotSummary.unchecked} snapshot(s) unchecked.`));
|
|
272
|
-
}
|
|
273
|
-
if (snapshotNotes.length > 0) {
|
|
274
|
-
this.log('\nSnapshot Summary:');
|
|
275
|
-
snapshotNotes.forEach((note) => this.log(note));
|
|
276
|
-
}
|
|
277
|
-
return this.log('\nSpec Files:\t', chalk.green(this.result.passed, 'passed') + ', ' + retries + failed + skipped + totalJobs, 'total', `(${percentCompleted}% completed)`, 'in', elapsed, this.#hasShard()
|
|
278
|
-
? `\nShard:\t\t ${this._config.shard.current} / ${this._config.shard.total}`
|
|
279
|
-
: '', '\n');
|
|
280
|
-
}
|
|
281
|
-
finalise() {
|
|
282
|
-
this.printReporters();
|
|
283
|
-
this.printSummary();
|
|
284
|
-
}
|
|
285
|
-
}
|