dd-trace 5.104.0 → 5.106.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/LICENSE-3rdparty.csv +90 -102
- package/index.d.ts +82 -3
- package/package.json +15 -15
- package/packages/datadog-core/src/storage.js +1 -1
- package/packages/datadog-instrumentations/src/aerospike.js +1 -1
- package/packages/datadog-instrumentations/src/ai.js +8 -7
- package/packages/datadog-instrumentations/src/aws-sdk.js +16 -2
- package/packages/datadog-instrumentations/src/azure-cosmos.js +7 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +3 -0
- package/packages/datadog-instrumentations/src/cucumber-worker-threads.js +19 -0
- package/packages/datadog-instrumentations/src/cucumber.js +390 -157
- package/packages/datadog-instrumentations/src/dns.js +54 -18
- package/packages/datadog-instrumentations/src/fastify.js +142 -82
- package/packages/datadog-instrumentations/src/graphql.js +188 -62
- package/packages/datadog-instrumentations/src/helpers/ai-messages.js +322 -14
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/openai-ai-guard.js +269 -0
- package/packages/datadog-instrumentations/src/helpers/promise-instrumentor.js +42 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/azure-cosmos.js +50 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langgraph.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +85 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +37 -236
- package/packages/datadog-instrumentations/src/hono.js +54 -3
- package/packages/datadog-instrumentations/src/http/server.js +9 -4
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +163 -0
- package/packages/datadog-instrumentations/src/jest.js +360 -150
- package/packages/datadog-instrumentations/src/kafkajs.js +120 -16
- package/packages/datadog-instrumentations/src/mocha/main.js +128 -17
- package/packages/datadog-instrumentations/src/nats.js +182 -0
- package/packages/datadog-instrumentations/src/nyc.js +38 -1
- package/packages/datadog-instrumentations/src/openai.js +33 -18
- package/packages/datadog-instrumentations/src/oracledb.js +6 -1
- package/packages/datadog-instrumentations/src/pino.js +17 -5
- package/packages/datadog-instrumentations/src/playwright.js +515 -292
- package/packages/datadog-instrumentations/src/router.js +76 -32
- package/packages/datadog-instrumentations/src/stripe.js +1 -1
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +218 -4
- package/packages/datadog-plugin-azure-cosmos/src/index.js +144 -0
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -1
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +1 -1
- package/packages/datadog-plugin-bunyan/src/index.js +28 -0
- package/packages/datadog-plugin-cucumber/src/index.js +17 -3
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +199 -28
- package/packages/datadog-plugin-cypress/src/support.js +69 -1
- package/packages/datadog-plugin-dns/src/lookup.js +8 -6
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +2 -0
- package/packages/datadog-plugin-graphql/src/resolve.js +64 -67
- package/packages/datadog-plugin-http/src/server.js +40 -15
- package/packages/datadog-plugin-jest/src/index.js +11 -3
- package/packages/datadog-plugin-jest/src/util.js +15 -8
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -0
- package/packages/datadog-plugin-langgraph/src/stream.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +19 -4
- package/packages/datadog-plugin-mongodb-core/src/index.js +281 -40
- package/packages/datadog-plugin-nats/src/consumer.js +43 -0
- package/packages/datadog-plugin-nats/src/index.js +20 -0
- package/packages/datadog-plugin-nats/src/producer.js +62 -0
- package/packages/datadog-plugin-nats/src/util.js +33 -0
- package/packages/datadog-plugin-next/src/index.js +5 -3
- package/packages/datadog-plugin-openai/src/tracing.js +15 -2
- package/packages/datadog-plugin-oracledb/src/index.js +13 -2
- package/packages/datadog-plugin-pino/src/index.js +42 -0
- package/packages/datadog-plugin-playwright/src/index.js +4 -4
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +1 -1
- package/packages/datadog-plugin-router/src/index.js +33 -44
- package/packages/datadog-plugin-selenium/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +5 -13
- package/packages/datadog-plugin-winston/src/index.js +30 -0
- package/packages/datadog-shimmer/src/shimmer.js +33 -40
- package/packages/dd-trace/src/aiguard/index.js +1 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +5 -6
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/utils.js +1 -1
- package/packages/dd-trace/src/appsec/user_tracking.js +5 -4
- package/packages/dd-trace/src/baggage.js +7 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +25 -13
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +70 -6
- package/packages/dd-trace/src/config/generated-config-types.d.ts +6 -2
- package/packages/dd-trace/src/config/supported-configurations.json +27 -8
- package/packages/dd-trace/src/datastreams/writer.js +2 -4
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -8
- package/packages/dd-trace/src/encode/0.4.js +124 -108
- package/packages/dd-trace/src/encode/0.5.js +114 -26
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +31 -23
- package/packages/dd-trace/src/encode/agentless-json.js +4 -2
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +32 -13
- package/packages/dd-trace/src/encode/span-stats.js +16 -16
- package/packages/dd-trace/src/encode/tags-processors.js +16 -0
- package/packages/dd-trace/src/id.js +15 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +92 -6
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +43 -21
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +9 -7
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +0 -16
- package/packages/dd-trace/src/llmobs/span_processor.js +3 -3
- package/packages/dd-trace/src/llmobs/tagger.js +9 -1
- package/packages/dd-trace/src/llmobs/telemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/util.js +66 -3
- package/packages/dd-trace/src/log/index.js +1 -1
- package/packages/dd-trace/src/msgpack/chunk.js +394 -10
- package/packages/dd-trace/src/msgpack/index.js +96 -2
- package/packages/dd-trace/src/openfeature/encoding.js +70 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +20 -0
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +143 -0
- package/packages/dd-trace/src/openfeature/span-enrichment.js +149 -0
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +4 -3
- package/packages/dd-trace/src/opentelemetry/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +22 -3
- package/packages/dd-trace/src/opentracing/propagation/log.js +18 -7
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +64 -77
- package/packages/dd-trace/src/opentracing/span.js +59 -19
- package/packages/dd-trace/src/opentracing/span_context.js +50 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +20 -20
- package/packages/dd-trace/src/plugins/database.js +7 -6
- package/packages/dd-trace/src/plugins/index.js +4 -0
- package/packages/dd-trace/src/plugins/log_injection.js +56 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -48
- package/packages/dd-trace/src/plugins/outbound.js +1 -1
- package/packages/dd-trace/src/plugins/plugin.js +15 -17
- package/packages/dd-trace/src/plugins/tracing.js +43 -5
- package/packages/dd-trace/src/plugins/util/test.js +236 -13
- package/packages/dd-trace/src/plugins/util/web.js +79 -65
- package/packages/dd-trace/src/priority_sampler.js +2 -2
- package/packages/dd-trace/src/profiling/config.js +10 -23
- package/packages/dd-trace/src/profiling/exporters/agent.js +11 -10
- package/packages/dd-trace/src/profiling/profiler.js +21 -11
- package/packages/dd-trace/src/profiling/profilers/wall.js +12 -7
- package/packages/dd-trace/src/sampling_rule.js +7 -7
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +10 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
- package/packages/dd-trace/src/service-naming/source-resolver.js +46 -0
- package/packages/dd-trace/src/span_format.js +190 -58
- package/packages/dd-trace/src/spanleak.js +1 -1
- package/packages/dd-trace/src/standalone/index.js +3 -3
- package/packages/dd-trace/src/tagger.js +0 -2
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +70 -39
- package/vendor/dist/@datadog/sketches-js/LICENSE +10 -36
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/packages/dd-trace/src/msgpack/encoder.js +0 -308
- package/packages/dd-trace/src/plugins/structured_log_plugin.js +0 -9
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
const realSetTimeout = setTimeout
|
|
5
5
|
|
|
6
6
|
const { readFileSync } = require('node:fs')
|
|
7
|
-
const { builtinModules } = require('node:module')
|
|
7
|
+
const { builtinModules, createRequire } = require('node:module')
|
|
8
8
|
const path = require('path')
|
|
9
9
|
const satisfies = require('../../../vendor/dist/semifies')
|
|
10
10
|
const { DD_MAJOR } = require('../../../version')
|
|
@@ -12,7 +12,8 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
12
12
|
const { getEnvironmentVariable } = require('../../dd-trace/src/config/helper')
|
|
13
13
|
const log = require('../../dd-trace/src/log')
|
|
14
14
|
const {
|
|
15
|
-
|
|
15
|
+
getCoveredFilesFromCoverage,
|
|
16
|
+
getExecutableFilesFromCoverage,
|
|
16
17
|
JEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
17
18
|
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
18
19
|
JEST_WORKER_TELEMETRY_PAYLOAD_CODE,
|
|
@@ -30,14 +31,21 @@ const {
|
|
|
30
31
|
logAttemptToFixTestExecution,
|
|
31
32
|
logTestOptimizationSummary,
|
|
32
33
|
getEfdRetryCount,
|
|
34
|
+
getTestCoverageLinesPercentage,
|
|
35
|
+
applySkippedCoverageToCoverage,
|
|
33
36
|
getTestOptimizationRequestResults,
|
|
34
37
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
35
38
|
const {
|
|
36
|
-
SEED_SUFFIX_RE,
|
|
37
39
|
getFormattedJestTestParameters,
|
|
38
40
|
getJestTestName,
|
|
41
|
+
getRawJestTestName,
|
|
39
42
|
getJestSuitesToRun,
|
|
43
|
+
removeSeedSuffixFromTestName,
|
|
40
44
|
} = require('../../datadog-plugin-jest/src/util')
|
|
45
|
+
const {
|
|
46
|
+
addCoverageBackfillUntestedFiles,
|
|
47
|
+
getCoverageBackfillFiles,
|
|
48
|
+
} = require('./jest/coverage-backfill')
|
|
41
49
|
const { addHook, channel } = require('./helpers/instrument')
|
|
42
50
|
|
|
43
51
|
const testSessionStartCh = channel('ci:jest:session:start')
|
|
@@ -84,11 +92,13 @@ const isJestWorker = !!getEnvironmentVariable('JEST_WORKER_ID')
|
|
|
84
92
|
const RETRY_TIMES = Symbol.for('RETRY_TIMES')
|
|
85
93
|
|
|
86
94
|
let skippableSuites = []
|
|
95
|
+
let skippableSuitesCoverage = {}
|
|
96
|
+
let skippedSuitesCoverage = {}
|
|
87
97
|
let knownTests = {}
|
|
88
98
|
let isCodeCoverageEnabled = false
|
|
89
|
-
let
|
|
99
|
+
let isCoverageReportUploadEnabled = false
|
|
100
|
+
let isItrEnabled = false
|
|
90
101
|
let isSuitesSkippingEnabled = false
|
|
91
|
-
let DD_TEST_TIA_KEEP_COV_CONFIG = false
|
|
92
102
|
let isUserCodeCoverageEnabled = false
|
|
93
103
|
let isSuitesSkipped = false
|
|
94
104
|
let numSkippedSuites = 0
|
|
@@ -106,6 +116,13 @@ let testManagementTests = {}
|
|
|
106
116
|
let testManagementAttemptToFixRetries = 0
|
|
107
117
|
let isImpactedTestsEnabled = false
|
|
108
118
|
let modifiedFiles = {}
|
|
119
|
+
let repositoryRoot
|
|
120
|
+
let lastCoverageMap
|
|
121
|
+
let lastCoverageMapRootDir
|
|
122
|
+
let coverageBackfillContexts
|
|
123
|
+
let coverageBackfillFiles
|
|
124
|
+
let coverageReporterClass
|
|
125
|
+
let coverageReporterRequire
|
|
109
126
|
let activeTestSuiteAbsolutePath
|
|
110
127
|
let isConsoleErrorWrapped = false
|
|
111
128
|
|
|
@@ -130,13 +147,13 @@ const efdSlowAbortedTests = new Set()
|
|
|
130
147
|
const efdNewTestCandidates = new Set()
|
|
131
148
|
// Tests that are genuinely new (not in known tests list).
|
|
132
149
|
const newTests = new Set()
|
|
133
|
-
const testSuiteAbsolutePathsWithFastCheck = new Set()
|
|
134
|
-
const testSuiteFastCheckUsage = new Map()
|
|
135
150
|
const testSuiteJestObjects = new Map()
|
|
136
151
|
const wrappedJestGlobals = new WeakSet()
|
|
137
152
|
const wrappedJestObjects = new WeakSet()
|
|
138
153
|
const wrappedWorkerInitializers = new WeakSet()
|
|
139
154
|
const publishedRuntimeReferenceErrors = new WeakMap()
|
|
155
|
+
const wrappedCoverageReporters = new WeakSet()
|
|
156
|
+
const coverageReporterRequires = new WeakMap()
|
|
140
157
|
|
|
141
158
|
const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
|
|
142
159
|
const ATR_RETRY_SUPPRESSION_FLAG = '_ddDisableAtrRetry'
|
|
@@ -145,12 +162,22 @@ const MINIMUM_JEST_VERSION_BEFORE_30 = DD_MAJOR >= 6 ? '>=28.0.0 <30.0.0' : '>=2
|
|
|
145
162
|
const MINIMUM_JEST_WORKER_VERSION_BEFORE_30 = DD_MAJOR >= 6 ? '>=28.0.0 <30.0.0' : '>=24.9.0 <30.0.0'
|
|
146
163
|
const MINIMUM_JEST_CONFIG_ASYNC_VERSION = DD_MAJOR >= 6 ? '>=28.0.0' : '>=25.1.0'
|
|
147
164
|
const MINIMUM_JEST_TEST_SCHEDULER_VERSION = DD_MAJOR >= 6 ? '>=28.0.0' : '>=27.0.0'
|
|
165
|
+
const MINIMUM_JEST_COVERAGE_BACKFILL_VERSION = '>=28.0.0'
|
|
148
166
|
const atrSuppressedErrors = new Map()
|
|
149
167
|
let hasWarnedDeprecatedJestVersion = false
|
|
168
|
+
let isJestCoverageBackfillSupported = false
|
|
150
169
|
|
|
151
170
|
// Track quarantined tests whose errors were suppressed, keyed by "suite › testName"
|
|
152
171
|
const quarantinedFailingTests = new Set()
|
|
153
172
|
|
|
173
|
+
function getJestRepositoryRoot (readConfigsResult) {
|
|
174
|
+
const configuredRepositoryRoot = readConfigsResult.configs
|
|
175
|
+
?.find(config => config.testEnvironmentOptions?._ddRepositoryRoot)
|
|
176
|
+
?.testEnvironmentOptions._ddRepositoryRoot
|
|
177
|
+
|
|
178
|
+
return configuredRepositoryRoot || process.cwd()
|
|
179
|
+
}
|
|
180
|
+
|
|
154
181
|
/**
|
|
155
182
|
* Sends suppressed quarantine test names from a worker process to the main process.
|
|
156
183
|
* Supports both child_process (process.send) and worker_threads (parentPort.postMessage).
|
|
@@ -293,9 +320,7 @@ function getAttemptToFixExecutionsFromJestResults (result) {
|
|
|
293
320
|
if (!testManagementTestsForSuite) continue
|
|
294
321
|
|
|
295
322
|
for (const { fullName, status } of testResults) {
|
|
296
|
-
const testName =
|
|
297
|
-
? fullName.replace(SEED_SUFFIX_RE, '')
|
|
298
|
-
: fullName
|
|
323
|
+
const testName = removeSeedSuffixFromTestName(fullName)
|
|
299
324
|
const testStatus = getTestStatusFromJestResult(status)
|
|
300
325
|
if (!testStatus) continue
|
|
301
326
|
|
|
@@ -341,7 +366,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
341
366
|
super(config, context)
|
|
342
367
|
const rootDir = config.globalConfig ? config.globalConfig.rootDir : config.rootDir
|
|
343
368
|
this.rootDir = rootDir
|
|
344
|
-
this.testSuite = getTestSuitePath(context.testPath, rootDir)
|
|
345
369
|
this.nameToParams = {}
|
|
346
370
|
this.global._ddtrace = global._ddtrace
|
|
347
371
|
this.hasSnapshotTests = undefined
|
|
@@ -354,6 +378,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
354
378
|
this.testEnvironmentOptions = getTestEnvironmentOptions(config)
|
|
355
379
|
|
|
356
380
|
const repositoryRoot = this.testEnvironmentOptions._ddRepositoryRoot
|
|
381
|
+
this.testSuite = getTestSuitePath(context.testPath, rootDir)
|
|
357
382
|
|
|
358
383
|
// TODO: could we grab testPath from `this.getVmContext().expect.getState()` instead?
|
|
359
384
|
// so we don't rely on context being passed (some custom test environment do not pass it)
|
|
@@ -542,14 +567,11 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
542
567
|
}
|
|
543
568
|
}
|
|
544
569
|
|
|
545
|
-
getShouldStripSeedFromTestName () {
|
|
546
|
-
return doesTestSuiteUseFastCheck(this.testSuiteAbsolutePath)
|
|
547
|
-
}
|
|
548
|
-
|
|
549
570
|
// At the `add_test` event we don't have the test object yet, so we can't use it
|
|
550
571
|
getTestNameFromAddTestEvent (event, state) {
|
|
551
|
-
const describeSuffix =
|
|
552
|
-
|
|
572
|
+
const describeSuffix = getRawJestTestName(state.currentDescribeBlock)
|
|
573
|
+
const testName = describeSuffix ? `${describeSuffix} ${event.testName}` : event.testName
|
|
574
|
+
return removeSeedSuffixFromTestName(testName)
|
|
553
575
|
}
|
|
554
576
|
|
|
555
577
|
async handleTestEvent (event, state) {
|
|
@@ -571,7 +593,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
571
593
|
})
|
|
572
594
|
}
|
|
573
595
|
if (event.name === 'test_start') {
|
|
574
|
-
const testName = getJestTestName(event.test
|
|
596
|
+
const testName = getJestTestName(event.test)
|
|
575
597
|
if (testsToBeRetried.has(testName)) {
|
|
576
598
|
// This is needed because we're retrying tests with the same name
|
|
577
599
|
this.resetSnapshotState()
|
|
@@ -775,7 +797,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
775
797
|
let attemptToFixFailed = false
|
|
776
798
|
let failedAllTests = false
|
|
777
799
|
let isAttemptToFix = false
|
|
778
|
-
const testName = getJestTestName(event.test
|
|
800
|
+
const testName = getJestTestName(event.test)
|
|
779
801
|
if (this.isTestManagementTestsEnabled) {
|
|
780
802
|
isAttemptToFix = this.testManagementTestsForThisSuite?.attemptToFix?.includes(testName)
|
|
781
803
|
if (isAttemptToFix) {
|
|
@@ -955,7 +977,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
955
977
|
// so Jest doesn't see the failure (prevents --bail from stopping the run).
|
|
956
978
|
const ctx = testContexts.get(test)
|
|
957
979
|
if (ctx?.isQuarantined && !ctx.isAttemptToFix) {
|
|
958
|
-
const testName = getJestTestName(test
|
|
980
|
+
const testName = getJestTestName(test)
|
|
959
981
|
quarantinedFailingTests.add(`${ctx.suite} › ${testName}`)
|
|
960
982
|
} else {
|
|
961
983
|
test.errors = errors
|
|
@@ -979,7 +1001,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
979
1001
|
testsToBeRetried.clear()
|
|
980
1002
|
}
|
|
981
1003
|
if (event.name === 'test_skip' || event.name === 'test_todo') {
|
|
982
|
-
const testName = getJestTestName(event.test
|
|
1004
|
+
const testName = getJestTestName(event.test)
|
|
983
1005
|
testSkippedCh.publish({
|
|
984
1006
|
test: {
|
|
985
1007
|
name: testName,
|
|
@@ -1129,8 +1151,107 @@ function getTestEnvironment (pkg, jestVersion) {
|
|
|
1129
1151
|
return getWrappedEnvironment(pkg, jestVersion)
|
|
1130
1152
|
}
|
|
1131
1153
|
|
|
1154
|
+
function getRepositoryRootFromConfig (config, fallbackRootDir) {
|
|
1155
|
+
return config?.testEnvironmentOptions?._ddRepositoryRoot || repositoryRoot || fallbackRootDir || process.cwd()
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
function getRepositoryRootFromContexts (contexts, fallbackRootDir) {
|
|
1159
|
+
const [firstContext] = contexts || []
|
|
1160
|
+
return getRepositoryRootFromConfig(firstContext?.config, fallbackRootDir)
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
function getRepositoryRootFromTest (test, fallbackRootDir) {
|
|
1164
|
+
return getRepositoryRootFromConfig(test?.context?.config, fallbackRootDir)
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
function hasSkippableSuitesCoverage () {
|
|
1168
|
+
return skippableSuitesCoverage &&
|
|
1169
|
+
typeof skippableSuitesCoverage === 'object' &&
|
|
1170
|
+
Object.keys(skippableSuitesCoverage).length > 0
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
function shouldCollectJestCoverageForTia () {
|
|
1174
|
+
return shouldReportJestSuiteCoverageForTia() ||
|
|
1175
|
+
(isJestCoverageBackfillSupported && isItrEnabled && isCoverageReportUploadEnabled)
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
function shouldReportJestSuiteCoverageForTia () {
|
|
1179
|
+
return isItrEnabled && isCodeCoverageEnabled
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
function hasJestCoverageMap () {
|
|
1183
|
+
return isUserCodeCoverageEnabled || shouldCollectJestCoverageForTia()
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// TIA coverage backfill is part of Datadog Code Coverage, not the per-suite TIA coverage upload.
|
|
1187
|
+
function isTiaCoverageBackfillEnabled () {
|
|
1188
|
+
return isJestCoverageBackfillSupported && isItrEnabled && isCoverageReportUploadEnabled && hasJestCoverageMap()
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
// Non-TIA Jest coverage keeps the legacy metric. TIA only reports it when Datadog Code Coverage is enabled and
|
|
1192
|
+
// either the run is complete locally or the skipped suites can be backfilled.
|
|
1193
|
+
function shouldReportCodeCoverageLinesPct () {
|
|
1194
|
+
if (!hasJestCoverageMap()) return false
|
|
1195
|
+
if (!isItrEnabled) return true
|
|
1196
|
+
if (!isCoverageReportUploadEnabled) return false
|
|
1197
|
+
|
|
1198
|
+
// If no suites were actually skipped, the local Jest coverage map is complete and does not need backfill.
|
|
1199
|
+
return !isSuitesSkipped || isTiaCoverageBackfillEnabled()
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
function getHookRequire (hookMeta) {
|
|
1203
|
+
if (!hookMeta?.moduleBaseDir) return
|
|
1204
|
+
|
|
1205
|
+
return createRequire(path.join(hookMeta.moduleBaseDir, 'package.json'))
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
function getCoverageBackfillRequire (CoverageReporter) {
|
|
1209
|
+
const hookedCoverageReporterRequire = CoverageReporter && coverageReporterRequires.get(CoverageReporter)
|
|
1210
|
+
if (hookedCoverageReporterRequire) return hookedCoverageReporterRequire
|
|
1211
|
+
if (coverageReporterRequire) return coverageReporterRequire
|
|
1212
|
+
|
|
1213
|
+
const coverageReporterFilename = CoverageReporter?.filename || coverageReporterClass?.filename
|
|
1214
|
+
if (coverageReporterFilename) {
|
|
1215
|
+
return createRequire(`${path.join(path.dirname(coverageReporterFilename), 'CoverageWorker')}.js`)
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
return require
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
function getTestContexts (tests) {
|
|
1222
|
+
if (!tests?.length) return
|
|
1223
|
+
|
|
1224
|
+
const contexts = new Set()
|
|
1225
|
+
for (const test of tests) {
|
|
1226
|
+
if (test.context) {
|
|
1227
|
+
contexts.add(test.context)
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
return contexts.size ? contexts : undefined
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
function getCoverageBackfillContexts (contexts) {
|
|
1234
|
+
return contexts?.size ? contexts : coverageBackfillContexts || contexts
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
function resetSuiteSkippingRunState () {
|
|
1238
|
+
isSuitesSkipped = false
|
|
1239
|
+
numSkippedSuites = 0
|
|
1240
|
+
hasUnskippableSuites = false
|
|
1241
|
+
hasForcedToRunSuites = false
|
|
1242
|
+
hasFilteredSkippableSuites = false
|
|
1243
|
+
skippedSuitesCoverage = {}
|
|
1244
|
+
lastCoverageMap = undefined
|
|
1245
|
+
lastCoverageMapRootDir = undefined
|
|
1246
|
+
coverageBackfillContexts = undefined
|
|
1247
|
+
coverageBackfillFiles = undefined
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1132
1250
|
function applySuiteSkipping (originalTests, rootDir, frameworkVersion) {
|
|
1133
|
-
|
|
1251
|
+
if (!isItrEnabled || !isSuitesSkippingEnabled) return originalTests
|
|
1252
|
+
|
|
1253
|
+
const suitePathRoot = getRepositoryRootFromTest(originalTests[0], rootDir)
|
|
1254
|
+
const jestSuitesToRun = getJestSuitesToRun(skippableSuites, originalTests, suitePathRoot)
|
|
1134
1255
|
hasFilteredSkippableSuites = true
|
|
1135
1256
|
log.debug('%d out of %d suites are going to run.', jestSuitesToRun.suitesToRun.length, originalTests.length)
|
|
1136
1257
|
hasUnskippableSuites = jestSuitesToRun.hasUnskippableSuites
|
|
@@ -1138,12 +1259,112 @@ function applySuiteSkipping (originalTests, rootDir, frameworkVersion) {
|
|
|
1138
1259
|
|
|
1139
1260
|
isSuitesSkipped = jestSuitesToRun.suitesToRun.length !== originalTests.length
|
|
1140
1261
|
numSkippedSuites = jestSuitesToRun.skippedSuites.length
|
|
1262
|
+
skippedSuitesCoverage = isSuitesSkipped && isTiaCoverageBackfillEnabled() && hasSkippableSuitesCoverage()
|
|
1263
|
+
? skippableSuitesCoverage
|
|
1264
|
+
: {}
|
|
1265
|
+
coverageBackfillContexts = isSuitesSkipped && isTiaCoverageBackfillEnabled()
|
|
1266
|
+
? getTestContexts(originalTests)
|
|
1267
|
+
: undefined
|
|
1268
|
+
coverageBackfillFiles = isSuitesSkipped && isTiaCoverageBackfillEnabled() && hasSkippableSuitesCoverage()
|
|
1269
|
+
? getCoverageBackfillFiles(skippableSuitesCoverage, suitePathRoot, getTestSuitePath)
|
|
1270
|
+
: undefined
|
|
1141
1271
|
|
|
1142
1272
|
itrSkippedSuitesCh.publish({ skippedSuites: jestSuitesToRun.skippedSuites, frameworkVersion })
|
|
1143
1273
|
|
|
1144
1274
|
return jestSuitesToRun.suitesToRun
|
|
1145
1275
|
}
|
|
1146
1276
|
|
|
1277
|
+
function applySkippedCoverageToJestCoverageMap (coverageMap, rootDir) {
|
|
1278
|
+
if (!coverageMap || !isSuitesSkipped || !isTiaCoverageBackfillEnabled()) return
|
|
1279
|
+
applySkippedCoverageToCoverage(
|
|
1280
|
+
coverageMap,
|
|
1281
|
+
skippedSuitesCoverage,
|
|
1282
|
+
rootDir || process.cwd()
|
|
1283
|
+
)
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
function reporterDispatcherWrapper (reporterDispatcherPackage) {
|
|
1287
|
+
const ReporterDispatcher = reporterDispatcherPackage.default ?? reporterDispatcherPackage
|
|
1288
|
+
if (ReporterDispatcher?.prototype?.onRunComplete) {
|
|
1289
|
+
shimmer.wrap(ReporterDispatcher.prototype, 'onRunComplete', onRunComplete => function (contexts, results) {
|
|
1290
|
+
if (isSuitesSkipped && isTiaCoverageBackfillEnabled()) {
|
|
1291
|
+
applySkippedCoverageToJestCoverageMap(results?.coverageMap, getRepositoryRootFromContexts(contexts))
|
|
1292
|
+
}
|
|
1293
|
+
return onRunComplete.apply(this, arguments)
|
|
1294
|
+
})
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
return reporterDispatcherPackage
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
function wrapCoverageReporter (CoverageReporter, hookMeta) {
|
|
1301
|
+
if (!CoverageReporter?.prototype?.onRunComplete || wrappedCoverageReporters.has(CoverageReporter)) {
|
|
1302
|
+
return
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
coverageReporterRequire = getHookRequire(hookMeta) || coverageReporterRequire
|
|
1306
|
+
if (coverageReporterRequire) {
|
|
1307
|
+
coverageReporterRequires.set(CoverageReporter, coverageReporterRequire)
|
|
1308
|
+
}
|
|
1309
|
+
coverageReporterClass = CoverageReporter
|
|
1310
|
+
wrappedCoverageReporters.add(CoverageReporter)
|
|
1311
|
+
if (CoverageReporter.prototype._addUntestedFiles) {
|
|
1312
|
+
shimmer.wrap(CoverageReporter.prototype, '_addUntestedFiles', addUntestedFiles => function (...args) {
|
|
1313
|
+
const rootDir = repositoryRoot || this._globalConfig?.rootDir || process.cwd()
|
|
1314
|
+
args[0] = getCoverageBackfillContexts(args[0])
|
|
1315
|
+
const result = addUntestedFiles.apply(this, args)
|
|
1316
|
+
if (!isSuitesSkipped || !isTiaCoverageBackfillEnabled()) return result
|
|
1317
|
+
|
|
1318
|
+
const addBackfillAndApplyCoverage = () => {
|
|
1319
|
+
return addCoverageBackfillUntestedFiles({
|
|
1320
|
+
coverageMap: this._coverageMap,
|
|
1321
|
+
testContexts: args[0],
|
|
1322
|
+
rootDir,
|
|
1323
|
+
CoverageReporter,
|
|
1324
|
+
coverageBackfillFiles,
|
|
1325
|
+
getCoverageBackfillRequire,
|
|
1326
|
+
}).then(() => {
|
|
1327
|
+
applySkippedCoverageToJestCoverageMap(this._coverageMap, rootDir)
|
|
1328
|
+
})
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
return Promise.resolve(result).then(value => {
|
|
1332
|
+
return addBackfillAndApplyCoverage().then(() => value)
|
|
1333
|
+
})
|
|
1334
|
+
})
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
shimmer.wrap(CoverageReporter.prototype, 'onRunComplete', onRunComplete => async function (contexts, results) {
|
|
1338
|
+
const coverageContexts = getCoverageBackfillContexts(contexts)
|
|
1339
|
+
const rootDir = getRepositoryRootFromContexts(coverageContexts, this._globalConfig?.rootDir)
|
|
1340
|
+
const coverageMap = results?.coverageMap || this._coverageMap
|
|
1341
|
+
if (isSuitesSkipped && isTiaCoverageBackfillEnabled()) {
|
|
1342
|
+
await addCoverageBackfillUntestedFiles({
|
|
1343
|
+
coverageMap,
|
|
1344
|
+
testContexts: coverageContexts,
|
|
1345
|
+
rootDir,
|
|
1346
|
+
CoverageReporter,
|
|
1347
|
+
coverageBackfillFiles,
|
|
1348
|
+
getCoverageBackfillRequire,
|
|
1349
|
+
})
|
|
1350
|
+
applySkippedCoverageToJestCoverageMap(coverageMap, rootDir)
|
|
1351
|
+
}
|
|
1352
|
+
lastCoverageMap = coverageMap
|
|
1353
|
+
lastCoverageMapRootDir = rootDir
|
|
1354
|
+
return onRunComplete.call(this, coverageContexts, results)
|
|
1355
|
+
})
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
function reportersWrapper (reportersPackage, _version, _isIitm, hookMeta) {
|
|
1359
|
+
wrapCoverageReporter(reportersPackage.CoverageReporter, hookMeta)
|
|
1360
|
+
return reportersPackage
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
function coverageReporterWrapper (coverageReporterPackage, _version, _isIitm, hookMeta) {
|
|
1364
|
+
wrapCoverageReporter(coverageReporterPackage.default ?? coverageReporterPackage, hookMeta)
|
|
1365
|
+
return coverageReporterPackage
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1147
1368
|
addHook({
|
|
1148
1369
|
name: 'jest-environment-node',
|
|
1149
1370
|
versions: [MINIMUM_JEST_VERSION],
|
|
@@ -1188,7 +1409,9 @@ function searchSourceWrapper (searchSourcePackage, frameworkVersion) {
|
|
|
1188
1409
|
const [{ rootDir, shard }] = arguments
|
|
1189
1410
|
|
|
1190
1411
|
if (isKnownTestsEnabled) {
|
|
1191
|
-
const projectSuites = testPaths.tests.map(test =>
|
|
1412
|
+
const projectSuites = testPaths.tests.map(test => {
|
|
1413
|
+
return getTestSuitePath(test.path, getRepositoryRootFromTest(test, test.context.config.rootDir))
|
|
1414
|
+
})
|
|
1192
1415
|
|
|
1193
1416
|
// If the `jest` key does not exist in the known tests response, we consider the Early Flake detection faulty.
|
|
1194
1417
|
const isFaulty = !knownTests?.jest ||
|
|
@@ -1208,14 +1431,11 @@ function searchSourceWrapper (searchSourcePackage, frameworkVersion) {
|
|
|
1208
1431
|
}
|
|
1209
1432
|
}
|
|
1210
1433
|
|
|
1434
|
+
// When Jest sharding is enabled, filter after Jest picks this process's shard. Different shards usually run in
|
|
1435
|
+
// different CI jobs, so their skippable requests can happen at different times and receive different responses.
|
|
1436
|
+
// Filtering before Jest shards would make each job shard a different base test list, which can cause duplicate
|
|
1437
|
+
// suite execution across shards.
|
|
1211
1438
|
if (shard?.shardCount > 1 || !isSuitesSkippingEnabled || !skippableSuites.length) {
|
|
1212
|
-
// If the user is using jest sharding, we want to apply the filtering of tests in the shard process.
|
|
1213
|
-
// The reason for this is the following:
|
|
1214
|
-
// The tests for different shards are likely being run in different CI jobs so
|
|
1215
|
-
// the requests to the skippable endpoint might be done at different times and their responses might be different.
|
|
1216
|
-
// If the skippable endpoint is returning different suites and we filter the list of tests here,
|
|
1217
|
-
// the base list of tests that is used for sharding might be different,
|
|
1218
|
-
// causing the shards to potentially run the same suite.
|
|
1219
1439
|
return testPaths
|
|
1220
1440
|
}
|
|
1221
1441
|
const { tests } = testPaths
|
|
@@ -1230,6 +1450,8 @@ function searchSourceWrapper (searchSourcePackage, frameworkVersion) {
|
|
|
1230
1450
|
function getCliWrapper (isNewJestVersion) {
|
|
1231
1451
|
return function cliWrapper (cli, jestVersion) {
|
|
1232
1452
|
warnDeprecatedJestVersion(jestVersion)
|
|
1453
|
+
isJestCoverageBackfillSupported = !!jestVersion &&
|
|
1454
|
+
satisfies(jestVersion, MINIMUM_JEST_COVERAGE_BACKFILL_VERSION)
|
|
1233
1455
|
|
|
1234
1456
|
if (isNewJestVersion) {
|
|
1235
1457
|
cli = shimmer.wrap(
|
|
@@ -1245,15 +1467,17 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1245
1467
|
return runCLI.apply(this, arguments)
|
|
1246
1468
|
}
|
|
1247
1469
|
|
|
1470
|
+
resetSuiteSkippingRunState()
|
|
1471
|
+
|
|
1248
1472
|
try {
|
|
1249
1473
|
const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh, {
|
|
1250
1474
|
frameworkVersion: jestVersion,
|
|
1251
1475
|
})
|
|
1252
1476
|
if (!err) {
|
|
1253
1477
|
isCodeCoverageEnabled = libraryConfig.isCodeCoverageEnabled
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1478
|
+
isCoverageReportUploadEnabled = libraryConfig.isCoverageReportUploadEnabled
|
|
1479
|
+
isItrEnabled = libraryConfig.isItrEnabled
|
|
1480
|
+
isSuitesSkippingEnabled = isItrEnabled && libraryConfig.isSuitesSkippingEnabled
|
|
1257
1481
|
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
1258
1482
|
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
1259
1483
|
earlyFlakeDetectionSlowTestRetries = libraryConfig.earlyFlakeDetectionSlowTestRetries ?? {}
|
|
@@ -1297,10 +1521,18 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1297
1521
|
|
|
1298
1522
|
if (isSuitesSkippingEnabled) {
|
|
1299
1523
|
try {
|
|
1300
|
-
const {
|
|
1301
|
-
|
|
1302
|
-
|
|
1524
|
+
const {
|
|
1525
|
+
err,
|
|
1526
|
+
skippableSuites: receivedSkippableSuites,
|
|
1527
|
+
skippableSuitesCoverage: receivedSkippableSuitesCoverage,
|
|
1528
|
+
} = skippableSuitesResponse || await getChannelPromise(skippableSuitesCh)
|
|
1529
|
+
if (err) {
|
|
1530
|
+
skippableSuitesCoverage = {}
|
|
1531
|
+
skippedSuitesCoverage = {}
|
|
1532
|
+
} else {
|
|
1303
1533
|
skippableSuites = receivedSkippableSuites
|
|
1534
|
+
skippableSuitesCoverage = receivedSkippableSuitesCoverage || {}
|
|
1535
|
+
skippedSuitesCoverage = {}
|
|
1304
1536
|
}
|
|
1305
1537
|
} catch (err) {
|
|
1306
1538
|
log.error('Jest test-suite skippable error', err)
|
|
@@ -1335,13 +1567,16 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1335
1567
|
}
|
|
1336
1568
|
|
|
1337
1569
|
const processArgv = process.argv.slice(2).join(' ')
|
|
1338
|
-
testSessionStartCh.publish({
|
|
1570
|
+
testSessionStartCh.publish({
|
|
1571
|
+
command: `jest ${processArgv}`,
|
|
1572
|
+
frameworkVersion: jestVersion,
|
|
1573
|
+
})
|
|
1339
1574
|
|
|
1340
1575
|
const result = await runCLI.apply(this, arguments)
|
|
1341
1576
|
|
|
1342
1577
|
const {
|
|
1343
1578
|
results: {
|
|
1344
|
-
coverageMap,
|
|
1579
|
+
coverageMap: resultCoverageMap,
|
|
1345
1580
|
numFailedTestSuites,
|
|
1346
1581
|
numFailedTests,
|
|
1347
1582
|
numRuntimeErrorTestSuites = 0,
|
|
@@ -1357,11 +1592,30 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1357
1592
|
const mustNotFlipSuccess = hasSuiteLevelFailures || hasRunLevelFailure
|
|
1358
1593
|
|
|
1359
1594
|
let testCodeCoverageLinesTotal
|
|
1595
|
+
let testSessionCoverageFiles
|
|
1596
|
+
const shouldReportTestSessionCoverage = isTiaCoverageBackfillEnabled()
|
|
1360
1597
|
|
|
1361
|
-
if (
|
|
1598
|
+
if (shouldReportCodeCoverageLinesPct()) {
|
|
1362
1599
|
try {
|
|
1363
|
-
const
|
|
1364
|
-
|
|
1600
|
+
const coverageMap = resultCoverageMap || lastCoverageMap
|
|
1601
|
+
const coverageRootDir = lastCoverageMapRootDir ||
|
|
1602
|
+
repositoryRoot ||
|
|
1603
|
+
result.globalConfig?.rootDir ||
|
|
1604
|
+
process.cwd()
|
|
1605
|
+
if (isSuitesSkipped) {
|
|
1606
|
+
applySkippedCoverageToJestCoverageMap(coverageMap, coverageRootDir)
|
|
1607
|
+
}
|
|
1608
|
+
testCodeCoverageLinesTotal = getTestCoverageLinesPercentage(
|
|
1609
|
+
coverageMap,
|
|
1610
|
+
undefined,
|
|
1611
|
+
coverageRootDir
|
|
1612
|
+
)
|
|
1613
|
+
if (shouldReportTestSessionCoverage) {
|
|
1614
|
+
testSessionCoverageFiles = getExecutableFilesFromCoverage(coverageMap).map(({ filename, bitmap }) => ({
|
|
1615
|
+
filename: getTestSuitePath(filename, coverageRootDir),
|
|
1616
|
+
bitmap,
|
|
1617
|
+
}))
|
|
1618
|
+
}
|
|
1365
1619
|
} catch {
|
|
1366
1620
|
// ignore errors
|
|
1367
1621
|
}
|
|
@@ -1383,9 +1637,7 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1383
1637
|
for (const { testResults, testFilePath } of result.results.testResults) {
|
|
1384
1638
|
const suite = getTestSuitePath(testFilePath, result.globalConfig.rootDir)
|
|
1385
1639
|
for (const { fullName } of testResults) {
|
|
1386
|
-
const name =
|
|
1387
|
-
? fullName.replace(SEED_SUFFIX_RE, '')
|
|
1388
|
-
: fullName
|
|
1640
|
+
const name = removeSeedSuffixFromTestName(fullName)
|
|
1389
1641
|
fullNameToSuite.set(name, suite)
|
|
1390
1642
|
}
|
|
1391
1643
|
}
|
|
@@ -1424,10 +1676,8 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1424
1676
|
.testResults.flatMap(({ testResults, testFilePath: testSuiteAbsolutePath }) => (
|
|
1425
1677
|
testResults.map(({ fullName: testName, status }) => (
|
|
1426
1678
|
{
|
|
1427
|
-
// Strip
|
|
1428
|
-
testName:
|
|
1429
|
-
? testName.replace(SEED_SUFFIX_RE, '')
|
|
1430
|
-
: testName,
|
|
1679
|
+
// Strip seed suffix so the name matches what was reported via TEST_NAME.
|
|
1680
|
+
testName: removeSeedSuffixFromTestName(testName),
|
|
1431
1681
|
testSuiteAbsolutePath,
|
|
1432
1682
|
status,
|
|
1433
1683
|
}
|
|
@@ -1546,7 +1796,9 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1546
1796
|
isSuitesSkipped,
|
|
1547
1797
|
isSuitesSkippingEnabled,
|
|
1548
1798
|
isCodeCoverageEnabled,
|
|
1799
|
+
isCoverageReportUploadEnabled,
|
|
1549
1800
|
testCodeCoverageLinesTotal,
|
|
1801
|
+
testSessionCoverageFiles,
|
|
1550
1802
|
numSkippedSuites,
|
|
1551
1803
|
hasUnskippableSuites,
|
|
1552
1804
|
hasForcedToRunSuites,
|
|
@@ -1572,7 +1824,7 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1572
1824
|
|
|
1573
1825
|
logSessionSummary(ignoredFailuresSummary, getAttemptToFixExecutionsFromJestResults(result))
|
|
1574
1826
|
|
|
1575
|
-
|
|
1827
|
+
resetSuiteSkippingRunState()
|
|
1576
1828
|
|
|
1577
1829
|
return result
|
|
1578
1830
|
}, {
|
|
@@ -1581,28 +1833,6 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1581
1833
|
}
|
|
1582
1834
|
}
|
|
1583
1835
|
|
|
1584
|
-
function coverageReporterWrapper (coverageReporter) {
|
|
1585
|
-
const CoverageReporter = coverageReporter.default ?? coverageReporter
|
|
1586
|
-
|
|
1587
|
-
/**
|
|
1588
|
-
* If ITR is active, we're running fewer tests, so of course the total code coverage is reduced.
|
|
1589
|
-
* This calculation adds no value, so we'll skip it, as long as the user has not manually opted in to code coverage,
|
|
1590
|
-
* in which case we'll leave it.
|
|
1591
|
-
*/
|
|
1592
|
-
// `_addUntestedFiles` is an async function
|
|
1593
|
-
shimmer.wrap(CoverageReporter.prototype, '_addUntestedFiles', addUntestedFiles => function (...args) {
|
|
1594
|
-
if (DD_TEST_TIA_KEEP_COV_CONFIG) {
|
|
1595
|
-
return addUntestedFiles.apply(this, args)
|
|
1596
|
-
}
|
|
1597
|
-
if (isCodeCoverageEnabledBecauseOfUs) {
|
|
1598
|
-
return Promise.resolve()
|
|
1599
|
-
}
|
|
1600
|
-
return addUntestedFiles.apply(this, args)
|
|
1601
|
-
})
|
|
1602
|
-
|
|
1603
|
-
return coverageReporter
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
1836
|
function shouldWaitForTestSuiteFinish (environment) {
|
|
1607
1837
|
return isJestWorker && environment.globalConfig?.workerIdleMemoryLimit !== undefined
|
|
1608
1838
|
}
|
|
@@ -1626,7 +1856,6 @@ function publishTestSuiteFinish (payload, waitForFinish) {
|
|
|
1626
1856
|
|
|
1627
1857
|
function cleanupTestSuiteState (testSuiteAbsolutePath) {
|
|
1628
1858
|
testSuiteMockedFiles.delete(testSuiteAbsolutePath)
|
|
1629
|
-
testSuiteFastCheckUsage.delete(testSuiteAbsolutePath)
|
|
1630
1859
|
testSuiteJestObjects.delete(testSuiteAbsolutePath)
|
|
1631
1860
|
}
|
|
1632
1861
|
|
|
@@ -1681,6 +1910,23 @@ addHook({
|
|
|
1681
1910
|
return sequencerPackage
|
|
1682
1911
|
})
|
|
1683
1912
|
|
|
1913
|
+
addHook({
|
|
1914
|
+
name: '@jest/core',
|
|
1915
|
+
file: 'build/cli/index.js',
|
|
1916
|
+
versions: [MINIMUM_JEST_VERSION_BEFORE_30],
|
|
1917
|
+
}, getCliWrapper(false))
|
|
1918
|
+
|
|
1919
|
+
addHook({
|
|
1920
|
+
name: '@jest/core',
|
|
1921
|
+
versions: ['>=30.0.0'],
|
|
1922
|
+
}, getCliWrapper(true))
|
|
1923
|
+
|
|
1924
|
+
addHook({
|
|
1925
|
+
name: '@jest/core',
|
|
1926
|
+
file: 'build/ReporterDispatcher.js',
|
|
1927
|
+
versions: [MINIMUM_JEST_VERSION],
|
|
1928
|
+
}, reporterDispatcherWrapper)
|
|
1929
|
+
|
|
1684
1930
|
if (DD_MAJOR < 6) {
|
|
1685
1931
|
addHook({
|
|
1686
1932
|
name: '@jest/reporters',
|
|
@@ -1689,29 +1935,16 @@ if (DD_MAJOR < 6) {
|
|
|
1689
1935
|
}, coverageReporterWrapper)
|
|
1690
1936
|
}
|
|
1691
1937
|
|
|
1692
|
-
addHook({
|
|
1693
|
-
name: '@jest/reporters',
|
|
1694
|
-
file: 'build/CoverageReporter.js',
|
|
1695
|
-
versions: [DD_MAJOR >= 6 ? '>=28.0.0' : '>=26.6.2'],
|
|
1696
|
-
}, coverageReporterWrapper)
|
|
1697
|
-
|
|
1698
1938
|
addHook({
|
|
1699
1939
|
name: '@jest/reporters',
|
|
1700
1940
|
versions: ['>=30.0.0'],
|
|
1701
|
-
},
|
|
1702
|
-
return shimmer.wrap(reporters, 'CoverageReporter', coverageReporterWrapper, { replaceGetter: true })
|
|
1703
|
-
})
|
|
1704
|
-
|
|
1705
|
-
addHook({
|
|
1706
|
-
name: '@jest/core',
|
|
1707
|
-
file: 'build/cli/index.js',
|
|
1708
|
-
versions: [MINIMUM_JEST_VERSION_BEFORE_30],
|
|
1709
|
-
}, getCliWrapper(false))
|
|
1941
|
+
}, reportersWrapper)
|
|
1710
1942
|
|
|
1711
1943
|
addHook({
|
|
1712
|
-
name: '@jest/
|
|
1713
|
-
|
|
1714
|
-
|
|
1944
|
+
name: '@jest/reporters',
|
|
1945
|
+
file: 'build/CoverageReporter.js',
|
|
1946
|
+
versions: [DD_MAJOR >= 6 ? '>=28.0.0' : '>=26.6.2'],
|
|
1947
|
+
}, coverageReporterWrapper)
|
|
1715
1948
|
|
|
1716
1949
|
function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
1717
1950
|
const adapter = jestAdapter.default ?? jestAdapter
|
|
@@ -1745,10 +1978,13 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
1745
1978
|
if (environment.testEnvironmentOptions?._ddTestCodeCoverageEnabled) {
|
|
1746
1979
|
const root = environment.repositoryRoot || environment.rootDir
|
|
1747
1980
|
|
|
1748
|
-
const
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1981
|
+
const coverageFiles = getCoveredFilesFromCoverage(environment.global.__coverage__)
|
|
1982
|
+
.map(file => ({
|
|
1983
|
+
...file,
|
|
1984
|
+
filename: getTestSuitePath(file.filename, root),
|
|
1985
|
+
}))
|
|
1986
|
+
const mockedFiles = getMockedFiles(environment.testSuiteAbsolutePath)
|
|
1987
|
+
.map(file => getTestSuitePath(file, root))
|
|
1752
1988
|
|
|
1753
1989
|
testSuiteCodeCoverageCh.publish({
|
|
1754
1990
|
coverageFiles,
|
|
@@ -1828,41 +2064,48 @@ addHook({
|
|
|
1828
2064
|
}, jestAdapterWrapper)
|
|
1829
2065
|
|
|
1830
2066
|
function configureTestEnvironment (readConfigsResult) {
|
|
1831
|
-
|
|
1832
|
-
testSessionConfigurationCh.publish(configs.map(config => config.testEnvironmentOptions))
|
|
1833
|
-
// We can't directly use isCodeCoverageEnabled when reporting coverage in `jestAdapterWrapper`
|
|
1834
|
-
// because `jestAdapterWrapper` runs in a different process. We have to go through `testEnvironmentOptions`
|
|
1835
|
-
for (const config of configs) {
|
|
1836
|
-
config.testEnvironmentOptions._ddTestCodeCoverageEnabled = isCodeCoverageEnabled
|
|
1837
|
-
}
|
|
1838
|
-
|
|
2067
|
+
repositoryRoot = getJestRepositoryRoot(readConfigsResult)
|
|
1839
2068
|
isUserCodeCoverageEnabled = !!readConfigsResult.globalConfig.collectCoverage
|
|
1840
|
-
isCodeCoverageEnabledBecauseOfUs =
|
|
1841
|
-
|
|
1842
|
-
if (readConfigsResult.globalConfig.forceExit) {
|
|
1843
|
-
log.warn("Jest's '--forceExit' flag has been passed. This may cause loss of data.")
|
|
1844
|
-
}
|
|
2069
|
+
const isCodeCoverageEnabledBecauseOfUs = shouldCollectJestCoverageForTia() && !isUserCodeCoverageEnabled
|
|
1845
2070
|
|
|
1846
2071
|
if (isCodeCoverageEnabledBecauseOfUs) {
|
|
1847
|
-
|
|
2072
|
+
readConfigsResult.globalConfig = {
|
|
1848
2073
|
...readConfigsResult.globalConfig,
|
|
1849
2074
|
collectCoverage: true,
|
|
2075
|
+
coverageReporters: ['none'],
|
|
1850
2076
|
}
|
|
1851
|
-
readConfigsResult.
|
|
2077
|
+
readConfigsResult.configs = readConfigsResult.configs.map(config => ({
|
|
2078
|
+
...config,
|
|
2079
|
+
coverageReporters: ['none'],
|
|
2080
|
+
}))
|
|
1852
2081
|
}
|
|
2082
|
+
|
|
2083
|
+
// We can't directly use the parent process flags when reporting suite coverage in `jestAdapterWrapper`
|
|
2084
|
+
// because `jestAdapterWrapper` runs in a different process. We have to go through `testEnvironmentOptions`.
|
|
2085
|
+
const configs = readConfigsResult.configs.map(config => {
|
|
2086
|
+
const testEnvironmentOptions = config.testEnvironmentOptions || {}
|
|
2087
|
+
testEnvironmentOptions._ddRepositoryRoot = repositoryRoot
|
|
2088
|
+
testEnvironmentOptions._ddTestCodeCoverageEnabled = shouldReportJestSuiteCoverageForTia()
|
|
2089
|
+
|
|
2090
|
+
return {
|
|
2091
|
+
...config,
|
|
2092
|
+
testEnvironmentOptions,
|
|
2093
|
+
}
|
|
2094
|
+
})
|
|
2095
|
+
readConfigsResult.configs = configs
|
|
2096
|
+
testSessionConfigurationCh.publish(readConfigsResult.configs.map(config => config.testEnvironmentOptions))
|
|
2097
|
+
repositoryRoot = getJestRepositoryRoot(readConfigsResult)
|
|
2098
|
+
|
|
2099
|
+
if (readConfigsResult.globalConfig.forceExit) {
|
|
2100
|
+
log.warn("Jest's '--forceExit' flag has been passed. This may cause loss of data.")
|
|
2101
|
+
}
|
|
2102
|
+
|
|
1853
2103
|
if (isSuitesSkippingEnabled) {
|
|
1854
2104
|
// If suite skipping is enabled, we pass `passWithNoTests` in case every test gets skipped.
|
|
1855
2105
|
const globalConfig = {
|
|
1856
2106
|
...readConfigsResult.globalConfig,
|
|
1857
2107
|
passWithNoTests: true,
|
|
1858
2108
|
}
|
|
1859
|
-
if (isCodeCoverageEnabledBecauseOfUs && !DD_TEST_TIA_KEEP_COV_CONFIG) {
|
|
1860
|
-
globalConfig.coverageReporters = ['none']
|
|
1861
|
-
readConfigsResult.configs = configs.map(config => ({
|
|
1862
|
-
...config,
|
|
1863
|
-
coverageReporters: ['none'],
|
|
1864
|
-
}))
|
|
1865
|
-
}
|
|
1866
2109
|
readConfigsResult.globalConfig = globalConfig
|
|
1867
2110
|
}
|
|
1868
2111
|
|
|
@@ -1897,6 +2140,7 @@ const DD_TEST_ENVIRONMENT_OPTION_KEYS = [
|
|
|
1897
2140
|
'_ddIsEarlyFlakeDetectionEnabled',
|
|
1898
2141
|
'_ddEarlyFlakeDetectionSlowTestRetries',
|
|
1899
2142
|
'_ddRepositoryRoot',
|
|
2143
|
+
'_ddTestCodeCoverageEnabled',
|
|
1900
2144
|
'_ddIsFlakyTestRetriesEnabled',
|
|
1901
2145
|
'_ddFlakyTestRetriesCount',
|
|
1902
2146
|
'_ddItrSkippingEnabledTags',
|
|
@@ -2080,38 +2324,6 @@ function wrapJestGlobalsForRuntime (runtime) {
|
|
|
2080
2324
|
})
|
|
2081
2325
|
}
|
|
2082
2326
|
|
|
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
2327
|
function getLastLoggedReferenceError (runtime) {
|
|
2116
2328
|
const loggedReferenceErrors = runtime?.loggedReferenceErrors
|
|
2117
2329
|
if (!loggedReferenceErrors?.size) return
|
|
@@ -2220,8 +2432,6 @@ addHook({
|
|
|
2220
2432
|
// To bypass jest's own require engine
|
|
2221
2433
|
return requireOutsideJestRequireEngine(this, moduleName)
|
|
2222
2434
|
}
|
|
2223
|
-
// This means that `@fast-check/jest` is used in the test file.
|
|
2224
|
-
recordFastCheckUsage(this, from, moduleName)
|
|
2225
2435
|
let returnedValue
|
|
2226
2436
|
try {
|
|
2227
2437
|
returnedValue = requireModuleOrMock.apply(this, arguments)
|