monocart-reporter 1.7.13 → 2.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.
Files changed (42) hide show
  1. package/README.md +10 -26
  2. package/lib/generate-data.js +7 -19
  3. package/lib/generate-report.js +13 -6
  4. package/lib/index.d.ts +82 -53
  5. package/lib/index.js +1 -4
  6. package/lib/index.mjs +0 -1
  7. package/lib/packages/monocart-common.js +1 -0
  8. package/lib/packages/monocart-network.js +1 -0
  9. package/lib/packages/monocart-reporter.js +1 -0
  10. package/lib/packages/monocart-vendor.js +22 -0
  11. package/lib/platform/share.js +0 -5
  12. package/lib/plugins/audit/audit.js +2 -2
  13. package/lib/plugins/coverage/coverage.js +77 -256
  14. package/lib/plugins/network/network.js +17 -13
  15. package/lib/plugins/state/client.js +1 -1
  16. package/lib/plugins/state/state.js +1 -1
  17. package/lib/utils/parse-source.js +1 -1
  18. package/lib/utils/util.js +25 -38
  19. package/lib/visitor.js +6 -26
  20. package/package.json +10 -8
  21. package/lib/plugins/coverage/converter/collect-source-maps.js +0 -194
  22. package/lib/plugins/coverage/converter/converter.js +0 -565
  23. package/lib/plugins/coverage/converter/dedupe.js +0 -110
  24. package/lib/plugins/coverage/converter/find-original-range.js +0 -581
  25. package/lib/plugins/coverage/converter/info-branch.js +0 -30
  26. package/lib/plugins/coverage/converter/info-function.js +0 -29
  27. package/lib/plugins/coverage/converter/info-line.js +0 -20
  28. package/lib/plugins/coverage/converter/position-mapping.js +0 -183
  29. package/lib/plugins/coverage/converter/source-path.js +0 -140
  30. package/lib/plugins/coverage/istanbul/istanbul-summary.js +0 -49
  31. package/lib/plugins/coverage/istanbul/istanbul.js +0 -171
  32. package/lib/plugins/coverage/v8/v8-summary.js +0 -80
  33. package/lib/plugins/coverage/v8/v8.js +0 -260
  34. package/lib/runtime/monocart-code-viewer.js +0 -1
  35. package/lib/runtime/monocart-common.js +0 -1
  36. package/lib/runtime/monocart-coverage.js +0 -14
  37. package/lib/runtime/monocart-formatter.js +0 -1
  38. package/lib/runtime/monocart-network.js +0 -1
  39. package/lib/runtime/monocart-reporter.js +0 -1
  40. package/lib/runtime/monocart-v8.js +0 -1
  41. package/lib/runtime/monocart-vendor.js +0 -22
  42. package/lib/utils/decode-mappings.js +0 -49
@@ -19,11 +19,6 @@ const Util = {
19
19
  name: 'network',
20
20
  contentType: 'text/html',
21
21
  reportFile: 'network-report.json'
22
- },
23
- // artifact will be removed finally
24
- artifact: {
25
- name: 'artifact',
26
- contentType: 'application/json'
27
22
  }
28
23
  },
29
24
 
@@ -73,7 +73,7 @@ const attachAuditReport = async (runnerResult, testInfo, options = {}) => {
73
73
  }
74
74
 
75
75
  options = {
76
- title: `Lighthouse Report - ${testInfo.title}`,
76
+ name: `Lighthouse Report - ${testInfo.title}`,
77
77
  outputDir: Util.resolveOutputDir(testInfo, options),
78
78
  outputName: `audit-${Util.resolveTestIdWithRetry(testInfo)}`,
79
79
  ... options
@@ -89,7 +89,7 @@ const attachAuditReport = async (runnerResult, testInfo, options = {}) => {
89
89
 
90
90
  // `.lhr` is the Lighthouse Result as a JS object
91
91
  const report = {
92
- title: options.title,
92
+ name: options.name,
93
93
  ... getSummaryReport(runnerResult.lhr)
94
94
  };
95
95
 
@@ -1,302 +1,123 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
-
3
+ const CoverageReport = require('monocart-coverage-reports');
4
4
  const Util = require('../../utils/util.js');
5
- const {
6
- initIstanbulData, mergeIstanbulCoverage, saveIstanbulReport
7
- } = require('./istanbul/istanbul.js');
8
- const {
9
- initV8ListAndSourcemap, mergeV8Coverage, saveV8Report
10
- } = require('./v8/v8.js');
11
-
12
- const { convertV8List } = require('./converter/converter.js');
13
-
14
- const artifactsDirName = '.artifacts';
15
-
16
- const defaultOptions = {
17
-
18
- // Defaults to test title
19
- // title
20
- // outputDir
21
- // outputName
22
-
23
- // (Boolean) Whether to convert to Istanbul report from V8 list. Defaults to `html-spa` report | (String) report name | (Array) multiple reports
24
- toIstanbul: false,
25
-
26
- // (Function) A filter function to execute for each element in the V8 list.
27
- entryFilter: null,
28
-
29
- // (Function) A filter function to execute for each element in the sources which unpacked from the source map.
30
- sourceFilter: null,
31
-
32
- // Istanbul Only
33
-
34
- // source path handler
35
- sourcePath: null,
36
-
37
- // (usually not used) source finder for Istanbul HTML report
38
- sourceFinder: null,
39
5
 
40
- // (Boolean) Whether to create `lcov.info`
41
- lcov: false,
6
+ const attachCoverageReport = async (data, testInfo, options = {}) => {
42
7
 
43
- // (Object) Istanbul watermarks, see [here](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-lib-report)
44
- // watermarks: {},
45
- // (Array) V8 watermarks, Defaults to `[50, 80]`
46
- // watermarks: [50, 80],
8
+ const reporterOptions = Util.resolveReporterOptions(testInfo);
47
9
 
48
- // (Boolean) Whether inline all scripts to the single HTML file. V8 only.
49
- inline: false
50
-
51
- };
52
-
53
- // ========================================================================================================
54
-
55
- const generateV8ListReport = async (v8list, coverageData, fileSources, options) => {
56
- const { toIstanbul, lcov } = options;
57
- const istanbulReport = toIstanbul || lcov;
58
- const v8Report = !toIstanbul;
59
-
60
- let report;
61
- if (istanbulReport) {
62
- report = await saveIstanbulReport(coverageData, fileSources, options);
63
- }
64
- if (v8Report) {
65
- report = await saveV8Report(v8list, options);
66
- }
67
-
68
- return report;
69
- };
70
-
71
- // ========================================================================================================
72
-
73
- const saveReportAttachment = (testInfo, report, htmlDir) => {
74
-
75
- const definition = Util.attachments.coverage;
76
- // save report
77
- const reportPath = path.resolve(htmlDir, definition.reportFile);
78
- Util.writeJSONSync(reportPath, report);
79
-
80
- testInfo.attachments.push({
81
- name: definition.name,
82
- contentType: definition.contentType,
83
- path: path.resolve(htmlDir, 'index.html')
84
- });
85
- };
86
-
87
- // ========================================================================================================
88
-
89
- const generateIstanbulReport = (istanbulData, testInfo, options) => {
90
-
91
- const { coverageData, fileSources } = initIstanbulData(istanbulData, options);
92
- const report = saveIstanbulReport(coverageData, fileSources, options);
93
-
94
- saveReportAttachment(testInfo, report, options.htmlDir);
95
-
96
- return report;
97
- };
98
-
99
-
100
- // ========================================================================================================
101
-
102
- const generateV8Coverage = async (v8list, testInfo, options) => {
103
-
104
- // init v8list and unpack sourcemap
105
- const inlineSourceMap = true;
106
- v8list = await initV8ListAndSourcemap(v8list, options, inlineSourceMap);
107
-
108
- const { coverageData, fileSources } = await convertV8List(v8list, options);
109
-
110
- const report = await generateV8ListReport(v8list, coverageData, fileSources, options);
111
-
112
- saveReportAttachment(testInfo, report, options.htmlDir);
113
-
114
- return report;
115
- };
116
-
117
- const attachCoverageReport = (data, testInfo, options = {}) => {
118
-
119
- const logging = Util.resolveLogging(testInfo, options);
120
- Util.initLoggingLevel(logging, 'coverage-attach');
121
-
122
- if (!data) {
123
- Util.logError(`invalid coverage data: ${testInfo.title}`);
124
- return;
125
- }
126
-
127
- options = {
128
- ... defaultOptions,
129
- // default title
130
- title: `Coverage Report - ${testInfo.title}`,
131
- outputDir: Util.resolveOutputDir(testInfo, options),
132
- outputName: `coverage-${Util.resolveTestIdWithRetry(testInfo)}`,
133
- ... options
134
- };
10
+ const outputDir = Util.resolveOutputDir(testInfo, options);
11
+ const folderName = `coverage-${Util.resolveTestIdWithRetry(testInfo)}`;
135
12
 
136
13
  // support multiple calls
137
- let htmlDir = path.resolve(options.outputDir, options.outputName);
138
- let i = 1;
14
+ let outputName = folderName;
15
+ let htmlDir = path.resolve(outputDir, outputName);
16
+ let i = 0;
139
17
  while (fs.existsSync(htmlDir)) {
140
- const outputName = `${options.outputName}-${i}`;
141
- htmlDir = path.resolve(options.outputDir, outputName);
142
18
  i += 1;
19
+ outputName = `${folderName}-${i}`;
20
+ htmlDir = path.resolve(outputDir, outputName);
143
21
  }
144
22
 
145
- Util.initDir(htmlDir);
146
- options.htmlDir = htmlDir;
147
-
148
- const dataType = Array.isArray(data) ? 'v8' : 'istanbul';
149
- // console.log('data type', dataType);
23
+ const coverageOptions = {
24
+ logging: reporterOptions.logging,
25
+ outputDir: htmlDir,
26
+ name: `Coverage Report - ${testInfo.title}`,
27
+ assetsPath: '../assets',
28
+ ... options
29
+ };
150
30
 
151
- if (dataType === 'v8') {
152
- return generateV8Coverage(data, testInfo, options);
31
+ const coverageReport = new CoverageReport(coverageOptions);
32
+ await coverageReport.add(data);
33
+ const coverageResults = await coverageReport.generate();
34
+
35
+ const reportPath = coverageResults.reportPath;
36
+ if (reportPath && fs.existsSync(reportPath)) {
37
+ // save report json
38
+ const definition = Util.attachments.coverage;
39
+ const reportJsonPath = path.resolve(htmlDir, definition.reportFile);
40
+ Util.writeJSONSync(reportJsonPath, coverageResults);
41
+
42
+ // save attachments html link
43
+ testInfo.attachments.push({
44
+ name: definition.name,
45
+ contentType: definition.contentType,
46
+ path: reportPath
47
+ });
153
48
  }
154
49
 
155
- return generateIstanbulReport(data, testInfo, options);
50
+ return coverageResults;
156
51
  };
157
52
 
158
53
  // ========================================================================================================
159
54
 
160
- // add coverage report to global, v8list only
161
- const addCoverageReport = async (data, testInfo, options = {}) => {
162
-
163
- const logging = Util.resolveLogging(testInfo, options);
164
- Util.initLoggingLevel(logging, 'coverage-add');
165
-
166
- if (!data) {
167
- Util.logError(`invalid coverage data: ${testInfo.title}`);
168
- return;
169
- }
170
-
171
- // global outputDir
172
- const outputDir = await Util.resolveGlobalOutputDir(testInfo, options);
173
-
174
- const coverageOptions = Util.resolveCoverageOptions(testInfo, options);
175
-
176
- options = {
177
- ... defaultOptions,
178
- // use reporter dir as output dir, NOT test output dir
179
- outputDir,
180
- outputName: 'coverage',
181
- ... coverageOptions
182
- };
183
-
184
- const reportDir = path.resolve(options.outputDir, options.outputName);
185
- // do NOT empty dir, there are previous artifacts generated
186
-
187
- // artifactsDir for temp artifact files
188
- const artifactsDir = path.resolve(reportDir, artifactsDirName);
189
- options.artifactsDir = artifactsDir;
55
+ const getGlobalCoverageOptions = async (reporterOptions) => {
190
56
 
191
- const filename = `coverage-${Util.resolveTestIdWithRetry(testInfo)}.json`;
192
- const jsonPath = path.resolve(artifactsDir, filename);
57
+ const reporterOutputFile = await Util.resolveOutputFile(reporterOptions.outputFile);
58
+ const outputDir = path.dirname(reporterOutputFile);
59
+ const htmlDir = path.resolve(outputDir, 'coverage');
193
60
 
194
- const report = {
195
- title: testInfo.title
61
+ const coverageOptions = {
62
+ logging: reporterOptions.logging,
63
+ outputDir: htmlDir,
64
+ name: `Coverage Report - ${reporterOptions.name}`,
65
+ assetsPath: '../assets',
66
+ // merge all global coverage options
67
+ ... reporterOptions.coverage
196
68
  };
197
69
 
198
- if (Array.isArray(data)) {
199
- // init v8list and unpack sourcemap
200
- const inlineSourceMap = false;
201
- report.data = await initV8ListAndSourcemap(data, options, inlineSourceMap);
202
- } else {
203
- // istanbul
204
- report.data = data;
205
- }
206
-
207
- const artifactContent = JSON.stringify({
208
- type: 'coverage',
209
- data: report
210
- });
211
-
212
- await Util.writeFile(jsonPath, artifactContent);
213
-
214
- const definition = Util.attachments.artifact;
215
- testInfo.attachments.push({
216
- name: definition.name,
217
- contentType: definition.contentType,
218
- path: jsonPath
219
- });
220
-
221
- return report;
70
+ return coverageOptions;
222
71
  };
223
72
 
224
- // ========================================================================================================
225
-
226
- const getGlobalCoverageData = async (dataList, options) => {
227
-
228
- // get first and check v8list or istanbul data
229
- const firstData = dataList[0].data;
230
- const dataType = Array.isArray(firstData) ? 'v8' : 'istanbul';
231
- // console.log('data type', dataType);
232
-
233
- // v8list
234
- if (dataType === 'v8') {
235
- // merge v8list first
236
- const v8list = await mergeV8Coverage(dataList, options);
237
- // console.log('after merge', v8list.map((it) => it.url));
73
+ // add coverage report to global, v8list only
74
+ const addCoverageReport = async (data, testInfo) => {
238
75
 
239
- const { coverageData, fileSources } = await convertV8List(v8list, options);
240
- return generateV8ListReport(v8list, coverageData, fileSources, options);
76
+ const reporterOptions = Util.resolveReporterOptions(testInfo);
77
+ const coverageOptions = await getGlobalCoverageOptions(reporterOptions);
241
78
 
242
- }
243
-
244
- // istanbul data
245
- const istanbulData = mergeIstanbulCoverage(dataList, options);
246
- const { coverageData, fileSources } = initIstanbulData(istanbulData, options);
247
- return saveIstanbulReport(coverageData, fileSources, options);
79
+ const coverageReport = new CoverageReport(coverageOptions);
80
+ const results = await coverageReport.add(data);
248
81
 
82
+ return results;
249
83
  };
250
84
 
251
- // global coverage report, run different process with addCoverageReport
252
- const addGlobalCoverageReport = async (dataList, coverageOptions) => {
85
+ const generateGlobalCoverageReport = async (reporterOptions) => {
253
86
 
254
- Util.logInfo('generating global coverage report ...');
87
+ const coverageOptions = await getGlobalCoverageOptions(reporterOptions);
255
88
 
256
- const options = {
257
- ... defaultOptions,
258
- ... coverageOptions
259
- };
89
+ const coverageReport = new CoverageReport(coverageOptions);
260
90
 
261
- const reportDir = path.resolve(options.outputDir, options.outputName);
91
+ // check if has cache
92
+ if (!coverageReport.hasCache()) {
93
+ return;
94
+ }
262
95
 
263
- // empty dir except artifacts dir
264
- if (fs.existsSync(reportDir)) {
265
- fs.readdirSync(reportDir).forEach((itemName) => {
266
- if (itemName === artifactsDirName) {
267
- return;
268
- }
269
- Util.rmSync(path.resolve(reportDir, itemName));
270
- });
96
+ const coverageResults = await coverageReport.generate();
97
+ if (!coverageResults) {
98
+ return;
271
99
  }
272
100
 
273
- options.htmlDir = reportDir;
101
+ // coverageResults: type, reportPath, name, watermarks, summary, files
274
102
 
275
- // artifactsDir for temp artifact files
276
- const artifactsDir = path.resolve(reportDir, artifactsDirName);
277
- options.artifactsDir = artifactsDir;
103
+ // showing list props: global, name, path, title
278
104
 
279
- const report = await getGlobalCoverageData(dataList, options);
280
- // console.log(report);
105
+ // console.log('global coverage report', report);
281
106
 
282
- // =============================================================
283
- // remove artifacts dir after report generated
284
- if (Util.loggingType !== 'debug') {
285
- Util.rmSync(artifactsDir);
107
+ const reportPath = coverageResults.reportPath;
108
+ if (reportPath && fs.existsSync(reportPath)) {
109
+ return {
110
+ global: true,
111
+ type: 'coverage',
112
+ name: coverageResults.name,
113
+ path: reportPath
114
+ };
286
115
  }
287
- // =============================================================
288
116
 
289
- return {
290
- global: true,
291
- name: 'coverage',
292
- path: report.htmlPath,
293
- summary: report.summary,
294
- title: options.title
295
- };
296
117
  };
297
118
 
298
119
  module.exports = {
299
120
  addCoverageReport,
300
- addGlobalCoverageReport,
301
- attachCoverageReport
121
+ attachCoverageReport,
122
+ generateGlobalCoverageReport
302
123
  };
@@ -96,21 +96,25 @@ const getNetworkSummary = (log) => {
96
96
 
97
97
  const saveNetworkHtmlReport = async (reportData, _options) => {
98
98
 
99
- const {
100
- htmlDir, outputDir, inline
101
- } = _options;
99
+ const { htmlDir, inline } = _options;
100
+
101
+ // deps
102
+ const jsFiles = ['monocart-code-viewer', 'monocart-formatter', 'turbogrid'].map((it) => {
103
+ return path.resolve(`node_modules/${it}/dist/${it}.js`);
104
+ });
105
+
106
+ jsFiles.push(path.resolve(__dirname, '../../packages/monocart-common.js'));
107
+ jsFiles.push(path.resolve(__dirname, '../../packages/monocart-network.js'));
102
108
 
103
109
  const options = {
104
110
  inline,
105
111
  reportData,
106
- jsFiles: ['monocart-code-viewer.js', 'monocart-formatter.js', 'monocart-common.js', 'monocart-network.js'],
107
- htmlDir,
112
+ jsFiles,
113
+ assetsPath: '../assets',
114
+ outputDir: htmlDir,
108
115
  htmlFile: 'index.html',
109
116
 
110
- outputDir,
111
- reportDataFile: 'network-data.js',
112
- assetsName: 'assets',
113
- assetsRelative: '../'
117
+ reportDataFile: 'network-data.js'
114
118
  };
115
119
 
116
120
  const htmlPath = await Util.saveHtmlReport(options);
@@ -131,7 +135,7 @@ const attachNetworkReport = async (har, testInfo, options = {}) => {
131
135
 
132
136
  options = {
133
137
  // default title
134
- title: `Network Report - ${testInfo.title}`,
138
+ name: `Network Report - ${testInfo.title}`,
135
139
  outputDir: Util.resolveOutputDir(testInfo, options),
136
140
  outputName: `network-${Util.resolveTestIdWithRetry(testInfo)}`,
137
141
  inline: false,
@@ -150,7 +154,7 @@ const attachNetworkReport = async (har, testInfo, options = {}) => {
150
154
 
151
155
  // save har
152
156
  const reportData = {
153
- title: options.title,
157
+ name: options.name,
154
158
  summary,
155
159
  ... harData
156
160
  };
@@ -158,14 +162,14 @@ const attachNetworkReport = async (har, testInfo, options = {}) => {
158
162
  const htmlPath = await saveNetworkHtmlReport(reportData, options);
159
163
 
160
164
  const report = {
161
- title: options.title,
165
+ name: options.name,
162
166
  ... harData.log,
163
167
  htmlPath,
164
168
  summary
165
169
  };
166
170
  delete report.entries;
167
171
 
168
- // save report
172
+ // save report json
169
173
  const definition = Util.attachments.network;
170
174
  const reportPath = path.resolve(htmlDir, definition.reportFile);
171
175
  Util.writeJSONSync(reportPath, report);
@@ -1,4 +1,4 @@
1
- const { WebSocket } = require('../../runtime/monocart-vendor.js');
1
+ const { WebSocket } = require('../../packages/monocart-vendor.js');
2
2
  const Util = require('../../utils/util.js');
3
3
 
4
4
  const getServerUrl = (options = {}) => {
@@ -1,5 +1,5 @@
1
1
  const EC = require('eight-colors');
2
- const { WebSocketServer } = require('../../runtime/monocart-vendor.js');
2
+ const { WebSocketServer } = require('../../packages/monocart-vendor.js');
3
3
  const Util = require('../../utils/util.js');
4
4
  const { getServerUrl, Client } = require('./client.js');
5
5
 
@@ -1,5 +1,5 @@
1
1
  const Util = require('./util.js');
2
- const { parse } = require('../runtime/monocart-vendor.js');
2
+ const { parse } = require('../packages/monocart-vendor.js');
3
3
 
4
4
  const parseSource = (data) => {
5
5
  const {
package/lib/utils/util.js CHANGED
@@ -8,6 +8,8 @@ const CG = require('console-grid');
8
8
  const Share = require('../platform/share.js');
9
9
  const { deflateSync } = require('lz-utils');
10
10
 
11
+ const defaultOptions = require('../default/options.js');
12
+
11
13
  const assetsName = 'assets';
12
14
 
13
15
  const Util = {
@@ -79,24 +81,16 @@ const Util = {
79
81
  return path.resolve(testInfo.outputDir, '../');
80
82
  },
81
83
 
82
- resolveGlobalOutputDir: async (testInfo, options) => {
83
- if (options && options.outputDir) {
84
- return options.outputDir;
85
- }
86
- const reporterOptions = Util.resolveReporterOptions(testInfo);
87
- const outputFile = await Util.resolveOutputFile(reporterOptions.outputFile);
88
- const outputDir = path.dirname(outputFile);
89
- return outputDir;
90
- },
91
-
92
84
  resolveOutputFile: async (outputFile) => {
85
+ // function to string first
93
86
  if (typeof outputFile === 'function') {
94
87
  outputFile = await outputFile();
95
88
  }
96
- if (typeof outputFile === 'string' && outputFile) {
97
- return outputFile;
89
+ // then check string
90
+ if (!outputFile || typeof outputFile !== 'string') {
91
+ outputFile = defaultOptions.outputFile;
98
92
  }
99
- return './test-results/report.html';
93
+ return path.resolve(outputFile);
100
94
  },
101
95
 
102
96
  resolveLogging: (testInfo, options) => {
@@ -107,14 +101,6 @@ const Util = {
107
101
  return reporterOptions.logging;
108
102
  },
109
103
 
110
- resolveCoverageOptions: (testInfo, options) => {
111
- const reporterOptions = Util.resolveReporterOptions(testInfo);
112
- return {
113
- ... reporterOptions.coverage,
114
- ... options
115
- };
116
- },
117
-
118
104
  resolveReporterOptions: (testInfo) => {
119
105
  if (!testInfo) {
120
106
  return {};
@@ -171,12 +157,11 @@ const Util = {
171
157
  inline,
172
158
  reportData,
173
159
  jsFiles,
174
- htmlDir,
160
+ assetsPath,
161
+ outputDir,
175
162
  htmlFile,
176
163
 
177
- outputDir,
178
- reportDataFile,
179
- assetsRelative
164
+ reportDataFile
180
165
  } = options;
181
166
 
182
167
  // report data
@@ -186,10 +171,9 @@ const Util = {
186
171
  // js libs
187
172
  const jsList = [];
188
173
  for (const jsFile of jsFiles) {
189
- const jsPath = path.resolve(__dirname, `../runtime/${jsFile}`);
190
- const jsStr = await Util.readFile(jsPath);
174
+ const jsStr = await Util.readFile(jsFile);
191
175
  jsList.push({
192
- file: jsFile,
176
+ filename: path.basename(jsFile),
193
177
  str: jsStr
194
178
  });
195
179
  }
@@ -206,10 +190,13 @@ const Util = {
206
190
  ].join(EOL);
207
191
  } else {
208
192
 
209
- await Util.writeFile(path.resolve(htmlDir, reportDataFile), reportDataStr);
193
+ await Util.writeFile(path.resolve(outputDir, reportDataFile), reportDataStr);
194
+
195
+ const assetsDir = path.resolve(outputDir, assetsPath);
196
+ const relAssetsDir = Util.relativePath(assetsDir, outputDir);
210
197
 
211
198
  for (const item of jsList) {
212
- const filePath = path.resolve(outputDir, assetsName, item.file);
199
+ const filePath = path.resolve(assetsDir, item.filename);
213
200
  if (!fs.existsSync(filePath)) {
214
201
  await Util.writeFile(filePath, item.str);
215
202
  }
@@ -217,12 +204,12 @@ const Util = {
217
204
 
218
205
  htmlStr = [
219
206
  `<script src="${reportDataFile}"></script>`,
220
- ... jsList.map((it) => `<script src="${assetsRelative}${assetsName}/${it.file}"></script>`)
207
+ ... jsList.map((it) => `<script src="${relAssetsDir}/${it.filename}"></script>`)
221
208
  ].join(EOL);
222
209
  }
223
210
 
224
211
  // html
225
- const htmlPath = path.resolve(htmlDir, htmlFile);
212
+ const htmlPath = path.resolve(outputDir, htmlFile);
226
213
  const template = Util.getTemplate(path.resolve(__dirname, '../default/template.html'));
227
214
  const html = Util.replace(template, {
228
215
  title: reportData.title,
@@ -319,7 +306,7 @@ const Util = {
319
306
  readFile: async (filePath) => {
320
307
  if (fs.existsSync(filePath)) {
321
308
  const buf = await readFile(filePath).catch((e) => {
322
- console.log(e);
309
+ Util.logError(`read file: ${filePath} ${e.message || e}`);
323
310
  });
324
311
  if (Buffer.isBuffer(buf)) {
325
312
  return buf.toString('utf8');
@@ -350,7 +337,7 @@ const Util = {
350
337
  }
351
338
  }
352
339
  await writeFile(filePath, content).catch((e) => {
353
- console.log(e);
340
+ Util.logError(`write file: ${filePath} ${e.message || e}`);
354
341
  });
355
342
  },
356
343
 
@@ -433,14 +420,14 @@ const Util = {
433
420
  if (Util.loggingLevel < Util.loggingLevels.error) {
434
421
  return;
435
422
  }
436
- EC.logRed(`[MCR] ${message}`);
423
+ EC.logRed(`[MR] ${message}`);
437
424
  },
438
425
 
439
426
  logInfo: (message) => {
440
427
  if (Util.loggingLevel < Util.loggingLevels.info) {
441
428
  return;
442
429
  }
443
- console.log(`[MCR] ${message}`);
430
+ console.log(`[MR] ${message}`);
444
431
  },
445
432
 
446
433
  // grid is info level
@@ -455,7 +442,7 @@ const Util = {
455
442
  if (Util.loggingLevel < Util.loggingLevels.debug) {
456
443
  return;
457
444
  }
458
- console.log(`[MCR] ${message}`);
445
+ console.log(`[MR] ${message}`);
459
446
  },
460
447
 
461
448
  // time is debug level
@@ -465,7 +452,7 @@ const Util = {
465
452
  }
466
453
  const duration = Date.now() - time_start;
467
454
  const durationH = Util.TSF(duration);
468
- const ls = [`[MCR] ${message}`, ' ('];
455
+ const ls = [`[MR] ${message}`, ' ('];
469
456
  if (duration <= 100) {
470
457
  ls.push(EC.green(durationH));
471
458
  } else if (duration < 500) {