dd-trace 6.16.0 → 6.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/ci/diagnose.js +0 -23
  2. package/ci/test-optimization-validation/approval-artifacts.js +0 -3
  3. package/ci/test-optimization-validation/approval.js +0 -6
  4. package/ci/test-optimization-validation/artifact-id.js +0 -1
  5. package/ci/test-optimization-validation/bounded-json.js +0 -1
  6. package/ci/test-optimization-validation/cli.js +0 -12
  7. package/ci/test-optimization-validation/command-output-policy.js +0 -1
  8. package/ci/test-optimization-validation/command-runner.js +0 -3
  9. package/ci/test-optimization-validation/environment.js +0 -4
  10. package/ci/test-optimization-validation/executable-approval.js +0 -1
  11. package/ci/test-optimization-validation/executable.js +0 -5
  12. package/ci/test-optimization-validation/framework-adapters/cucumber.js +0 -6
  13. package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
  14. package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
  15. package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
  16. package/ci/test-optimization-validation/generated-test-contract.js +0 -5
  17. package/ci/test-optimization-validation/generated-verifier.js +0 -1
  18. package/ci/test-optimization-validation/literal-environment.js +0 -1
  19. package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
  20. package/ci/test-optimization-validation/manifest-schema.js +0 -21
  21. package/ci/test-optimization-validation/offline-fixtures.js +0 -4
  22. package/ci/test-optimization-validation/plan-writer.js +0 -11
  23. package/ci/test-optimization-validation/preflight-runner.js +0 -1
  24. package/ci/test-optimization-validation/redaction.js +0 -4
  25. package/ci/test-optimization-validation/report-writer.js +0 -16
  26. package/ci/test-optimization-validation/runner-command.js +0 -3
  27. package/ci/test-optimization-validation/runner-contract.js +0 -4
  28. package/ci/test-optimization-validation/safe-files.js +0 -1
  29. package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
  30. package/ci/test-optimization-validation/scenarios/ci-wiring.js +0 -1
  31. package/ci/test-optimization-validation/source-text.js +0 -3
  32. package/ci/vitest-no-worker-init-setup.mjs +41 -16
  33. package/index.d.ts +165 -0
  34. package/package.json +17 -16
  35. package/packages/datadog-esbuild/src/utils.js +0 -2
  36. package/packages/datadog-instrumentations/src/aerospike.js +28 -6
  37. package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -2
  38. package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
  39. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +0 -2
  40. package/packages/datadog-instrumentations/src/console.js +97 -0
  41. package/packages/datadog-instrumentations/src/cucumber.js +72 -12
  42. package/packages/datadog-instrumentations/src/cypress-config.js +0 -23
  43. package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
  44. package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
  45. package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -0
  46. package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +0 -3
  47. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
  48. package/packages/datadog-instrumentations/src/helpers/register.js +4 -0
  49. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +72 -24
  50. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +39 -0
  51. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -17
  52. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +12 -0
  53. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
  54. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
  55. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +16 -0
  56. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
  57. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +0 -5
  58. package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
  59. package/packages/datadog-instrumentations/src/jest.js +141 -51
  60. package/packages/datadog-instrumentations/src/knex.js +0 -1
  61. package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
  62. package/packages/datadog-instrumentations/src/mariadb.js +0 -2
  63. package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
  64. package/packages/datadog-instrumentations/src/mocha/main.js +22 -25
  65. package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
  66. package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
  67. package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
  68. package/packages/datadog-instrumentations/src/mysql2.js +0 -2
  69. package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
  70. package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
  71. package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
  72. package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
  73. package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
  74. package/packages/datadog-instrumentations/src/openai.js +51 -12
  75. package/packages/datadog-instrumentations/src/oracledb.js +9 -3
  76. package/packages/datadog-instrumentations/src/playwright-reporter.js +3 -16
  77. package/packages/datadog-instrumentations/src/playwright.js +238 -55
  78. package/packages/datadog-instrumentations/src/postgres.js +7 -0
  79. package/packages/datadog-instrumentations/src/router.js +0 -2
  80. package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
  81. package/packages/datadog-instrumentations/src/sequelize.js +0 -1
  82. package/packages/datadog-instrumentations/src/supabase.js +15 -0
  83. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
  84. package/packages/datadog-instrumentations/src/vitest-main.js +37 -17
  85. package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
  86. package/packages/datadog-instrumentations/src/vitest-worker.js +49 -13
  87. package/packages/datadog-instrumentations/src/webdriverio.js +23 -42
  88. package/packages/datadog-instrumentations/src/ws.js +0 -1
  89. package/packages/datadog-plugin-ai/src/utils.js +0 -2
  90. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
  91. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
  92. package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
  93. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +0 -1
  94. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
  95. package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
  96. package/packages/datadog-plugin-azure-durable-functions/src/index.js +0 -1
  97. package/packages/datadog-plugin-cucumber/src/index.js +10 -0
  98. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +171 -75
  99. package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
  100. package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
  101. package/packages/datadog-plugin-cypress/src/support.js +52 -7
  102. package/packages/datadog-plugin-graphql/src/resolve-error.js +1 -2
  103. package/packages/datadog-plugin-graphql/src/utils.js +0 -5
  104. package/packages/datadog-plugin-jest/src/index.js +13 -0
  105. package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
  106. package/packages/datadog-plugin-mocha/src/index.js +39 -11
  107. package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
  108. package/packages/datadog-plugin-openai/src/index.js +16 -1
  109. package/packages/datadog-plugin-openai/src/realtime.js +144 -0
  110. package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
  111. package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
  112. package/packages/datadog-plugin-playwright/src/index.js +76 -9
  113. package/packages/datadog-plugin-postgres/src/index.js +167 -0
  114. package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
  115. package/packages/datadog-plugin-redis/src/index.js +15 -1
  116. package/packages/datadog-plugin-supabase/src/error.js +18 -0
  117. package/packages/datadog-plugin-supabase/src/index.js +21 -0
  118. package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
  119. package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
  120. package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
  121. package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
  122. package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
  123. package/packages/datadog-plugin-supabase/src/url.js +17 -0
  124. package/packages/datadog-plugin-vitest/src/index.js +10 -0
  125. package/packages/datadog-plugin-ws/src/util.js +0 -4
  126. package/packages/datadog-turbopack/index.js +0 -6
  127. package/packages/datadog-turbopack/src/loader.js +0 -16
  128. package/packages/datadog-webpack/src/loader.js +0 -1
  129. package/packages/dd-trace/src/aiguard/client.js +2 -3
  130. package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
  131. package/packages/dd-trace/src/aiguard/index.js +2 -2
  132. package/packages/dd-trace/src/aiguard/integrations/index.js +1 -1
  133. package/packages/dd-trace/src/aiguard/integrations/openai.js +81 -7
  134. package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
  135. package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
  136. package/packages/dd-trace/src/aiguard/messages/utils.js +0 -1
  137. package/packages/dd-trace/src/aiguard/redaction.js +0 -1
  138. package/packages/dd-trace/src/aiguard/sdk.js +1 -1
  139. package/packages/dd-trace/src/appsec/activation.js +1 -1
  140. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
  141. package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
  142. package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
  143. package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
  144. package/packages/dd-trace/src/appsec/iast/index.js +1 -1
  145. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
  146. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
  147. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
  148. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
  149. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
  150. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
  151. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
  152. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
  153. package/packages/dd-trace/src/appsec/index.js +2 -2
  154. package/packages/dd-trace/src/appsec/lambda.js +71 -2
  155. package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
  156. package/packages/dd-trace/src/appsec/remote_config.js +8 -6
  157. package/packages/dd-trace/src/appsec/reporter.js +10 -6
  158. package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
  159. package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
  160. package/packages/dd-trace/src/appsec/waf/index.js +2 -2
  161. package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
  162. package/packages/dd-trace/src/carrier.js +0 -5
  163. package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
  164. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
  165. package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
  166. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
  167. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
  168. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
  169. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
  170. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
  171. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
  172. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
  173. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
  174. package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
  175. package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
  176. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
  177. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
  178. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
  179. package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
  180. package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
  181. package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
  182. package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
  183. package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
  184. package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
  185. package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
  186. package/packages/dd-trace/src/config/defaults.js +3 -2
  187. package/packages/dd-trace/src/config/generated-config-types.d.ts +73 -67
  188. package/packages/dd-trace/src/config/helper.js +0 -1
  189. package/packages/dd-trace/src/config/index.js +24 -24
  190. package/packages/dd-trace/src/config/parsers.js +34 -6
  191. package/packages/dd-trace/src/config/remote_config.js +25 -109
  192. package/packages/dd-trace/src/config/supported-configurations.json +139 -10
  193. package/packages/dd-trace/src/datastreams/encoding.js +0 -1
  194. package/packages/dd-trace/src/datastreams/pathway.js +0 -1
  195. package/packages/dd-trace/src/debugger/constants.js +10 -0
  196. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +62 -10
  197. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  198. package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
  199. package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
  200. package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
  201. package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
  202. package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +21 -8
  203. package/packages/dd-trace/src/debugger/devtools_client/send.js +40 -14
  204. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
  205. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
  206. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
  207. package/packages/dd-trace/src/debugger/devtools_client/status.js +20 -6
  208. package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
  209. package/packages/dd-trace/src/debugger/index.js +50 -2
  210. package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
  211. package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
  212. package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
  213. package/packages/dd-trace/src/dogstatsd.js +0 -23
  214. package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
  215. package/packages/dd-trace/src/encode/0.4.js +0 -7
  216. package/packages/dd-trace/src/encode/0.5.js +0 -2
  217. package/packages/dd-trace/src/encode/tags-processors.js +0 -1
  218. package/packages/dd-trace/src/evp_proxy/discovery.js +0 -1
  219. package/packages/dd-trace/src/evp_proxy/path.js +0 -2
  220. package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
  221. package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
  222. package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
  223. package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
  224. package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
  225. package/packages/dd-trace/src/exporters/common/request.js +1 -0
  226. package/packages/dd-trace/src/exporters/common/url.js +0 -2
  227. package/packages/dd-trace/src/exporters/common/writer.js +0 -2
  228. package/packages/dd-trace/src/id.js +0 -11
  229. package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
  230. package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
  231. package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
  232. package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
  233. package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
  234. package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
  235. package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
  236. package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
  237. package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
  238. package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
  239. package/packages/dd-trace/src/llmobs/index.js +1 -3
  240. package/packages/dd-trace/src/llmobs/noop.js +10 -0
  241. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
  242. package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
  243. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
  244. package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
  245. package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
  246. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
  247. package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
  248. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
  249. package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
  250. package/packages/dd-trace/src/llmobs/prompts/manager.js +639 -0
  251. package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
  252. package/packages/dd-trace/src/llmobs/prompts/prompt.js +92 -0
  253. package/packages/dd-trace/src/llmobs/sdk.js +21 -6
  254. package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
  255. package/packages/dd-trace/src/llmobs/tagger.js +30 -7
  256. package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
  257. package/packages/dd-trace/src/llmobs/util.js +0 -34
  258. package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
  259. package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
  260. package/packages/dd-trace/src/log/channels.js +3 -0
  261. package/packages/dd-trace/src/log/index.js +23 -5
  262. package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
  263. package/packages/dd-trace/src/msgpack/chunk.js +0 -1
  264. package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
  265. package/packages/dd-trace/src/openfeature/encoding.js +0 -2
  266. package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
  267. package/packages/dd-trace/src/openfeature/index.js +0 -4
  268. package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
  269. package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
  270. package/packages/dd-trace/src/openfeature/writers/base.js +0 -6
  271. package/packages/dd-trace/src/openfeature/writers/exposures.js +0 -5
  272. package/packages/dd-trace/src/openfeature/writers/util.js +0 -4
  273. package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
  274. package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
  275. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
  276. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
  277. package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +0 -1
  278. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
  279. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
  280. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -14
  281. package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
  282. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +30 -13
  283. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
  284. package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
  285. package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
  286. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
  287. package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
  288. package/packages/dd-trace/src/opentracing/span_context.js +0 -1
  289. package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
  290. package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
  291. package/packages/dd-trace/src/plugins/ci_plugin.js +0 -1
  292. package/packages/dd-trace/src/plugins/database.js +2 -6
  293. package/packages/dd-trace/src/plugins/index.js +7 -0
  294. package/packages/dd-trace/src/plugins/plugin.js +0 -4
  295. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  296. package/packages/dd-trace/src/plugins/util/git.js +1 -3
  297. package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
  298. package/packages/dd-trace/src/plugins/util/llm.js +0 -2
  299. package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
  300. package/packages/dd-trace/src/plugins/util/test.js +21 -20
  301. package/packages/dd-trace/src/plugins/util/url.js +0 -5
  302. package/packages/dd-trace/src/priority_sampler.js +0 -6
  303. package/packages/dd-trace/src/process-tags/index.js +0 -1
  304. package/packages/dd-trace/src/profiler.js +132 -35
  305. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
  306. package/packages/dd-trace/src/profiling/profiler.js +101 -41
  307. package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
  308. package/packages/dd-trace/src/propagation-hash/index.js +0 -1
  309. package/packages/dd-trace/src/proxy.js +21 -45
  310. package/packages/dd-trace/src/random_sampler.js +0 -4
  311. package/packages/dd-trace/src/rate_limiter.js +0 -4
  312. package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
  313. package/packages/dd-trace/src/remote_config/index.js +0 -1
  314. package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
  315. package/packages/dd-trace/src/sampler.js +0 -4
  316. package/packages/dd-trace/src/sampling_rule.js +0 -7
  317. package/packages/dd-trace/src/serverless/vercel.js +0 -1
  318. package/packages/dd-trace/src/serverless.js +0 -1
  319. package/packages/dd-trace/src/service-naming/index.js +0 -1
  320. package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
  321. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
  322. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
  323. package/packages/dd-trace/src/span_processor.js +2 -2
  324. package/packages/dd-trace/src/span_sampler.js +0 -1
  325. package/packages/dd-trace/src/standalone/product.js +2 -2
  326. package/packages/dd-trace/src/standalone/tracesource.js +0 -1
  327. package/packages/dd-trace/src/startup-log.js +1 -1
  328. package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
  329. package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
  330. package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
  331. package/packages/dd-trace/src/telemetry/metrics.js +0 -2
  332. package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
  333. package/packages/dd-trace/src/util.js +13 -1
  334. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
@@ -18,6 +18,9 @@ const {
18
18
  getEfdRetryCountForDuration,
19
19
  hasEfdRetries,
20
20
  } = require('../../dd-trace/src/ci-visibility/efd-retry-policy')
21
+ const {
22
+ getDynamicAtrRetryCount,
23
+ } = require('../../dd-trace/src/ci-visibility/dynamic-atr-retries')
21
24
  const { FINAL_FLUSH_FALLBACK_DELAY, FINAL_FLUSH_TIMEOUT } =
22
25
  require('../../dd-trace/src/ci-visibility/final-flush')
23
26
  const {
@@ -85,6 +88,8 @@ const testFinishCh = channel('ci:jest:test:finish')
85
88
  const testErrCh = channel('ci:jest:test:err')
86
89
  const testFnCh = channel('ci:jest:test:fn')
87
90
  const testSuiteHookFnCh = channel('ci:jest:test-suite:hook:fn')
91
+ const consoleLogSubmissionCh = channel('ci:log-submission:console')
92
+ const logSubmissionFlushCh = channel('ci:log-submission:flush')
88
93
 
89
94
  const skippableSuitesCh = channel('ci:jest:test-suite:skippable')
90
95
  const libraryConfigurationCh = channel('ci:jest:library-configuration')
@@ -171,6 +176,14 @@ const efdExpectedExecutions = new Map()
171
176
  const efdSlowAbortedTests = new Set()
172
177
  // Tests whose first execution determines the duration-based EFD retry count.
173
178
  const efdCandidates = new Set()
179
+ // Per-declaration dynamic ATR retry count, retained across attempts of the same Jest test object.
180
+ const dynamicAtrRetryCountByTest = new Map()
181
+ // Jest only accepts a suite-wide retry ceiling. Terminal dynamic failures are
182
+ // temporarily cleared to keep that ceiling from scheduling another retry, then
183
+ // restored before Jest reports the suite result.
184
+ const dynamicAtrFinalErrorsByTest = new Map()
185
+ // Custom environments may prevent extensions after their base constructor runs.
186
+ const dynamicAtrResultHandlerRegistrations = new WeakMap()
174
187
  // Tests that are genuinely new (not in known tests list).
175
188
  const newTests = new Set()
176
189
  const testSuiteJestObjects = new Map()
@@ -256,7 +269,6 @@ function getJestRepositoryRoot (readConfigsResult) {
256
269
  * Returns true if the data was sent (worker mode), false if in main process (runInBand).
257
270
  *
258
271
  * @param {string[]} testNames
259
- * @returns {boolean}
260
272
  */
261
273
  function sendQuarantineInfoToMainProcess (testNames) {
262
274
  const payload = [JEST_WORKER_QUARANTINE_PAYLOAD_CODE, JSON.stringify(testNames)]
@@ -342,7 +354,6 @@ function getTestStats (testStatuses) {
342
354
  * totalCount: number,
343
355
  * efdFailureCount: number
344
356
  * } | undefined} ignoredFailures
345
- * @returns {string}
346
357
  */
347
358
  function formatIgnoredFailuresSummary (ignoredFailures) {
348
359
  if (!ignoredFailures?.efdFailureCount) return ''
@@ -515,7 +526,6 @@ function getOriginalConcurrentTest (concurrentTest) {
515
526
  *
516
527
  * @param {(...args: unknown[]) => unknown} wrappedConcurrentTest
517
528
  * @param {(...args: unknown[]) => unknown} originalConcurrentTest
518
- * @returns {void}
519
529
  */
520
530
  function setOriginalConcurrentTest (wrappedConcurrentTest, originalConcurrentTest) {
521
531
  Object.defineProperty(wrappedConcurrentTest, DD_JEST_CONCURRENT_TEST_ORIGINAL, {
@@ -524,6 +534,31 @@ function setOriginalConcurrentTest (wrappedConcurrentTest, originalConcurrentTes
524
534
  })
525
535
  }
526
536
 
537
+ /**
538
+ * Stops further retries only after Jest's test-result handlers have observed the failure.
539
+ *
540
+ * @param {{ name: string, test?: { errors: unknown[] } }} event
541
+ */
542
+ function suppressDynamicAtrErrors (event) {
543
+ if (event.name === 'test_done' && dynamicAtrFinalErrorsByTest.has(event.test)) {
544
+ event.test.errors = []
545
+ }
546
+ }
547
+
548
+ /**
549
+ * Restores terminal failures before custom environments inspect the completed describe block.
550
+ *
551
+ * @param {{ name: string }} event
552
+ */
553
+ function restoreDynamicAtrErrors (event) {
554
+ if (event.name !== 'run_describe_finish' || dynamicAtrFinalErrorsByTest.size === 0) return
555
+
556
+ for (const [test, errors] of dynamicAtrFinalErrorsByTest) {
557
+ test.errors = errors
558
+ }
559
+ dynamicAtrFinalErrorsByTest.clear()
560
+ }
561
+
527
562
  /**
528
563
  * Wraps a custom Jest environment handler so Datadog still observes events even
529
564
  * when the custom environment does not call `super.handleTestEvent`.
@@ -542,6 +577,7 @@ function getWrappedCustomHandleTestEvent (handleTestEvent, datadogHandleTestEven
542
577
  }
543
578
 
544
579
  const wrappedHandleTestEvent = function (event, state) {
580
+ restoreDynamicAtrErrors(event)
545
581
  const result = handleTestEvent.call(this, event, state)
546
582
  const runDatadogHandler = value => {
547
583
  if (isDatadogJestEventHandled(event)) return value
@@ -573,7 +609,6 @@ function getWrappedCustomHandleTestEvent (handleTestEvent, datadogHandleTestEven
573
609
  * @param {object} test
574
610
  * @param {boolean} hasFocusedTests
575
611
  * @param {RegExp|undefined} testNamePattern
576
- * @returns {boolean}
577
612
  */
578
613
  function isJestTestSkipped (test, hasFocusedTests, testNamePattern) {
579
614
  if (
@@ -642,11 +677,14 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
642
677
  this.isEarlyFlakeDetectionEnabled = this.testEnvironmentOptions._ddIsEarlyFlakeDetectionEnabled
643
678
  this.isFlakyTestRetriesEnabled = this.testEnvironmentOptions._ddIsFlakyTestRetriesEnabled
644
679
  this.flakyTestRetriesCount = this.testEnvironmentOptions._ddFlakyTestRetriesCount
680
+ this.isDynamicAtrEnabled = this.testEnvironmentOptions._ddIsDynamicAtrEnabled
681
+ this.dynamicAtrBuckets = this.testEnvironmentOptions._ddDynamicAtrBuckets
645
682
  this.isDiEnabled = this.testEnvironmentOptions._ddIsDiEnabled
646
683
  this.isKnownTestsEnabled = this.testEnvironmentOptions._ddIsKnownTestsEnabled
647
684
  this.isTestManagementTestsEnabled = this.testEnvironmentOptions._ddIsTestManagementTestsEnabled
648
685
  this.isImpactedTestsEnabled = this.testEnvironmentOptions._ddIsImpactedTestsEnabled
649
686
  this.hasConcurrentTests = false
687
+ this.concurrentTestState = undefined
650
688
  this.concurrentTestContexts = new Map()
651
689
  this.concurrentTestStates = new WeakMap()
652
690
  this.concurrentTestSourceFns = new WeakMap()
@@ -678,7 +716,18 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
678
716
  if (this.isFlakyTestRetriesEnabled) {
679
717
  const currentNumRetries = this.global[RETRY_TIMES]
680
718
  if (!currentNumRetries) {
681
- this.global[RETRY_TIMES] = this.flakyTestRetriesCount
719
+ // When dynamic ATR is enabled, use the max bucket value as the initial count.
720
+ // The actual duration-based count is computed per test after the first attempt.
721
+ if (this.isDynamicAtrEnabled) {
722
+ this.global[RETRY_TIMES] = Math.max(
723
+ 1,
724
+ this.dynamicAtrBuckets
725
+ ? Math.max(...this.dynamicAtrBuckets)
726
+ : this.#earlyFlakeDetectionRetryPolicy.schedulingRetryCount
727
+ )
728
+ } else {
729
+ this.global[RETRY_TIMES] = this.flakyTestRetriesCount
730
+ }
682
731
  }
683
732
  }
684
733
 
@@ -733,7 +782,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
733
782
  * Rebuilds serial `test.each` so every generated row function keeps its parameters.
734
783
  *
735
784
  * @param {Function|undefined} test
736
- * @returns {void}
737
785
  */
738
786
  bindTestEach (test) {
739
787
  if (typeof test?.each !== 'function') return
@@ -782,7 +830,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
782
830
  * in older Jest versions execute inside their test span context.
783
831
  *
784
832
  * @param {object} state
785
- * @returns {void}
786
833
  */
787
834
  wrapConcurrentTest (state) {
788
835
  this.concurrentTestState = state
@@ -794,7 +841,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
794
841
  *
795
842
  * @param {Function|undefined} test
796
843
  * @param {object} state
797
- * @returns {void}
798
844
  */
799
845
  wrapConcurrentTestGlobals (test, state) {
800
846
  if (!state) return
@@ -814,7 +860,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
814
860
  * @param {object} target
815
861
  * @param {string} methodName
816
862
  * @param {object} state
817
- * @returns {void}
818
863
  */
819
864
  wrapConcurrentTestFunction (target, methodName, state) {
820
865
  let concurrentTest = target?.[methodName]
@@ -860,7 +905,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
860
905
  *
861
906
  * @param {Function} concurrentTest
862
907
  * @param {boolean} needsEachError
863
- * @returns {void}
864
908
  */
865
909
  bindConcurrentEach (concurrentTest, needsEachError) {
866
910
  if (typeof concurrentTest?.each !== 'function') return
@@ -1000,7 +1044,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1000
1044
  *
1001
1045
  * @param {Error|undefined} asyncError
1002
1046
  * @param {Function|undefined} testFn
1003
- * @returns {boolean}
1004
1047
  */
1005
1048
  isTestModified (asyncError, testFn) {
1006
1049
  if (!this.isImpactedTestsEnabled || !asyncError || typeof testFn !== 'function') return false
@@ -1038,7 +1081,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1038
1081
  *
1039
1082
  * @param {string} testName
1040
1083
  * @param {object} ctx
1041
- * @returns {void}
1042
1084
  */
1043
1085
  removeConcurrentTestContext (testName, ctx) {
1044
1086
  const contexts = this.concurrentTestContexts.get(testName)
@@ -1058,7 +1100,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1058
1100
  *
1059
1101
  * @param {string} name
1060
1102
  * @param {unknown[]} params
1061
- * @returns {void}
1062
1103
  */
1063
1104
  setNameToParams (name, params) {
1064
1105
  this.nameToParams[name] = [...params]
@@ -1069,7 +1110,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1069
1110
  *
1070
1111
  * @param {string} name
1071
1112
  * @param {unknown[]|object} params
1072
- * @returns {void}
1073
1113
  */
1074
1114
  appendNameToParams (name, params) {
1075
1115
  if (this.nameToParams[name]) {
@@ -1082,7 +1122,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1082
1122
  /**
1083
1123
  * @param {object} concurrentTestState
1084
1124
  * @param {number|undefined} startedAt
1085
- * @returns {void}
1086
1125
  */
1087
1126
  completePre30ConcurrentTest (concurrentTestState, startedAt) {
1088
1127
  if (!concurrentTestState.trackEfdCompletion) return
@@ -1123,12 +1162,10 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1123
1162
  enqueueDetachedEfdRetry (retryGate, ctx, run) {
1124
1163
  /**
1125
1164
  * @param {() => void} resolve
1126
- * @returns {void}
1127
1165
  */
1128
1166
  const enqueue = (resolve) => {
1129
1167
  /**
1130
1168
  * @param {boolean} shouldRun
1131
- * @returns {void}
1132
1169
  */
1133
1170
  const onDecision = (shouldRun) => {
1134
1171
  if (!shouldRun) {
@@ -1147,7 +1184,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1147
1184
  const retry = { ctx, resolve, start }
1148
1185
  /**
1149
1186
  * @param {unknown} error
1150
- * @returns {void}
1151
1187
  */
1152
1188
  const onRejected = (error) => {
1153
1189
  retry.ctx.detachedEfdRetryError = error
@@ -1206,9 +1242,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1206
1242
  })
1207
1243
  }
1208
1244
 
1209
- /**
1210
- * @returns {void}
1211
- */
1212
1245
  drainDetachedEfdRetries () {
1213
1246
  const queue = this.#detachedEfdRetryQueue
1214
1247
  if (!queue) return
@@ -1225,7 +1258,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1225
1258
 
1226
1259
  /**
1227
1260
  * @param {DetachedEfdRetry} retry
1228
- * @returns {void}
1229
1261
  */
1230
1262
  finishDetachedEfdRetry (retry) {
1231
1263
  this.#activeDetachedEfdRetries--
@@ -1238,7 +1270,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1238
1270
  *
1239
1271
  * @param {() => unknown} run
1240
1272
  * @param {(error?: Error) => void} done
1241
- * @returns {void}
1242
1273
  */
1243
1274
  runCallbackEfdRetry (run, done) {
1244
1275
  let result
@@ -1324,7 +1355,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1324
1355
  * `handleTestEvent` without calling `super.handleTestEvent`.
1325
1356
  *
1326
1357
  * @param {(event: object, state: object) => Promise<void>|void} datadogHandleTestEvent
1327
- * @returns {void}
1328
1358
  */
1329
1359
  wrapCustomHandleTestEvent (datadogHandleTestEvent) {
1330
1360
  const descriptor = Object.getOwnPropertyDescriptor(this, 'handleTestEvent')
@@ -1471,7 +1501,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1471
1501
  * Registers retry tests while Jest still accepts additions to the test tree.
1472
1502
  *
1473
1503
  * @param {JestRetryOptions} options
1474
- * @returns {number}
1475
1504
  */
1476
1505
  retryTest ({
1477
1506
  concurrentTestState: registeredConcurrentTestState,
@@ -1557,7 +1586,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1557
1586
  * `add_test` dispatch, where Jest would report it as a test file error.
1558
1587
  *
1559
1588
  * @param {JestRetryOptions} retryOptions
1560
- * @returns {boolean}
1561
1589
  */
1562
1590
  registerRetryTests (retryOptions) {
1563
1591
  // Jest turns later additions into "Cannot add a test after tests have started running".
@@ -1606,7 +1634,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1606
1634
  * @param {string} testName
1607
1635
  * @param {object} executedTest The Jest test node that selected the retry count.
1608
1636
  * @param {number} [retryCount] Retries to keep. Every retry is dropped when omitted.
1609
- * @returns {number} Retries left to run.
1610
1637
  */
1611
1638
  discardEfdRetries (testName, executedTest, retryCount = 0) {
1612
1639
  const siblings = getTestEntries(executedTest.parent)
@@ -1655,7 +1682,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1655
1682
  * @param {object} describeBlock
1656
1683
  * @param {boolean} hasFocusedTests
1657
1684
  * @param {RegExp|undefined} testNamePattern
1658
- * @returns {number}
1659
1685
  */
1660
1686
  markPre30ConcurrentTests (describeBlock, hasFocusedTests, testNamePattern) {
1661
1687
  if (describeBlock.mode === 'skip') return 0
@@ -1687,7 +1713,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1687
1713
  /**
1688
1714
  * @param {object} describeBlock
1689
1715
  * @param {object} state
1690
- * @returns {void}
1691
1716
  */
1692
1717
  preparePre30ConcurrentTests (describeBlock, state) {
1693
1718
  const testNamePattern = state.testNamePattern
@@ -1705,7 +1730,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1705
1730
 
1706
1731
  /**
1707
1732
  * @param {object[]} tests
1708
- * @returns {void}
1709
1733
  */
1710
1734
  orderConcurrentEfdRetries (tests) {
1711
1735
  if (!this.#efdRetryGatesByName) return
@@ -1727,7 +1751,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1727
1751
  /**
1728
1752
  * @param {string} testName
1729
1753
  * @param {number} durationMs
1730
- * @returns {void}
1731
1754
  */
1732
1755
  determineEfdRetries (testName, durationMs) {
1733
1756
  if (efdDeterminedRetries.has(testName)) return
@@ -1746,9 +1769,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1746
1769
  }
1747
1770
  }
1748
1771
 
1749
- /**
1750
- * @returns {void}
1751
- */
1752
1772
  removeDiscardedEfdRetries () {
1753
1773
  if (!this.#discardedEfdRetryTests) return
1754
1774
 
@@ -1774,7 +1794,6 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1774
1794
  *
1775
1795
  * @param {object} event
1776
1796
  * @param {object} state
1777
- * @returns {void}
1778
1797
  */
1779
1798
  handleAddTestEvent (event, state) {
1780
1799
  if (event.concurrent) {
@@ -1879,11 +1898,17 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
1879
1898
  this.handleAddTestEvent(event, state)
1880
1899
  }
1881
1900
 
1901
+ restoreDynamicAtrErrors(event)
1902
+
1882
1903
  if (super.handleTestEvent) {
1883
1904
  await super.handleTestEvent(event, state)
1884
1905
  }
1885
1906
 
1886
- if (event.name === 'setup') {
1907
+ if (event.name === 'run_start') {
1908
+ const registerResultHandler = dynamicAtrResultHandlerRegistrations.get(this)
1909
+ dynamicAtrResultHandlerRegistrations.delete(this)
1910
+ registerResultHandler?.()
1911
+ } else if (event.name === 'setup') {
1887
1912
  this.wrapConcurrentTest(state)
1888
1913
  this.bindTestEach(this.global.test)
1889
1914
  }
@@ -2190,7 +2215,24 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
2190
2215
 
2191
2216
  // ATR: set failedAllTests when all auto test retries were exhausted and every attempt failed
2192
2217
  if (this.isFlakyTestRetriesEnabled && !isAttemptToFix && !isEfdRetry) {
2193
- const maxRetries = Number(this.global[RETRY_TIMES]) || 0
2218
+ // Dynamic ATR: after the first attempt, compute the duration-based retry budget.
2219
+ if (
2220
+ this.isDynamicAtrEnabled &&
2221
+ event.test?.invocations === 1 &&
2222
+ !dynamicAtrRetryCountByTest.has(event.test)
2223
+ ) {
2224
+ const dynamicCount = getDynamicAtrRetryCount(
2225
+ event.test.duration ?? 0,
2226
+ this.#earlyFlakeDetectionRetryPolicy,
2227
+ this.dynamicAtrBuckets
2228
+ )
2229
+ // Jest captures this ceiling when it starts running the describe block.
2230
+ const nativeRetryCount = Math.max(0, Number.parseInt(this.global[RETRY_TIMES], 10) || 0)
2231
+ dynamicAtrRetryCountByTest.set(event.test, Math.min(dynamicCount, nativeRetryCount))
2232
+ }
2233
+ const maxRetries = this.isDynamicAtrEnabled && dynamicAtrRetryCountByTest.has(event.test)
2234
+ ? dynamicAtrRetryCountByTest.get(event.test)
2235
+ : (Number(this.global[RETRY_TIMES]) || 0)
2194
2236
  if (event.test?.invocations === maxRetries + 1 && status === 'fail') {
2195
2237
  failedAllTests = true
2196
2238
  }
@@ -2199,7 +2241,12 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
2199
2241
  const promises = {}
2200
2242
  const numRetries = this.global[RETRY_TIMES]
2201
2243
  const numTestExecutions = event.test?.invocations
2202
- const willBeRetriedByAutoTestRetry = numRetries > 0 && numTestExecutions - 1 < numRetries
2244
+ // Dynamic ATR: use the per-test duration-based count instead of the global flat limit.
2245
+ const dynamicAtrCount = this.isDynamicAtrEnabled && dynamicAtrRetryCountByTest.has(event.test)
2246
+ ? dynamicAtrRetryCountByTest.get(event.test)
2247
+ : undefined
2248
+ const effectiveMaxRetries = dynamicAtrCount === undefined ? numRetries : dynamicAtrCount
2249
+ const willBeRetriedByAutoTestRetry = effectiveMaxRetries > 0 && numTestExecutions - 1 < effectiveMaxRetries
2203
2250
  const isFailedTestReplayAllowed = !this.hasConcurrentTests
2204
2251
  const willBeRetriedByFailedTestReplay = isFailedTestReplayAllowed && willBeRetriedByAutoTestRetry
2205
2252
  const mightHitBreakpoint = this.isDiEnabled && isFailedTestReplayAllowed && numTestExecutions >= 2
@@ -2216,6 +2263,11 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
2216
2263
  }
2217
2264
  }
2218
2265
 
2266
+ // Quarantine must consume terminal failures before we save errors for Jest's final result.
2267
+ if (dynamicAtrCount !== undefined && failedAllTests && event.test.errors?.length) {
2268
+ dynamicAtrFinalErrorsByTest.set(event.test, event.test.errors)
2269
+ }
2270
+
2219
2271
  const ctx = testContexts.get(event.test)
2220
2272
  if (!ctx) {
2221
2273
  log.warn('"ci:jest:test_done": no context found for test "%s"', testName)
@@ -2241,7 +2293,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
2241
2293
  !!ctx.isModified,
2242
2294
  isEfdRetry,
2243
2295
  isAttemptToFix,
2244
- numTestExecutions)
2296
+ numTestExecutions,
2297
+ dynamicAtrCount)
2245
2298
 
2246
2299
  if (status === 'fail') {
2247
2300
  const shouldSetProbe = this.isDiEnabled && willBeRetriedByFailedTestReplay && numTestExecutions === 1
@@ -2310,6 +2363,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
2310
2363
  efdDeterminedRetries.clear()
2311
2364
  efdExpectedExecutions.clear()
2312
2365
  efdSlowAbortedTests.clear()
2366
+ dynamicAtrRetryCountByTest.clear()
2313
2367
  efdCandidates.clear()
2314
2368
  newTests.clear()
2315
2369
  retriedTestsToNumAttempts.clear()
@@ -2365,14 +2419,15 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
2365
2419
  return { isEfdEnabled, isEfdActive, isFinalEfdTestExecution, finalStatus }
2366
2420
  }
2367
2421
 
2368
- getAtrResult ({ status, isEfdRetry, isAttemptToFix, numberOfTestInvocations }) {
2422
+ getAtrResult ({ status, isEfdRetry, isAttemptToFix, numberOfTestInvocations, dynamicAtrRetryCount }) {
2423
+ const maxRetries = dynamicAtrRetryCount ?? Number(this.global[RETRY_TIMES])
2369
2424
  const isAtrEnabled =
2370
2425
  this.isFlakyTestRetriesEnabled &&
2371
2426
  !isEfdRetry &&
2372
2427
  !isAttemptToFix &&
2373
- Number.isFinite(this.global[RETRY_TIMES])
2428
+ Number.isFinite(maxRetries)
2374
2429
  const isLastAtrRetry =
2375
- status === 'pass' || numberOfTestInvocations >= (Number(this.global[RETRY_TIMES]) + 1)
2430
+ status === 'pass' || numberOfTestInvocations >= (maxRetries + 1)
2376
2431
  const isFinalAtrTestExecution = isAtrEnabled && isLastAtrRetry
2377
2432
 
2378
2433
  // For ATR: The last execution's status is what the framework reports
@@ -2404,7 +2459,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
2404
2459
  isModifiedTest,
2405
2460
  isEfdRetry,
2406
2461
  isAttemptToFix,
2407
- numberOfTestInvocations
2462
+ numberOfTestInvocations,
2463
+ dynamicAtrRetryCount
2408
2464
  ) {
2409
2465
  const numberOfExecutedRetries = retriedTestsToNumAttempts.get(testName) ?? 0
2410
2466
 
@@ -2413,7 +2469,13 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
2413
2469
  isNewTest,
2414
2470
  isModifiedTest,
2415
2471
  })
2416
- const atrResult = this.getAtrResult({ status, isEfdRetry, isAttemptToFix, numberOfTestInvocations })
2472
+ const atrResult = this.getAtrResult({
2473
+ status,
2474
+ isEfdRetry,
2475
+ isAttemptToFix,
2476
+ numberOfTestInvocations,
2477
+ dynamicAtrRetryCount,
2478
+ })
2417
2479
  const attemptToFixResult = this.getAttemptToFixResult({
2418
2480
  testName,
2419
2481
  isAttemptToFix,
@@ -2735,7 +2797,10 @@ async function waitForTestSessionFinish (payload) {
2735
2797
 
2736
2798
  publishWithCompletion(testSessionFinishCh, payload, onDone)
2737
2799
 
2738
- const waitingResult = await Promise.race([flushPromise, timeoutPromise])
2800
+ const waitingResult = await Promise.race([
2801
+ Promise.all([flushPromise, getChannelPromise(logSubmissionFlushCh)]),
2802
+ timeoutPromise,
2803
+ ])
2739
2804
 
2740
2805
  if (waitingResult === 'timeout') {
2741
2806
  log.error('Timeout waiting for the tracer to flush')
@@ -3258,14 +3323,16 @@ function getCliWrapper (isNewJestVersion) {
3258
3323
 
3259
3324
  // Determine session status after EFD and quarantine checks have potentially modified success
3260
3325
  let status, error
3326
+ const isExpectedEmptySession = numTotalTests === 0 && numTotalTestSuites === 0
3261
3327
  if (result.results.success) {
3262
- status = numTotalTests === 0 && numTotalTestSuites === 0 ? 'skip' : 'pass'
3328
+ status = isExpectedEmptySession ? 'skip' : 'pass'
3263
3329
  } else {
3264
3330
  status = 'fail'
3265
3331
  error = new Error(`Failed test suites: ${numFailedTestSuites}. Failed tests: ${numFailedTests}`)
3266
3332
  }
3267
3333
 
3268
3334
  await waitForTestSessionFinish(getTestSessionFinishPayload(status, error, {
3335
+ isExpectedEmptySession: result.results.success && isExpectedEmptySession,
3269
3336
  ...getTestSessionCoveragePayload(result.results, result.globalConfig?.rootDir),
3270
3337
  }))
3271
3338
 
@@ -3322,7 +3389,6 @@ function cleanupTestSuiteState (testSuiteAbsolutePath) {
3322
3389
  * Rechecks custom handlers after Jest has finished constructing the environment.
3323
3390
  *
3324
3391
  * @param {object} environment
3325
- * @returns {void}
3326
3392
  */
3327
3393
  function wrapEnvironmentCustomHandleTestEvent (environment) {
3328
3394
  const datadogHandleTestEvent = environment[DD_JEST_HANDLE_TEST_EVENT_DATADOG]
@@ -3426,7 +3492,7 @@ addHook({
3426
3492
  versions: [DD_MAJOR >= 6 ? '>=28.0.0' : '>=26.6.2'],
3427
3493
  }, coverageReporterWrapper)
3428
3494
 
3429
- function jestAdapterWrapper (jestAdapter, jestVersion) {
3495
+ function jestAdapterWrapper (jestAdapter, jestVersion, isIitm, hookMeta) {
3430
3496
  const adapter = jestAdapter.default ?? jestAdapter
3431
3497
  const newAdapter = shimmer.wrapFunction(adapter, adapter => function (...args) {
3432
3498
  const environment = args[2]
@@ -3436,6 +3502,18 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
3436
3502
 
3437
3503
  wrapEnvironmentCustomHandleTestEvent(environment)
3438
3504
 
3505
+ if (environment.isDynamicAtrEnabled && environment.isFlakyTestRetriesEnabled) {
3506
+ // Register at run_start, after Circus installs its per-test reporter and snapshot handlers.
3507
+ dynamicAtrResultHandlerRegistrations.set(environment, () => {
3508
+ if (satisfies(jestVersion, '>=30.0.0')) {
3509
+ environment.global[Symbol.for('EVENT_HANDLERS')].push(suppressDynamicAtrErrors)
3510
+ } else {
3511
+ const circusState = args[3].requireInternalModule(path.join(hookMeta.moduleBaseDir, 'build/state.js'))
3512
+ circusState.addEventHandler(suppressDynamicAtrErrors)
3513
+ }
3514
+ })
3515
+ }
3516
+
3439
3517
  testSuiteStartCh.publish({
3440
3518
  testSuite: environment.testSuite,
3441
3519
  testEnvironmentOptions: environment.testEnvironmentOptions,
@@ -3628,6 +3706,8 @@ const DD_TEST_ENVIRONMENT_OPTION_KEYS = [
3628
3706
  '_ddTestCodeCoverageEnabled',
3629
3707
  '_ddIsFlakyTestRetriesEnabled',
3630
3708
  '_ddFlakyTestRetriesCount',
3709
+ '_ddIsDynamicAtrEnabled',
3710
+ '_ddDynamicAtrBuckets',
3631
3711
  '_ddItrSkippingEnabledTags',
3632
3712
  '_ddIsDiEnabled',
3633
3713
  '_ddIsKnownTestsEnabled',
@@ -3744,6 +3824,19 @@ const JEST_LOGGING_LIBRARIES = new Set([
3744
3824
  const disabledJestInstrumentations = new Set(
3745
3825
  getValueFromEnvSources('DD_TRACE_DISABLED_INSTRUMENTATIONS')?.split(',')
3746
3826
  )
3827
+
3828
+ addHook({
3829
+ name: '@jest/console',
3830
+ versions: [MINIMUM_JEST_VERSION],
3831
+ }, jestConsole => {
3832
+ const isConsoleDisabled = disabledJestInstrumentations.has('console') ||
3833
+ disabledJestInstrumentations.has('node:console')
3834
+ if (!isConsoleDisabled && consoleLogSubmissionCh.hasSubscribers) {
3835
+ require('./console').wrapJestConsole(jestConsole)
3836
+ }
3837
+ return jestConsole
3838
+ })
3839
+
3747
3840
  const LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE = new Set([
3748
3841
  'selenium-webdriver',
3749
3842
  'selenium-webdriver/chrome',
@@ -3887,7 +3980,6 @@ function requireOutsideJestRequireEngine (runtime, moduleName) {
3887
3980
  * @param {object} runtime
3888
3981
  * @param {string} from
3889
3982
  * @param {string} moduleName
3890
- * @returns {void}
3891
3983
  */
3892
3984
  function recordJestEsmLoggingModulePath (runtime, from, moduleName) {
3893
3985
  if (
@@ -3933,7 +4025,6 @@ function getJestEsmLoggingModuleName (runtime, from, modulePath) {
3933
4025
 
3934
4026
  /**
3935
4027
  * @param {object} runtime
3936
- * @returns {void}
3937
4028
  */
3938
4029
  function wrapJestEsmLoader (runtime) {
3939
4030
  const esmLoader = runtime?.esmLoader
@@ -3994,7 +4085,6 @@ function getJestBypassModulePath (runtime, from, moduleName) {
3994
4085
  * @param {object} runtime
3995
4086
  * @param {string} from
3996
4087
  * @param {string} moduleName
3997
- * @returns {string}
3998
4088
  */
3999
4089
  function resolveJestModulePath (runtime, from, moduleName) {
4000
4090
  if (path.isAbsolute(moduleName)) return moduleName
@@ -128,7 +128,6 @@ function wrapCallbackWithFinish (callback, finish, context) {
128
128
 
129
129
  /**
130
130
  * @param {{ pool?: { numFree?: () => number, numPendingAcquires?: () => number } }} client
131
- * @returns {boolean}
132
131
  */
133
132
  function knexHasIdleConnection (client) {
134
133
  const pool = client.pool