dd-trace 5.101.0 → 5.103.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/ext/exporters.js +1 -0
- package/package.json +20 -17
- package/packages/datadog-esbuild/src/utils.js +2 -2
- package/packages/datadog-instrumentations/src/aerospike.js +2 -2
- package/packages/datadog-instrumentations/src/ai.js +9 -9
- package/packages/datadog-instrumentations/src/amqplib.js +6 -7
- package/packages/datadog-instrumentations/src/anthropic.js +10 -10
- package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
- package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
- package/packages/datadog-instrumentations/src/avsc.js +6 -6
- package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
- package/packages/datadog-instrumentations/src/bluebird.js +2 -2
- package/packages/datadog-instrumentations/src/body-parser.js +2 -2
- package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
- package/packages/datadog-instrumentations/src/child_process.js +12 -12
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +41 -24
- package/packages/datadog-instrumentations/src/connect.js +7 -7
- package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
- package/packages/datadog-instrumentations/src/cookie.js +2 -2
- package/packages/datadog-instrumentations/src/couchbase.js +73 -238
- package/packages/datadog-instrumentations/src/crypto.js +4 -4
- package/packages/datadog-instrumentations/src/cucumber.js +78 -17
- package/packages/datadog-instrumentations/src/dns.js +0 -3
- package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
- package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
- package/packages/datadog-instrumentations/src/electron.js +240 -0
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
- package/packages/datadog-instrumentations/src/express-session.js +4 -4
- package/packages/datadog-instrumentations/src/express.js +10 -11
- package/packages/datadog-instrumentations/src/fastify.js +2 -2
- package/packages/datadog-instrumentations/src/fetch.js +5 -5
- package/packages/datadog-instrumentations/src/fs.js +14 -14
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
- package/packages/datadog-instrumentations/src/google-genai.js +4 -4
- package/packages/datadog-instrumentations/src/graphql.js +13 -12
- package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
- package/packages/datadog-instrumentations/src/hapi.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +9 -9
- package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/kafka.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
- package/packages/datadog-instrumentations/src/hono.js +2 -2
- package/packages/datadog-instrumentations/src/http/client.js +6 -6
- package/packages/datadog-instrumentations/src/http/server.js +9 -9
- package/packages/datadog-instrumentations/src/ioredis.js +16 -12
- package/packages/datadog-instrumentations/src/jest.js +382 -81
- package/packages/datadog-instrumentations/src/kafkajs.js +165 -174
- package/packages/datadog-instrumentations/src/knex.js +17 -17
- package/packages/datadog-instrumentations/src/koa.js +12 -12
- package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
- package/packages/datadog-instrumentations/src/lodash.js +4 -4
- package/packages/datadog-instrumentations/src/mariadb.js +13 -13
- package/packages/datadog-instrumentations/src/memcached.js +2 -2
- package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +3 -3
- package/packages/datadog-instrumentations/src/mocha/main.js +85 -11
- package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
- package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
- package/packages/datadog-instrumentations/src/mongodb-core.js +42 -30
- package/packages/datadog-instrumentations/src/mongodb.js +5 -5
- package/packages/datadog-instrumentations/src/mongoose.js +21 -21
- package/packages/datadog-instrumentations/src/mquery.js +5 -5
- package/packages/datadog-instrumentations/src/multer.js +4 -4
- package/packages/datadog-instrumentations/src/mysql.js +16 -16
- package/packages/datadog-instrumentations/src/mysql2.js +4 -4
- package/packages/datadog-instrumentations/src/net.js +14 -8
- package/packages/datadog-instrumentations/src/nyc.js +5 -5
- package/packages/datadog-instrumentations/src/openai.js +19 -19
- package/packages/datadog-instrumentations/src/oracledb.js +6 -6
- package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
- package/packages/datadog-instrumentations/src/pg.js +39 -25
- package/packages/datadog-instrumentations/src/pino.js +6 -10
- package/packages/datadog-instrumentations/src/playwright.js +445 -68
- package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
- package/packages/datadog-instrumentations/src/redis.js +20 -12
- package/packages/datadog-instrumentations/src/restify.js +2 -2
- package/packages/datadog-instrumentations/src/router.js +12 -12
- package/packages/datadog-instrumentations/src/stripe.js +12 -12
- package/packages/datadog-instrumentations/src/vitest.js +107 -26
- package/packages/datadog-instrumentations/src/winston.js +4 -4
- package/packages/datadog-instrumentations/src/ws.js +7 -7
- package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
- package/packages/datadog-plugin-aws-sdk/src/base.js +70 -28
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +20 -13
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +46 -36
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +34 -23
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +14 -15
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +74 -55
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +20 -18
- package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
- package/packages/datadog-plugin-couchbase/src/index.js +58 -52
- package/packages/datadog-plugin-cucumber/src/index.js +5 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +215 -26
- package/packages/datadog-plugin-cypress/src/support.js +13 -1
- package/packages/datadog-plugin-electron/src/index.js +17 -0
- package/packages/datadog-plugin-electron/src/ipc.js +143 -0
- package/packages/datadog-plugin-electron/src/net.js +82 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
- package/packages/datadog-plugin-graphql/src/execute.js +6 -28
- package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
- package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
- package/packages/datadog-plugin-graphql/src/utils.js +29 -0
- package/packages/datadog-plugin-grpc/src/client.js +6 -7
- package/packages/datadog-plugin-grpc/src/util.js +57 -22
- package/packages/datadog-plugin-http/src/client.js +3 -7
- package/packages/datadog-plugin-jest/src/index.js +92 -50
- package/packages/datadog-plugin-jest/src/util.js +1 -2
- package/packages/datadog-plugin-mocha/src/index.js +5 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +36 -69
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/services.js +2 -1
- package/packages/datadog-plugin-openai/src/tracing.js +12 -23
- package/packages/datadog-plugin-pg/src/index.js +3 -3
- package/packages/datadog-plugin-playwright/src/index.js +5 -1
- package/packages/datadog-plugin-redis/src/index.js +18 -23
- package/packages/datadog-plugin-vitest/src/index.js +8 -1
- package/packages/datadog-shimmer/src/shimmer.js +7 -1
- package/packages/dd-trace/src/aiguard/index.js +3 -1
- package/packages/dd-trace/src/aiguard/sdk.js +36 -30
- package/packages/dd-trace/src/aiguard/tags.js +20 -11
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +4 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +21 -24
- package/packages/dd-trace/src/appsec/reporter.js +3 -1
- package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
- package/packages/dd-trace/src/azure_metadata.js +17 -6
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
- package/packages/dd-trace/src/config/defaults.js +3 -14
- package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -1
- package/packages/dd-trace/src/config/git_properties.js +2 -2
- package/packages/dd-trace/src/config/helper.js +4 -0
- package/packages/dd-trace/src/config/index.js +2 -2
- package/packages/dd-trace/src/config/major-overrides.js +98 -0
- package/packages/dd-trace/src/config/parsers.js +7 -1
- package/packages/dd-trace/src/config/supported-configurations.json +51 -38
- package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
- package/packages/dd-trace/src/datastreams/index.js +2 -1
- package/packages/dd-trace/src/datastreams/manager.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
- package/packages/dd-trace/src/debugger/index.js +7 -7
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +748 -232
- package/packages/dd-trace/src/encode/0.5.js +47 -10
- package/packages/dd-trace/src/encode/agentless-json.js +1 -1
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
- package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/electron/index.js +49 -0
- package/packages/dd-trace/src/external-logger/src/index.js +2 -1
- package/packages/dd-trace/src/git_metadata.js +10 -8
- package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
- package/packages/dd-trace/src/lambda/index.js +62 -14
- package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
- package/packages/dd-trace/src/llmobs/index.js +13 -2
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +6 -3
- package/packages/dd-trace/src/llmobs/sdk.js +24 -26
- package/packages/dd-trace/src/llmobs/span_processor.js +25 -5
- package/packages/dd-trace/src/llmobs/util.js +1 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
- package/packages/dd-trace/src/msgpack/chunk.js +6 -3
- package/packages/dd-trace/src/openfeature/noop.js +40 -36
- package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
- package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
- package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +49 -4
- package/packages/dd-trace/src/plugins/database.js +54 -12
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +2 -4
- package/packages/dd-trace/src/plugins/util/ci.js +9 -9
- package/packages/dd-trace/src/plugins/util/git-cache.js +23 -23
- package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
- package/packages/dd-trace/src/plugins/util/test.js +56 -12
- package/packages/dd-trace/src/plugins/util/url.js +1 -3
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +18 -16
- package/packages/dd-trace/src/plugins/util/web.js +5 -7
- package/packages/dd-trace/src/priority_sampler.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
- package/packages/dd-trace/src/profiling/profilers/wall.js +5 -6
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
- package/packages/dd-trace/src/rate_limiter.js +1 -1
- package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
- package/packages/dd-trace/src/ritm.js +2 -1
- package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
- package/packages/dd-trace/src/scope.js +3 -10
- package/packages/dd-trace/src/serverless.js +6 -6
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +27 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/span_stats.js +1 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
- package/packages/dd-trace/src/tracer.js +7 -7
- package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
|
@@ -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,
|
|
@@ -26,13 +29,13 @@ const {
|
|
|
26
29
|
recordAttemptToFixExecution,
|
|
27
30
|
logAttemptToFixTestExecution,
|
|
28
31
|
logTestOptimizationSummary,
|
|
32
|
+
getEfdRetryCount,
|
|
29
33
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
30
34
|
const {
|
|
31
35
|
SEED_SUFFIX_RE,
|
|
32
36
|
getFormattedJestTestParameters,
|
|
33
37
|
getJestTestName,
|
|
34
38
|
getJestSuitesToRun,
|
|
35
|
-
getEfdRetryCount,
|
|
36
39
|
} = require('../../datadog-plugin-jest/src/util')
|
|
37
40
|
const { addHook, channel } = require('./helpers/instrument')
|
|
38
41
|
|
|
@@ -74,6 +77,7 @@ const CHILD_MESSAGE_CALL = 1
|
|
|
74
77
|
|
|
75
78
|
// Maximum time we'll wait for the tracer to flush
|
|
76
79
|
const FLUSH_TIMEOUT = 10_000
|
|
80
|
+
const isJestWorker = !!getEnvironmentVariable('JEST_WORKER_ID')
|
|
77
81
|
|
|
78
82
|
// https://github.com/jestjs/jest/blob/41f842a46bb2691f828c3a5f27fc1d6290495b82/packages/jest-circus/src/types.ts#L9C8-L9C54
|
|
79
83
|
const RETRY_TIMES = Symbol.for('RETRY_TIMES')
|
|
@@ -101,6 +105,8 @@ let testManagementTests = {}
|
|
|
101
105
|
let testManagementAttemptToFixRetries = 0
|
|
102
106
|
let isImpactedTestsEnabled = false
|
|
103
107
|
let modifiedFiles = {}
|
|
108
|
+
let activeTestSuiteAbsolutePath
|
|
109
|
+
let isConsoleErrorWrapped = false
|
|
104
110
|
|
|
105
111
|
const testContexts = new WeakMap()
|
|
106
112
|
const originalTestFns = new WeakMap()
|
|
@@ -124,7 +130,12 @@ const efdNewTestCandidates = new Set()
|
|
|
124
130
|
// Tests that are genuinely new (not in known tests list).
|
|
125
131
|
const newTests = new Set()
|
|
126
132
|
const testSuiteAbsolutePathsWithFastCheck = new Set()
|
|
133
|
+
const testSuiteFastCheckUsage = new Map()
|
|
127
134
|
const testSuiteJestObjects = new Map()
|
|
135
|
+
const wrappedJestGlobals = new WeakSet()
|
|
136
|
+
const wrappedJestObjects = new WeakSet()
|
|
137
|
+
const wrappedWorkerInitializers = new WeakSet()
|
|
138
|
+
const publishedRuntimeReferenceErrors = new WeakMap()
|
|
128
139
|
|
|
129
140
|
const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
|
|
130
141
|
const ATR_RETRY_SUPPRESSION_FLAG = '_ddDisableAtrRetry'
|
|
@@ -303,6 +314,26 @@ function getAttemptToFixExecutionsFromJestResults (result) {
|
|
|
303
314
|
return executions
|
|
304
315
|
}
|
|
305
316
|
|
|
317
|
+
function wrapConsoleErrorForJestReferenceErrors () {
|
|
318
|
+
if (isConsoleErrorWrapped) return
|
|
319
|
+
|
|
320
|
+
isConsoleErrorWrapped = true
|
|
321
|
+
// eslint-disable-next-line no-console
|
|
322
|
+
const originalConsoleError = console.error
|
|
323
|
+
// eslint-disable-next-line no-console
|
|
324
|
+
console.error = function () {
|
|
325
|
+
const [message] = arguments
|
|
326
|
+
if (
|
|
327
|
+
typeof message === 'string' &&
|
|
328
|
+
message.includes('Jest environment has been torn down') &&
|
|
329
|
+
activeTestSuiteAbsolutePath
|
|
330
|
+
) {
|
|
331
|
+
publishRuntimeReferenceError({ _testPath: activeTestSuiteAbsolutePath }, message)
|
|
332
|
+
}
|
|
333
|
+
return originalConsoleError.apply(this, arguments)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
306
337
|
function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
307
338
|
return class DatadogEnvironment extends BaseEnvironment {
|
|
308
339
|
constructor (config, context) {
|
|
@@ -314,6 +345,9 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
314
345
|
this.global._ddtrace = global._ddtrace
|
|
315
346
|
this.hasSnapshotTests = undefined
|
|
316
347
|
this.testSuiteAbsolutePath = context.testPath
|
|
348
|
+
activeTestSuiteAbsolutePath = this.testSuiteAbsolutePath
|
|
349
|
+
wrapConsoleErrorForJestReferenceErrors()
|
|
350
|
+
this.globalConfig = config.globalConfig
|
|
317
351
|
|
|
318
352
|
this.displayName = config.projectConfig?.displayName?.name || config.displayName
|
|
319
353
|
this.testEnvironmentOptions = getTestEnvironmentOptions(config)
|
|
@@ -423,6 +457,10 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
423
457
|
*/
|
|
424
458
|
resetMockState () {
|
|
425
459
|
try {
|
|
460
|
+
if (this.moduleMocker?.clearAllMocks) {
|
|
461
|
+
this.moduleMocker.clearAllMocks()
|
|
462
|
+
return
|
|
463
|
+
}
|
|
426
464
|
const jestObject = testSuiteJestObjects.get(this.testSuiteAbsolutePath)
|
|
427
465
|
if (jestObject?.clearAllMocks) {
|
|
428
466
|
jestObject.clearAllMocks()
|
|
@@ -504,7 +542,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
504
542
|
}
|
|
505
543
|
|
|
506
544
|
getShouldStripSeedFromTestName () {
|
|
507
|
-
return
|
|
545
|
+
return doesTestSuiteUseFastCheck(this.testSuiteAbsolutePath)
|
|
508
546
|
}
|
|
509
547
|
|
|
510
548
|
// At the `add_test` event we don't have the test object yet, so we can't use it
|
|
@@ -521,13 +559,13 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
521
559
|
const setNameToParams = (name, params) => { this.nameToParams[name] = [...params] }
|
|
522
560
|
|
|
523
561
|
if (event.name === 'setup' && this.global.test) {
|
|
524
|
-
shimmer.wrap(this.global.test, 'each', each => function () {
|
|
525
|
-
const testParameters = getFormattedJestTestParameters(
|
|
526
|
-
const eachBind = each.apply(this,
|
|
527
|
-
return function () {
|
|
528
|
-
const [testName] =
|
|
562
|
+
shimmer.wrap(this.global.test, 'each', each => function (...args) {
|
|
563
|
+
const testParameters = getFormattedJestTestParameters(args)
|
|
564
|
+
const eachBind = each.apply(this, args)
|
|
565
|
+
return function (...args) {
|
|
566
|
+
const [testName] = args
|
|
529
567
|
setNameToParams(testName, testParameters)
|
|
530
|
-
return eachBind.apply(this,
|
|
568
|
+
return eachBind.apply(this, args)
|
|
531
569
|
}
|
|
532
570
|
})
|
|
533
571
|
}
|
|
@@ -624,16 +662,16 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
624
662
|
} else {
|
|
625
663
|
originalHookFns.set(hook, hookFn)
|
|
626
664
|
}
|
|
627
|
-
const newHookFn = shimmer.wrapFunction(hookFn, hookFn => function () {
|
|
628
|
-
return testFnCh.runStores(ctx, () => hookFn.apply(this,
|
|
665
|
+
const newHookFn = shimmer.wrapFunction(hookFn, hookFn => function (...args) {
|
|
666
|
+
return testFnCh.runStores(ctx, () => hookFn.apply(this, args))
|
|
629
667
|
})
|
|
630
668
|
hook.fn = newHookFn
|
|
631
669
|
}
|
|
632
670
|
const originalFn = event.test.fn
|
|
633
671
|
originalTestFns.set(event.test, originalFn)
|
|
634
672
|
|
|
635
|
-
const newFn = shimmer.wrapFunction(event.test.fn, testFn => function () {
|
|
636
|
-
return testFnCh.runStores(ctx, () => testFn.apply(this,
|
|
673
|
+
const newFn = shimmer.wrapFunction(event.test.fn, testFn => function (...args) {
|
|
674
|
+
return testFnCh.runStores(ctx, () => testFn.apply(this, args))
|
|
637
675
|
})
|
|
638
676
|
|
|
639
677
|
event.test.fn = newFn
|
|
@@ -648,8 +686,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
648
686
|
} else {
|
|
649
687
|
originalHookFns.set(event.hook, hookFn)
|
|
650
688
|
}
|
|
651
|
-
event.hook.fn = shimmer.wrapFunction(hookFn, hookFn => function () {
|
|
652
|
-
return testSuiteHookFnCh.runStores(ctx, () => hookFn.apply(this,
|
|
689
|
+
event.hook.fn = shimmer.wrapFunction(hookFn, hookFn => function (...args) {
|
|
690
|
+
return testSuiteHookFnCh.runStores(ctx, () => hookFn.apply(this, args))
|
|
653
691
|
})
|
|
654
692
|
}
|
|
655
693
|
|
|
@@ -843,8 +881,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
843
881
|
const willBeRetriedByFailedTestReplay = numRetries > 0 && numTestExecutions - 1 < numRetries
|
|
844
882
|
const mightHitBreakpoint = this.isDiEnabled && numTestExecutions >= 2
|
|
845
883
|
|
|
846
|
-
// For quarantined tests,
|
|
847
|
-
//
|
|
884
|
+
// For quarantined tests, track failures so the session can be marked as passing later,
|
|
885
|
+
// and suppress errors so Jest does not mark the test suite as failing.
|
|
848
886
|
// The actual status ('fail') is already captured above for dd-trace reporting.
|
|
849
887
|
// Only suppress on the final execution — not when ATR/EFD/ATF will retry the test.
|
|
850
888
|
if (!event.test?.[ATR_RETRY_SUPPRESSION_FLAG] && !willBeRetriedByFailedTestReplay) {
|
|
@@ -1055,7 +1093,19 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
1055
1093
|
}
|
|
1056
1094
|
}
|
|
1057
1095
|
}
|
|
1058
|
-
|
|
1096
|
+
const clearActiveTestSuite = () => {
|
|
1097
|
+
realSetTimeout(() => {
|
|
1098
|
+
if (activeTestSuiteAbsolutePath === this.testSuiteAbsolutePath) {
|
|
1099
|
+
activeTestSuiteAbsolutePath = undefined
|
|
1100
|
+
}
|
|
1101
|
+
}, 0)
|
|
1102
|
+
}
|
|
1103
|
+
const result = super.teardown()
|
|
1104
|
+
if (result?.then) {
|
|
1105
|
+
return result.finally(clearActiveTestSuite)
|
|
1106
|
+
}
|
|
1107
|
+
clearActiveTestSuite()
|
|
1108
|
+
return result
|
|
1059
1109
|
}
|
|
1060
1110
|
}
|
|
1061
1111
|
}
|
|
@@ -1492,7 +1542,8 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1492
1542
|
const timeoutPromise = new Promise((resolve) => {
|
|
1493
1543
|
timeoutId = realSetTimeout(() => {
|
|
1494
1544
|
resolve('timeout')
|
|
1495
|
-
}, FLUSH_TIMEOUT)
|
|
1545
|
+
}, FLUSH_TIMEOUT)
|
|
1546
|
+
timeoutId.unref?.()
|
|
1496
1547
|
})
|
|
1497
1548
|
|
|
1498
1549
|
testSessionFinishCh.publish({
|
|
@@ -1544,19 +1595,46 @@ function coverageReporterWrapper (coverageReporter) {
|
|
|
1544
1595
|
* in which case we'll leave it.
|
|
1545
1596
|
*/
|
|
1546
1597
|
// `_addUntestedFiles` is an async function
|
|
1547
|
-
shimmer.wrap(CoverageReporter.prototype, '_addUntestedFiles', addUntestedFiles => function () {
|
|
1598
|
+
shimmer.wrap(CoverageReporter.prototype, '_addUntestedFiles', addUntestedFiles => function (...args) {
|
|
1548
1599
|
if (DD_TEST_TIA_KEEP_COV_CONFIG) {
|
|
1549
|
-
return addUntestedFiles.apply(this,
|
|
1600
|
+
return addUntestedFiles.apply(this, args)
|
|
1550
1601
|
}
|
|
1551
1602
|
if (isCodeCoverageEnabledBecauseOfUs) {
|
|
1552
1603
|
return Promise.resolve()
|
|
1553
1604
|
}
|
|
1554
|
-
return addUntestedFiles.apply(this,
|
|
1605
|
+
return addUntestedFiles.apply(this, args)
|
|
1555
1606
|
})
|
|
1556
1607
|
|
|
1557
1608
|
return coverageReporter
|
|
1558
1609
|
}
|
|
1559
1610
|
|
|
1611
|
+
function shouldWaitForTestSuiteFinish (environment) {
|
|
1612
|
+
return isJestWorker && environment.globalConfig?.workerIdleMemoryLimit !== undefined
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
function publishTestSuiteFinish (payload, waitForFinish) {
|
|
1616
|
+
if (!testSuiteFinishCh.hasSubscribers) return
|
|
1617
|
+
|
|
1618
|
+
if (!waitForFinish) {
|
|
1619
|
+
testSuiteFinishCh.publish(payload)
|
|
1620
|
+
return
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
return new Promise(resolve => {
|
|
1624
|
+
testSuiteFinishCh.publish({
|
|
1625
|
+
...payload,
|
|
1626
|
+
waitForFinish,
|
|
1627
|
+
onDone: resolve,
|
|
1628
|
+
})
|
|
1629
|
+
})
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
function cleanupTestSuiteState (testSuiteAbsolutePath) {
|
|
1633
|
+
testSuiteMockedFiles.delete(testSuiteAbsolutePath)
|
|
1634
|
+
testSuiteFastCheckUsage.delete(testSuiteAbsolutePath)
|
|
1635
|
+
testSuiteJestObjects.delete(testSuiteAbsolutePath)
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1560
1638
|
addHook({
|
|
1561
1639
|
name: '@jest/core',
|
|
1562
1640
|
file: 'build/TestScheduler.js',
|
|
@@ -1594,8 +1672,8 @@ addHook({
|
|
|
1594
1672
|
name: '@jest/test-sequencer',
|
|
1595
1673
|
versions: ['>=28'],
|
|
1596
1674
|
}, (sequencerPackage, frameworkVersion) => {
|
|
1597
|
-
shimmer.wrap(sequencerPackage.default.prototype, 'shard', shard => function () {
|
|
1598
|
-
const shardedTests = shard.apply(this,
|
|
1675
|
+
shimmer.wrap(sequencerPackage.default.prototype, 'shard', shard => function (...args) {
|
|
1676
|
+
const shardedTests = shard.apply(this, args)
|
|
1599
1677
|
|
|
1600
1678
|
if (!shardedTests.length || !isSuitesSkippingEnabled || !skippableSuites.length) {
|
|
1601
1679
|
return shardedTests
|
|
@@ -1642,10 +1720,10 @@ addHook({
|
|
|
1642
1720
|
|
|
1643
1721
|
function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
1644
1722
|
const adapter = jestAdapter.default ?? jestAdapter
|
|
1645
|
-
const newAdapter = shimmer.wrapFunction(adapter, adapter => function () {
|
|
1646
|
-
const environment =
|
|
1723
|
+
const newAdapter = shimmer.wrapFunction(adapter, adapter => function (...args) {
|
|
1724
|
+
const environment = args[2]
|
|
1647
1725
|
if (!environment || !environment.testEnvironmentOptions) {
|
|
1648
|
-
return adapter.apply(this,
|
|
1726
|
+
return adapter.apply(this, args)
|
|
1649
1727
|
}
|
|
1650
1728
|
testSuiteStartCh.publish({
|
|
1651
1729
|
testSuite: environment.testSuite,
|
|
@@ -1655,7 +1733,7 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
1655
1733
|
frameworkVersion: jestVersion,
|
|
1656
1734
|
testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
|
|
1657
1735
|
})
|
|
1658
|
-
return adapter.apply(this,
|
|
1736
|
+
return adapter.apply(this, args).then(suiteResults => {
|
|
1659
1737
|
const { numFailingTests, skipped, failureMessage: errorMessage } = suiteResults
|
|
1660
1738
|
let status = 'pass'
|
|
1661
1739
|
if (skipped) {
|
|
@@ -1675,7 +1753,7 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
1675
1753
|
const getFilesWithPath = (files) => files.map(file => getTestSuitePath(file, root))
|
|
1676
1754
|
|
|
1677
1755
|
const coverageFiles = getFilesWithPath(getCoveredFilenamesFromCoverage(environment.global.__coverage__))
|
|
1678
|
-
const mockedFiles = getFilesWithPath(
|
|
1756
|
+
const mockedFiles = getFilesWithPath(getMockedFiles(environment.testSuiteAbsolutePath))
|
|
1679
1757
|
|
|
1680
1758
|
testSuiteCodeCoverageCh.publish({
|
|
1681
1759
|
coverageFiles,
|
|
@@ -1684,19 +1762,51 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
1684
1762
|
testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
|
|
1685
1763
|
})
|
|
1686
1764
|
}
|
|
1687
|
-
|
|
1765
|
+
const waitForFinish = shouldWaitForTestSuiteFinish(environment)
|
|
1766
|
+
const finishPayload = {
|
|
1767
|
+
status,
|
|
1768
|
+
errorMessage,
|
|
1769
|
+
testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
|
|
1770
|
+
}
|
|
1771
|
+
if (waitForFinish) {
|
|
1772
|
+
const finishPromise = publishTestSuiteFinish(finishPayload, waitForFinish)
|
|
1773
|
+
if (finishPromise) {
|
|
1774
|
+
return finishPromise.then(() => {
|
|
1775
|
+
// Cleanup per-suite state to avoid memory leaks
|
|
1776
|
+
cleanupTestSuiteState(environment.testSuiteAbsolutePath)
|
|
1777
|
+
|
|
1778
|
+
return suiteResults
|
|
1779
|
+
})
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
publishTestSuiteFinish(finishPayload, waitForFinish)
|
|
1688
1783
|
|
|
1689
1784
|
// Cleanup per-suite state to avoid memory leaks
|
|
1690
|
-
|
|
1691
|
-
testSuiteJestObjects.delete(environment.testSuiteAbsolutePath)
|
|
1785
|
+
cleanupTestSuiteState(environment.testSuiteAbsolutePath)
|
|
1692
1786
|
|
|
1693
1787
|
return suiteResults
|
|
1694
1788
|
}).catch(error => {
|
|
1695
|
-
|
|
1789
|
+
const waitForFinish = shouldWaitForTestSuiteFinish(environment)
|
|
1790
|
+
const finishPayload = {
|
|
1791
|
+
status: 'fail',
|
|
1792
|
+
error,
|
|
1793
|
+
testSuiteAbsolutePath: environment.testSuiteAbsolutePath,
|
|
1794
|
+
}
|
|
1795
|
+
if (waitForFinish) {
|
|
1796
|
+
const finishPromise = publishTestSuiteFinish(finishPayload, waitForFinish)
|
|
1797
|
+
if (finishPromise) {
|
|
1798
|
+
return finishPromise.then(() => {
|
|
1799
|
+
// Cleanup per-suite state to avoid memory leaks
|
|
1800
|
+
cleanupTestSuiteState(environment.testSuiteAbsolutePath)
|
|
1801
|
+
|
|
1802
|
+
throw error
|
|
1803
|
+
})
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
publishTestSuiteFinish(finishPayload, waitForFinish)
|
|
1696
1807
|
|
|
1697
1808
|
// Cleanup per-suite state to avoid memory leaks
|
|
1698
|
-
|
|
1699
|
-
testSuiteJestObjects.delete(environment.testSuiteAbsolutePath)
|
|
1809
|
+
cleanupTestSuiteState(environment.testSuiteAbsolutePath)
|
|
1700
1810
|
|
|
1701
1811
|
throw error
|
|
1702
1812
|
})
|
|
@@ -1773,8 +1883,8 @@ function jestConfigAsyncWrapper (jestConfig) {
|
|
|
1773
1883
|
}
|
|
1774
1884
|
|
|
1775
1885
|
function jestConfigSyncWrapper (jestConfig) {
|
|
1776
|
-
return shimmer.wrap(jestConfig, 'readConfigs', readConfigs => function () {
|
|
1777
|
-
const readConfigsResult = readConfigs.apply(this,
|
|
1886
|
+
return shimmer.wrap(jestConfig, 'readConfigs', readConfigs => function (...args) {
|
|
1887
|
+
const readConfigsResult = readConfigs.apply(this, args)
|
|
1778
1888
|
configureTestEnvironment(readConfigsResult)
|
|
1779
1889
|
return readConfigsResult
|
|
1780
1890
|
})
|
|
@@ -1794,6 +1904,7 @@ const DD_TEST_ENVIRONMENT_OPTION_KEYS = [
|
|
|
1794
1904
|
'_ddRepositoryRoot',
|
|
1795
1905
|
'_ddIsFlakyTestRetriesEnabled',
|
|
1796
1906
|
'_ddFlakyTestRetriesCount',
|
|
1907
|
+
'_ddItrSkippingEnabledTags',
|
|
1797
1908
|
'_ddIsDiEnabled',
|
|
1798
1909
|
'_ddIsKnownTestsEnabled',
|
|
1799
1910
|
'_ddIsTestManagementTestsEnabled',
|
|
@@ -1904,39 +2015,195 @@ const LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE = new Set([
|
|
|
1904
2015
|
'winston',
|
|
1905
2016
|
])
|
|
1906
2017
|
|
|
2018
|
+
function recordMockedFile (suiteFilePath, moduleName) {
|
|
2019
|
+
if (!suiteFilePath || typeof moduleName !== 'string') return
|
|
2020
|
+
|
|
2021
|
+
const existingMockedFiles = testSuiteMockedFiles.get(suiteFilePath) || []
|
|
2022
|
+
const suiteDir = path.dirname(suiteFilePath)
|
|
2023
|
+
const mockPath = path.resolve(suiteDir, moduleName)
|
|
2024
|
+
existingMockedFiles.push(mockPath)
|
|
2025
|
+
testSuiteMockedFiles.set(suiteFilePath, existingMockedFiles)
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
const JEST_STATIC_MOCK_CALL_RE = /\bjest\.(?:mock|doMock|unstable_mockModule)\(\s*(['"`])([^'"`]+)\1/g
|
|
2029
|
+
|
|
2030
|
+
function getStaticMockedFiles (suiteFilePath) {
|
|
2031
|
+
if (!suiteFilePath) return []
|
|
2032
|
+
|
|
2033
|
+
const mockedFiles = []
|
|
2034
|
+
try {
|
|
2035
|
+
const source = readFileSync(suiteFilePath, 'utf8')
|
|
2036
|
+
let match
|
|
2037
|
+
JEST_STATIC_MOCK_CALL_RE.lastIndex = 0
|
|
2038
|
+
while ((match = JEST_STATIC_MOCK_CALL_RE.exec(source)) !== null) {
|
|
2039
|
+
mockedFiles.push(path.resolve(path.dirname(suiteFilePath), match[2]))
|
|
2040
|
+
}
|
|
2041
|
+
} catch {
|
|
2042
|
+
// ignore errors
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
return mockedFiles
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
function getMockedFiles (suiteFilePath) {
|
|
2049
|
+
const mockedFiles = testSuiteMockedFiles.get(suiteFilePath)
|
|
2050
|
+
if (mockedFiles?.length) {
|
|
2051
|
+
return mockedFiles
|
|
2052
|
+
}
|
|
2053
|
+
return getStaticMockedFiles(suiteFilePath)
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
function wrapJestObject (jestObject, suiteFilePath) {
|
|
2057
|
+
if (!jestObject || !suiteFilePath || wrappedJestObjects.has(jestObject)) return
|
|
2058
|
+
|
|
2059
|
+
testSuiteJestObjects.set(suiteFilePath, jestObject)
|
|
2060
|
+
wrappedJestObjects.add(jestObject)
|
|
2061
|
+
|
|
2062
|
+
shimmer.wrap(jestObject, 'mock', mock => function (moduleName) {
|
|
2063
|
+
// If the library is mocked with `jest.mock`, we don't want to bypass jest's own require engine
|
|
2064
|
+
if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
|
|
2065
|
+
LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.delete(moduleName)
|
|
2066
|
+
}
|
|
2067
|
+
recordMockedFile(suiteFilePath, moduleName)
|
|
2068
|
+
return mock.apply(this, arguments)
|
|
2069
|
+
})
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
function wrapJestGlobalsForRuntime (runtime) {
|
|
2073
|
+
const jestGlobals = runtime?.jestGlobals
|
|
2074
|
+
if (!jestGlobals || wrappedJestGlobals.has(jestGlobals) || typeof jestGlobals.jestObjectFor !== 'function') {
|
|
2075
|
+
return
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
wrappedJestGlobals.add(jestGlobals)
|
|
2079
|
+
shimmer.wrap(jestGlobals, 'jestObjectFor', jestObjectFor => function (from) {
|
|
2080
|
+
const jestObject = jestObjectFor.apply(this, arguments)
|
|
2081
|
+
wrapJestObject(jestObject, from)
|
|
2082
|
+
return jestObject
|
|
2083
|
+
})
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
function recordFastCheckUsage (runtime, from, moduleName) {
|
|
2087
|
+
if (moduleName !== '@fast-check/jest') return
|
|
2088
|
+
|
|
2089
|
+
if (from) {
|
|
2090
|
+
testSuiteAbsolutePathsWithFastCheck.add(from)
|
|
2091
|
+
testSuiteFastCheckUsage.set(from, true)
|
|
2092
|
+
}
|
|
2093
|
+
if (runtime?._testPath) {
|
|
2094
|
+
testSuiteAbsolutePathsWithFastCheck.add(runtime._testPath)
|
|
2095
|
+
testSuiteFastCheckUsage.set(runtime._testPath, true)
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
function doesTestSuiteUseFastCheck (testSuiteAbsolutePath) {
|
|
2100
|
+
if (!testSuiteAbsolutePath) return false
|
|
2101
|
+
if (testSuiteFastCheckUsage.has(testSuiteAbsolutePath)) {
|
|
2102
|
+
return testSuiteFastCheckUsage.get(testSuiteAbsolutePath)
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
try {
|
|
2106
|
+
const usesFastCheck = readFileSync(testSuiteAbsolutePath, 'utf8').includes('@fast-check/jest')
|
|
2107
|
+
testSuiteFastCheckUsage.set(testSuiteAbsolutePath, usesFastCheck)
|
|
2108
|
+
if (usesFastCheck) {
|
|
2109
|
+
testSuiteAbsolutePathsWithFastCheck.add(testSuiteAbsolutePath)
|
|
2110
|
+
}
|
|
2111
|
+
return usesFastCheck
|
|
2112
|
+
} catch {
|
|
2113
|
+
testSuiteFastCheckUsage.set(testSuiteAbsolutePath, false)
|
|
2114
|
+
return false
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
function getLastLoggedReferenceError (runtime) {
|
|
2119
|
+
const loggedReferenceErrors = runtime?.loggedReferenceErrors
|
|
2120
|
+
if (!loggedReferenceErrors?.size) return
|
|
2121
|
+
return [...loggedReferenceErrors].pop()
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
function publishRuntimeReferenceError (runtime, errorMessage) {
|
|
2125
|
+
if (!errorMessage || !runtime?._testPath) return
|
|
2126
|
+
|
|
2127
|
+
let publishedErrors = publishedRuntimeReferenceErrors.get(runtime)
|
|
2128
|
+
if (!publishedErrors) {
|
|
2129
|
+
publishedErrors = new Set()
|
|
2130
|
+
publishedRuntimeReferenceErrors.set(runtime, publishedErrors)
|
|
2131
|
+
}
|
|
2132
|
+
if (publishedErrors.has(errorMessage)) return
|
|
2133
|
+
|
|
2134
|
+
publishedErrors.add(errorMessage)
|
|
2135
|
+
testSuiteErrorCh.publish({
|
|
2136
|
+
errorMessage,
|
|
2137
|
+
testSuiteAbsolutePath: runtime._testPath,
|
|
2138
|
+
})
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
function isBetweenTestsReferenceError (error) {
|
|
2142
|
+
return error?.name === 'ReferenceError' &&
|
|
2143
|
+
typeof error.message === 'string' &&
|
|
2144
|
+
error.message.includes('outside of the scope of the test code')
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
function reportBetweenTestsReferenceError (runtime, moduleName, originalErrorMessage) {
|
|
2148
|
+
if (typeof moduleName !== 'string') return false
|
|
2149
|
+
|
|
2150
|
+
const fallbackErrorMessage = moduleName.startsWith('node:') || builtinModules.includes(moduleName)
|
|
2151
|
+
? 'You are trying to access a Node.js module outside of the scope of the test code.'
|
|
2152
|
+
: 'You are trying to `require` a file after the Jest environment has been torn down.'
|
|
2153
|
+
const errorMessage = originalErrorMessage || fallbackErrorMessage
|
|
2154
|
+
|
|
2155
|
+
if (typeof runtime._logFormattedReferenceError === 'function') {
|
|
2156
|
+
runtime._logFormattedReferenceError(errorMessage)
|
|
2157
|
+
}
|
|
2158
|
+
publishRuntimeReferenceError(runtime, getLastLoggedReferenceError(runtime) || errorMessage)
|
|
2159
|
+
process.exitCode = 1
|
|
2160
|
+
return true
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
function requireOutsideJestRequireEngine (runtime, moduleName) {
|
|
2164
|
+
if (typeof runtime._requireCoreModule === 'function') {
|
|
2165
|
+
return runtime._requireCoreModule(moduleName)
|
|
2166
|
+
}
|
|
2167
|
+
return require(moduleName)
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
function formatDefaultStackTrace (error, structuredStackTrace) {
|
|
2171
|
+
const errorString = Error.prototype.toString.call(error)
|
|
2172
|
+
if (structuredStackTrace.length === 0) return errorString
|
|
2173
|
+
|
|
2174
|
+
return `${errorString}\n at ${structuredStackTrace.join('\n at ')}`
|
|
2175
|
+
}
|
|
2176
|
+
|
|
1907
2177
|
addHook({
|
|
1908
2178
|
name: 'jest-runtime',
|
|
1909
2179
|
versions: [MINIMUM_JEST_VERSION],
|
|
1910
2180
|
}, (runtimePackage) => {
|
|
1911
2181
|
const Runtime = runtimePackage.default ?? runtimePackage
|
|
1912
2182
|
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
2183
|
+
if (typeof Runtime.prototype._createJestObjectFor === 'function') {
|
|
2184
|
+
shimmer.wrap(Runtime.prototype, '_createJestObjectFor', _createJestObjectFor => function (from) {
|
|
2185
|
+
const result = _createJestObjectFor.apply(this, arguments)
|
|
2186
|
+
const suiteFilePath = this._testPath || from
|
|
1916
2187
|
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
2188
|
+
wrapJestObject(result, suiteFilePath)
|
|
2189
|
+
return result
|
|
2190
|
+
})
|
|
2191
|
+
}
|
|
1921
2192
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
if (
|
|
1928
|
-
|
|
1929
|
-
const suiteDir = path.dirname(suiteFilePath)
|
|
1930
|
-
const mockPath = path.resolve(suiteDir, moduleName)
|
|
1931
|
-
existingMockedFiles.push(mockPath)
|
|
1932
|
-
testSuiteMockedFiles.set(suiteFilePath, existingMockedFiles)
|
|
2193
|
+
shimmer.wrap(Runtime.prototype, 'requireModule', requireModule => function (from, moduleName) {
|
|
2194
|
+
wrapJestGlobalsForRuntime(this)
|
|
2195
|
+
try {
|
|
2196
|
+
return requireModule.apply(this, arguments)
|
|
2197
|
+
} catch (error) {
|
|
2198
|
+
if (isBetweenTestsReferenceError(error)) {
|
|
2199
|
+
reportBetweenTestsReferenceError(this, moduleName, error.message)
|
|
1933
2200
|
}
|
|
1934
|
-
|
|
1935
|
-
}
|
|
1936
|
-
return result
|
|
2201
|
+
throw error
|
|
2202
|
+
}
|
|
1937
2203
|
})
|
|
1938
2204
|
|
|
1939
2205
|
shimmer.wrap(Runtime.prototype, 'requireModuleOrMock', requireModuleOrMock => function (from, moduleName) {
|
|
2206
|
+
wrapJestGlobalsForRuntime(this)
|
|
1940
2207
|
// `requireModuleOrMock` may log errors to the console. If we don't remove ourselves
|
|
1941
2208
|
// from the stack trace, the user might see a useless stack trace rather than the error
|
|
1942
2209
|
// that `jest` tries to show.
|
|
@@ -1945,32 +2212,33 @@ addHook({
|
|
|
1945
2212
|
const filteredStackTrace = structuredStackTrace
|
|
1946
2213
|
.filter(callSite => !callSite.getFileName()?.includes('datadog-instrumentations/src/jest.js'))
|
|
1947
2214
|
|
|
1948
|
-
|
|
2215
|
+
if (typeof originalPrepareStackTrace === 'function') {
|
|
2216
|
+
return originalPrepareStackTrace(error, filteredStackTrace)
|
|
2217
|
+
}
|
|
2218
|
+
return formatDefaultStackTrace(error, filteredStackTrace)
|
|
1949
2219
|
}
|
|
1950
2220
|
try {
|
|
1951
2221
|
// TODO: do this for every library that we instrument
|
|
1952
2222
|
if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
|
|
1953
2223
|
// To bypass jest's own require engine
|
|
1954
|
-
return this
|
|
2224
|
+
return requireOutsideJestRequireEngine(this, moduleName)
|
|
1955
2225
|
}
|
|
1956
2226
|
// This means that `@fast-check/jest` is used in the test file.
|
|
1957
|
-
|
|
1958
|
-
|
|
2227
|
+
recordFastCheckUsage(this, from, moduleName)
|
|
2228
|
+
let returnedValue
|
|
2229
|
+
try {
|
|
2230
|
+
returnedValue = requireModuleOrMock.apply(this, arguments)
|
|
2231
|
+
} catch (error) {
|
|
2232
|
+
if (isBetweenTestsReferenceError(error)) {
|
|
2233
|
+
reportBetweenTestsReferenceError(this, moduleName, error.message)
|
|
2234
|
+
}
|
|
2235
|
+
throw error
|
|
1959
2236
|
}
|
|
1960
|
-
const returnedValue = requireModuleOrMock.apply(this, arguments)
|
|
1961
2237
|
if (process.exitCode === 1) {
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
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
|
-
}
|
|
2238
|
+
publishRuntimeReferenceError(
|
|
2239
|
+
this,
|
|
2240
|
+
getLastLoggedReferenceError(this) || 'An error occurred while importing a module'
|
|
2241
|
+
)
|
|
1974
2242
|
}
|
|
1975
2243
|
return returnedValue
|
|
1976
2244
|
} finally {
|
|
@@ -1979,14 +2247,35 @@ addHook({
|
|
|
1979
2247
|
}
|
|
1980
2248
|
})
|
|
1981
2249
|
|
|
2250
|
+
if (Runtime.prototype._logFormattedReferenceError) {
|
|
2251
|
+
shimmer.wrap(Runtime.prototype, '_logFormattedReferenceError', logFormattedReferenceError => function () {
|
|
2252
|
+
// eslint-disable-next-line no-console
|
|
2253
|
+
const originalConsoleError = console.error
|
|
2254
|
+
let loggedReferenceError
|
|
2255
|
+
// eslint-disable-next-line no-console
|
|
2256
|
+
console.error = function () {
|
|
2257
|
+
loggedReferenceError = arguments[0]
|
|
2258
|
+
return originalConsoleError.apply(this, arguments)
|
|
2259
|
+
}
|
|
2260
|
+
try {
|
|
2261
|
+
const result = logFormattedReferenceError.apply(this, arguments)
|
|
2262
|
+
publishRuntimeReferenceError(this, getLastLoggedReferenceError(this) || loggedReferenceError)
|
|
2263
|
+
return result
|
|
2264
|
+
} finally {
|
|
2265
|
+
// eslint-disable-next-line no-console
|
|
2266
|
+
console.error = originalConsoleError
|
|
2267
|
+
}
|
|
2268
|
+
})
|
|
2269
|
+
}
|
|
2270
|
+
|
|
1982
2271
|
return runtimePackage
|
|
1983
2272
|
})
|
|
1984
2273
|
|
|
1985
2274
|
function onMessageWrapper (onMessage) {
|
|
1986
|
-
return function () {
|
|
1987
|
-
const response =
|
|
2275
|
+
return function (...args) {
|
|
2276
|
+
const response = args[0]
|
|
1988
2277
|
if (!Array.isArray(response)) {
|
|
1989
|
-
return onMessage.apply(this,
|
|
2278
|
+
return onMessage.apply(this, args)
|
|
1990
2279
|
}
|
|
1991
2280
|
|
|
1992
2281
|
const [code, data] = response
|
|
@@ -2013,7 +2302,7 @@ function onMessageWrapper (onMessage) {
|
|
|
2013
2302
|
}
|
|
2014
2303
|
return
|
|
2015
2304
|
}
|
|
2016
|
-
return onMessage.apply(this,
|
|
2305
|
+
return onMessage.apply(this, args)
|
|
2017
2306
|
}
|
|
2018
2307
|
}
|
|
2019
2308
|
|
|
@@ -2065,11 +2354,23 @@ function wrapWorkerChannel (worker) {
|
|
|
2065
2354
|
shimmer.wrap(workerChannel, worker._child ? 'send' : 'postMessage', sendWrapper)
|
|
2066
2355
|
}
|
|
2067
2356
|
|
|
2357
|
+
function wrapWorkerInitializer (worker) {
|
|
2358
|
+
if (wrappedWorkerInitializers.has(worker) || typeof worker.initialize !== 'function') return
|
|
2359
|
+
|
|
2360
|
+
wrappedWorkerInitializers.add(worker)
|
|
2361
|
+
shimmer.wrap(worker, 'initialize', initialize => function () {
|
|
2362
|
+
const result = initialize.apply(this, arguments)
|
|
2363
|
+
wrapWorkerChannel(this)
|
|
2364
|
+
return result
|
|
2365
|
+
})
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2068
2368
|
function wrapWorker (worker) {
|
|
2069
2369
|
// ChildProcessWorker uses _child (child_process), ExperimentalWorker uses _worker (worker_threads)
|
|
2070
2370
|
const workerChannel = worker._child || worker._worker
|
|
2071
2371
|
if (!workerChannel) return
|
|
2072
2372
|
|
|
2373
|
+
wrapWorkerInitializer(worker)
|
|
2073
2374
|
wrapWorkerChannel(worker)
|
|
2074
2375
|
shimmer.wrap(worker, '_onMessage', onMessageWrapper)
|
|
2075
2376
|
workerChannel.removeAllListeners('message')
|
|
@@ -2077,8 +2378,8 @@ function wrapWorker (worker) {
|
|
|
2077
2378
|
}
|
|
2078
2379
|
|
|
2079
2380
|
function enqueueWrapper (enqueue) {
|
|
2080
|
-
return function () {
|
|
2081
|
-
shimmer.wrap(
|
|
2381
|
+
return function (...args) {
|
|
2382
|
+
shimmer.wrap(args[0], 'onStart', onStart => function (worker) {
|
|
2082
2383
|
if (worker) {
|
|
2083
2384
|
const currentChannel = worker._child || worker._worker
|
|
2084
2385
|
const previousChannel = wrappedWorkerChannels.get(worker)
|
|
@@ -2095,7 +2396,7 @@ function enqueueWrapper (enqueue) {
|
|
|
2095
2396
|
}
|
|
2096
2397
|
return onStart.apply(this, arguments)
|
|
2097
2398
|
})
|
|
2098
|
-
return enqueue.apply(this,
|
|
2399
|
+
return enqueue.apply(this, args)
|
|
2099
2400
|
}
|
|
2100
2401
|
}
|
|
2101
2402
|
|