@jsenv/test 1.0.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.
Files changed (56) hide show
  1. package/dist/controllable_child_process.mjs +129 -0
  2. package/dist/controllable_worker_thread.mjs +91 -0
  3. package/dist/importmap_node_loader.mjs +551 -0
  4. package/dist/js/execute_using_dynamic_import.js +850 -0
  5. package/dist/js/v8_coverage.js +508 -0
  6. package/dist/jsenv_test.js +5993 -0
  7. package/dist/no_experimental_warnings.cjs +10 -0
  8. package/package.json +56 -0
  9. package/src/coverage/babel_plugin_instrument.js +48 -0
  10. package/src/coverage/coverage_reporter_html_directory.js +32 -0
  11. package/src/coverage/coverage_reporter_json_file.js +17 -0
  12. package/src/coverage/coverage_reporter_text_log.js +19 -0
  13. package/src/coverage/empty_coverage_factory.js +52 -0
  14. package/src/coverage/file_by_file_coverage.js +25 -0
  15. package/src/coverage/istanbul_coverage_composition.js +28 -0
  16. package/src/coverage/istanbul_coverage_map_from_coverage.js +16 -0
  17. package/src/coverage/list_files_not_covered.js +15 -0
  18. package/src/coverage/missing_coverage.js +41 -0
  19. package/src/coverage/report_to_coverage.js +198 -0
  20. package/src/coverage/v8_and_istanbul.js +37 -0
  21. package/src/coverage/v8_coverage.js +26 -0
  22. package/src/coverage/v8_coverage_composition.js +24 -0
  23. package/src/coverage/v8_coverage_node_directory.js +85 -0
  24. package/src/coverage/v8_coverage_to_istanbul.js +99 -0
  25. package/src/execution/execute.js +111 -0
  26. package/src/execution/execute_steps.js +423 -0
  27. package/src/execution/execute_test_plan.js +372 -0
  28. package/src/execution/execution_colors.js +10 -0
  29. package/src/execution/execution_steps.js +65 -0
  30. package/src/execution/gc.js +9 -0
  31. package/src/execution/logs_file_execution.js +427 -0
  32. package/src/execution/logs_file_execution.test.mjs +41 -0
  33. package/src/execution/run.js +160 -0
  34. package/src/execution/web_server_param.js +73 -0
  35. package/src/main.js +10 -0
  36. package/src/runtime_browsers/chromium.js +24 -0
  37. package/src/runtime_browsers/firefox.js +23 -0
  38. package/src/runtime_browsers/middleware_istanbul.js +65 -0
  39. package/src/runtime_browsers/middleware_js_supervisor.js +98 -0
  40. package/src/runtime_browsers/using_playwright.js +573 -0
  41. package/src/runtime_browsers/webkit.js +40 -0
  42. package/src/runtime_node/child_exec_options.js +166 -0
  43. package/src/runtime_node/controllable_child_process.mjs +135 -0
  44. package/src/runtime_node/controllable_worker_thread.mjs +103 -0
  45. package/src/runtime_node/exec_options.js +57 -0
  46. package/src/runtime_node/execute_using_dynamic_import.js +53 -0
  47. package/src/runtime_node/exit_codes.js +9 -0
  48. package/src/runtime_node/importmap_node_loader.mjs +51 -0
  49. package/src/runtime_node/importmap_node_loader_file_url.js +4 -0
  50. package/src/runtime_node/kill_process_tree.js +76 -0
  51. package/src/runtime_node/no_experimental_warnings.cjs +13 -0
  52. package/src/runtime_node/no_experimental_warnings_file_url.js +4 -0
  53. package/src/runtime_node/node_child_process.js +374 -0
  54. package/src/runtime_node/node_execution_performance.js +67 -0
  55. package/src/runtime_node/node_worker_thread.js +301 -0
  56. package/src/runtime_node/profiler_v8_coverage.js +56 -0
@@ -0,0 +1,24 @@
1
+ import { createRuntimeUsingPlaywright } from "./using_playwright.js"
2
+
3
+ const chromiumParams = {
4
+ browserName: "chromium",
5
+ // browserVersion will be set by "browser._initializer.version"
6
+ // see also https://github.com/microsoft/playwright/releases
7
+ browserVersion: "unset",
8
+ coveragePlaywrightAPIAvailable: true,
9
+ }
10
+
11
+ export const chromium = (params) => {
12
+ return createRuntimeUsingPlaywright({
13
+ ...chromiumParams,
14
+ ...params,
15
+ })
16
+ }
17
+
18
+ export const chromiumIsolatedTab = (params) => {
19
+ return createRuntimeUsingPlaywright({
20
+ ...chromiumParams,
21
+ isolatedTab: true,
22
+ ...params,
23
+ })
24
+ }
@@ -0,0 +1,23 @@
1
+ import { createRuntimeUsingPlaywright } from "./using_playwright.js"
2
+
3
+ const firefoxParams = {
4
+ browserName: "firefox",
5
+ // browserVersion will be set by "browser._initializer.version"
6
+ // see also https://github.com/microsoft/playwright/releases
7
+ browserVersion: "unset",
8
+ }
9
+
10
+ export const firefox = (params) => {
11
+ return createRuntimeUsingPlaywright({
12
+ ...firefoxParams,
13
+ ...params,
14
+ })
15
+ }
16
+
17
+ export const firefoxIsolatedTab = (params) => {
18
+ return createRuntimeUsingPlaywright({
19
+ ...firefoxParams,
20
+ isolatedTab: true,
21
+ ...params,
22
+ })
23
+ }
@@ -0,0 +1,65 @@
1
+ import { URL_META } from "@jsenv/url-meta"
2
+ import { applyBabelPlugins } from "@jsenv/ast"
3
+ import { SOURCEMAP, generateSourcemapDataUrl } from "@jsenv/sourcemap"
4
+ import { WEB_URL_CONVERTER } from "@jsenv/core/src/helpers/web_url_converter.js"
5
+
6
+ import { babelPluginInstrument } from "../coverage/babel_plugin_instrument.js"
7
+
8
+ export const initIstanbulMiddleware = async (
9
+ page,
10
+ { webServer, rootDirectoryUrl, coverageConfig },
11
+ ) => {
12
+ const associations = URL_META.resolveAssociations(
13
+ { cover: coverageConfig },
14
+ rootDirectoryUrl,
15
+ )
16
+ await page.route("**", async (route) => {
17
+ const request = route.request()
18
+ const url = request.url() // transform into a local url
19
+ const fileUrl = WEB_URL_CONVERTER.asFileUrl(url, webServer)
20
+ const needsInstrumentation = URL_META.applyAssociations({
21
+ url: fileUrl,
22
+ associations,
23
+ }).cover
24
+ if (!needsInstrumentation) {
25
+ route.fallback()
26
+ return
27
+ }
28
+ const response = await route.fetch()
29
+ const originalBody = await response.text()
30
+ try {
31
+ const result = await applyBabelPlugins({
32
+ babelPlugins: [babelPluginInstrument],
33
+ urlInfo: {
34
+ originalUrl: fileUrl,
35
+ // jsenv server could send info to know it's a js module or js classic
36
+ // but in the end it's not super important
37
+ // - it's ok to parse js classic as js module considering it's only for istanbul instrumentation
38
+ type: "js_module",
39
+ content: originalBody,
40
+ },
41
+ })
42
+ let code = result.code
43
+ code = SOURCEMAP.writeComment({
44
+ contentType: "text/javascript",
45
+ content: code,
46
+ specifier: generateSourcemapDataUrl(result.map),
47
+ })
48
+ route.fulfill({
49
+ response,
50
+ body: code,
51
+ headers: {
52
+ ...response.headers(),
53
+ "content-length": Buffer.byteLength(code),
54
+ },
55
+ })
56
+ } catch (e) {
57
+ if (e.code === "PARSE_ERROR") {
58
+ route.fulfill({ response })
59
+ } else {
60
+ console.error(e)
61
+ route.fulfill({ response })
62
+ }
63
+ }
64
+ })
65
+ }
@@ -0,0 +1,98 @@
1
+ import { readFileSync } from "node:fs"
2
+ import { urlToExtension } from "@jsenv/urls"
3
+ import {
4
+ injectSupervisorIntoHTML,
5
+ supervisorFileUrl,
6
+ } from "@jsenv/core/src/plugins/supervisor/html_supervisor_injection.js"
7
+
8
+ export const initJsSupervisorMiddleware = async (
9
+ page,
10
+ { webServer, fileUrl, fileServerUrl },
11
+ ) => {
12
+ const inlineScriptContents = new Map()
13
+
14
+ const interceptHtmlToExecute = async ({ route }) => {
15
+ const response = await route.fetch()
16
+ const originalBody = await response.text()
17
+ const injectionResult = await injectSupervisorIntoHTML(
18
+ {
19
+ content: originalBody,
20
+ url: fileUrl,
21
+ },
22
+ {
23
+ supervisorScriptSrc: `/@fs/${supervisorFileUrl.slice(
24
+ "file:///".length,
25
+ )}`,
26
+ supervisorOptions: {},
27
+ inlineAsRemote: true,
28
+ webServer,
29
+ onInlineScript: ({ src, textContent }) => {
30
+ const inlineScriptWebUrl = new URL(src, `${webServer.origin}/`).href
31
+ inlineScriptContents.set(inlineScriptWebUrl, textContent)
32
+ },
33
+ },
34
+ )
35
+ route.fulfill({
36
+ response,
37
+ body: injectionResult.content,
38
+ headers: {
39
+ ...response.headers(),
40
+ "content-length": Buffer.byteLength(injectionResult.content),
41
+ },
42
+ })
43
+ }
44
+
45
+ const interceptInlineScript = ({ url, route }) => {
46
+ const inlineScriptContent = inlineScriptContents.get(url)
47
+ route.fulfill({
48
+ status: 200,
49
+ body: inlineScriptContent,
50
+ headers: {
51
+ "content-type": "text/javascript",
52
+ "content-length": Buffer.byteLength(inlineScriptContent),
53
+ },
54
+ })
55
+ }
56
+
57
+ const interceptFileSystemUrl = ({ url, route }) => {
58
+ const relativeUrl = url.slice(webServer.origin.length)
59
+ const fsPath = relativeUrl.slice("/@fs/".length)
60
+ const fsUrl = `file:///${fsPath}`
61
+ const fileContent = readFileSync(new URL(fsUrl), "utf8")
62
+ route.fulfill({
63
+ status: 200,
64
+ body: fileContent,
65
+ headers: {
66
+ "content-type": "text/javascript",
67
+ "content-length": Buffer.byteLength(fileContent),
68
+ },
69
+ })
70
+ }
71
+
72
+ await page.route("**", async (route) => {
73
+ const request = route.request()
74
+ const url = request.url()
75
+ if (url === fileServerUrl && urlToExtension(url) === ".html") {
76
+ interceptHtmlToExecute({
77
+ url,
78
+ request,
79
+ route,
80
+ })
81
+ return
82
+ }
83
+ if (inlineScriptContents.has(url)) {
84
+ interceptInlineScript({
85
+ url,
86
+ request,
87
+ route,
88
+ })
89
+ return
90
+ }
91
+ const fsServerUrl = new URL("/@fs/", webServer.origin)
92
+ if (url.startsWith(fsServerUrl)) {
93
+ interceptFileSystemUrl({ url, request, route })
94
+ return
95
+ }
96
+ route.fallback()
97
+ })
98
+ }