dd-trace 5.53.0 → 5.54.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 (319) hide show
  1. package/LICENSE-3rdparty.csv +2 -1
  2. package/index.d.ts +33 -16
  3. package/initialize.mjs +3 -4
  4. package/package.json +36 -34
  5. package/packages/datadog-core/src/utils/src/get.js +1 -1
  6. package/packages/datadog-core/src/utils/src/has.js +1 -1
  7. package/packages/datadog-core/src/utils/src/kebabcase.js +4 -6
  8. package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
  9. package/packages/datadog-core/src/utils/src/pick.js +2 -2
  10. package/packages/datadog-core/src/utils/src/set.js +1 -1
  11. package/packages/datadog-core/src/utils/src/uniq.js +1 -1
  12. package/packages/datadog-instrumentations/src/amqp10.js +19 -17
  13. package/packages/datadog-instrumentations/src/amqplib.js +52 -35
  14. package/packages/datadog-instrumentations/src/apollo.js +2 -2
  15. package/packages/datadog-instrumentations/src/aws-sdk.js +1 -1
  16. package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -4
  17. package/packages/datadog-instrumentations/src/child_process.js +1 -2
  18. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +88 -73
  19. package/packages/datadog-instrumentations/src/couchbase.js +3 -3
  20. package/packages/datadog-instrumentations/src/cucumber.js +87 -40
  21. package/packages/datadog-instrumentations/src/cypress.js +2 -1
  22. package/packages/datadog-instrumentations/src/dns.js +1 -1
  23. package/packages/datadog-instrumentations/src/fs.js +1 -1
  24. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +28 -34
  25. package/packages/datadog-instrumentations/src/graphql.js +7 -10
  26. package/packages/datadog-instrumentations/src/grpc/client.js +11 -23
  27. package/packages/datadog-instrumentations/src/grpc/server.js +7 -20
  28. package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +16 -10
  29. package/packages/datadog-instrumentations/src/helpers/hook.js +1 -1
  30. package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -1
  31. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -41
  32. package/packages/datadog-instrumentations/src/helpers/register.js +5 -7
  33. package/packages/datadog-instrumentations/src/http/client.js +14 -20
  34. package/packages/datadog-instrumentations/src/jest.js +137 -48
  35. package/packages/datadog-instrumentations/src/kafkajs.js +52 -44
  36. package/packages/datadog-instrumentations/src/knex.js +4 -4
  37. package/packages/datadog-instrumentations/src/ldapjs.js +3 -4
  38. package/packages/datadog-instrumentations/src/mariadb.js +38 -61
  39. package/packages/datadog-instrumentations/src/mocha/main.js +63 -24
  40. package/packages/datadog-instrumentations/src/mocha/utils.js +36 -12
  41. package/packages/datadog-instrumentations/src/mocha/worker.js +6 -0
  42. package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
  43. package/packages/datadog-instrumentations/src/mysql.js +20 -36
  44. package/packages/datadog-instrumentations/src/mysql2.js +53 -47
  45. package/packages/datadog-instrumentations/src/net.js +1 -1
  46. package/packages/datadog-instrumentations/src/next.js +1 -0
  47. package/packages/datadog-instrumentations/src/nyc.js +1 -1
  48. package/packages/datadog-instrumentations/src/openai.js +21 -23
  49. package/packages/datadog-instrumentations/src/oracledb.js +1 -1
  50. package/packages/datadog-instrumentations/src/pg.js +1 -2
  51. package/packages/datadog-instrumentations/src/playwright.js +112 -69
  52. package/packages/datadog-instrumentations/src/redis.js +3 -3
  53. package/packages/datadog-instrumentations/src/restify.js +2 -2
  54. package/packages/datadog-instrumentations/src/rhea.js +42 -54
  55. package/packages/datadog-instrumentations/src/router.js +22 -25
  56. package/packages/datadog-instrumentations/src/tedious.js +1 -1
  57. package/packages/datadog-instrumentations/src/vitest.js +77 -28
  58. package/packages/datadog-plugin-amqp10/src/consumer.js +7 -3
  59. package/packages/datadog-plugin-amqp10/src/producer.js +7 -3
  60. package/packages/datadog-plugin-amqplib/src/client.js +6 -2
  61. package/packages/datadog-plugin-amqplib/src/consumer.js +7 -3
  62. package/packages/datadog-plugin-amqplib/src/producer.js +7 -3
  63. package/packages/datadog-plugin-amqplib/src/util.js +1 -1
  64. package/packages/datadog-plugin-apollo/src/gateway/request.js +5 -6
  65. package/packages/datadog-plugin-apollo/src/gateway/validate.js +2 -3
  66. package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
  67. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
  68. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +13 -13
  69. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +24 -31
  70. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
  71. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +6 -6
  72. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
  73. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
  74. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +4 -5
  75. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
  76. package/packages/datadog-plugin-aws-sdk/src/util.js +5 -6
  77. package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -1
  78. package/packages/datadog-plugin-child_process/src/index.js +4 -4
  79. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +23 -23
  80. package/packages/datadog-plugin-cucumber/src/index.js +57 -2
  81. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +97 -27
  82. package/packages/datadog-plugin-cypress/src/plugin.js +11 -1
  83. package/packages/datadog-plugin-cypress/src/support.js +24 -5
  84. package/packages/datadog-plugin-express/src/code_origin.js +30 -0
  85. package/packages/datadog-plugin-express/src/index.js +10 -12
  86. package/packages/datadog-plugin-express/src/tracing.js +19 -0
  87. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +7 -3
  88. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +12 -7
  89. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +6 -2
  90. package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +26 -9
  91. package/packages/datadog-plugin-graphql/src/execute.js +2 -2
  92. package/packages/datadog-plugin-graphql/src/index.js +7 -6
  93. package/packages/datadog-plugin-graphql/src/resolve.js +2 -2
  94. package/packages/datadog-plugin-graphql/src/tools/index.js +1 -0
  95. package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -0
  96. package/packages/datadog-plugin-graphql/src/tools/transforms.js +1 -0
  97. package/packages/datadog-plugin-grpc/src/client.js +2 -2
  98. package/packages/datadog-plugin-grpc/src/util.js +2 -2
  99. package/packages/datadog-plugin-http/src/client.js +18 -7
  100. package/packages/datadog-plugin-http2/src/client.js +20 -20
  101. package/packages/datadog-plugin-jest/src/index.js +23 -21
  102. package/packages/datadog-plugin-jest/src/util.js +8 -8
  103. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +3 -1
  104. package/packages/datadog-plugin-kafkajs/src/consumer.js +9 -5
  105. package/packages/datadog-plugin-kafkajs/src/producer.js +8 -3
  106. package/packages/datadog-plugin-kafkajs/src/utils.js +1 -1
  107. package/packages/datadog-plugin-langchain/src/handlers/chain.js +7 -7
  108. package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -2
  109. package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +6 -4
  110. package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +5 -4
  111. package/packages/datadog-plugin-langchain/src/tracing.js +11 -10
  112. package/packages/datadog-plugin-mariadb/src/index.js +3 -9
  113. package/packages/datadog-plugin-mocha/src/index.js +33 -13
  114. package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
  115. package/packages/datadog-plugin-mysql/src/index.js +11 -9
  116. package/packages/datadog-plugin-mysql2/src/index.js +16 -0
  117. package/packages/datadog-plugin-net/src/tcp.js +1 -1
  118. package/packages/datadog-plugin-next/src/index.js +6 -5
  119. package/packages/datadog-plugin-openai/src/services.js +6 -10
  120. package/packages/datadog-plugin-openai/src/tracing.js +10 -14
  121. package/packages/datadog-plugin-oracledb/src/index.js +1 -1
  122. package/packages/datadog-plugin-playwright/src/index.js +22 -2
  123. package/packages/datadog-plugin-redis/src/index.js +1 -1
  124. package/packages/datadog-plugin-rhea/src/consumer.js +8 -6
  125. package/packages/datadog-plugin-rhea/src/producer.js +5 -2
  126. package/packages/datadog-plugin-router/src/index.js +1 -1
  127. package/packages/datadog-plugin-selenium/src/index.js +1 -6
  128. package/packages/datadog-plugin-vitest/src/index.js +47 -31
  129. package/packages/datadog-shimmer/src/shimmer.js +4 -8
  130. package/packages/dd-trace/src/appsec/api_security_sampler.js +2 -2
  131. package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
  132. package/packages/dd-trace/src/appsec/blocking.js +6 -20
  133. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
  134. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +1 -1
  135. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +1 -1
  136. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +4 -6
  137. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +7 -12
  138. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +4 -6
  139. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +4 -0
  140. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +9 -12
  141. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +5 -4
  142. package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +2 -3
  143. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
  144. package/packages/dd-trace/src/appsec/iast/index.js +1 -0
  145. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +102 -7
  146. package/packages/dd-trace/src/appsec/iast/path-line.js +7 -8
  147. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +6 -13
  148. package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +6 -6
  149. package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +2 -2
  150. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +3 -3
  151. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +4 -28
  152. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -7
  153. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +3 -4
  154. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  155. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -7
  156. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
  157. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +6 -6
  158. package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -1
  159. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +1 -1
  160. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +1 -1
  161. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +7 -7
  162. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +23 -24
  163. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +3 -3
  164. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +4 -4
  165. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +6 -11
  166. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +9 -11
  167. package/packages/dd-trace/src/appsec/index.js +1 -1
  168. package/packages/dd-trace/src/appsec/rasp/index.js +15 -15
  169. package/packages/dd-trace/src/appsec/rasp/lfi.js +2 -1
  170. package/packages/dd-trace/src/appsec/reporter.js +233 -40
  171. package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
  172. package/packages/dd-trace/src/appsec/stack_trace.js +2 -4
  173. package/packages/dd-trace/src/appsec/telemetry/rasp.js +3 -5
  174. package/packages/dd-trace/src/appsec/telemetry/waf.js +3 -5
  175. package/packages/dd-trace/src/appsec/user_tracking.js +3 -5
  176. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -2
  177. package/packages/dd-trace/src/azure_metadata.js +2 -7
  178. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +1 -1
  179. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +2 -2
  180. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
  181. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -3
  182. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
  183. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
  184. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
  185. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +6 -4
  186. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -2
  187. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +0 -2
  188. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -1
  189. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +1 -1
  190. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +8 -5
  191. package/packages/dd-trace/src/ci-visibility/telemetry.js +4 -0
  192. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
  193. package/packages/dd-trace/src/config.js +82 -51
  194. package/packages/dd-trace/src/config_stable.js +3 -3
  195. package/packages/dd-trace/src/datastreams/encoding.js +9 -9
  196. package/packages/dd-trace/src/datastreams/fnv.js +1 -1
  197. package/packages/dd-trace/src/datastreams/pathway.js +4 -4
  198. package/packages/dd-trace/src/datastreams/processor.js +5 -7
  199. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
  200. package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +4 -6
  201. package/packages/dd-trace/src/datastreams/size.js +1 -1
  202. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +74 -67
  203. package/packages/dd-trace/src/debugger/devtools_client/condition.js +6 -8
  204. package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -1
  205. package/packages/dd-trace/src/debugger/devtools_client/index.js +7 -1
  206. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +18 -38
  207. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
  208. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +8 -10
  209. package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +3 -3
  210. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +2 -10
  211. package/packages/dd-trace/src/debugger/devtools_client/state.js +10 -3
  212. package/packages/dd-trace/src/dogstatsd.js +5 -4
  213. package/packages/dd-trace/src/encode/0.4.js +9 -9
  214. package/packages/dd-trace/src/encode/0.5.js +1 -1
  215. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +3 -3
  216. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
  217. package/packages/dd-trace/src/encode/tags-processors.js +1 -1
  218. package/packages/dd-trace/src/exporter.js +6 -6
  219. package/packages/dd-trace/src/exporters/agent/writer.js +1 -5
  220. package/packages/dd-trace/src/exporters/common/docker.js +1 -1
  221. package/packages/dd-trace/src/exporters/common/form-data.js +6 -4
  222. package/packages/dd-trace/src/exporters/common/request.js +1 -1
  223. package/packages/dd-trace/src/exporters/common/util.js +1 -1
  224. package/packages/dd-trace/src/external-logger/src/index.js +5 -5
  225. package/packages/dd-trace/src/flare/file.js +1 -5
  226. package/packages/dd-trace/src/format.js +1 -1
  227. package/packages/dd-trace/src/git_properties.js +1 -1
  228. package/packages/dd-trace/src/id.js +12 -6
  229. package/packages/dd-trace/src/iitm.js +10 -22
  230. package/packages/dd-trace/src/lambda/handler.js +6 -6
  231. package/packages/dd-trace/src/lambda/runtime/patch.js +4 -4
  232. package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
  233. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +6 -6
  234. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +2 -6
  235. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -3
  236. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +6 -6
  237. package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -1
  238. package/packages/dd-trace/src/llmobs/sdk.js +2 -2
  239. package/packages/dd-trace/src/llmobs/tagger.js +110 -96
  240. package/packages/dd-trace/src/llmobs/util.js +9 -9
  241. package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
  242. package/packages/dd-trace/src/llmobs/writers/util.js +1 -1
  243. package/packages/dd-trace/src/log/index.js +4 -4
  244. package/packages/dd-trace/src/log/log.js +1 -1
  245. package/packages/dd-trace/src/log/writer.js +2 -2
  246. package/packages/dd-trace/src/msgpack/chunk.js +3 -3
  247. package/packages/dd-trace/src/msgpack/encoder.js +28 -28
  248. package/packages/dd-trace/src/noop/dogstatsd.js +6 -6
  249. package/packages/dd-trace/src/noop/span.js +3 -5
  250. package/packages/dd-trace/src/noop/tracer.js +1 -2
  251. package/packages/dd-trace/src/opentelemetry/span_processor.js +2 -2
  252. package/packages/dd-trace/src/opentelemetry/tracer.js +6 -5
  253. package/packages/dd-trace/src/opentracing/propagation/log.js +6 -8
  254. package/packages/dd-trace/src/opentracing/propagation/text_map.js +27 -23
  255. package/packages/dd-trace/src/opentracing/propagation/tracestate.js +8 -4
  256. package/packages/dd-trace/src/opentracing/span.js +9 -14
  257. package/packages/dd-trace/src/opentracing/tracer.js +9 -6
  258. package/packages/dd-trace/src/payload-tagging/index.js +1 -1
  259. package/packages/dd-trace/src/payload-tagging/tagging.js +6 -6
  260. package/packages/dd-trace/src/pkg.js +1 -1
  261. package/packages/dd-trace/src/plugins/ci_plugin.js +62 -10
  262. package/packages/dd-trace/src/plugins/consumer.js +2 -2
  263. package/packages/dd-trace/src/plugins/inbound.js +5 -1
  264. package/packages/dd-trace/src/plugins/index.js +0 -1
  265. package/packages/dd-trace/src/plugins/outbound.js +4 -5
  266. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  267. package/packages/dd-trace/src/plugins/producer.js +2 -2
  268. package/packages/dd-trace/src/plugins/storage.js +2 -2
  269. package/packages/dd-trace/src/plugins/util/ci.js +23 -15
  270. package/packages/dd-trace/src/plugins/util/git.js +165 -11
  271. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -1
  272. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  273. package/packages/dd-trace/src/plugins/util/llm.js +27 -10
  274. package/packages/dd-trace/src/plugins/util/stacktrace.js +1 -1
  275. package/packages/dd-trace/src/plugins/util/test.js +311 -48
  276. package/packages/dd-trace/src/plugins/util/url.js +1 -1
  277. package/packages/dd-trace/src/plugins/util/urlfilter.js +13 -17
  278. package/packages/dd-trace/src/plugins/util/user-provided-git.js +12 -3
  279. package/packages/dd-trace/src/plugins/util/web.js +5 -4
  280. package/packages/dd-trace/src/priority_sampler.js +22 -22
  281. package/packages/dd-trace/src/profiling/config.js +44 -8
  282. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +5 -5
  283. package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
  284. package/packages/dd-trace/src/profiling/profiler.js +37 -2
  285. package/packages/dd-trace/src/profiling/profilers/events.js +14 -17
  286. package/packages/dd-trace/src/profiling/profilers/shared.js +6 -1
  287. package/packages/dd-trace/src/profiling/profilers/space.js +3 -3
  288. package/packages/dd-trace/src/profiling/profilers/wall.js +6 -7
  289. package/packages/dd-trace/src/profiling/ssi-heuristics.js +3 -5
  290. package/packages/dd-trace/src/profiling/tagger.js +3 -5
  291. package/packages/dd-trace/src/profiling/webspan-utils.js +1 -1
  292. package/packages/dd-trace/src/proxy.js +7 -9
  293. package/packages/dd-trace/src/random_sampler.js +40 -0
  294. package/packages/dd-trace/src/rate_limiter.js +4 -4
  295. package/packages/dd-trace/src/remote_config/index.js +3 -7
  296. package/packages/dd-trace/src/remote_config/manager.js +25 -13
  297. package/packages/dd-trace/src/require-package-json.js +1 -1
  298. package/packages/dd-trace/src/ritm.js +4 -4
  299. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
  300. package/packages/dd-trace/src/sampler.js +33 -4
  301. package/packages/dd-trace/src/sampling_rule.js +12 -3
  302. package/packages/dd-trace/src/scope.js +1 -1
  303. package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
  304. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -3
  305. package/packages/dd-trace/src/span_processor.js +3 -3
  306. package/packages/dd-trace/src/span_sampler.js +4 -1
  307. package/packages/dd-trace/src/standalone/tracesource.js +1 -1
  308. package/packages/dd-trace/src/startup-log.js +2 -2
  309. package/packages/dd-trace/src/telemetry/dependencies.js +4 -4
  310. package/packages/dd-trace/src/telemetry/logs/log-collector.js +9 -10
  311. package/packages/dd-trace/src/telemetry/metrics.js +10 -5
  312. package/packages/dd-trace/src/telemetry/send-data.js +1 -1
  313. package/packages/dd-trace/src/telemetry/telemetry.js +23 -24
  314. package/packages/dd-trace/src/util.js +1 -1
  315. package/version.js +1 -0
  316. package/packages/datadog-instrumentations/src/paperplane.js +0 -77
  317. package/packages/datadog-plugin-paperplane/src/index.js +0 -25
  318. package/packages/datadog-plugin-paperplane/src/logger.js +0 -11
  319. package/packages/datadog-plugin-paperplane/src/server.js +0 -24
@@ -73,6 +73,10 @@ addHook({ name: 'cassandra-driver', versions: ['>=4.4'] }, cassandra => {
73
73
  return cassandra
74
74
  })
75
75
 
76
+ const isValid = (args) => {
77
+ return args.length === 4 || typeof args[3] === 'function'
78
+ }
79
+
76
80
  addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'] }, cassandra => {
77
81
  shimmer.wrap(cassandra.Client.prototype, '_innerExecute', _innerExecute =>
78
82
  function (query, params, execOptions, callback) {
@@ -81,9 +85,6 @@ addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'] }, cassandra => {
81
85
  }
82
86
  const callbackResource = new AsyncResource('bound-anonymous-fn')
83
87
  const asyncResource = new AsyncResource('bound-anonymous-fn')
84
- const isValid = (args) => {
85
- return args.length === 4 || typeof args[3] === 'function'
86
- }
87
88
 
88
89
  if (!isValid(arguments)) {
89
90
  return _innerExecute.apply(this, arguments)
@@ -176,7 +177,7 @@ function finish (finishCh, errorCh, error) {
176
177
  if (error) {
177
178
  errorCh.publish(error)
178
179
  }
179
- finishCh.publish(undefined)
180
+ finishCh.publish()
180
181
  }
181
182
 
182
183
  function wrapCallback (finishCh, errorCh, asyncResource, callback) {
@@ -233,8 +233,7 @@ function wrapChildProcessAsyncMethod (ChildProcess, shell = false) {
233
233
  childProcessChannel.error.publish(e)
234
234
  })
235
235
 
236
- childProcess.on('close', (code) => {
237
- code = code || 0
236
+ childProcess.on('close', (code = 0) => {
238
237
  if (!errorExecuted && code !== 0) {
239
238
  childProcessChannel.error.publish()
240
239
  }
@@ -2,8 +2,7 @@
2
2
 
3
3
  const {
4
4
  addHook,
5
- channel,
6
- AsyncResource
5
+ channel
7
6
  } = require('./helpers/instrument')
8
7
  const shimmer = require('../../datadog-shimmer')
9
8
 
@@ -32,7 +31,6 @@ const disabledHeaderWeakSet = new WeakSet()
32
31
  // we need to store the offset per partition per topic for the consumer to track offsets for DSM
33
32
  const latestConsumerOffsets = new Map()
34
33
 
35
- // Customize the instrumentation for Confluent Kafka JavaScript
36
34
  addHook({ name: '@confluentinc/kafka-javascript', versions: ['>=1.0.0'] }, (module) => {
37
35
  // Hook native module classes first
38
36
  instrumentBaseModule(module)
@@ -55,30 +53,32 @@ function instrumentBaseModule (module) {
55
53
  // Hook the produce method
56
54
  if (typeof producer?.produce === 'function') {
57
55
  shimmer.wrap(producer, 'produce', function wrapProduce (produce) {
58
- return function wrappedProduce (topic, partition, message, key, timestamp, opaque) {
56
+ return function wrappedProduce (topic, partition, message, key, timestamp, opaque, headers) {
59
57
  if (!channels.producerStart.hasSubscribers) {
60
58
  return produce.apply(this, arguments)
61
59
  }
62
60
 
63
61
  const brokers = this.globalConfig?.['bootstrap.servers']
64
62
 
65
- const asyncResource = new AsyncResource('bound-anonymous-fn')
66
- return asyncResource.runInAsyncScope(() => {
67
- try {
68
- channels.producerStart.publish({
69
- topic,
70
- messages: [{ key, value: message }],
71
- bootstrapServers: brokers
72
- })
63
+ const ctx = {
64
+ topic,
65
+ messages: [{ key, value: message }],
66
+ bootstrapServers: brokers
67
+ }
73
68
 
74
- const result = produce.apply(this, arguments)
69
+ return channels.producerStart.runStores(ctx, () => {
70
+ try {
71
+ const headers = convertHeaders(ctx.messages[0].headers)
72
+ const result = produce.apply(this, [topic, partition, message, key, timestamp, opaque, headers])
75
73
 
76
- channels.producerCommit.publish(undefined)
77
- channels.producerFinish.publish(undefined)
74
+ ctx.result = result
75
+ channels.producerCommit.publish(ctx)
76
+ channels.producerFinish.publish(ctx)
78
77
  return result
79
78
  } catch (error) {
80
- channels.producerError.publish(error)
81
- channels.producerFinish.publish(undefined)
79
+ ctx.error = error
80
+ channels.producerError.publish(ctx)
81
+ channels.producerFinish.publish(ctx)
82
82
  throw error
83
83
  }
84
84
  })
@@ -110,32 +110,39 @@ function instrumentBaseModule (module) {
110
110
  callback = numMessages
111
111
  }
112
112
 
113
+ const ctx = {
114
+ groupId
115
+ }
113
116
  // Handle callback-based consumption
114
117
  if (typeof callback === 'function') {
115
118
  return consume.call(this, numMessages, function wrappedCallback (err, messages) {
116
119
  if (messages && messages.length > 0) {
117
120
  messages.forEach(message => {
118
- channels.consumerStart.publish({
119
- topic: message?.topic,
120
- partition: message?.partition,
121
- message,
122
- groupId
123
- })
121
+ ctx.topic = message?.topic
122
+ ctx.partition = message?.partition
123
+ ctx.message = message
124
+
125
+ // TODO: We should be using publish here instead of runStores but we need bindStart to be called
126
+ channels.consumerStart.runStores(ctx, () => {})
124
127
  updateLatestOffset(message?.topic, message?.partition, message?.offset, groupId)
125
128
  })
126
129
  }
127
130
 
128
131
  if (err) {
129
- channels.consumerError.publish(err)
132
+ ctx.error = err
133
+ channels.consumerError.publish(ctx)
130
134
  }
131
135
 
132
136
  try {
133
137
  const result = callback.apply(this, arguments)
134
- channels.consumerFinish.publish(undefined)
138
+ if (messages && messages.length > 0) {
139
+ channels.consumerFinish.publish(ctx)
140
+ }
135
141
  return result
136
142
  } catch (error) {
137
- channels.consumerError.publish(error)
138
- channels.consumerFinish.publish(undefined)
143
+ ctx.error = error
144
+ channels.consumerError.publish(ctx)
145
+ channels.consumerFinish.publish(ctx)
139
146
  throw error
140
147
  }
141
148
  })
@@ -204,45 +211,44 @@ function instrumentKafkaJS (kafkaJS) {
204
211
  return send.apply(this, arguments)
205
212
  }
206
213
 
207
- const asyncResource = new AsyncResource('bound-anonymous-fn')
208
- return asyncResource.runInAsyncScope(() => {
209
- try {
210
- channels.producerStart.publish({
211
- topic: payload?.topic,
212
- messages: payload?.messages || [],
213
- bootstrapServers: kafka._ddBrokers,
214
- disableHeaderInjection: disabledHeaderWeakSet.has(producer)
215
- })
214
+ const ctx = {
215
+ topic: payload?.topic,
216
+ messages: payload?.messages || [],
217
+ bootstrapServers: kafka._ddBrokers,
218
+ disableHeaderInjection: disabledHeaderWeakSet.has(producer)
219
+ }
216
220
 
221
+ return channels.producerStart.runStores(ctx, () => {
222
+ try {
217
223
  const result = send.apply(this, arguments)
218
224
 
219
- result.then(
220
- asyncResource.bind(res => {
221
- channels.producerCommit.publish(res)
222
- channels.producerFinish.publish(undefined)
223
- }),
224
- asyncResource.bind(err => {
225
- if (err) {
226
- // Fixes bug where we would inject message headers for kafka brokers
227
- // that don't support headers (version <0.11). On the error, we disable
228
- // header injection. Tnfortunately the error name / type is not more specific.
229
- // This approach is implemented by other tracers as well.
230
- if (err.name === 'KafkaJSError' && err.type === 'ERR_UNKNOWN') {
231
- disabledHeaderWeakSet.add(producer)
232
- log.error('Kafka Broker responded with UNKNOWN_SERVER_ERROR (-1). ' +
233
- 'Please look at broker logs for more information. ' +
234
- 'Tracer message header injection for Kafka is disabled.')
235
- }
236
- channels.producerError.publish(err)
225
+ result.then((res) => {
226
+ ctx.result = res
227
+ channels.producerCommit.publish(ctx)
228
+ channels.producerFinish.publish(ctx)
229
+ }, (err) => {
230
+ if (err) {
231
+ // Fixes bug where we would inject message headers for kafka brokers
232
+ // that don't support headers (version <0.11). On the error, we disable
233
+ // header injection. Tnfortunately the error name / type is not more specific.
234
+ // This approach is implemented by other tracers as well.
235
+ if (err.name === 'KafkaJSError' && err.type === 'ERR_UNKNOWN') {
236
+ disabledHeaderWeakSet.add(producer)
237
+ log.error('Kafka Broker responded with UNKNOWN_SERVER_ERROR (-1). ' +
238
+ 'Please look at broker logs for more information. ' +
239
+ 'Tracer message header injection for Kafka is disabled.')
237
240
  }
238
- channels.producerFinish.publish(undefined)
239
- })
240
- )
241
+ ctx.error = err
242
+ channels.producerError.publish(ctx)
243
+ }
244
+ channels.producerFinish.publish(ctx)
245
+ })
241
246
 
242
247
  return result
243
248
  } catch (e) {
244
- channels.producerError.publish(e)
245
- channels.producerFinish.publish(undefined)
249
+ ctx.error = e
250
+ channels.producerError.publish(ctx)
251
+ channels.producerFinish.publish(ctx)
246
252
  throw e
247
253
  }
248
254
  })
@@ -350,10 +356,11 @@ function wrapKafkaCallback (callback, { startCh, commitCh, finishCh, errorCh },
350
356
  return function wrappedKafkaCallback (payload) {
351
357
  const commitPayload = getPayload(payload)
352
358
 
353
- const asyncResource = new AsyncResource('bound-anonymous-fn')
354
- return asyncResource.runInAsyncScope(() => {
355
- startCh.publish(commitPayload)
359
+ const ctx = {
360
+ extractedArgs: commitPayload
361
+ }
356
362
 
363
+ return startCh.runStores(ctx, () => {
357
364
  updateLatestOffset(commitPayload?.topic, commitPayload?.partition, commitPayload?.offset, commitPayload?.groupId)
358
365
 
359
366
  try {
@@ -361,22 +368,25 @@ function wrapKafkaCallback (callback, { startCh, commitCh, finishCh, errorCh },
361
368
 
362
369
  if (result && typeof result.then === 'function') {
363
370
  return result
364
- .then(asyncResource.bind(res => {
365
- finishCh.publish(undefined)
371
+ .then((res) => {
372
+ ctx.result = res
373
+ finishCh.publish(ctx)
366
374
  return res
367
- }))
368
- .catch(asyncResource.bind(err => {
369
- errorCh.publish(err)
370
- finishCh.publish(undefined)
375
+ })
376
+ .catch((err) => {
377
+ ctx.error = err
378
+ errorCh.publish(ctx)
379
+ finishCh.publish(ctx)
371
380
  throw err
372
- }))
381
+ })
373
382
  } else {
374
- finishCh.publish(undefined)
383
+ finishCh.publish(ctx)
375
384
  return result
376
385
  }
377
386
  } catch (error) {
378
- errorCh.publish(error)
379
- finishCh.publish(undefined)
387
+ ctx.error = error
388
+ errorCh.publish(ctx)
389
+ finishCh.publish(ctx)
380
390
  throw error
381
391
  }
382
392
  })
@@ -402,5 +412,10 @@ function updateLatestOffset (topic, partition, offset, groupId) {
402
412
  }
403
413
 
404
414
  function getLatestOffsets () {
405
- return Array.from(latestConsumerOffsets.values())
415
+ return [...latestConsumerOffsets.values()]
416
+ }
417
+
418
+ function convertHeaders (headers) {
419
+ // convert headers from object to array of objects with 1 key and value per array entry
420
+ return Object.entries(headers).map(([key, value]) => ({ [key.toString()]: value.toString() }))
406
421
  }
@@ -32,7 +32,7 @@ function wrapMaybeInvoke (_maybeInvoke) {
32
32
  const callbackIndex = args.length - 1
33
33
  const callback = args[callbackIndex]
34
34
 
35
- if (callback instanceof Function) {
35
+ if (typeof callback === 'function') {
36
36
  args[callbackIndex] = AsyncResource.bind(callback)
37
37
  }
38
38
 
@@ -184,12 +184,12 @@ addHook({ name: 'couchbase', file: 'lib/bucket.js', versions: ['^2.6.12'] }, Buc
184
184
  startCh.publish({ resource: n1qlQuery, bucket: { name: this.name || this._name }, seedNodes: this._dd_hosts })
185
185
 
186
186
  emitter.once('rows', asyncResource.bind(() => {
187
- finishCh.publish(undefined)
187
+ finishCh.publish()
188
188
  }))
189
189
 
190
190
  emitter.once(errorMonitor, asyncResource.bind((error) => {
191
191
  errorCh.publish(error)
192
- finishCh.publish(undefined)
192
+ finishCh.publish()
193
193
  }))
194
194
 
195
195
  try {
@@ -24,6 +24,8 @@ const skippableSuitesCh = channel('ci:cucumber:test-suite:skippable')
24
24
  const sessionStartCh = channel('ci:cucumber:session:start')
25
25
  const sessionFinishCh = channel('ci:cucumber:session:finish')
26
26
  const testManagementTestsCh = channel('ci:cucumber:test-management-tests')
27
+ const impactedTestsCh = channel('ci:cucumber:modified-tests')
28
+ const isModifiedCh = channel('ci:cucumber:is-modified-test')
27
29
 
28
30
  const workerReportTraceCh = channel('ci:cucumber:worker-report:trace')
29
31
 
@@ -42,7 +44,7 @@ const {
42
44
  } = require('../../dd-trace/src/plugins/util/test')
43
45
 
44
46
  const isMarkedAsUnskippable = (pickle) => {
45
- return !!pickle.tags.find(tag => tag.name === '@datadog:unskippable')
47
+ return pickle.tags.some(tag => tag.name === '@datadog:unskippable')
46
48
  }
47
49
 
48
50
  // We'll preserve the original coverage here
@@ -55,6 +57,7 @@ const lastStatusByPickleId = new Map()
55
57
  const numRetriesByPickleId = new Map()
56
58
  const numAttemptToCtx = new Map()
57
59
  const newTestsByTestFullname = new Map()
60
+ const modifiedTestsByPickleId = new Map()
58
61
 
59
62
  let eventDataCollector = null
60
63
  let pickleByFile = {}
@@ -74,15 +77,17 @@ let isEarlyFlakeDetectionFaulty = false
74
77
  let isFlakyTestRetriesEnabled = false
75
78
  let isKnownTestsEnabled = false
76
79
  let isTestManagementTestsEnabled = false
80
+ let isImpactedTestsEnabled = false
77
81
  let testManagementAttemptToFixRetries = 0
78
82
  let testManagementTests = {}
83
+ let modifiedTests = {}
79
84
  let numTestRetries = 0
80
85
  let knownTests = []
81
86
  let skippedSuites = []
82
87
  let isSuitesSkipped = false
83
88
 
84
89
  function getSuiteStatusFromTestStatuses (testStatuses) {
85
- if (testStatuses.some(status => status === 'fail')) {
90
+ if (testStatuses.includes('fail')) {
86
91
  return 'fail'
87
92
  }
88
93
  if (testStatuses.every(status => status === 'skip')) {
@@ -133,7 +138,7 @@ function getTestStatusFromRetries (testStatuses) {
133
138
  if (testStatuses.every(status => status === 'fail')) {
134
139
  return 'fail'
135
140
  }
136
- if (testStatuses.some(status => status === 'pass')) {
141
+ if (testStatuses.includes('pass')) {
137
142
  return 'pass'
138
143
  }
139
144
  return 'pass'
@@ -246,7 +251,7 @@ function wrapRun (pl, isLatestVersion) {
246
251
  }
247
252
  const ctx = testStartPayload
248
253
  numAttemptToCtx.set(numAttempt, ctx)
249
- testStartCh.runStores(ctx, () => { })
254
+ testStartCh.runStores(ctx, () => {})
250
255
  const promises = {}
251
256
  try {
252
257
  this.eventBroadcaster.on('envelope', shimmer.wrapFunction(null, () => async (testCase) => {
@@ -258,7 +263,7 @@ function wrapRun (pl, isLatestVersion) {
258
263
  try {
259
264
  const cucumberResult = this.getWorstStepResult()
260
265
  error = getErrorFromCucumberResult(cucumberResult)
261
- } catch (e) {
266
+ } catch {
262
267
  // ignore error
263
268
  }
264
269
 
@@ -276,7 +281,7 @@ function wrapRun (pl, isLatestVersion) {
276
281
  const newCtx = { ...testStartPayload, promises }
277
282
  numAttemptToCtx.set(numAttempt, newCtx)
278
283
 
279
- testStartCh.runStores(newCtx, () => { })
284
+ testStartCh.runStores(newCtx, () => {})
280
285
  }
281
286
  }
282
287
  }))
@@ -305,6 +310,7 @@ function wrapRun (pl, isLatestVersion) {
305
310
  let hasFailedAttemptToFix = false
306
311
  let isDisabled = false
307
312
  let isQuarantined = false
313
+ let isModified = false
308
314
 
309
315
  if (isTestManagementTestsEnabled) {
310
316
  const testSuitePath = getTestSuitePath(testFileAbsolutePath, process.cwd())
@@ -329,10 +335,17 @@ function wrapRun (pl, isLatestVersion) {
329
335
  }
330
336
  }
331
337
 
332
- if (isKnownTestsEnabled && status !== 'skip' && !isAttemptToFix) {
333
- const numRetries = numRetriesByPickleId.get(this.pickle.id)
338
+ const numRetries = numRetriesByPickleId.get(this.pickle.id)
339
+
340
+ if (isImpactedTestsEnabled) {
341
+ isModified = modifiedTestsByPickleId.get(this.pickle.id)
342
+ }
334
343
 
344
+ if (isKnownTestsEnabled && status !== 'skip') {
335
345
  isNew = numRetries !== undefined
346
+ }
347
+
348
+ if (isNew || isModified) {
336
349
  isEfdRetry = numRetries > 0
337
350
  }
338
351
 
@@ -357,6 +370,7 @@ function wrapRun (pl, isLatestVersion) {
357
370
  hasFailedAttemptToFix,
358
371
  isDisabled,
359
372
  isQuarantined,
373
+ isModified,
360
374
  ...attemptCtx.currentStore
361
375
  })
362
376
  })
@@ -451,14 +465,15 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
451
465
  isKnownTestsEnabled = configurationResponse.libraryConfig?.isKnownTestsEnabled
452
466
  isTestManagementTestsEnabled = configurationResponse.libraryConfig?.isTestManagementEnabled
453
467
  testManagementAttemptToFixRetries = configurationResponse.libraryConfig?.testManagementAttemptToFixRetries
468
+ isImpactedTestsEnabled = configurationResponse.libraryConfig?.isImpactedTestsEnabled
454
469
 
455
470
  if (isKnownTestsEnabled) {
456
471
  const knownTestsResponse = await getChannelPromise(knownTestsCh)
457
- if (!knownTestsResponse.err) {
458
- knownTests = knownTestsResponse.knownTests
459
- } else {
472
+ if (knownTestsResponse.err) {
460
473
  isEarlyFlakeDetectionEnabled = false
461
474
  isKnownTestsEnabled = false
475
+ } else {
476
+ knownTests = knownTestsResponse.knownTests
462
477
  }
463
478
  }
464
479
 
@@ -488,7 +503,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
488
503
  this.pickleIds = picklesToRun
489
504
  }
490
505
 
491
- skippedSuites = Array.from(filteredPickles.skippedSuites)
506
+ skippedSuites = [...filteredPickles.skippedSuites]
492
507
  itrCorrelationId = skippableResponse.itrCorrelationId
493
508
  }
494
509
  }
@@ -510,10 +525,17 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
510
525
 
511
526
  if (isTestManagementTestsEnabled) {
512
527
  const testManagementTestsResponse = await getChannelPromise(testManagementTestsCh)
513
- if (!testManagementTestsResponse.err) {
514
- testManagementTests = testManagementTestsResponse.testManagementTests
515
- } else {
528
+ if (testManagementTestsResponse.err) {
516
529
  isTestManagementTestsEnabled = false
530
+ } else {
531
+ testManagementTests = testManagementTestsResponse.testManagementTests
532
+ }
533
+ }
534
+
535
+ if (isImpactedTestsEnabled) {
536
+ const impactedTestsResponse = await getChannelPromise(impactedTestsCh)
537
+ if (!impactedTestsResponse.err) {
538
+ modifiedTests = impactedTestsResponse.modifiedTests
517
539
  }
518
540
  }
519
541
 
@@ -547,7 +569,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
547
569
  originalCoverageMap.merge(fromCoverageMapToCoverage(untestedCoverage))
548
570
  }
549
571
  testCodeCoverageLinesTotal = originalCoverageMap.getCoverageSummary().lines.pct
550
- } catch (e) {
572
+ } catch {
551
573
  // ignore errors
552
574
  }
553
575
  // restore the original coverage
@@ -577,12 +599,15 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
577
599
  // Handles EFD in both the main process and the worker process.
578
600
  function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = false, isWorker = false) {
579
601
  return async function () {
580
- let pickle
581
- if (isNewerCucumberVersion) {
582
- pickle = arguments[0].pickle
583
- } else {
584
- pickle = this.eventDataCollector.getPickle(arguments[0])
585
- }
602
+ const pickle = isNewerCucumberVersion
603
+ ? arguments[0].pickle
604
+ : this.eventDataCollector.getPickle(arguments[0])
605
+ const testCase = isNewerCucumberVersion
606
+ ? arguments[0].testCase
607
+ : arguments[1]
608
+ const gherkinDocument = isNewerCucumberVersion
609
+ ? arguments[0].gherkinDocument
610
+ : this.eventDataCollector.getGherkinDocument(pickle.uri)
586
611
 
587
612
  const testFileAbsolutePath = pickle.uri
588
613
  const testSuitePath = getTestSuitePath(testFileAbsolutePath, process.cwd())
@@ -604,6 +629,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
604
629
  let isAttemptToFix = false
605
630
  let isDisabled = false
606
631
  let isQuarantined = false
632
+ let isModified = false
607
633
 
608
634
  if (isTestManagementTestsEnabled) {
609
635
  const testProperties = getTestProperties(testSuitePath, pickle.name)
@@ -616,6 +642,24 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
616
642
  }
617
643
  }
618
644
 
645
+ if (isImpactedTestsEnabled) {
646
+ const setIsModified = (receivedIsModified) => { isModified = receivedIsModified }
647
+ const scenarios = gherkinDocument.feature?.children?.filter(
648
+ children => pickle.astNodeIds.includes(children.scenario.id)
649
+ ).map(scenario => scenario.scenario)
650
+ const stepIds = testCase?.testSteps?.flatMap(testStep => testStep.stepDefinitionIds)
651
+
652
+ isModifiedCh.publish({
653
+ scenarios,
654
+ testFileAbsolutePath: gherkinDocument.uri,
655
+ modifiedTests,
656
+ stepIds,
657
+ stepDefinitions: this.supportCodeLibrary.stepDefinitions,
658
+ setIsModified
659
+ })
660
+ modifiedTestsByPickleId.set(pickle.id, isModified)
661
+ }
662
+
619
663
  if (isKnownTestsEnabled && !isAttemptToFix) {
620
664
  isNew = isNewTest(testSuitePath, pickle.name)
621
665
  if (isNew) {
@@ -626,7 +670,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
626
670
  let runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
627
671
 
628
672
  const testStatuses = lastStatusByPickleId.get(pickle.id)
629
- const lastTestStatus = testStatuses[testStatuses.length - 1]
673
+ const lastTestStatus = testStatuses.at(-1)
630
674
 
631
675
  // New tests should not be marked as attempt to fix, so EFD + Attempt to fix should not be enabled at the same time
632
676
  if (isAttemptToFix && lastTestStatus !== 'skip') {
@@ -637,7 +681,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
637
681
  }
638
682
 
639
683
  // If it's a new test and it hasn't been skipped, we run it again
640
- if (isEarlyFlakeDetectionEnabled && lastTestStatus !== 'skip' && isNew) {
684
+ if (isEarlyFlakeDetectionEnabled && lastTestStatus !== 'skip' && (isNew || isModified)) {
641
685
  for (let retryIndex = 0; retryIndex < earlyFlakeDetectionNumRetries; retryIndex++) {
642
686
  numRetriesByPickleId.set(pickle.id, retryIndex + 1)
643
687
  runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
@@ -646,7 +690,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
646
690
  let testStatus = lastTestStatus
647
691
  let shouldBePassedByEFD = false
648
692
  let shouldBePassedByTestManagement = false
649
- if (isNew && isEarlyFlakeDetectionEnabled) {
693
+ if ((isNew || isModified) && isEarlyFlakeDetectionEnabled) {
650
694
  /**
651
695
  * If Early Flake Detection (EFD) is enabled the logic is as follows:
652
696
  * - If all attempts for a test are failing, the test has failed and we will let the test process fail.
@@ -667,10 +711,10 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
667
711
  shouldBePassedByTestManagement = true
668
712
  }
669
713
 
670
- if (!pickleResultByFile[testFileAbsolutePath]) {
671
- pickleResultByFile[testFileAbsolutePath] = [testStatus]
672
- } else {
714
+ if (pickleResultByFile[testFileAbsolutePath]) {
673
715
  pickleResultByFile[testFileAbsolutePath].push(testStatus)
716
+ } else {
717
+ pickleResultByFile[testFileAbsolutePath] = [testStatus]
674
718
  }
675
719
 
676
720
  // If it's a worker, suite events are handled in `getWrappedParseWorkerMessage`
@@ -694,7 +738,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
694
738
  testSuiteFinishCh.publish({ status: testSuiteStatus, testSuitePath })
695
739
  }
696
740
 
697
- if (isNewerCucumberVersion && isEarlyFlakeDetectionEnabled && isNew) {
741
+ if (isNewerCucumberVersion && isEarlyFlakeDetectionEnabled && (isNew || isModified)) {
698
742
  return shouldBePassedByEFD
699
743
  }
700
744
 
@@ -721,13 +765,7 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
721
765
  }
722
766
  }
723
767
 
724
- let envelope
725
-
726
- if (isNewVersion) {
727
- envelope = message.envelope
728
- } else {
729
- envelope = message.jsonEnvelope
730
- }
768
+ const envelope = isNewVersion ? message.envelope : message.jsonEnvelope
731
769
 
732
770
  if (!envelope) {
733
771
  return parseWorkerMessageFunction.apply(this, arguments)
@@ -737,7 +775,7 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
737
775
  if (typeof parsed === 'string') {
738
776
  try {
739
777
  parsed = JSON.parse(envelope)
740
- } catch (e) {
778
+ } catch {
741
779
  // ignore errors and continue
742
780
  return parseWorkerMessageFunction.apply(this, arguments)
743
781
  }
@@ -790,11 +828,11 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
790
828
  if (isEarlyFlakeDetectionEnabled && isNew) {
791
829
  const testFullname = `${pickle.uri}:${pickle.name}`
792
830
  let testStatuses = newTestsByTestFullname.get(testFullname)
793
- if (!testStatuses) {
831
+ if (testStatuses) {
832
+ testStatuses.push(status)
833
+ } else {
794
834
  testStatuses = [status]
795
835
  newTestsByTestFullname.set(testFullname, testStatuses)
796
- } else {
797
- testStatuses.push(status)
798
836
  }
799
837
  // We have finished all retries
800
838
  if (testStatuses.length === earlyFlakeDetectionNumRetries + 1) {
@@ -947,6 +985,11 @@ addHook({
947
985
  this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
948
986
  }
949
987
 
988
+ if (isImpactedTestsEnabled) {
989
+ this.options.worldParameters._ddImpactedTestsEnabled = isImpactedTestsEnabled
990
+ this.options.worldParameters._ddModifiedTests = modifiedTests
991
+ }
992
+
950
993
  return startWorker.apply(this, arguments)
951
994
  })
952
995
  return adapterPackage
@@ -973,6 +1016,10 @@ addHook({
973
1016
  if (isEarlyFlakeDetectionEnabled) {
974
1017
  earlyFlakeDetectionNumRetries = this.options.worldParameters._ddEarlyFlakeDetectionNumRetries
975
1018
  }
1019
+ isImpactedTestsEnabled = !!this.options.worldParameters._ddImpactedTestsEnabled
1020
+ if (isImpactedTestsEnabled) {
1021
+ modifiedTests = this.options.worldParameters._ddModifiedTests
1022
+ }
976
1023
  }
977
1024
  )
978
1025
  return workerPackage
@@ -1,8 +1,9 @@
1
1
  const { addHook } = require('./helpers/instrument')
2
+ const { DD_MAJOR } = require('../../../version')
2
3
 
3
4
  // No handler because this is only useful for testing.
4
5
  // Cypress plugin does not patch any library.
5
6
  addHook({
6
7
  name: 'cypress',
7
- versions: ['>=6.7.0']
8
+ versions: DD_MAJOR >= 6 ? ['>=10.2.0'] : ['>=6.7.0']
8
9
  }, lib => lib)