dd-trace 5.79.0 → 5.81.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 (242) hide show
  1. package/LICENSE-3rdparty.csv +79 -87
  2. package/ext/tags.d.ts +1 -0
  3. package/ext/tags.js +1 -0
  4. package/index.d.ts +46 -39
  5. package/initialize.mjs +10 -10
  6. package/loader-hook.mjs +10 -3
  7. package/package.json +23 -40
  8. package/packages/datadog-core/src/storage.js +4 -4
  9. package/packages/datadog-esbuild/index.js +36 -19
  10. package/packages/datadog-esbuild/src/utils.js +5 -1
  11. package/packages/datadog-instrumentations/index.js +1 -0
  12. package/packages/datadog-instrumentations/src/anthropic.js +12 -0
  13. package/packages/datadog-instrumentations/src/aws-sdk.js +13 -2
  14. package/packages/datadog-instrumentations/src/azure-service-bus.js +43 -36
  15. package/packages/datadog-instrumentations/src/cucumber.js +2 -2
  16. package/packages/datadog-instrumentations/src/find-my-way.js +6 -5
  17. package/packages/datadog-instrumentations/src/google-genai.js +120 -0
  18. package/packages/datadog-instrumentations/src/graphql.js +20 -0
  19. package/packages/datadog-instrumentations/src/helpers/hook.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  21. package/packages/datadog-instrumentations/src/helpers/instrument.js +12 -1
  22. package/packages/datadog-instrumentations/src/helpers/register.js +6 -1
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +27 -0
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +152 -0
  25. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +5 -0
  26. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langchain.js +237 -0
  27. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.js +9 -0
  28. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +11 -0
  29. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +139 -0
  30. package/packages/datadog-instrumentations/src/jest.js +1 -1
  31. package/packages/datadog-instrumentations/src/langchain.js +3 -109
  32. package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
  33. package/packages/datadog-instrumentations/src/mysql2.js +1 -1
  34. package/packages/datadog-instrumentations/src/playwright.js +65 -16
  35. package/packages/datadog-instrumentations/src/router.js +1 -1
  36. package/packages/datadog-instrumentations/src/selenium.js +3 -1
  37. package/packages/datadog-instrumentations/src/ws.js +35 -17
  38. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +3 -2
  39. package/packages/datadog-plugin-azure-service-bus/src/producer.js +14 -5
  40. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
  41. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +23 -2
  42. package/packages/datadog-plugin-cypress/src/plugin.js +1 -1
  43. package/packages/datadog-plugin-cypress/src/support.js +73 -31
  44. package/packages/datadog-plugin-google-genai/src/index.js +17 -0
  45. package/packages/datadog-plugin-google-genai/src/tracing.js +41 -0
  46. package/packages/datadog-plugin-graphql/src/tools/transforms.js +5 -4
  47. package/packages/datadog-plugin-jest/src/util.js +4 -3
  48. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -1
  49. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -1
  50. package/packages/datadog-plugin-langchain/src/tracing.js +7 -3
  51. package/packages/datadog-plugin-next/src/index.js +11 -3
  52. package/packages/datadog-plugin-openai/src/stream-helpers.js +1 -1
  53. package/packages/datadog-shimmer/src/shimmer.js +2 -2
  54. package/packages/dd-trace/src/aiguard/sdk.js +29 -14
  55. package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
  56. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  57. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  58. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -2
  59. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  60. package/packages/dd-trace/src/appsec/reporter.js +0 -4
  61. package/packages/dd-trace/src/baggage.js +11 -0
  62. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +4 -8
  63. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +1 -1
  64. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
  65. package/packages/dd-trace/src/config.js +81 -7
  66. package/packages/dd-trace/src/config_defaults.js +15 -2
  67. package/packages/dd-trace/src/datastreams/encoding.js +23 -6
  68. package/packages/dd-trace/src/datastreams/pathway.js +40 -1
  69. package/packages/dd-trace/src/datastreams/processor.js +1 -1
  70. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
  71. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +15 -5
  72. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
  73. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  74. package/packages/dd-trace/src/debugger/devtools_client/index.js +30 -15
  75. package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
  76. package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +24 -18
  77. package/packages/dd-trace/src/debugger/devtools_client/send.js +18 -8
  78. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +103 -15
  79. package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +25 -0
  80. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +56 -25
  81. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +64 -23
  82. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +3 -1
  83. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +404 -0
  84. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  85. package/packages/dd-trace/src/debugger/devtools_client/state.js +7 -2
  86. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
  87. package/packages/dd-trace/src/debugger/index.js +1 -1
  88. package/packages/dd-trace/src/encode/0.4.js +3 -3
  89. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +2 -2
  90. package/packages/dd-trace/src/encode/span-stats.js +7 -1
  91. package/packages/dd-trace/src/exporters/agent/writer.js +6 -13
  92. package/packages/dd-trace/src/histogram.js +1 -1
  93. package/packages/dd-trace/src/id.js +60 -0
  94. package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -3
  95. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  96. package/packages/dd-trace/src/llmobs/index.js +5 -5
  97. package/packages/dd-trace/src/llmobs/noop.js +6 -0
  98. package/packages/dd-trace/src/llmobs/plugins/ai/index.js +1 -0
  99. package/packages/dd-trace/src/llmobs/plugins/genai/index.js +104 -0
  100. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +486 -0
  101. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +2 -2
  102. package/packages/dd-trace/src/llmobs/plugins/{openai.js → openai/index.js} +87 -39
  103. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +114 -0
  104. package/packages/dd-trace/src/llmobs/sdk.js +10 -1
  105. package/packages/dd-trace/src/llmobs/span_processor.js +11 -6
  106. package/packages/dd-trace/src/llmobs/tagger.js +35 -17
  107. package/packages/dd-trace/src/msgpack/chunk.js +2 -2
  108. package/packages/dd-trace/src/msgpack/encoder.js +2 -3
  109. package/packages/dd-trace/src/msgpack/index.js +2 -2
  110. package/packages/dd-trace/src/openfeature/flagging_provider.js +5 -3
  111. package/packages/dd-trace/src/opentelemetry/logs/index.js +3 -3
  112. package/packages/dd-trace/src/opentelemetry/logs/logger.js +14 -8
  113. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +6 -4
  114. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +9 -17
  115. package/packages/dd-trace/src/opentelemetry/metrics/constants.js +34 -0
  116. package/packages/dd-trace/src/opentelemetry/metrics/index.js +81 -0
  117. package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +225 -0
  118. package/packages/dd-trace/src/opentelemetry/metrics/meter.js +171 -0
  119. package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +54 -0
  120. package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +62 -0
  121. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +251 -0
  122. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +532 -0
  123. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +10 -18
  124. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +36 -22
  125. package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +2 -2
  126. package/packages/dd-trace/src/opentelemetry/span.js +1 -1
  127. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
  128. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
  129. package/packages/dd-trace/src/payload-tagging/index.js +2 -2
  130. package/packages/dd-trace/src/plugin_manager.js +4 -2
  131. package/packages/dd-trace/src/plugins/database.js +1 -0
  132. package/packages/dd-trace/src/plugins/index.js +1 -0
  133. package/packages/dd-trace/src/plugins/plugin.js +7 -9
  134. package/packages/dd-trace/src/plugins/util/test.js +3 -3
  135. package/packages/dd-trace/src/plugins/util/url.js +119 -1
  136. package/packages/dd-trace/src/plugins/util/web.js +10 -41
  137. package/packages/dd-trace/src/process-tags/index.js +81 -0
  138. package/packages/dd-trace/src/profiling/config.js +1 -1
  139. package/packages/dd-trace/src/profiling/exporter_cli.js +7 -6
  140. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  141. package/packages/dd-trace/src/profiling/profilers/events.js +10 -1
  142. package/packages/dd-trace/src/proxy.js +5 -0
  143. package/packages/dd-trace/src/rate_limiter.js +1 -1
  144. package/packages/dd-trace/src/remote_config/manager.js +1 -1
  145. package/packages/dd-trace/src/require-package-json.js +1 -1
  146. package/packages/dd-trace/src/ritm.js +1 -1
  147. package/packages/dd-trace/src/service-naming/index.js +31 -4
  148. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  149. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  150. package/packages/dd-trace/src/{format.js → span_format.js} +9 -4
  151. package/packages/dd-trace/src/span_processor.js +16 -11
  152. package/packages/dd-trace/src/span_stats.js +15 -4
  153. package/packages/dd-trace/src/spanleak.js +1 -1
  154. package/packages/dd-trace/src/supported-configurations.json +13 -0
  155. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  156. package/packages/dd-trace/src/telemetry/telemetry.js +11 -2
  157. package/vendor/dist/@datadog/sketches-js/LICENSE +39 -0
  158. package/vendor/dist/@datadog/sketches-js/index.js +1 -0
  159. package/vendor/dist/@datadog/source-map/LICENSE +28 -0
  160. package/vendor/dist/@datadog/source-map/index.js +1 -0
  161. package/vendor/dist/@isaacs/ttlcache/LICENSE +55 -0
  162. package/vendor/dist/@isaacs/ttlcache/index.js +1 -0
  163. package/vendor/dist/@opentelemetry/core/LICENSE +201 -0
  164. package/vendor/dist/@opentelemetry/core/index.js +1 -0
  165. package/vendor/dist/@opentelemetry/resources/LICENSE +201 -0
  166. package/vendor/dist/@opentelemetry/resources/index.js +1 -0
  167. package/vendor/dist/astring/LICENSE +19 -0
  168. package/vendor/dist/astring/index.js +1 -0
  169. package/vendor/dist/crypto-randomuuid/index.js +1 -0
  170. package/vendor/dist/escape-string-regexp/LICENSE +9 -0
  171. package/vendor/dist/escape-string-regexp/index.js +1 -0
  172. package/vendor/dist/esquery/LICENSE +24 -0
  173. package/vendor/dist/esquery/index.js +1 -0
  174. package/vendor/dist/ignore/LICENSE +21 -0
  175. package/vendor/dist/ignore/index.js +1 -0
  176. package/vendor/dist/istanbul-lib-coverage/LICENSE +24 -0
  177. package/vendor/dist/istanbul-lib-coverage/index.js +1 -0
  178. package/vendor/dist/jest-docblock/LICENSE +21 -0
  179. package/vendor/dist/jest-docblock/index.js +1 -0
  180. package/vendor/dist/jsonpath-plus/LICENSE +22 -0
  181. package/vendor/dist/jsonpath-plus/index.js +1 -0
  182. package/vendor/dist/limiter/LICENSE +19 -0
  183. package/vendor/dist/limiter/index.js +1 -0
  184. package/vendor/dist/lodash.sortby/LICENSE +47 -0
  185. package/vendor/dist/lodash.sortby/index.js +1 -0
  186. package/vendor/dist/lru-cache/LICENSE +15 -0
  187. package/vendor/dist/lru-cache/index.js +1 -0
  188. package/vendor/dist/meriyah/LICENSE +7 -0
  189. package/vendor/dist/meriyah/index.js +1 -0
  190. package/vendor/dist/module-details-from-path/LICENSE +21 -0
  191. package/vendor/dist/module-details-from-path/index.js +1 -0
  192. package/vendor/dist/mutexify/promise/LICENSE +21 -0
  193. package/vendor/dist/mutexify/promise/index.js +1 -0
  194. package/vendor/dist/opentracing/LICENSE +201 -0
  195. package/vendor/dist/opentracing/binary_carrier.d.ts +11 -0
  196. package/vendor/dist/opentracing/constants.d.ts +61 -0
  197. package/vendor/dist/opentracing/examples/demo/demo.d.ts +2 -0
  198. package/vendor/dist/opentracing/ext/tags.d.ts +90 -0
  199. package/vendor/dist/opentracing/functions.d.ts +20 -0
  200. package/vendor/dist/opentracing/global_tracer.d.ts +14 -0
  201. package/vendor/dist/opentracing/index.d.ts +12 -0
  202. package/vendor/dist/opentracing/index.js +1 -0
  203. package/vendor/dist/opentracing/mock_tracer/index.d.ts +5 -0
  204. package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +13 -0
  205. package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +16 -0
  206. package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +50 -0
  207. package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +26 -0
  208. package/vendor/dist/opentracing/noop.d.ts +8 -0
  209. package/vendor/dist/opentracing/reference.d.ts +33 -0
  210. package/vendor/dist/opentracing/span.d.ts +147 -0
  211. package/vendor/dist/opentracing/span_context.d.ts +26 -0
  212. package/vendor/dist/opentracing/test/api_compatibility.d.ts +16 -0
  213. package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +3 -0
  214. package/vendor/dist/opentracing/test/noop_implementation.d.ts +4 -0
  215. package/vendor/dist/opentracing/test/opentracing_api.d.ts +3 -0
  216. package/vendor/dist/opentracing/test/unittest.d.ts +2 -0
  217. package/vendor/dist/opentracing/tracer.d.ts +127 -0
  218. package/vendor/dist/path-to-regexp/LICENSE +21 -0
  219. package/vendor/dist/path-to-regexp/index.js +1 -0
  220. package/vendor/dist/pprof-format/LICENSE +8 -0
  221. package/vendor/dist/pprof-format/index.js +1 -0
  222. package/vendor/dist/protobufjs/LICENSE +39 -0
  223. package/vendor/dist/protobufjs/index.js +1 -0
  224. package/vendor/dist/protobufjs/minimal/LICENSE +39 -0
  225. package/vendor/dist/protobufjs/minimal/index.js +1 -0
  226. package/vendor/dist/retry/LICENSE +21 -0
  227. package/vendor/dist/retry/index.js +1 -0
  228. package/vendor/dist/rfdc/LICENSE +15 -0
  229. package/vendor/dist/rfdc/index.js +1 -0
  230. package/vendor/dist/semifies/LICENSE +201 -0
  231. package/vendor/dist/semifies/index.js +1 -0
  232. package/vendor/dist/shell-quote/LICENSE +24 -0
  233. package/vendor/dist/shell-quote/index.js +1 -0
  234. package/vendor/dist/source-map/LICENSE +28 -0
  235. package/vendor/dist/source-map/index.js +1 -0
  236. package/vendor/dist/source-map/lib/util/LICENSE +28 -0
  237. package/vendor/dist/source-map/lib/util/index.js +1 -0
  238. package/vendor/dist/source-map/mappings.wasm +0 -0
  239. package/vendor/dist/tlhunter-sorted-set/LICENSE +21 -0
  240. package/vendor/dist/tlhunter-sorted-set/index.js +1 -0
  241. package/vendor/dist/ttl-set/LICENSE +21 -0
  242. package/vendor/dist/ttl-set/index.js +1 -0
@@ -4,7 +4,7 @@ const { errorMonitor } = require('node:events')
4
4
 
5
5
  const { channel, addHook } = require('./helpers/instrument')
6
6
  const shimmer = require('../../datadog-shimmer')
7
- const satisfies = require('semifies')
7
+ const satisfies = require('../../../vendor/dist/semifies')
8
8
 
9
9
  function wrapConnection (Connection, version) {
10
10
  const startCh = channel('apm:mysql2:query:start')
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const satisfies = require('semifies')
3
+ const satisfies = require('../../../vendor/dist/semifies')
4
4
 
5
5
  const { addHook, channel } = require('./helpers/instrument')
6
6
  const shimmer = require('../../datadog-shimmer')
@@ -11,6 +11,9 @@ const {
11
11
  getIsFaultyEarlyFlakeDetection
12
12
  } = require('../../dd-trace/src/plugins/util/test')
13
13
  const log = require('../../dd-trace/src/log')
14
+ const {
15
+ getEnvironmentVariable
16
+ } = require('../../dd-trace/src/config-helper')
14
17
  const { DD_MAJOR } = require('../../../version')
15
18
 
16
19
  const testStartCh = channel('ci:playwright:test:start')
@@ -38,7 +41,7 @@ const testSuiteToTestStatuses = new Map()
38
41
  const testSuiteToErrors = new Map()
39
42
  const testsToTestStatuses = new Map()
40
43
 
41
- const RUM_FLUSH_WAIT_TIME = 1000
44
+ const RUM_FLUSH_WAIT_TIME = Number(getEnvironmentVariable('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) || 1000
42
45
 
43
46
  let applyRepeatEachIndex = null
44
47
 
@@ -481,6 +484,15 @@ function dispatcherRunWrapper (run) {
481
484
 
482
485
  function dispatcherRunWrapperNew (run) {
483
486
  return function (testGroups) {
487
+ // Filter out disabled tests from testGroups before they get scheduled
488
+ if (isTestManagementTestsEnabled) {
489
+ testGroups.forEach(group => {
490
+ group.tests = group.tests.filter(test => !test._ddIsDisabled)
491
+ })
492
+ // Remove empty groups
493
+ testGroups = testGroups.filter(group => group.tests.length > 0)
494
+ }
495
+
484
496
  if (!this._allTests) {
485
497
  // Removed in https://github.com/microsoft/playwright/commit/1e52c37b254a441cccf332520f60225a5acc14c7
486
498
  // Not available from >=1.44.0
@@ -678,10 +690,11 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
678
690
 
679
691
  const projects = getProjectsFromRunner(this, config)
680
692
 
681
- const shouldSetRetries = isFlakyTestRetriesEnabled &&
682
- flakyTestRetriesCount > 0 &&
683
- !isTestManagementTestsEnabled
684
- if (shouldSetRetries) {
693
+ // ATR and `--retries` are now compatible with Test Management.
694
+ // Test Management tests have their retries set to 0 at the test level,
695
+ // preventing them from being retried by ATR or `--retries`.
696
+ const shouldSetATRRetries = isFlakyTestRetriesEnabled && flakyTestRetriesCount > 0
697
+ if (shouldSetATRRetries) {
685
698
  projects.forEach(project => {
686
699
  if (project.retries === 0) { // Only if it hasn't been set by the user
687
700
  project.retries = flakyTestRetriesCount
@@ -713,6 +726,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
713
726
  })
714
727
  })
715
728
 
729
+ let preventedToFail = false
730
+
716
731
  const sessionStatus = runAllTestsReturn.status || runAllTestsReturn
717
732
 
718
733
  if (isTestManagementTestsEnabled && sessionStatus === 'failed') {
@@ -721,23 +736,30 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
721
736
  let totalPureQuarantinedFailedTestCount = 0
722
737
 
723
738
  for (const [fqn, testStatuses] of testsToTestStatuses.entries()) {
724
- const failedCount = testStatuses.filter(status => status === 'fail').length
725
- totalFailedTestCount += failedCount
726
- if (quarantinedButNotAttemptToFixFqns.has(fqn)) {
727
- totalPureQuarantinedFailedTestCount += failedCount
739
+ // Only count as failed if the final status (after retries) is 'fail'
740
+ const lastStatus = testStatuses[testStatuses.length - 1]
741
+ if (lastStatus === 'fail') {
742
+ totalFailedTestCount += 1
743
+ if (quarantinedButNotAttemptToFixFqns.has(fqn)) {
744
+ totalPureQuarantinedFailedTestCount += 1
745
+ }
728
746
  }
729
747
  }
730
748
 
731
749
  for (const test of quarantinedOrDisabledTestsAttemptToFix) {
732
750
  const testFqn = getTestFullyQualifiedName(test)
733
751
  const testStatuses = testsToTestStatuses.get(testFqn)
734
- totalAttemptToFixFailedTestCount += testStatuses.filter(status => status === 'fail').length
752
+ // Only count as failed if the final status (after retries) is 'fail'
753
+ if (testStatuses && testStatuses[testStatuses.length - 1] === 'fail') {
754
+ totalAttemptToFixFailedTestCount += 1
755
+ }
735
756
  }
736
757
 
737
758
  const totalIgnorableFailures = totalAttemptToFixFailedTestCount + totalPureQuarantinedFailedTestCount
738
759
 
739
760
  if (totalFailedTestCount > 0 && totalFailedTestCount === totalIgnorableFailures) {
740
761
  runAllTestsReturn = 'passed'
762
+ preventedToFail = true
741
763
  }
742
764
  }
743
765
 
@@ -745,7 +767,7 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
745
767
  onDone = resolve
746
768
  })
747
769
  testSessionFinishCh.publish({
748
- status: STATUS_TO_TEST_STATUS[sessionStatus],
770
+ status: preventedToFail ? 'pass' : STATUS_TO_TEST_STATUS[sessionStatus],
749
771
  isEarlyFlakeDetectionEnabled,
750
772
  isEarlyFlakeDetectionFaulty,
751
773
  isTestManagementTestsEnabled,
@@ -893,6 +915,9 @@ addHook({
893
915
  if (testProperties.disabled) {
894
916
  test._ddIsDisabled = true
895
917
  test.expectedStatus = 'skipped'
918
+ // setting test.expectedStatus to 'skipped' does not work for every case,
919
+ // so we need to filter out disabled tests in dispatcherRunWrapperNew,
920
+ // so they don't get to the workers
896
921
  continue
897
922
  }
898
923
  if (testProperties.quarantined) {
@@ -905,6 +930,8 @@ addHook({
905
930
  }
906
931
  if (testProperties.attemptToFix) {
907
932
  test._ddIsAttemptToFix = true
933
+ // Prevent ATR or `--retries` from retrying attemptToFix tests
934
+ test.retries = 0
908
935
  const fileSuite = getSuiteType(test, 'file')
909
936
 
910
937
  if (!fileSuitesWithManagedTestsToProjects.has(fileSuite)) {
@@ -979,6 +1006,8 @@ addHook({
979
1006
  newTests.forEach(newTest => {
980
1007
  newTest._ddIsNew = true
981
1008
  if (isEarlyFlakeDetectionEnabled && newTest.expectedStatus !== 'skipped' && !newTest._ddIsModified) {
1009
+ // Prevent ATR or `--retries` from retrying new tests if EFD is enabled
1010
+ newTest.retries = 0
982
1011
  const fileSuite = getSuiteType(newTest, 'file')
983
1012
  if (!fileSuitesWithNewTestsToProjects.has(fileSuite)) {
984
1013
  fileSuitesWithNewTestsToProjects.set(fileSuite, getSuiteType(newTest, 'project'))
@@ -1052,9 +1081,19 @@ addHook({
1052
1081
 
1053
1082
  try {
1054
1083
  if (page) {
1055
- const isRumActive = await page.evaluate(() => {
1056
- return window.DD_RUM && window.DD_RUM.getInternalContext ? !!window.DD_RUM.getInternalContext() : false
1084
+ const { isRumInstrumented, isRumActive, rumSamplingRate } = await page.evaluate(() => {
1085
+ const isRumInstrumented = !!window.DD_RUM
1086
+ const isRumActive = window.DD_RUM && window.DD_RUM.getInternalContext
1087
+ ? !!window.DD_RUM.getInternalContext()
1088
+ : false
1089
+ const rumSamplingRate = window.DD_RUM && window.DD_RUM.getInitConfiguration
1090
+ ? window.DD_RUM.getInitConfiguration().sessionSampleRate
1091
+ : null
1092
+ return { isRumInstrumented, isRumActive, rumSamplingRate }
1057
1093
  })
1094
+ if (isRumInstrumented && rumSamplingRate < 100 && !isRumActive) {
1095
+ log.debug("RUM was detected on the page, but it isn't active because the sampling rate is below 100%")
1096
+ }
1058
1097
 
1059
1098
  if (isRumActive) {
1060
1099
  testPageGotoCh.publish({
@@ -1063,8 +1102,9 @@ addHook({
1063
1102
  })
1064
1103
  }
1065
1104
  }
1066
- } catch {
1105
+ } catch (e) {
1067
1106
  // ignore errors such as redirects, context destroyed, etc
1107
+ log.error('goto hook error', e)
1068
1108
  }
1069
1109
 
1070
1110
  return response
@@ -1156,8 +1196,9 @@ addHook({
1156
1196
  }
1157
1197
  }
1158
1198
  }
1159
- } catch {
1199
+ } catch (e) {
1160
1200
  // ignore errors
1201
+ log.error('afterEach hook error', e)
1161
1202
  }
1162
1203
  },
1163
1204
  title: 'afterEach hook',
@@ -1270,6 +1311,10 @@ function generateSummaryWrapper (generateSummary) {
1270
1311
  const {
1271
1312
  _requireFile: testSuiteAbsolutePath,
1272
1313
  location: { line: testSourceLine },
1314
+ _ddIsNew: isNew,
1315
+ _ddIsDisabled: isDisabled,
1316
+ _ddIsModified: isModified,
1317
+ _ddIsQuarantined: isQuarantined
1273
1318
  } = test
1274
1319
  const browserName = getBrowserNameFromProjects(sessionProjects, test)
1275
1320
 
@@ -1278,6 +1323,10 @@ function generateSummaryWrapper (generateSummary) {
1278
1323
  testSuiteAbsolutePath,
1279
1324
  testSourceLine,
1280
1325
  browserName,
1326
+ isNew,
1327
+ isDisabled,
1328
+ isModified,
1329
+ isQuarantined
1281
1330
  })
1282
1331
  }
1283
1332
  }
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const METHODS = [...require('http').METHODS.map(v => v.toLowerCase()), 'all']
4
- const pathToRegExp = require('path-to-regexp')
4
+ const pathToRegExp = require('../../../vendor/dist/path-to-regexp')
5
5
  const shimmer = require('../../datadog-shimmer')
6
6
  const { addHook, channel } = require('./helpers/instrument')
7
7
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  const { addHook, channel } = require('./helpers/instrument')
4
4
  const shimmer = require('../../datadog-shimmer')
5
+ const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
5
6
 
6
7
  const ciSeleniumDriverGetStartCh = channel('ci:selenium:driver:get')
7
8
 
@@ -15,7 +16,8 @@ if (window.DD_RUM && window.DD_RUM.stopSession) {
15
16
  `
16
17
  const IS_RUM_ACTIVE_SCRIPT = 'return !!window.DD_RUM'
17
18
 
18
- const DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS = 500
19
+ const DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS =
20
+ Number(getEnvironmentVariable('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) || 500
19
21
  const DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME = 'datadog-ci-visibility-test-execution-id'
20
22
 
21
23
  // TODO: can we increase the supported version range?
@@ -12,6 +12,9 @@ const producerCh = tracingChannel('ws:send')
12
12
  const receiverCh = tracingChannel('ws:receive')
13
13
  const closeCh = tracingChannel('ws:close')
14
14
  const emitCh = channel('tracing:ws:server:connect:emit')
15
+ // TODO: Add a error channel / handle error events properly.
16
+
17
+ const eventHandlerMap = new WeakMap()
15
18
 
16
19
  function wrapHandleUpgrade (handleUpgrade) {
17
20
  return function () {
@@ -67,24 +70,37 @@ function createWrapEmit (emit) {
67
70
  }
68
71
 
69
72
  function createWrappedHandler (handler) {
70
- return function wrappedMessageHandler (data, binary) {
73
+ return shimmer.wrapFunction(handler, originalHandler => function (data, binary) {
71
74
  const byteLength = dataLength(data)
72
75
 
73
76
  const ctx = { data, binary, socket: this._sender?._socket, byteLength }
74
77
 
75
- return receiverCh.traceSync(handler, ctx, this, data, binary)
76
- }
78
+ return receiverCh.traceSync(originalHandler, ctx, this, data, binary)
79
+ })
77
80
  }
78
81
 
79
82
  function wrapListener (originalOn) {
80
83
  return function (eventName, handler) {
81
84
  if (eventName === 'message') {
82
- return originalOn.call(this, eventName, createWrappedHandler(handler))
85
+ // Prevent multiple wrapping of the same handler in case the user adds the listener multiple times
86
+ const wrappedHandler = eventHandlerMap.get(handler) ?? createWrappedHandler(handler)
87
+ eventHandlerMap.set(handler, wrappedHandler)
88
+ return originalOn.call(this, eventName, wrappedHandler)
83
89
  }
84
90
  return originalOn.apply(this, arguments)
85
91
  }
86
92
  }
87
93
 
94
+ function removeListener (originalOff) {
95
+ return function (eventName, handler) {
96
+ if (eventName === 'message') {
97
+ const wrappedHandler = eventHandlerMap.get(handler)
98
+ return originalOff.call(this, eventName, wrappedHandler)
99
+ }
100
+ return originalOff.apply(this, arguments)
101
+ }
102
+ }
103
+
88
104
  function wrapClose (close) {
89
105
  return function (code, data) {
90
106
  // _closeFrameReceived is set to true when receiver receives a close frame from a peer
@@ -115,22 +131,24 @@ addHook({
115
131
  versions: ['>=8.0.0']
116
132
  }, ws => {
117
133
  shimmer.wrap(ws.prototype, 'send', wrapSend)
118
- shimmer.wrap(ws.prototype, 'on', wrapListener)
119
134
  shimmer.wrap(ws.prototype, 'close', wrapClose)
135
+
136
+ // TODO: Do not wrap these methods. Instead, add a listener to the websocket instance when one is created.
137
+ // That way it avoids producing too many spans for the same websocket instance and less user code is impacted.
138
+ shimmer.wrap(ws.prototype, 'on', wrapListener)
139
+ shimmer.wrap(ws.prototype, 'addListener', wrapListener)
140
+ shimmer.wrap(ws.prototype, 'off', removeListener)
141
+ shimmer.wrap(ws.prototype, 'removeListener', removeListener)
142
+
120
143
  return ws
121
144
  })
122
145
 
123
- function detectType (data) {
124
- if (typeof Blob !== 'undefined' && data instanceof Blob) return 'Blob'
125
- if (typeof Buffer !== 'undefined' && Buffer.isBuffer(data)) return 'Buffer'
126
- if (typeof data === 'string') return 'string'
127
- return 'Unknown'
128
- }
129
-
130
146
  function dataLength (data) {
131
- const type = detectType(data)
132
- if (type === 'Blob') return data.size
133
- if (type === 'Buffer') return data.length
134
- if (type === 'string') return Buffer.byteLength(data)
135
- return 0
147
+ if (typeof data === 'string') {
148
+ return Buffer.byteLength(data)
149
+ }
150
+ if (data instanceof Blob) {
151
+ return data.size
152
+ }
153
+ return data?.length ?? 0
136
154
  }
@@ -27,8 +27,9 @@ const PROVIDER = {
27
27
  * Coerce the chunks into a single response body.
28
28
  *
29
29
  * @param {Array<{ chunk: { bytes: Buffer } }>} chunks
30
- * @param {string} provider
31
- * @returns {Object}
30
+ * @param {string} modelProvider
31
+ * @param {string} modelName
32
+ * @returns {Generation | Record<never, never>}
32
33
  */
33
34
  function extractTextAndResponseReasonFromStream (chunks, modelProvider, modelName) {
34
35
  const modelProviderUpper = modelProvider.toUpperCase()
@@ -2,6 +2,7 @@
2
2
 
3
3
  const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
4
4
  const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
5
+ const spanContexts = new WeakMap()
5
6
 
6
7
  class AzureServiceBusProducerPlugin extends ProducerPlugin {
7
8
  static get id () { return 'azure-service-bus' }
@@ -36,7 +37,12 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
36
37
  }
37
38
 
38
39
  if (batchLinksAreEnabled()) {
39
- ctx.batch._spanContexts.push(span.context())
40
+ const spanContext = spanContexts.get(ctx.batch)
41
+ if (spanContext) {
42
+ spanContext.push(span.context())
43
+ } else {
44
+ spanContexts.set(ctx.batch, [span.context()])
45
+ }
40
46
  injectTraceContext(this.tracer, span, ctx.msg)
41
47
  }
42
48
  }
@@ -47,9 +53,12 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
47
53
  if (isBatch) {
48
54
  span.setTag('messaging.batch.message_count', messages.count)
49
55
  if (batchLinksAreEnabled()) {
50
- messages._spanContexts.forEach(spanContext => {
51
- span.addLink(spanContext)
52
- })
56
+ const contexts = spanContexts.get(messages)
57
+ if (contexts) {
58
+ for (const spanContext of contexts) {
59
+ span.addLink(spanContext)
60
+ }
61
+ }
53
62
  }
54
63
  } else if (Array.isArray(messages)) {
55
64
  span.setTag('messaging.batch.message_count', messages.length)
@@ -64,7 +73,7 @@ class AzureServiceBusProducerPlugin extends ProducerPlugin {
64
73
  }
65
74
 
66
75
  asyncEnd (ctx) {
67
- super.finish()
76
+ super.finish(ctx)
68
77
  }
69
78
  }
70
79
 
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const shellParser = require('shell-quote/parse')
3
+ const shellParser = require('../../../vendor/dist/shell-quote').parse
4
4
 
5
5
  const ALLOWED_ENV_VARIABLES = new Set(['LD_PRELOAD', 'LD_LIBRARY_PATH', 'PATH'])
6
6
  const PROCESS_DENYLIST = new Set(['md5'])
@@ -133,6 +133,14 @@ function getCypressCommand (details) {
133
133
  return `${TEST_FRAMEWORK_NAME} ${details.specPattern || ''}`
134
134
  }
135
135
 
136
+ function getIsTestIsolationEnabled (cypressConfig) {
137
+ if (!cypressConfig) {
138
+ // If we can't read testIsolation config parameter, we default to allowing retries
139
+ return true
140
+ }
141
+ return cypressConfig.testIsolation === undefined ? true : cypressConfig.testIsolation
142
+ }
143
+
136
144
  function getLibraryConfiguration (tracer, testConfiguration) {
137
145
  return new Promise(resolve => {
138
146
  if (!tracer._tracer._exporter?.getLibraryConfiguration) {
@@ -296,6 +304,12 @@ class CypressPlugin {
296
304
  this.tracer = tracer
297
305
  this.cypressConfig = cypressConfig
298
306
 
307
+ this.isTestIsolationEnabled = getIsTestIsolationEnabled(cypressConfig)
308
+
309
+ if (!this.isTestIsolationEnabled) {
310
+ log.warn('Test isolation is disabled, retries will not be enabled')
311
+ }
312
+
299
313
  // we have to do it here because the tracer is not initialized in the constructor
300
314
  this.testEnvironmentMetadata[DD_TEST_IS_USER_PROVIDED_SERVICE] =
301
315
  tracer._tracer._config.isServiceUserProvided ? 'true' : 'false'
@@ -324,7 +338,7 @@ class CypressPlugin {
324
338
  this.isEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
325
339
  this.earlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
326
340
  this.isKnownTestsEnabled = isKnownTestsEnabled
327
- if (isFlakyTestRetriesEnabled) {
341
+ if (isFlakyTestRetriesEnabled && this.isTestIsolationEnabled) {
328
342
  this.isFlakyTestRetriesEnabled = true
329
343
  this.cypressConfig.retries.runMode = flakyTestRetriesCount
330
344
  }
@@ -467,6 +481,7 @@ class CypressPlugin {
467
481
  // We need to make sure that the plugin is initialized before running the tests
468
482
  // This is for the case where the user has not returned the promise from the init function
469
483
  await this.libraryConfigurationPromise
484
+
470
485
  this.command = getCypressCommand(details)
471
486
  this.frameworkVersion = getCypressVersion(details)
472
487
  this.rootDir = getRootDir(details)
@@ -801,7 +816,8 @@ class CypressPlugin {
801
816
  testManagementTests: this.getTestSuiteProperties(testSuite),
802
817
  isImpactedTestsEnabled: this.isImpactedTestsEnabled,
803
818
  isModifiedTest: this.getIsTestModified(testSuiteAbsolutePath),
804
- repositoryRoot: this.repositoryRoot
819
+ repositoryRoot: this.repositoryRoot,
820
+ isTestIsolationEnabled: this.isTestIsolationEnabled
805
821
  }
806
822
 
807
823
  if (this.testSuiteSpan) {
@@ -962,6 +978,11 @@ class CypressPlugin {
962
978
  this.activeTestSpan.addTags(tags)
963
979
  }
964
980
  return null
981
+ },
982
+ 'dd:log': (message) => {
983
+ // eslint-disable-next-line no-console
984
+ console.log(`[datadog] ${message}`)
985
+ return null
965
986
  }
966
987
  }
967
988
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  const NoopTracer = require('../../dd-trace/src/noop/tracer')
4
4
  const cypressPlugin = require('./cypress-plugin')
5
- const satisfies = require('semifies')
5
+ const satisfies = require('../../../vendor/dist/semifies')
6
6
  const { DD_MAJOR } = require('../../../version')
7
7
 
8
8
  const noopTask = {
@@ -9,6 +9,9 @@ let testManagementAttemptToFixRetries = 0
9
9
  let testManagementTests = {}
10
10
  let isImpactedTestsEnabled = false
11
11
  let isModifiedTest = false
12
+ let isTestIsolationEnabled = false
13
+ // Array of test names that have been retried and the reason
14
+ const retryReasonsByTestName = new Map()
12
15
 
13
16
  // We need to grab the original window as soon as possible,
14
17
  // in case the test changes the origin. If the test does change the origin,
@@ -43,17 +46,20 @@ function getTestProperties (testName) {
43
46
  return { isAttemptToFix, isDisabled, isQuarantined }
44
47
  }
45
48
 
46
- function retryTest (test, suiteTests, numRetries, tags) {
49
+ function getRetriedTests (test, numRetries, tags) {
50
+ const retriedTests = []
47
51
  for (let retryIndex = 0; retryIndex < numRetries; retryIndex++) {
48
- const clonedTest = test.clone()
49
52
  // TODO: signal in framework logs that this is a retry.
50
53
  // TODO: Change it so these tests are allowed to fail.
51
- // TODO: figure out if reported duration is skewed.
52
- suiteTests.unshift(clonedTest)
54
+ const clonedTest = test.clone()
53
55
  tags.forEach(tag => {
54
- clonedTest[tag] = true
56
+ if (tag) {
57
+ clonedTest[tag] = true
58
+ }
55
59
  })
60
+ retriedTests.push(clonedTest)
56
61
  }
62
+ return retriedTests
57
63
  }
58
64
 
59
65
  const oldRunTests = Cypress.mocha.getRunner().runTests
@@ -61,45 +67,80 @@ Cypress.mocha.getRunner().runTests = function (suite, fn) {
61
67
  if (!isKnownTestsEnabled && !isTestManagementEnabled && !isImpactedTestsEnabled) {
62
68
  return oldRunTests.apply(this, arguments)
63
69
  }
64
- // We copy the new tests at the beginning of the suite run (runTests), so that they're run
65
- // multiple times.
66
- suite.tests.forEach(test => {
67
- const testName = test.fullTitle()
70
+ // We copy the tests array and add retries to it, then assign it back to suite.tests
71
+ // to avoid modifying the array while iterating over it
72
+ const testsWithRetries = []
68
73
 
74
+ for (let testIndex = 0; testIndex < suite.tests.length; testIndex++) {
75
+ const test = suite.tests[testIndex]
76
+ const testName = test.fullTitle()
69
77
  const { isAttemptToFix } = getTestProperties(testName)
78
+ const isSkipped = test.isPending()
70
79
 
71
- if (isTestManagementEnabled && isAttemptToFix && !test.isPending()) {
72
- test._ddIsAttemptToFix = true
73
- retryTest(test, suite.tests, testManagementAttemptToFixRetries, ['_ddIsAttemptToFix'])
74
- }
75
- if (isImpactedTestsEnabled && isModifiedTest) {
80
+ const isAtemptToFix = isTestManagementEnabled && isAttemptToFix && !isSkipped
81
+ const isModified = isImpactedTestsEnabled && isModifiedTest
82
+ const isNew = isKnownTestsEnabled && !isSkipped && isNewTest(test)
83
+
84
+ // We want is_modified and is_new regardless of the retry reason
85
+ if (isModified) {
76
86
  test._ddIsModified = true
77
- if (isEarlyFlakeDetectionEnabled && !isAttemptToFix) {
78
- retryTest(
79
- test,
80
- suite.tests,
81
- earlyFlakeDetectionNumRetries,
82
- ['_ddIsModified', '_ddIsEfdRetry', isKnownTestsEnabled && isNewTest(test) && '_ddIsNew']
83
- )
84
- }
85
87
  }
86
- if (isKnownTestsEnabled && !test._ddIsNew && !test.isPending() && isNewTest(test)) {
88
+ if (isNew) {
87
89
  test._ddIsNew = true
88
- if (isImpactedTestsEnabled && isModifiedTest) {
89
- test._ddIsModified = true
90
- }
91
- if (isEarlyFlakeDetectionEnabled && !isAttemptToFix && !isModifiedTest) {
92
- retryTest(test, suite.tests, earlyFlakeDetectionNumRetries, ['_ddIsNew', '_ddIsEfdRetry'])
93
- }
94
90
  }
95
- })
91
+
92
+ // Add the original test first
93
+ testsWithRetries.push(test)
94
+
95
+ if (!isTestIsolationEnabled) {
96
+ continue
97
+ }
98
+
99
+ // Then add retries right after it
100
+ let retriedTests = []
101
+ let retryMessage = ''
102
+ if (isAtemptToFix) {
103
+ test._ddIsAttemptToFix = true
104
+ retryMessage = 'because it is an attempt to fix'
105
+ retriedTests = getRetriedTests(test, testManagementAttemptToFixRetries, ['_ddIsAttemptToFix'])
106
+ } else if (isModified && isEarlyFlakeDetectionEnabled) {
107
+ retryMessage = 'to detect flakes because it is modified'
108
+ retriedTests = getRetriedTests(test, earlyFlakeDetectionNumRetries, [
109
+ '_ddIsModified',
110
+ '_ddIsEfdRetry',
111
+ isKnownTestsEnabled && isNewTest(test) && '_ddIsNew'
112
+ ])
113
+ } else if (isNew && isEarlyFlakeDetectionEnabled) {
114
+ retryMessage = 'to detect flakes because it is new'
115
+ retriedTests = getRetriedTests(test, earlyFlakeDetectionNumRetries, ['_ddIsNew', '_ddIsEfdRetry'])
116
+ }
117
+
118
+ testsWithRetries.push(...retriedTests)
119
+
120
+ if (retryMessage) {
121
+ retryReasonsByTestName.set(testName, retryMessage)
122
+ }
123
+ }
124
+
125
+ suite.tests = testsWithRetries
96
126
 
97
127
  return oldRunTests.apply(this, [suite, fn])
98
128
  }
99
129
 
100
130
  beforeEach(function () {
131
+ const testName = Cypress.mocha.getRunner().suite.ctx.currentTest.fullTitle()
132
+
133
+ const retryMessage = retryReasonsByTestName.get(testName)
134
+ if (retryMessage) {
135
+ cy.task(
136
+ 'dd:log',
137
+ `Retrying "${testName}" ${retryMessage}`
138
+ )
139
+ retryReasonsByTestName.delete(testName)
140
+ }
141
+
101
142
  cy.task('dd:beforeEach', {
102
- testName: Cypress.mocha.getRunner().suite.ctx.currentTest.fullTitle(),
143
+ testName,
103
144
  testSuite: Cypress.mocha.getRootSuite().file
104
145
  }).then(({ traceId, shouldSkip }) => {
105
146
  Cypress.env('traceId', traceId)
@@ -127,6 +168,7 @@ before(function () {
127
168
  testManagementTests = suiteConfig.testManagementTests
128
169
  isImpactedTestsEnabled = suiteConfig.isImpactedTestsEnabled
129
170
  isModifiedTest = suiteConfig.isModifiedTest
171
+ isTestIsolationEnabled = suiteConfig.isTestIsolationEnabled
130
172
  }
131
173
  })
132
174
  })
@@ -0,0 +1,17 @@
1
+ 'use strict'
2
+
3
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
4
+ const GenAiTracingPlugin = require('./tracing')
5
+ const GenAiLLMObsPlugin = require('../../dd-trace/src/llmobs/plugins/genai')
6
+
7
+ class GenAiPlugin extends CompositePlugin {
8
+ static id = 'google-genai'
9
+ static get plugins () {
10
+ return {
11
+ llmobs: GenAiLLMObsPlugin,
12
+ tracing: GenAiTracingPlugin
13
+ }
14
+ }
15
+ }
16
+
17
+ module.exports = GenAiPlugin