dd-trace 5.102.0 → 5.104.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 (201) hide show
  1. package/ext/exporters.js +1 -0
  2. package/index.d.ts +25 -3
  3. package/package.json +15 -13
  4. package/packages/datadog-esbuild/src/utils.js +2 -2
  5. package/packages/datadog-instrumentations/src/ai.js +1 -1
  6. package/packages/datadog-instrumentations/src/aws-sdk.js +2 -2
  7. package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -2
  8. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +32 -15
  9. package/packages/datadog-instrumentations/src/couchbase.js +69 -220
  10. package/packages/datadog-instrumentations/src/cucumber.js +104 -31
  11. package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
  12. package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
  13. package/packages/datadog-instrumentations/src/electron.js +240 -0
  14. package/packages/datadog-instrumentations/src/fetch.js +5 -5
  15. package/packages/datadog-instrumentations/src/graphql.js +13 -17
  16. package/packages/datadog-instrumentations/src/grpc/client.js +48 -32
  17. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +2 -2
  18. package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
  21. package/packages/datadog-instrumentations/src/helpers/kafka.js +58 -0
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +3 -2
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +19 -5
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +14 -13
  25. package/packages/datadog-instrumentations/src/http/client.js +2 -2
  26. package/packages/datadog-instrumentations/src/ioredis.js +18 -14
  27. package/packages/datadog-instrumentations/src/jest.js +382 -84
  28. package/packages/datadog-instrumentations/src/kafkajs.js +184 -174
  29. package/packages/datadog-instrumentations/src/mariadb.js +1 -1
  30. package/packages/datadog-instrumentations/src/memcached.js +2 -1
  31. package/packages/datadog-instrumentations/src/mocha/main.js +309 -56
  32. package/packages/datadog-instrumentations/src/mocha/utils.js +48 -8
  33. package/packages/datadog-instrumentations/src/mongodb-core.js +34 -9
  34. package/packages/datadog-instrumentations/src/mongoose.js +10 -12
  35. package/packages/datadog-instrumentations/src/mysql.js +2 -2
  36. package/packages/datadog-instrumentations/src/mysql2.js +1 -1
  37. package/packages/datadog-instrumentations/src/pg.js +25 -11
  38. package/packages/datadog-instrumentations/src/playwright.js +449 -60
  39. package/packages/datadog-instrumentations/src/redis.js +19 -10
  40. package/packages/datadog-instrumentations/src/router.js +4 -2
  41. package/packages/datadog-instrumentations/src/vitest.js +246 -149
  42. package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
  43. package/packages/datadog-plugin-aws-sdk/src/base.js +18 -24
  44. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
  45. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -1
  46. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
  47. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
  48. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
  49. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
  50. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -2
  51. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
  52. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
  53. package/packages/datadog-plugin-couchbase/src/index.js +58 -52
  54. package/packages/datadog-plugin-cucumber/src/index.js +1 -0
  55. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +239 -40
  56. package/packages/datadog-plugin-cypress/src/support.js +13 -1
  57. package/packages/datadog-plugin-elasticsearch/src/index.js +28 -8
  58. package/packages/datadog-plugin-electron/src/index.js +17 -0
  59. package/packages/datadog-plugin-electron/src/ipc.js +143 -0
  60. package/packages/datadog-plugin-electron/src/net.js +82 -0
  61. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
  62. package/packages/datadog-plugin-graphql/src/execute.js +6 -28
  63. package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
  64. package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
  65. package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
  66. package/packages/datadog-plugin-graphql/src/utils.js +33 -1
  67. package/packages/datadog-plugin-grpc/src/client.js +6 -7
  68. package/packages/datadog-plugin-grpc/src/util.js +57 -22
  69. package/packages/datadog-plugin-http/src/client.js +2 -2
  70. package/packages/datadog-plugin-jest/src/index.js +92 -50
  71. package/packages/datadog-plugin-kafkajs/src/producer.js +32 -0
  72. package/packages/datadog-plugin-mocha/src/index.js +1 -0
  73. package/packages/datadog-plugin-mongodb-core/src/index.js +70 -69
  74. package/packages/datadog-plugin-mysql/src/index.js +1 -1
  75. package/packages/datadog-plugin-openai/src/services.js +2 -1
  76. package/packages/datadog-plugin-pg/src/index.js +3 -3
  77. package/packages/datadog-plugin-playwright/src/index.js +4 -0
  78. package/packages/datadog-plugin-redis/src/index.js +54 -24
  79. package/packages/datadog-plugin-undici/src/index.js +19 -0
  80. package/packages/datadog-plugin-vitest/src/index.js +19 -7
  81. package/packages/datadog-shimmer/src/shimmer.js +35 -0
  82. package/packages/dd-trace/src/aiguard/index.js +3 -1
  83. package/packages/dd-trace/src/aiguard/sdk.js +36 -30
  84. package/packages/dd-trace/src/aiguard/tags.js +20 -11
  85. package/packages/dd-trace/src/appsec/blocking.js +2 -2
  86. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -2
  87. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  88. package/packages/dd-trace/src/appsec/index.js +10 -3
  89. package/packages/dd-trace/src/appsec/reporter.js +19 -5
  90. package/packages/dd-trace/src/azure_metadata.js +17 -6
  91. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
  92. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
  93. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
  94. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
  95. package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -1
  96. package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +5 -3
  97. package/packages/dd-trace/src/config/defaults.js +3 -14
  98. package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -1
  99. package/packages/dd-trace/src/config/helper.js +4 -0
  100. package/packages/dd-trace/src/config/index.js +2 -2
  101. package/packages/dd-trace/src/config/major-overrides.js +98 -0
  102. package/packages/dd-trace/src/config/parsers.js +7 -1
  103. package/packages/dd-trace/src/config/supported-configurations.json +60 -38
  104. package/packages/dd-trace/src/crashtracking/crashtracker.js +15 -3
  105. package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
  106. package/packages/dd-trace/src/datastreams/context.js +4 -2
  107. package/packages/dd-trace/src/datastreams/manager.js +1 -1
  108. package/packages/dd-trace/src/datastreams/processor.js +2 -2
  109. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
  110. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  111. package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
  112. package/packages/dd-trace/src/debugger/index.js +7 -7
  113. package/packages/dd-trace/src/dogstatsd.js +2 -2
  114. package/packages/dd-trace/src/encode/0.4.js +45 -54
  115. package/packages/dd-trace/src/encode/0.5.js +34 -3
  116. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +26 -19
  117. package/packages/dd-trace/src/encode/agentless-json.js +1 -1
  118. package/packages/dd-trace/src/exporter.js +2 -0
  119. package/packages/dd-trace/src/exporters/agent/index.js +2 -1
  120. package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
  121. package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
  122. package/packages/dd-trace/src/exporters/common/agents.js +3 -1
  123. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
  124. package/packages/dd-trace/src/exporters/common/request.js +4 -2
  125. package/packages/dd-trace/src/exporters/electron/index.js +49 -0
  126. package/packages/dd-trace/src/external-logger/src/index.js +2 -1
  127. package/packages/dd-trace/src/git_metadata.js +10 -8
  128. package/packages/dd-trace/src/id.js +17 -4
  129. package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
  130. package/packages/dd-trace/src/lambda/handler.js +2 -4
  131. package/packages/dd-trace/src/lambda/index.js +62 -14
  132. package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
  133. package/packages/dd-trace/src/llmobs/index.js +13 -2
  134. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
  135. package/packages/dd-trace/src/llmobs/sdk.js +10 -0
  136. package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
  137. package/packages/dd-trace/src/log/writer.js +3 -1
  138. package/packages/dd-trace/src/noop/span.js +3 -1
  139. package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
  140. package/packages/dd-trace/src/openfeature/writers/exposures.js +51 -20
  141. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +3 -2
  142. package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
  143. package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
  144. package/packages/dd-trace/src/plugins/apollo.js +3 -1
  145. package/packages/dd-trace/src/plugins/ci_plugin.js +52 -17
  146. package/packages/dd-trace/src/plugins/database.js +54 -12
  147. package/packages/dd-trace/src/plugins/index.js +1 -0
  148. package/packages/dd-trace/src/plugins/log_plugin.js +3 -1
  149. package/packages/dd-trace/src/plugins/plugin.js +2 -4
  150. package/packages/dd-trace/src/plugins/tracing.js +5 -3
  151. package/packages/dd-trace/src/plugins/util/ci.js +8 -8
  152. package/packages/dd-trace/src/plugins/util/git-cache.js +20 -18
  153. package/packages/dd-trace/src/plugins/util/git.js +3 -1
  154. package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
  155. package/packages/dd-trace/src/plugins/util/test.js +119 -5
  156. package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -15
  157. package/packages/dd-trace/src/plugins/util/web.js +11 -0
  158. package/packages/dd-trace/src/priority_sampler.js +1 -1
  159. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  160. package/packages/dd-trace/src/profiling/profilers/wall.js +1 -1
  161. package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
  162. package/packages/dd-trace/src/rate_limiter.js +1 -1
  163. package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
  164. package/packages/dd-trace/src/ritm.js +2 -1
  165. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
  166. package/packages/dd-trace/src/scope.js +7 -5
  167. package/packages/dd-trace/src/serverless.js +5 -2
  168. package/packages/dd-trace/src/service-naming/extra-services.js +14 -0
  169. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +20 -0
  170. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  171. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +20 -0
  172. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  173. package/packages/dd-trace/src/span_stats.js +1 -1
  174. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  175. package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
  176. package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
  177. package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
  178. package/vendor/dist/opentracing/LICENSE +0 -201
  179. package/vendor/dist/opentracing/binary_carrier.d.ts +0 -11
  180. package/vendor/dist/opentracing/constants.d.ts +0 -61
  181. package/vendor/dist/opentracing/examples/demo/demo.d.ts +0 -2
  182. package/vendor/dist/opentracing/ext/tags.d.ts +0 -90
  183. package/vendor/dist/opentracing/functions.d.ts +0 -20
  184. package/vendor/dist/opentracing/global_tracer.d.ts +0 -14
  185. package/vendor/dist/opentracing/index.d.ts +0 -12
  186. package/vendor/dist/opentracing/index.js +0 -1
  187. package/vendor/dist/opentracing/mock_tracer/index.d.ts +0 -5
  188. package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +0 -13
  189. package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +0 -16
  190. package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +0 -50
  191. package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +0 -26
  192. package/vendor/dist/opentracing/noop.d.ts +0 -8
  193. package/vendor/dist/opentracing/reference.d.ts +0 -33
  194. package/vendor/dist/opentracing/span.d.ts +0 -147
  195. package/vendor/dist/opentracing/span_context.d.ts +0 -26
  196. package/vendor/dist/opentracing/test/api_compatibility.d.ts +0 -16
  197. package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +0 -3
  198. package/vendor/dist/opentracing/test/noop_implementation.d.ts +0 -4
  199. package/vendor/dist/opentracing/test/opentracing_api.d.ts +0 -3
  200. package/vendor/dist/opentracing/test/unittest.d.ts +0 -2
  201. package/vendor/dist/opentracing/tracer.d.ts +0 -127
@@ -3,10 +3,13 @@
3
3
  // Capture real timers at module load time, before any test can install fake timers.
4
4
  const realSetTimeout = setTimeout
5
5
 
6
+ const { readFileSync } = require('node:fs')
7
+ const { builtinModules } = require('node:module')
6
8
  const path = require('path')
7
9
  const satisfies = require('../../../vendor/dist/semifies')
8
10
  const { DD_MAJOR } = require('../../../version')
9
11
  const shimmer = require('../../datadog-shimmer')
12
+ const { getEnvironmentVariable } = require('../../dd-trace/src/config/helper')
10
13
  const log = require('../../dd-trace/src/log')
11
14
  const {
12
15
  getCoveredFilenamesFromCoverage,
@@ -27,6 +30,7 @@ const {
27
30
  logAttemptToFixTestExecution,
28
31
  logTestOptimizationSummary,
29
32
  getEfdRetryCount,
33
+ getTestOptimizationRequestResults,
30
34
  } = require('../../dd-trace/src/plugins/util/test')
31
35
  const {
32
36
  SEED_SUFFIX_RE,
@@ -74,6 +78,7 @@ const CHILD_MESSAGE_CALL = 1
74
78
 
75
79
  // Maximum time we'll wait for the tracer to flush
76
80
  const FLUSH_TIMEOUT = 10_000
81
+ const isJestWorker = !!getEnvironmentVariable('JEST_WORKER_ID')
77
82
 
78
83
  // https://github.com/jestjs/jest/blob/41f842a46bb2691f828c3a5f27fc1d6290495b82/packages/jest-circus/src/types.ts#L9C8-L9C54
79
84
  const RETRY_TIMES = Symbol.for('RETRY_TIMES')
@@ -101,6 +106,8 @@ let testManagementTests = {}
101
106
  let testManagementAttemptToFixRetries = 0
102
107
  let isImpactedTestsEnabled = false
103
108
  let modifiedFiles = {}
109
+ let activeTestSuiteAbsolutePath
110
+ let isConsoleErrorWrapped = false
104
111
 
105
112
  const testContexts = new WeakMap()
106
113
  const originalTestFns = new WeakMap()
@@ -124,7 +131,12 @@ const efdNewTestCandidates = new Set()
124
131
  // Tests that are genuinely new (not in known tests list).
125
132
  const newTests = new Set()
126
133
  const testSuiteAbsolutePathsWithFastCheck = new Set()
134
+ const testSuiteFastCheckUsage = new Map()
127
135
  const testSuiteJestObjects = new Map()
136
+ const wrappedJestGlobals = new WeakSet()
137
+ const wrappedJestObjects = new WeakSet()
138
+ const wrappedWorkerInitializers = new WeakSet()
139
+ const publishedRuntimeReferenceErrors = new WeakMap()
128
140
 
129
141
  const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
130
142
  const ATR_RETRY_SUPPRESSION_FLAG = '_ddDisableAtrRetry'
@@ -303,6 +315,26 @@ function getAttemptToFixExecutionsFromJestResults (result) {
303
315
  return executions
304
316
  }
305
317
 
318
+ function wrapConsoleErrorForJestReferenceErrors () {
319
+ if (isConsoleErrorWrapped) return
320
+
321
+ isConsoleErrorWrapped = true
322
+ // eslint-disable-next-line no-console
323
+ const originalConsoleError = console.error
324
+ // eslint-disable-next-line no-console
325
+ console.error = function () {
326
+ const [message] = arguments
327
+ if (
328
+ typeof message === 'string' &&
329
+ message.includes('Jest environment has been torn down') &&
330
+ activeTestSuiteAbsolutePath
331
+ ) {
332
+ publishRuntimeReferenceError({ _testPath: activeTestSuiteAbsolutePath }, message)
333
+ }
334
+ return originalConsoleError.apply(this, arguments)
335
+ }
336
+ }
337
+
306
338
  function getWrappedEnvironment (BaseEnvironment, jestVersion) {
307
339
  return class DatadogEnvironment extends BaseEnvironment {
308
340
  constructor (config, context) {
@@ -314,6 +346,9 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
314
346
  this.global._ddtrace = global._ddtrace
315
347
  this.hasSnapshotTests = undefined
316
348
  this.testSuiteAbsolutePath = context.testPath
349
+ activeTestSuiteAbsolutePath = this.testSuiteAbsolutePath
350
+ wrapConsoleErrorForJestReferenceErrors()
351
+ this.globalConfig = config.globalConfig
317
352
 
318
353
  this.displayName = config.projectConfig?.displayName?.name || config.displayName
319
354
  this.testEnvironmentOptions = getTestEnvironmentOptions(config)
@@ -423,6 +458,10 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
423
458
  */
424
459
  resetMockState () {
425
460
  try {
461
+ if (this.moduleMocker?.clearAllMocks) {
462
+ this.moduleMocker.clearAllMocks()
463
+ return
464
+ }
426
465
  const jestObject = testSuiteJestObjects.get(this.testSuiteAbsolutePath)
427
466
  if (jestObject?.clearAllMocks) {
428
467
  jestObject.clearAllMocks()
@@ -504,7 +543,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
504
543
  }
505
544
 
506
545
  getShouldStripSeedFromTestName () {
507
- return testSuiteAbsolutePathsWithFastCheck.has(this.testSuiteAbsolutePath)
546
+ return doesTestSuiteUseFastCheck(this.testSuiteAbsolutePath)
508
547
  }
509
548
 
510
549
  // At the `add_test` event we don't have the test object yet, so we can't use it
@@ -843,8 +882,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
843
882
  const willBeRetriedByFailedTestReplay = numRetries > 0 && numTestExecutions - 1 < numRetries
844
883
  const mightHitBreakpoint = this.isDiEnabled && numTestExecutions >= 2
845
884
 
846
- // For quarantined tests, suppress errors so Jest doesn't count them as failures.
847
- // This prevents --bail from stopping the test run on quarantined test failures.
885
+ // For quarantined tests, track failures so the session can be marked as passing later,
886
+ // and suppress errors so Jest does not mark the test suite as failing.
848
887
  // The actual status ('fail') is already captured above for dd-trace reporting.
849
888
  // Only suppress on the final execution — not when ATR/EFD/ATF will retry the test.
850
889
  if (!event.test?.[ATR_RETRY_SUPPRESSION_FLAG] && !willBeRetriedByFailedTestReplay) {
@@ -1055,7 +1094,19 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1055
1094
  }
1056
1095
  }
1057
1096
  }
1058
- return super.teardown()
1097
+ const clearActiveTestSuite = () => {
1098
+ realSetTimeout(() => {
1099
+ if (activeTestSuiteAbsolutePath === this.testSuiteAbsolutePath) {
1100
+ activeTestSuiteAbsolutePath = undefined
1101
+ }
1102
+ }, 0)
1103
+ }
1104
+ const result = super.teardown()
1105
+ if (result?.then) {
1106
+ return result.finally(clearActiveTestSuite)
1107
+ }
1108
+ clearActiveTestSuite()
1109
+ return result
1059
1110
  }
1060
1111
  }
1061
1112
  }
@@ -1123,6 +1174,12 @@ function getWrappedScheduleTests (scheduleTests, frameworkVersion) {
1123
1174
  }
1124
1175
  }
1125
1176
 
1177
+ function getChannelPromise (channelToPublishTo, payload = {}) {
1178
+ return new Promise(resolve => {
1179
+ channelToPublishTo.publish({ ...payload, onDone: resolve })
1180
+ })
1181
+ }
1182
+
1126
1183
  function searchSourceWrapper (searchSourcePackage, frameworkVersion) {
1127
1184
  const SearchSource = searchSourcePackage.default ?? searchSourcePackage
1128
1185
 
@@ -1184,17 +1241,14 @@ function getCliWrapper (isNewJestVersion) {
1184
1241
  }
1185
1242
  return shimmer.wrap(cli, 'runCLI', runCLI => async function () {
1186
1243
  let onDone
1187
- const configurationPromise = new Promise((resolve) => {
1188
- onDone = resolve
1189
- })
1190
1244
  if (!libraryConfigurationCh.hasSubscribers) {
1191
1245
  return runCLI.apply(this, arguments)
1192
1246
  }
1193
1247
 
1194
- libraryConfigurationCh.publish({ onDone, frameworkVersion: jestVersion })
1195
-
1196
1248
  try {
1197
- const { err, libraryConfig } = await configurationPromise
1249
+ const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh, {
1250
+ frameworkVersion: jestVersion,
1251
+ })
1198
1252
  if (!err) {
1199
1253
  isCodeCoverageEnabled = libraryConfig.isCodeCoverageEnabled
1200
1254
  isSuitesSkippingEnabled = libraryConfig.isSuitesSkippingEnabled
@@ -1213,15 +1267,22 @@ function getCliWrapper (isNewJestVersion) {
1213
1267
  log.error('Jest library configuration error', err)
1214
1268
  }
1215
1269
 
1216
- if (isKnownTestsEnabled) {
1217
- const knownTestsPromise = new Promise((resolve) => {
1218
- onDone = resolve
1219
- })
1220
-
1221
- knownTestsCh.publish({ onDone })
1270
+ const {
1271
+ knownTestsResponse,
1272
+ testManagementTestsResponse,
1273
+ skippableSuitesResponse,
1274
+ } = await getTestOptimizationRequestResults({
1275
+ isKnownTestsEnabled,
1276
+ isTestManagementTestsEnabled,
1277
+ isSuitesSkippingEnabled,
1278
+ getKnownTests: () => getChannelPromise(knownTestsCh),
1279
+ getTestManagementTests: () => getChannelPromise(testManagementTestsCh),
1280
+ getSkippableSuites: () => getChannelPromise(skippableSuitesCh),
1281
+ })
1222
1282
 
1283
+ if (isKnownTestsEnabled) {
1223
1284
  try {
1224
- const { err, knownTests: receivedKnownTests } = await knownTestsPromise
1285
+ const { err, knownTests: receivedKnownTests } = knownTestsResponse || await getChannelPromise(knownTestsCh)
1225
1286
  if (err) {
1226
1287
  // We disable EFD if there has been an error in the known tests request
1227
1288
  isEarlyFlakeDetectionEnabled = false
@@ -1235,14 +1296,9 @@ function getCliWrapper (isNewJestVersion) {
1235
1296
  }
1236
1297
 
1237
1298
  if (isSuitesSkippingEnabled) {
1238
- const skippableSuitesPromise = new Promise((resolve) => {
1239
- onDone = resolve
1240
- })
1241
-
1242
- skippableSuitesCh.publish({ onDone })
1243
-
1244
1299
  try {
1245
- const { err, skippableSuites: receivedSkippableSuites } = await skippableSuitesPromise
1300
+ const { err, skippableSuites: receivedSkippableSuites } =
1301
+ skippableSuitesResponse || await getChannelPromise(skippableSuitesCh)
1246
1302
  if (!err) {
1247
1303
  skippableSuites = receivedSkippableSuites
1248
1304
  }
@@ -1252,14 +1308,9 @@ function getCliWrapper (isNewJestVersion) {
1252
1308
  }
1253
1309
 
1254
1310
  if (isTestManagementTestsEnabled) {
1255
- const testManagementTestsPromise = new Promise((resolve) => {
1256
- onDone = resolve
1257
- })
1258
-
1259
- testManagementTestsCh.publish({ onDone })
1260
-
1261
1311
  try {
1262
- const { err, testManagementTests: receivedTestManagementTests } = await testManagementTestsPromise
1312
+ const { err, testManagementTests: receivedTestManagementTests } =
1313
+ testManagementTestsResponse || await getChannelPromise(testManagementTestsCh)
1263
1314
  if (err) {
1264
1315
  isTestManagementTestsEnabled = false
1265
1316
  testManagementTests = {}
@@ -1273,14 +1324,8 @@ function getCliWrapper (isNewJestVersion) {
1273
1324
  }
1274
1325
 
1275
1326
  if (isImpactedTestsEnabled) {
1276
- const impactedTestsPromise = new Promise((resolve) => {
1277
- onDone = resolve
1278
- })
1279
-
1280
- modifiedFilesCh.publish({ onDone })
1281
-
1282
1327
  try {
1283
- const { err, modifiedFiles: receivedModifiedFiles } = await impactedTestsPromise
1328
+ const { err, modifiedFiles: receivedModifiedFiles } = await getChannelPromise(modifiedFilesCh)
1284
1329
  if (!err) {
1285
1330
  modifiedFiles = receivedModifiedFiles
1286
1331
  }
@@ -1492,7 +1537,8 @@ function getCliWrapper (isNewJestVersion) {
1492
1537
  const timeoutPromise = new Promise((resolve) => {
1493
1538
  timeoutId = realSetTimeout(() => {
1494
1539
  resolve('timeout')
1495
- }, FLUSH_TIMEOUT).unref()
1540
+ }, FLUSH_TIMEOUT)
1541
+ timeoutId.unref?.()
1496
1542
  })
1497
1543
 
1498
1544
  testSessionFinishCh.publish({
@@ -1557,6 +1603,33 @@ function coverageReporterWrapper (coverageReporter) {
1557
1603
  return coverageReporter
1558
1604
  }
1559
1605
 
1606
+ function shouldWaitForTestSuiteFinish (environment) {
1607
+ return isJestWorker && environment.globalConfig?.workerIdleMemoryLimit !== undefined
1608
+ }
1609
+
1610
+ function publishTestSuiteFinish (payload, waitForFinish) {
1611
+ if (!testSuiteFinishCh.hasSubscribers) return
1612
+
1613
+ if (!waitForFinish) {
1614
+ testSuiteFinishCh.publish(payload)
1615
+ return
1616
+ }
1617
+
1618
+ return new Promise(resolve => {
1619
+ testSuiteFinishCh.publish({
1620
+ ...payload,
1621
+ waitForFinish,
1622
+ onDone: resolve,
1623
+ })
1624
+ })
1625
+ }
1626
+
1627
+ function cleanupTestSuiteState (testSuiteAbsolutePath) {
1628
+ testSuiteMockedFiles.delete(testSuiteAbsolutePath)
1629
+ testSuiteFastCheckUsage.delete(testSuiteAbsolutePath)
1630
+ testSuiteJestObjects.delete(testSuiteAbsolutePath)
1631
+ }
1632
+
1560
1633
  addHook({
1561
1634
  name: '@jest/core',
1562
1635
  file: 'build/TestScheduler.js',
@@ -1675,7 +1748,7 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
1675
1748
  const getFilesWithPath = (files) => files.map(file => getTestSuitePath(file, root))
1676
1749
 
1677
1750
  const coverageFiles = getFilesWithPath(getCoveredFilenamesFromCoverage(environment.global.__coverage__))
1678
- const mockedFiles = getFilesWithPath(testSuiteMockedFiles.get(environment.testSuiteAbsolutePath) || [])
1751
+ const mockedFiles = getFilesWithPath(getMockedFiles(environment.testSuiteAbsolutePath))
1679
1752
 
1680
1753
  testSuiteCodeCoverageCh.publish({
1681
1754
  coverageFiles,
@@ -1684,19 +1757,51 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
1684
1757
  testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
1685
1758
  })
1686
1759
  }
1687
- testSuiteFinishCh.publish({ status, errorMessage, testSuiteAbsolutePath: environment.testSuiteAbsolutePath })
1760
+ const waitForFinish = shouldWaitForTestSuiteFinish(environment)
1761
+ const finishPayload = {
1762
+ status,
1763
+ errorMessage,
1764
+ testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
1765
+ }
1766
+ if (waitForFinish) {
1767
+ const finishPromise = publishTestSuiteFinish(finishPayload, waitForFinish)
1768
+ if (finishPromise) {
1769
+ return finishPromise.then(() => {
1770
+ // Cleanup per-suite state to avoid memory leaks
1771
+ cleanupTestSuiteState(environment.testSuiteAbsolutePath)
1772
+
1773
+ return suiteResults
1774
+ })
1775
+ }
1776
+ }
1777
+ publishTestSuiteFinish(finishPayload, waitForFinish)
1688
1778
 
1689
1779
  // Cleanup per-suite state to avoid memory leaks
1690
- testSuiteMockedFiles.delete(environment.testSuiteAbsolutePath)
1691
- testSuiteJestObjects.delete(environment.testSuiteAbsolutePath)
1780
+ cleanupTestSuiteState(environment.testSuiteAbsolutePath)
1692
1781
 
1693
1782
  return suiteResults
1694
1783
  }).catch(error => {
1695
- testSuiteFinishCh.publish({ status: 'fail', error, testSuiteAbsolutePath: environment.testSuiteAbsolutePath })
1784
+ const waitForFinish = shouldWaitForTestSuiteFinish(environment)
1785
+ const finishPayload = {
1786
+ status: 'fail',
1787
+ error,
1788
+ testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
1789
+ }
1790
+ if (waitForFinish) {
1791
+ const finishPromise = publishTestSuiteFinish(finishPayload, waitForFinish)
1792
+ if (finishPromise) {
1793
+ return finishPromise.then(() => {
1794
+ // Cleanup per-suite state to avoid memory leaks
1795
+ cleanupTestSuiteState(environment.testSuiteAbsolutePath)
1796
+
1797
+ throw error
1798
+ })
1799
+ }
1800
+ }
1801
+ publishTestSuiteFinish(finishPayload, waitForFinish)
1696
1802
 
1697
1803
  // Cleanup per-suite state to avoid memory leaks
1698
- testSuiteMockedFiles.delete(environment.testSuiteAbsolutePath)
1699
- testSuiteJestObjects.delete(environment.testSuiteAbsolutePath)
1804
+ cleanupTestSuiteState(environment.testSuiteAbsolutePath)
1700
1805
 
1701
1806
  throw error
1702
1807
  })
@@ -1794,6 +1899,7 @@ const DD_TEST_ENVIRONMENT_OPTION_KEYS = [
1794
1899
  '_ddRepositoryRoot',
1795
1900
  '_ddIsFlakyTestRetriesEnabled',
1796
1901
  '_ddFlakyTestRetriesCount',
1902
+ '_ddItrSkippingEnabledTags',
1797
1903
  '_ddIsDiEnabled',
1798
1904
  '_ddIsKnownTestsEnabled',
1799
1905
  '_ddIsTestManagementTestsEnabled',
@@ -1904,39 +2010,197 @@ const LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE = new Set([
1904
2010
  'winston',
1905
2011
  ])
1906
2012
 
2013
+ function recordMockedFile (suiteFilePath, moduleName) {
2014
+ if (!suiteFilePath || typeof moduleName !== 'string') return
2015
+
2016
+ const existingMockedFiles = testSuiteMockedFiles.get(suiteFilePath) || []
2017
+ const suiteDir = path.dirname(suiteFilePath)
2018
+ const mockPath = path.resolve(suiteDir, moduleName)
2019
+ existingMockedFiles.push(mockPath)
2020
+ testSuiteMockedFiles.set(suiteFilePath, existingMockedFiles)
2021
+ }
2022
+
2023
+ const JEST_STATIC_MOCK_CALL_RE = /\bjest\.(?:mock|doMock|unstable_mockModule)\(\s*(['"`])([^'"`]+)\1/g
2024
+
2025
+ function getStaticMockedFiles (suiteFilePath) {
2026
+ if (!suiteFilePath) return []
2027
+
2028
+ const mockedFiles = []
2029
+ try {
2030
+ const source = readFileSync(suiteFilePath, 'utf8')
2031
+ let match
2032
+ JEST_STATIC_MOCK_CALL_RE.lastIndex = 0
2033
+ while ((match = JEST_STATIC_MOCK_CALL_RE.exec(source)) !== null) {
2034
+ mockedFiles.push(path.resolve(path.dirname(suiteFilePath), match[2]))
2035
+ }
2036
+ } catch {
2037
+ // ignore errors
2038
+ }
2039
+
2040
+ return mockedFiles
2041
+ }
2042
+
2043
+ function getMockedFiles (suiteFilePath) {
2044
+ const mockedFiles = testSuiteMockedFiles.get(suiteFilePath)
2045
+ const staticMockedFiles = getStaticMockedFiles(suiteFilePath)
2046
+
2047
+ if (mockedFiles?.length) {
2048
+ return [...new Set([...mockedFiles, ...staticMockedFiles])]
2049
+ }
2050
+ return staticMockedFiles
2051
+ }
2052
+
2053
+ function wrapJestObject (jestObject, suiteFilePath) {
2054
+ if (!jestObject || !suiteFilePath || wrappedJestObjects.has(jestObject)) return
2055
+
2056
+ testSuiteJestObjects.set(suiteFilePath, jestObject)
2057
+ wrappedJestObjects.add(jestObject)
2058
+
2059
+ shimmer.wrap(jestObject, 'mock', mock => function (moduleName) {
2060
+ // If the library is mocked with `jest.mock`, we don't want to bypass jest's own require engine
2061
+ if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
2062
+ LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.delete(moduleName)
2063
+ }
2064
+ recordMockedFile(suiteFilePath, moduleName)
2065
+ return mock.apply(this, arguments)
2066
+ })
2067
+ }
2068
+
2069
+ function wrapJestGlobalsForRuntime (runtime) {
2070
+ const jestGlobals = runtime?.jestGlobals
2071
+ if (!jestGlobals || wrappedJestGlobals.has(jestGlobals) || typeof jestGlobals.jestObjectFor !== 'function') {
2072
+ return
2073
+ }
2074
+
2075
+ wrappedJestGlobals.add(jestGlobals)
2076
+ shimmer.wrap(jestGlobals, 'jestObjectFor', jestObjectFor => function (from) {
2077
+ const jestObject = jestObjectFor.apply(this, arguments)
2078
+ wrapJestObject(jestObject, from)
2079
+ return jestObject
2080
+ })
2081
+ }
2082
+
2083
+ function recordFastCheckUsage (runtime, from, moduleName) {
2084
+ if (moduleName !== '@fast-check/jest') return
2085
+
2086
+ if (from) {
2087
+ testSuiteAbsolutePathsWithFastCheck.add(from)
2088
+ testSuiteFastCheckUsage.set(from, true)
2089
+ }
2090
+ if (runtime?._testPath) {
2091
+ testSuiteAbsolutePathsWithFastCheck.add(runtime._testPath)
2092
+ testSuiteFastCheckUsage.set(runtime._testPath, true)
2093
+ }
2094
+ }
2095
+
2096
+ function doesTestSuiteUseFastCheck (testSuiteAbsolutePath) {
2097
+ if (!testSuiteAbsolutePath) return false
2098
+ if (testSuiteFastCheckUsage.has(testSuiteAbsolutePath)) {
2099
+ return testSuiteFastCheckUsage.get(testSuiteAbsolutePath)
2100
+ }
2101
+
2102
+ try {
2103
+ const usesFastCheck = readFileSync(testSuiteAbsolutePath, 'utf8').includes('@fast-check/jest')
2104
+ testSuiteFastCheckUsage.set(testSuiteAbsolutePath, usesFastCheck)
2105
+ if (usesFastCheck) {
2106
+ testSuiteAbsolutePathsWithFastCheck.add(testSuiteAbsolutePath)
2107
+ }
2108
+ return usesFastCheck
2109
+ } catch {
2110
+ testSuiteFastCheckUsage.set(testSuiteAbsolutePath, false)
2111
+ return false
2112
+ }
2113
+ }
2114
+
2115
+ function getLastLoggedReferenceError (runtime) {
2116
+ const loggedReferenceErrors = runtime?.loggedReferenceErrors
2117
+ if (!loggedReferenceErrors?.size) return
2118
+ return [...loggedReferenceErrors].pop()
2119
+ }
2120
+
2121
+ function publishRuntimeReferenceError (runtime, errorMessage) {
2122
+ if (!errorMessage || !runtime?._testPath) return
2123
+
2124
+ let publishedErrors = publishedRuntimeReferenceErrors.get(runtime)
2125
+ if (!publishedErrors) {
2126
+ publishedErrors = new Set()
2127
+ publishedRuntimeReferenceErrors.set(runtime, publishedErrors)
2128
+ }
2129
+ if (publishedErrors.has(errorMessage)) return
2130
+
2131
+ publishedErrors.add(errorMessage)
2132
+ testSuiteErrorCh.publish({
2133
+ errorMessage,
2134
+ testSuiteAbsolutePath: runtime._testPath,
2135
+ })
2136
+ }
2137
+
2138
+ function isBetweenTestsReferenceError (error) {
2139
+ return error?.name === 'ReferenceError' &&
2140
+ typeof error.message === 'string' &&
2141
+ error.message.includes('outside of the scope of the test code')
2142
+ }
2143
+
2144
+ function reportBetweenTestsReferenceError (runtime, moduleName, originalErrorMessage) {
2145
+ if (typeof moduleName !== 'string') return false
2146
+
2147
+ const fallbackErrorMessage = moduleName.startsWith('node:') || builtinModules.includes(moduleName)
2148
+ ? 'You are trying to access a Node.js module outside of the scope of the test code.'
2149
+ : 'You are trying to `require` a file after the Jest environment has been torn down.'
2150
+ const errorMessage = originalErrorMessage || fallbackErrorMessage
2151
+
2152
+ if (typeof runtime._logFormattedReferenceError === 'function') {
2153
+ runtime._logFormattedReferenceError(errorMessage)
2154
+ }
2155
+ publishRuntimeReferenceError(runtime, getLastLoggedReferenceError(runtime) || errorMessage)
2156
+ process.exitCode = 1
2157
+ return true
2158
+ }
2159
+
2160
+ function requireOutsideJestRequireEngine (runtime, moduleName) {
2161
+ if (typeof runtime._requireCoreModule === 'function') {
2162
+ return runtime._requireCoreModule(moduleName)
2163
+ }
2164
+ return require(moduleName)
2165
+ }
2166
+
2167
+ function formatDefaultStackTrace (error, structuredStackTrace) {
2168
+ const errorString = Error.prototype.toString.call(error)
2169
+ if (structuredStackTrace.length === 0) return errorString
2170
+
2171
+ return `${errorString}\n at ${structuredStackTrace.join('\n at ')}`
2172
+ }
2173
+
1907
2174
  addHook({
1908
2175
  name: 'jest-runtime',
1909
2176
  versions: [MINIMUM_JEST_VERSION],
1910
2177
  }, (runtimePackage) => {
1911
2178
  const Runtime = runtimePackage.default ?? runtimePackage
1912
2179
 
1913
- shimmer.wrap(Runtime.prototype, '_createJestObjectFor', _createJestObjectFor => function (from) {
1914
- const result = _createJestObjectFor.apply(this, arguments)
1915
- const suiteFilePath = this._testPath || from
2180
+ if (typeof Runtime.prototype._createJestObjectFor === 'function') {
2181
+ shimmer.wrap(Runtime.prototype, '_createJestObjectFor', _createJestObjectFor => function (from) {
2182
+ const result = _createJestObjectFor.apply(this, arguments)
2183
+ const suiteFilePath = this._testPath || from
1916
2184
 
1917
- // Store the jest object so we can access it later for resetting mock state
1918
- if (suiteFilePath) {
1919
- testSuiteJestObjects.set(suiteFilePath, result)
1920
- }
2185
+ wrapJestObject(result, suiteFilePath)
2186
+ return result
2187
+ })
2188
+ }
1921
2189
 
1922
- shimmer.wrap(result, 'mock', mock => function (moduleName) {
1923
- // If the library is mocked with `jest.mock`, we don't want to bypass jest's own require engine
1924
- if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
1925
- LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.delete(moduleName)
1926
- }
1927
- if (suiteFilePath) {
1928
- const existingMockedFiles = testSuiteMockedFiles.get(suiteFilePath) || []
1929
- const suiteDir = path.dirname(suiteFilePath)
1930
- const mockPath = path.resolve(suiteDir, moduleName)
1931
- existingMockedFiles.push(mockPath)
1932
- testSuiteMockedFiles.set(suiteFilePath, existingMockedFiles)
2190
+ shimmer.wrap(Runtime.prototype, 'requireModule', requireModule => function (from, moduleName) {
2191
+ wrapJestGlobalsForRuntime(this)
2192
+ try {
2193
+ return requireModule.apply(this, arguments)
2194
+ } catch (error) {
2195
+ if (isBetweenTestsReferenceError(error)) {
2196
+ reportBetweenTestsReferenceError(this, moduleName, error.message)
1933
2197
  }
1934
- return mock.apply(this, arguments)
1935
- })
1936
- return result
2198
+ throw error
2199
+ }
1937
2200
  })
1938
2201
 
1939
2202
  shimmer.wrap(Runtime.prototype, 'requireModuleOrMock', requireModuleOrMock => function (from, moduleName) {
2203
+ wrapJestGlobalsForRuntime(this)
1940
2204
  // `requireModuleOrMock` may log errors to the console. If we don't remove ourselves
1941
2205
  // from the stack trace, the user might see a useless stack trace rather than the error
1942
2206
  // that `jest` tries to show.
@@ -1945,32 +2209,33 @@ addHook({
1945
2209
  const filteredStackTrace = structuredStackTrace
1946
2210
  .filter(callSite => !callSite.getFileName()?.includes('datadog-instrumentations/src/jest.js'))
1947
2211
 
1948
- return originalPrepareStackTrace(error, filteredStackTrace)
2212
+ if (typeof originalPrepareStackTrace === 'function') {
2213
+ return originalPrepareStackTrace(error, filteredStackTrace)
2214
+ }
2215
+ return formatDefaultStackTrace(error, filteredStackTrace)
1949
2216
  }
1950
2217
  try {
1951
2218
  // TODO: do this for every library that we instrument
1952
2219
  if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
1953
2220
  // To bypass jest's own require engine
1954
- return this._requireCoreModule(moduleName)
2221
+ return requireOutsideJestRequireEngine(this, moduleName)
1955
2222
  }
1956
2223
  // This means that `@fast-check/jest` is used in the test file.
1957
- if (moduleName === '@fast-check/jest') {
1958
- testSuiteAbsolutePathsWithFastCheck.add(this._testPath)
2224
+ recordFastCheckUsage(this, from, moduleName)
2225
+ let returnedValue
2226
+ try {
2227
+ returnedValue = requireModuleOrMock.apply(this, arguments)
2228
+ } catch (error) {
2229
+ if (isBetweenTestsReferenceError(error)) {
2230
+ reportBetweenTestsReferenceError(this, moduleName, error.message)
2231
+ }
2232
+ throw error
1959
2233
  }
1960
- const returnedValue = requireModuleOrMock.apply(this, arguments)
1961
2234
  if (process.exitCode === 1) {
1962
- if (this.loggedReferenceErrors?.size > 0) {
1963
- const errorMessage = [...this.loggedReferenceErrors][0]
1964
- testSuiteErrorCh.publish({
1965
- errorMessage,
1966
- testSuiteAbsolutePath: this._testPath,
1967
- })
1968
- } else {
1969
- testSuiteErrorCh.publish({
1970
- errorMessage: 'An error occurred while importing a module',
1971
- testSuiteAbsolutePath: this._testPath,
1972
- })
1973
- }
2235
+ publishRuntimeReferenceError(
2236
+ this,
2237
+ getLastLoggedReferenceError(this) || 'An error occurred while importing a module'
2238
+ )
1974
2239
  }
1975
2240
  return returnedValue
1976
2241
  } finally {
@@ -1979,6 +2244,27 @@ addHook({
1979
2244
  }
1980
2245
  })
1981
2246
 
2247
+ if (Runtime.prototype._logFormattedReferenceError) {
2248
+ shimmer.wrap(Runtime.prototype, '_logFormattedReferenceError', logFormattedReferenceError => function () {
2249
+ // eslint-disable-next-line no-console
2250
+ const originalConsoleError = console.error
2251
+ let loggedReferenceError
2252
+ // eslint-disable-next-line no-console
2253
+ console.error = function () {
2254
+ loggedReferenceError = arguments[0]
2255
+ return originalConsoleError.apply(this, arguments)
2256
+ }
2257
+ try {
2258
+ const result = logFormattedReferenceError.apply(this, arguments)
2259
+ publishRuntimeReferenceError(this, getLastLoggedReferenceError(this) || loggedReferenceError)
2260
+ return result
2261
+ } finally {
2262
+ // eslint-disable-next-line no-console
2263
+ console.error = originalConsoleError
2264
+ }
2265
+ })
2266
+ }
2267
+
1982
2268
  return runtimePackage
1983
2269
  })
1984
2270
 
@@ -2065,11 +2351,23 @@ function wrapWorkerChannel (worker) {
2065
2351
  shimmer.wrap(workerChannel, worker._child ? 'send' : 'postMessage', sendWrapper)
2066
2352
  }
2067
2353
 
2354
+ function wrapWorkerInitializer (worker) {
2355
+ if (wrappedWorkerInitializers.has(worker) || typeof worker.initialize !== 'function') return
2356
+
2357
+ wrappedWorkerInitializers.add(worker)
2358
+ shimmer.wrap(worker, 'initialize', initialize => function () {
2359
+ const result = initialize.apply(this, arguments)
2360
+ wrapWorkerChannel(this)
2361
+ return result
2362
+ })
2363
+ }
2364
+
2068
2365
  function wrapWorker (worker) {
2069
2366
  // ChildProcessWorker uses _child (child_process), ExperimentalWorker uses _worker (worker_threads)
2070
2367
  const workerChannel = worker._child || worker._worker
2071
2368
  if (!workerChannel) return
2072
2369
 
2370
+ wrapWorkerInitializer(worker)
2073
2371
  wrapWorkerChannel(worker)
2074
2372
  shimmer.wrap(worker, '_onMessage', onMessageWrapper)
2075
2373
  workerChannel.removeAllListeners('message')