@jsenv/core 27.3.2 → 27.4.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 +16 -4
- package/dist/controllable_child_process.mjs +1 -0
- package/dist/controllable_worker_thread.mjs +1 -0
- package/dist/js/event_source_client.js +45 -24
- package/dist/js/execute_using_dynamic_import.js +5 -3
- package/dist/js/html_supervisor_installer.js +368 -139
- package/dist/main.js +668 -471
- package/package.json +5 -6
- package/src/build/build.js +6 -4
- package/src/build/graph_utils.js +14 -11
- package/src/execute/run.js +29 -28
- package/src/execute/runtimes/browsers/from_playwright.js +90 -92
- package/src/execute/runtimes/node/execute_using_dynamic_import.js +8 -2
- package/src/execute/runtimes/node/node_child_process.js +2 -0
- package/src/execute/runtimes/node/node_worker_thread.js +11 -6
- package/src/helpers/event_source/event_source.js +38 -17
- package/src/omega/errors.js +41 -9
- package/src/omega/kitchen.js +35 -19
- package/src/omega/omega_server.js +54 -1
- package/src/omega/server/file_service.js +30 -3
- package/src/omega/url_graph/url_graph_report.js +2 -4
- package/src/omega/url_graph.js +29 -16
- package/src/plugins/autoreload/dev_sse/client/event_source_client.js +8 -8
- package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +160 -172
- package/src/plugins/autoreload/jsenv_plugin_autoreload.js +0 -4
- package/src/plugins/bundling/js_module/bundle_js_module.js +0 -1
- package/src/plugins/html_supervisor/client/error_in_document.js +268 -121
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +47 -5
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +37 -12
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +1 -2
- package/src/plugins/plugins.js +0 -2
- package/src/plugins/url_analysis/js/js_urls.js +0 -9
- package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +3 -1
- package/src/test/coverage/report_to_coverage.js +16 -11
- package/src/test/execute_plan.js +3 -2
- package/src/test/execute_test_plan.js +3 -1
- package/src/test/logs_file_execution.js +60 -27
- package/src/test/logs_file_execution.test.mjs +41 -0
|
@@ -50,7 +50,7 @@ export const reportToCoverage = async (
|
|
|
50
50
|
coverageMethodForNodeJs !== "NODE_V8_COVERAGE"
|
|
51
51
|
) {
|
|
52
52
|
logger.warn(
|
|
53
|
-
`
|
|
53
|
+
`"${executionName}" execution of ${file} did not properly write coverage into ${executionResult.coverageFileUrl}`,
|
|
54
54
|
)
|
|
55
55
|
}
|
|
56
56
|
},
|
|
@@ -152,18 +152,23 @@ const getCoverageFromReport = async ({ signal, report, onMissing }) => {
|
|
|
152
152
|
const executionResultForFileOnRuntime =
|
|
153
153
|
executionResultForFile[executionName]
|
|
154
154
|
const { coverageFileUrl } = executionResultForFileOnRuntime
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
155
|
+
let executionCoverage
|
|
156
|
+
try {
|
|
157
|
+
executionCoverage = JSON.parse(
|
|
158
|
+
String(readFileSync(new URL(coverageFileUrl))),
|
|
159
|
+
)
|
|
160
|
+
} catch (e) {
|
|
161
|
+
if (e.code === "ENOENT" || e.name === "SyntaxError") {
|
|
162
|
+
onMissing({
|
|
163
|
+
executionName,
|
|
164
|
+
file,
|
|
165
|
+
executionResult: executionResultForFileOnRuntime,
|
|
166
|
+
})
|
|
167
|
+
return
|
|
168
|
+
}
|
|
169
|
+
throw e
|
|
162
170
|
}
|
|
163
171
|
|
|
164
|
-
const executionCoverage = JSON.parse(
|
|
165
|
-
String(readFileSync(new URL(coverageFileUrl))),
|
|
166
|
-
)
|
|
167
172
|
if (isV8Coverage(executionCoverage)) {
|
|
168
173
|
v8Coverage = v8Coverage
|
|
169
174
|
? composeTwoV8Coverages(v8Coverage, executionCoverage)
|
package/src/test/execute_plan.js
CHANGED
|
@@ -143,7 +143,7 @@ export const executePlan = async (
|
|
|
143
143
|
createDetailedMessage(
|
|
144
144
|
`process.env.NODE_V8_COVERAGE is required to generate coverage for Node.js subprocesses`,
|
|
145
145
|
{
|
|
146
|
-
"suggestion": `
|
|
146
|
+
"suggestion": `set process.env.NODE_V8_COVERAGE`,
|
|
147
147
|
"suggestion 2": `use coverageMethodForNodeJs: "Profiler". But it means coverage for child_process and worker_thread cannot be collected`,
|
|
148
148
|
},
|
|
149
149
|
),
|
|
@@ -224,7 +224,8 @@ export const executePlan = async (
|
|
|
224
224
|
getCustomBabelPlugins: ({ clientRuntimeCompat }) => {
|
|
225
225
|
if (
|
|
226
226
|
coverageEnabled &&
|
|
227
|
-
|
|
227
|
+
(coverageMethodForBrowsers !== "playwright_api" ||
|
|
228
|
+
Object.keys(clientRuntimeCompat)[0] !== "chrome")
|
|
228
229
|
) {
|
|
229
230
|
return {
|
|
230
231
|
"transform-instrument": [
|
|
@@ -67,7 +67,9 @@ export const executeTestPlan = async ({
|
|
|
67
67
|
},
|
|
68
68
|
coverageIncludeMissing = true,
|
|
69
69
|
coverageAndExecutionAllowed = false,
|
|
70
|
-
coverageMethodForNodeJs =
|
|
70
|
+
coverageMethodForNodeJs = process.env.NODE_V8_COVERAGE
|
|
71
|
+
? "NODE_V8_COVERAGE"
|
|
72
|
+
: "Profiler",
|
|
71
73
|
coverageMethodForBrowsers = "playwright_api", // "istanbul" also accepted
|
|
72
74
|
coverageV8ConflictWarning = true,
|
|
73
75
|
coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
|
|
@@ -217,7 +217,6 @@ const formatConsoleCalls = (consoleCalls) => {
|
|
|
217
217
|
if (consoleCalls.length === 0) {
|
|
218
218
|
return ""
|
|
219
219
|
}
|
|
220
|
-
|
|
221
220
|
const repartition = {
|
|
222
221
|
debug: 0,
|
|
223
222
|
info: 0,
|
|
@@ -225,17 +224,10 @@ const formatConsoleCalls = (consoleCalls) => {
|
|
|
225
224
|
error: 0,
|
|
226
225
|
log: 0,
|
|
227
226
|
}
|
|
228
|
-
let consoleOutput = ``
|
|
229
227
|
consoleCalls.forEach((consoleCall) => {
|
|
230
228
|
repartition[consoleCall.type]++
|
|
231
|
-
const text = consoleCall.text
|
|
232
|
-
const textFormatted = prefixFirstAndIndentRemainingLines({
|
|
233
|
-
prefix: CONSOLE_ICONS[consoleCall.type],
|
|
234
|
-
text,
|
|
235
|
-
trimLastLine: consoleCall === consoleCalls[consoleCalls.length - 1],
|
|
236
|
-
})
|
|
237
|
-
consoleOutput += textFormatted
|
|
238
229
|
})
|
|
230
|
+
const consoleOutput = formatConsoleOutput(consoleCalls)
|
|
239
231
|
|
|
240
232
|
return `${ANSI.color(
|
|
241
233
|
`-------- ${formatConsoleSummary(repartition)} --------`,
|
|
@@ -245,6 +237,65 @@ ${consoleOutput}
|
|
|
245
237
|
${ANSI.color(`-------------------------`, ANSI.GREY)}`
|
|
246
238
|
}
|
|
247
239
|
|
|
240
|
+
export const formatConsoleOutput = (consoleCalls) => {
|
|
241
|
+
// inside Node.js you can do process.stdout.write()
|
|
242
|
+
// and in that case the consoleCall is not suffixed with "\n"
|
|
243
|
+
// we want to keep these calls together in the output
|
|
244
|
+
const regroupedCalls = []
|
|
245
|
+
consoleCalls.forEach((consoleCall, index) => {
|
|
246
|
+
if (index === 0) {
|
|
247
|
+
regroupedCalls.push(consoleCall)
|
|
248
|
+
return
|
|
249
|
+
}
|
|
250
|
+
const previousCall = consoleCalls[index - 1]
|
|
251
|
+
if (previousCall.type !== consoleCall.type) {
|
|
252
|
+
regroupedCalls.push(consoleCall)
|
|
253
|
+
return
|
|
254
|
+
}
|
|
255
|
+
if (previousCall.text.endsWith("\n")) {
|
|
256
|
+
regroupedCalls.push(consoleCall)
|
|
257
|
+
return
|
|
258
|
+
}
|
|
259
|
+
if (previousCall.text.endsWith("\r")) {
|
|
260
|
+
regroupedCalls.push(consoleCall)
|
|
261
|
+
return
|
|
262
|
+
}
|
|
263
|
+
const previousRegroupedCallIndex = regroupedCalls.length - 1
|
|
264
|
+
const previousRegroupedCall = regroupedCalls[previousRegroupedCallIndex]
|
|
265
|
+
previousRegroupedCall.text = `${previousRegroupedCall.text}${consoleCall.text}`
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
let consoleOutput = ``
|
|
269
|
+
regroupedCalls.forEach((regroupedCall, index) => {
|
|
270
|
+
const text = regroupedCall.text
|
|
271
|
+
const textFormatted = prefixFirstAndIndentRemainingLines({
|
|
272
|
+
prefix: CONSOLE_ICONS[regroupedCall.type],
|
|
273
|
+
text,
|
|
274
|
+
trimLastLine: index === regroupedCalls.length - 1,
|
|
275
|
+
})
|
|
276
|
+
consoleOutput += textFormatted
|
|
277
|
+
})
|
|
278
|
+
return consoleOutput
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const prefixFirstAndIndentRemainingLines = ({ prefix, text, trimLastLine }) => {
|
|
282
|
+
const lines = text.split(/\r?\n/)
|
|
283
|
+
const firstLine = lines.shift()
|
|
284
|
+
let result = `${prefix} ${firstLine}`
|
|
285
|
+
let i = 0
|
|
286
|
+
const indentation = ` `
|
|
287
|
+
while (i < lines.length) {
|
|
288
|
+
const line = lines[i].trim()
|
|
289
|
+
i++
|
|
290
|
+
result += line.length
|
|
291
|
+
? `\n${indentation}${line}`
|
|
292
|
+
: trimLastLine && i === lines.length
|
|
293
|
+
? ""
|
|
294
|
+
: `\n`
|
|
295
|
+
}
|
|
296
|
+
return result
|
|
297
|
+
}
|
|
298
|
+
|
|
248
299
|
const CONSOLE_ICONS = {
|
|
249
300
|
debug: UNICODE.DEBUG,
|
|
250
301
|
info: UNICODE.INFO,
|
|
@@ -274,24 +325,6 @@ const formatConsoleSummary = (repartition) => {
|
|
|
274
325
|
return `console (${parts.join(" ")})`
|
|
275
326
|
}
|
|
276
327
|
|
|
277
|
-
const prefixFirstAndIndentRemainingLines = ({ prefix, text, trimLastLine }) => {
|
|
278
|
-
const lines = text.split(/\r?\n/)
|
|
279
|
-
const firstLine = lines.shift()
|
|
280
|
-
let result = `${prefix} ${firstLine}`
|
|
281
|
-
let i = 0
|
|
282
|
-
const indentation = ` `
|
|
283
|
-
while (i < lines.length) {
|
|
284
|
-
const line = lines[i].trim()
|
|
285
|
-
i++
|
|
286
|
-
result += line.length
|
|
287
|
-
? `\n${indentation}${line}`
|
|
288
|
-
: trimLastLine && i === lines.length
|
|
289
|
-
? ""
|
|
290
|
-
: `\n`
|
|
291
|
-
}
|
|
292
|
-
return result
|
|
293
|
-
}
|
|
294
|
-
|
|
295
328
|
const formatExecution = ({ label, details = {}, consoleOutput }) => {
|
|
296
329
|
let message = ``
|
|
297
330
|
message += label
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { assert } from "@jsenv/assert"
|
|
2
|
+
|
|
3
|
+
import { formatConsoleOutput } from "./logs_file_execution.js"
|
|
4
|
+
|
|
5
|
+
{
|
|
6
|
+
const actual = formatConsoleOutput([
|
|
7
|
+
{ type: "log", text: "a\n" },
|
|
8
|
+
{ type: "log", text: "b\n" },
|
|
9
|
+
])
|
|
10
|
+
const expected = ` a
|
|
11
|
+
b`
|
|
12
|
+
assert({ actual, expected })
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
{
|
|
16
|
+
const actual = formatConsoleOutput([
|
|
17
|
+
{ type: "log", text: "a" },
|
|
18
|
+
{ type: "log", text: "b" },
|
|
19
|
+
])
|
|
20
|
+
const expected = ` ab`
|
|
21
|
+
assert({ actual, expected })
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
{
|
|
25
|
+
const actual = formatConsoleOutput([
|
|
26
|
+
{
|
|
27
|
+
type: "log",
|
|
28
|
+
text: `1
|
|
29
|
+
2`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: "log",
|
|
33
|
+
text: `alpha
|
|
34
|
+
beta`,
|
|
35
|
+
},
|
|
36
|
+
])
|
|
37
|
+
const expected = ` 1
|
|
38
|
+
2alpha
|
|
39
|
+
beta`
|
|
40
|
+
assert({ actual, expected })
|
|
41
|
+
}
|