dd-trace 5.41.1 → 5.42.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 (59) hide show
  1. package/LICENSE-3rdparty.csv +1 -0
  2. package/index.d.ts +8 -1
  3. package/package.json +6 -3
  4. package/packages/datadog-esbuild/index.js +3 -1
  5. package/packages/datadog-instrumentations/src/cucumber.js +37 -29
  6. package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +102 -0
  7. package/packages/datadog-instrumentations/src/{check_require_cache.js → helpers/check-require-cache.js} +2 -2
  8. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -2
  9. package/packages/datadog-instrumentations/src/helpers/register.js +4 -1
  10. package/packages/datadog-instrumentations/src/jest.js +72 -49
  11. package/packages/datadog-instrumentations/src/langchain.js +29 -10
  12. package/packages/datadog-instrumentations/src/mocha/main.js +53 -34
  13. package/packages/datadog-instrumentations/src/mocha/utils.js +34 -24
  14. package/packages/datadog-instrumentations/src/mocha/worker.js +7 -8
  15. package/packages/datadog-instrumentations/src/openai.js +1 -1
  16. package/packages/datadog-instrumentations/src/playwright.js +37 -30
  17. package/packages/datadog-instrumentations/src/vitest.js +64 -29
  18. package/packages/datadog-plugin-cucumber/src/index.js +13 -4
  19. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +41 -35
  20. package/packages/datadog-plugin-cypress/src/plugin.js +10 -0
  21. package/packages/datadog-plugin-google-cloud-vertexai/src/index.js +195 -0
  22. package/packages/datadog-plugin-jest/src/index.js +18 -6
  23. package/packages/datadog-plugin-langchain/src/handlers/embedding.js +4 -1
  24. package/packages/datadog-plugin-mocha/src/index.js +13 -4
  25. package/packages/datadog-plugin-playwright/src/index.js +19 -5
  26. package/packages/datadog-plugin-vitest/src/index.js +41 -17
  27. package/packages/dd-trace/src/appsec/api_security_sampler.js +7 -3
  28. package/packages/dd-trace/src/appsec/blocking.js +23 -16
  29. package/packages/dd-trace/src/appsec/graphql.js +13 -6
  30. package/packages/dd-trace/src/appsec/rasp/utils.js +0 -1
  31. package/packages/dd-trace/src/appsec/reporter.js +35 -0
  32. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -3
  33. package/packages/dd-trace/src/appsec/telemetry/index.js +5 -1
  34. package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -1
  35. package/packages/dd-trace/src/appsec/telemetry/waf.js +16 -1
  36. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +43 -13
  37. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
  38. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +15 -14
  39. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +1 -2
  40. package/packages/dd-trace/src/ci-visibility/telemetry.js +2 -1
  41. package/packages/dd-trace/src/ci-visibility/{quarantined-tests/get-quarantined-tests.js → test-management/get-test-management-tests.js} +5 -5
  42. package/packages/dd-trace/src/config.js +11 -1
  43. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -2
  44. package/packages/dd-trace/src/lambda/runtime/patch.js +5 -3
  45. package/packages/dd-trace/src/lambda/runtime/ritm.js +13 -18
  46. package/packages/dd-trace/src/llmobs/plugins/openai.js +27 -2
  47. package/packages/dd-trace/src/opentracing/span.js +3 -0
  48. package/packages/dd-trace/src/plugins/ci_plugin.js +38 -10
  49. package/packages/dd-trace/src/plugins/index.js +1 -0
  50. package/packages/dd-trace/src/plugins/util/git.js +7 -3
  51. package/packages/dd-trace/src/plugins/util/test.js +10 -0
  52. package/packages/dd-trace/src/plugins/util/web.js +5 -2
  53. package/packages/dd-trace/src/priority_sampler.js +116 -15
  54. package/packages/dd-trace/src/sampler.js +9 -0
  55. package/packages/dd-trace/src/standalone/product.js +6 -2
  56. package/packages/dd-trace/src/startup-log.js +2 -1
  57. package/packages/dd-trace/src/telemetry/metrics.js +0 -8
  58. package/packages/dd-trace/src/tracer.js +1 -1
  59. /package/packages/datadog-instrumentations/src/{utils/src → helpers}/extract-package-and-module-path.js +0 -0
@@ -13,7 +13,7 @@ const testSessionFinishCh = channel('ci:playwright:session:finish')
13
13
 
14
14
  const libraryConfigurationCh = channel('ci:playwright:library-configuration')
15
15
  const knownTestsCh = channel('ci:playwright:known-tests')
16
- const quarantinedTestsCh = channel('ci:playwright:quarantined-tests')
16
+ const testManagementTestsCh = channel('ci:playwright:test-management-tests')
17
17
 
18
18
  const testSuiteStartCh = channel('ci:playwright:test-suite:start')
19
19
  const testSuiteFinishCh = channel('ci:playwright:test-suite:finish')
@@ -42,23 +42,19 @@ let earlyFlakeDetectionNumRetries = 0
42
42
  let isFlakyTestRetriesEnabled = false
43
43
  let flakyTestRetriesCount = 0
44
44
  let knownTests = {}
45
- let isQuarantinedTestsEnabled = false
46
- let quarantinedTests = {}
45
+ let isTestManagementTestsEnabled = false
46
+ let testManagementTests = {}
47
47
  let rootDir = ''
48
48
  const MINIMUM_SUPPORTED_VERSION_RANGE_EFD = '>=1.38.0'
49
49
 
50
- function isQuarantineTest (test) {
50
+ function getTestProperties (test) {
51
51
  const testName = getTestFullname(test)
52
52
  const testSuite = getTestSuitePath(test._requireFile, rootDir)
53
53
 
54
- return quarantinedTests
55
- ?.playwright
56
- ?.suites
57
- ?.[testSuite]
58
- ?.tests
59
- ?.[testName]
60
- ?.properties
61
- ?.quarantined
54
+ const { disabled, quarantined } =
55
+ testManagementTests?.playwright?.suites?.[testSuite]?.tests?.[testName]?.properties || {}
56
+
57
+ return { disabled, quarantined }
62
58
  }
63
59
 
64
60
  function isNewTest (test) {
@@ -283,7 +279,13 @@ function testBeginHandler (test, browserName) {
283
279
  const testAsyncResource = new AsyncResource('bound-anonymous-fn')
284
280
  testToAr.set(test, testAsyncResource)
285
281
  testAsyncResource.runInAsyncScope(() => {
286
- testStartCh.publish({ testName, testSuiteAbsolutePath, testSourceLine, browserName })
282
+ testStartCh.publish({
283
+ testName,
284
+ testSuiteAbsolutePath,
285
+ testSourceLine,
286
+ browserName,
287
+ isDisabled: test._ddIsDisabled
288
+ })
287
289
  })
288
290
  }
289
291
 
@@ -442,12 +444,12 @@ function runnerHook (runnerExport, playwrightVersion) {
442
444
  earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
443
445
  isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
444
446
  flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
445
- isQuarantinedTestsEnabled = libraryConfig.isQuarantinedTestsEnabled
447
+ isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
446
448
  }
447
449
  } catch (e) {
448
450
  isEarlyFlakeDetectionEnabled = false
449
451
  isKnownTestsEnabled = false
450
- isQuarantinedTestsEnabled = false
452
+ isTestManagementTestsEnabled = false
451
453
  log.error('Playwright session start error', e)
452
454
  }
453
455
 
@@ -467,17 +469,17 @@ function runnerHook (runnerExport, playwrightVersion) {
467
469
  }
468
470
  }
469
471
 
470
- if (isQuarantinedTestsEnabled && satisfies(playwrightVersion, MINIMUM_SUPPORTED_VERSION_RANGE_EFD)) {
472
+ if (isTestManagementTestsEnabled && satisfies(playwrightVersion, MINIMUM_SUPPORTED_VERSION_RANGE_EFD)) {
471
473
  try {
472
- const { err, quarantinedTests: receivedQuarantinedTests } = await getChannelPromise(quarantinedTestsCh)
474
+ const { err, testManagementTests: receivedTestManagementTests } = await getChannelPromise(testManagementTestsCh)
473
475
  if (!err) {
474
- quarantinedTests = receivedQuarantinedTests
476
+ testManagementTests = receivedTestManagementTests
475
477
  } else {
476
- isQuarantinedTestsEnabled = false
478
+ isTestManagementTestsEnabled = false
477
479
  }
478
480
  } catch (err) {
479
- isQuarantinedTestsEnabled = false
480
- log.error('Playwright quarantined tests error', err)
481
+ isTestManagementTestsEnabled = false
482
+ log.error('Playwright test management tests error', err)
481
483
  }
482
484
  }
483
485
 
@@ -513,7 +515,7 @@ function runnerHook (runnerExport, playwrightVersion) {
513
515
  testSessionFinishCh.publish({
514
516
  status: STATUS_TO_TEST_STATUS[sessionStatus],
515
517
  isEarlyFlakeDetectionEnabled,
516
- isQuarantinedTestsEnabled,
518
+ isTestManagementTestsEnabled,
517
519
  onDone
518
520
  })
519
521
  })
@@ -523,7 +525,7 @@ function runnerHook (runnerExport, playwrightVersion) {
523
525
  remainingTestsByFile = {}
524
526
 
525
527
  // TODO: we can trick playwright into thinking the session passed by returning
526
- // 'passed' here. We might be able to use this for both EFD and Quarantined tests.
528
+ // 'passed' here. We might be able to use this for both EFD and Test Management tests.
527
529
  return runAllTestsReturn
528
530
  })
529
531
 
@@ -594,19 +596,24 @@ addHook({
594
596
  const oldCreateRootSuite = loadUtilsPackage.createRootSuite
595
597
 
596
598
  async function newCreateRootSuite () {
597
- if (!isKnownTestsEnabled && !isQuarantinedTestsEnabled) {
599
+ if (!isKnownTestsEnabled && !isTestManagementTestsEnabled) {
598
600
  return oldCreateRootSuite.apply(this, arguments)
599
601
  }
600
602
  const rootSuite = await oldCreateRootSuite.apply(this, arguments)
601
603
 
602
604
  const allTests = rootSuite.allTests()
603
605
 
604
- if (isQuarantinedTestsEnabled) {
605
- const testsToBeIgnored = allTests.filter(isQuarantineTest)
606
- testsToBeIgnored.forEach(test => {
607
- test._ddIsQuarantined = true
608
- test.expectedStatus = 'skipped'
609
- })
606
+ if (isTestManagementTestsEnabled) {
607
+ for (const test of allTests) {
608
+ const testProperties = getTestProperties(test)
609
+ if (testProperties.disabled) {
610
+ test._ddIsDisabled = true
611
+ test.expectedStatus = 'skipped'
612
+ } else if (testProperties.quarantined) {
613
+ test._ddIsQuarantined = true
614
+ test.expectedStatus = 'skipped'
615
+ }
616
+ }
610
617
  }
611
618
 
612
619
  if (isKnownTestsEnabled) {
@@ -9,6 +9,7 @@ const testPassCh = channel('ci:vitest:test:pass')
9
9
  const testErrorCh = channel('ci:vitest:test:error')
10
10
  const testSkipCh = channel('ci:vitest:test:skip')
11
11
  const isNewTestCh = channel('ci:vitest:test:is-new')
12
+ const isDisabledCh = channel('ci:vitest:test:is-disabled')
12
13
  const isQuarantinedCh = channel('ci:vitest:test:is-quarantined')
13
14
 
14
15
  // test suite hooks
@@ -22,11 +23,12 @@ const testSessionFinishCh = channel('ci:vitest:session:finish')
22
23
  const libraryConfigurationCh = channel('ci:vitest:library-configuration')
23
24
  const knownTestsCh = channel('ci:vitest:known-tests')
24
25
  const isEarlyFlakeDetectionFaultyCh = channel('ci:vitest:is-early-flake-detection-faulty')
25
- const quarantinedTestsCh = channel('ci:vitest:quarantined-tests')
26
+ const testManagementTestsCh = channel('ci:vitest:test-management-tests')
26
27
 
27
28
  const taskToAsync = new WeakMap()
28
29
  const taskToStatuses = new WeakMap()
29
30
  const newTasks = new WeakSet()
31
+ const disabledTasks = new WeakSet()
30
32
  const quarantinedTasks = new WeakSet()
31
33
  let isRetryReasonEfd = false
32
34
  const switchedStatuses = new WeakSet()
@@ -50,8 +52,9 @@ function getProvidedContext () {
50
52
  _ddKnownTests: knownTests,
51
53
  _ddEarlyFlakeDetectionNumRetries: numRepeats,
52
54
  _ddIsKnownTestsEnabled: isKnownTestsEnabled,
53
- _ddIsQuarantinedTestsEnabled: isQuarantinedTestsEnabled,
54
- _ddQuarantinedTests: quarantinedTests
55
+ _ddIsTestManagementTestsEnabled: isTestManagementTestsEnabled,
56
+ _ddTestManagementTests: testManagementTests,
57
+ _ddIsFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled
55
58
  } = globalThis.__vitest_worker__.providedContext
56
59
 
57
60
  return {
@@ -60,8 +63,9 @@ function getProvidedContext () {
60
63
  knownTests,
61
64
  numRepeats,
62
65
  isKnownTestsEnabled,
63
- isQuarantinedTestsEnabled,
64
- quarantinedTests
66
+ isTestManagementTestsEnabled,
67
+ testManagementTests,
68
+ isFlakyTestRetriesEnabled
65
69
  }
66
70
  } catch (e) {
67
71
  log.error('Vitest workers could not parse provided context, so some features will not work.')
@@ -71,8 +75,8 @@ function getProvidedContext () {
71
75
  knownTests: {},
72
76
  numRepeats: 0,
73
77
  isKnownTestsEnabled: false,
74
- isQuarantinedTestsEnabled: false,
75
- quarantinedTests: {}
78
+ isTestManagementTestsEnabled: false,
79
+ testManagementTests: {}
76
80
  }
77
81
  }
78
82
  }
@@ -167,10 +171,10 @@ function getSortWrapper (sort) {
167
171
  let earlyFlakeDetectionNumRetries = 0
168
172
  let isEarlyFlakeDetectionFaulty = false
169
173
  let isKnownTestsEnabled = false
170
- let isQuarantinedTestsEnabled = false
174
+ let isTestManagementTestsEnabled = false
171
175
  let isDiEnabled = false
172
176
  let knownTests = {}
173
- let quarantinedTests = {}
177
+ let testManagementTests = {}
174
178
 
175
179
  try {
176
180
  const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh)
@@ -181,7 +185,7 @@ function getSortWrapper (sort) {
181
185
  earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
182
186
  isDiEnabled = libraryConfig.isDiEnabled
183
187
  isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
184
- isQuarantinedTestsEnabled = libraryConfig.isQuarantinedTestsEnabled
188
+ isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
185
189
  }
186
190
  } catch (e) {
187
191
  isFlakyTestRetriesEnabled = false
@@ -192,6 +196,12 @@ function getSortWrapper (sort) {
192
196
 
193
197
  if (isFlakyTestRetriesEnabled && !this.ctx.config.retry && flakyTestRetriesCount > 0) {
194
198
  this.ctx.config.retry = flakyTestRetriesCount
199
+ try {
200
+ const workspaceProject = this.ctx.getCoreWorkspaceProject()
201
+ workspaceProject._provided._ddIsFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
202
+ } catch (e) {
203
+ log.warn('Could not send library configuration to workers.')
204
+ }
195
205
  }
196
206
 
197
207
  if (isKnownTestsEnabled) {
@@ -241,20 +251,20 @@ function getSortWrapper (sort) {
241
251
  }
242
252
  }
243
253
 
244
- if (isQuarantinedTestsEnabled) {
245
- const { err, quarantinedTests: receivedQuarantinedTests } = await getChannelPromise(quarantinedTestsCh)
254
+ if (isTestManagementTestsEnabled) {
255
+ const { err, testManagementTests: receivedTestManagementTests } = await getChannelPromise(testManagementTestsCh)
246
256
  if (!err) {
247
- quarantinedTests = receivedQuarantinedTests
257
+ testManagementTests = receivedTestManagementTests
248
258
  try {
249
259
  const workspaceProject = this.ctx.getCoreWorkspaceProject()
250
- workspaceProject._provided._ddIsQuarantinedTestsEnabled = isQuarantinedTestsEnabled
251
- workspaceProject._provided._ddQuarantinedTests = quarantinedTests
260
+ workspaceProject._provided._ddIsTestManagementTestsEnabled = isTestManagementTestsEnabled
261
+ workspaceProject._provided._ddTestManagementTests = testManagementTests
252
262
  } catch (e) {
253
- log.warn('Could not send quarantined tests to workers so Quarantine will not work.')
263
+ log.warn('Could not send test management tests to workers so Test Management will not work.')
254
264
  }
255
265
  } else {
256
- isQuarantinedTestsEnabled = false
257
- log.error('Could not get quarantined tests.')
266
+ isTestManagementTestsEnabled = false
267
+ log.error('Could not get test management tests.')
258
268
  }
259
269
  }
260
270
 
@@ -292,7 +302,7 @@ function getSortWrapper (sort) {
292
302
  error,
293
303
  isEarlyFlakeDetectionEnabled,
294
304
  isEarlyFlakeDetectionFaulty,
295
- isQuarantinedTestsEnabled,
305
+ isTestManagementTestsEnabled,
296
306
  onFinish
297
307
  })
298
308
  })
@@ -337,9 +347,25 @@ addHook({
337
347
  knownTests,
338
348
  isEarlyFlakeDetectionEnabled,
339
349
  isKnownTestsEnabled,
340
- numRepeats
350
+ numRepeats,
351
+ isTestManagementTestsEnabled,
352
+ testManagementTests
341
353
  } = getProvidedContext()
342
354
 
355
+ if (isTestManagementTestsEnabled) {
356
+ isDisabledCh.publish({
357
+ testManagementTests,
358
+ testSuiteAbsolutePath: task.file.filepath,
359
+ testName,
360
+ onDone: (isTestDisabled) => {
361
+ if (isTestDisabled) {
362
+ disabledTasks.add(task)
363
+ task.mode = 'skip'
364
+ }
365
+ }
366
+ })
367
+ }
368
+
343
369
  if (isKnownTestsEnabled) {
344
370
  isNewTestCh.publish({
345
371
  knownTests,
@@ -364,7 +390,7 @@ addHook({
364
390
  // `onAfterRunTask` is run after all repetitions or attempts are run
365
391
  // `onAfterRunTask` is an async function
366
392
  shimmer.wrap(VitestTestRunner.prototype, 'onAfterRunTask', onAfterRunTask => function (task) {
367
- const { isEarlyFlakeDetectionEnabled, isQuarantinedTestsEnabled } = getProvidedContext()
393
+ const { isEarlyFlakeDetectionEnabled, isTestManagementTestsEnabled } = getProvidedContext()
368
394
 
369
395
  if (isEarlyFlakeDetectionEnabled && taskToStatuses.has(task)) {
370
396
  const statuses = taskToStatuses.get(task)
@@ -377,7 +403,7 @@ addHook({
377
403
  }
378
404
  }
379
405
 
380
- if (isQuarantinedTestsEnabled) {
406
+ if (isTestManagementTestsEnabled) {
381
407
  if (quarantinedTasks.has(task)) {
382
408
  task.result.state = 'pass'
383
409
  }
@@ -400,17 +426,17 @@ addHook({
400
426
  isKnownTestsEnabled,
401
427
  isEarlyFlakeDetectionEnabled,
402
428
  isDiEnabled,
403
- isQuarantinedTestsEnabled,
404
- quarantinedTests
429
+ isTestManagementTestsEnabled,
430
+ testManagementTests
405
431
  } = getProvidedContext()
406
432
 
407
433
  if (isKnownTestsEnabled) {
408
434
  isNew = newTasks.has(task)
409
435
  }
410
436
 
411
- if (isQuarantinedTestsEnabled) {
437
+ if (isTestManagementTestsEnabled) {
412
438
  isQuarantinedCh.publish({
413
- quarantinedTests,
439
+ testManagementTests,
414
440
  testSuiteAbsolutePath: task.file.filepath,
415
441
  testName,
416
442
  onDone: (isTestQuarantined) => {
@@ -624,9 +650,16 @@ addHook({
624
650
  // From >=3.0.1, the first arguments changes from a string to an object containing the filepath
625
651
  const testSuiteAbsolutePath = testPaths[0]?.filepath || testPaths[0]
626
652
 
653
+ const { isEarlyFlakeDetectionEnabled, isFlakyTestRetriesEnabled } = getProvidedContext()
654
+
627
655
  const testSuiteAsyncResource = new AsyncResource('bound-anonymous-fn')
628
656
  testSuiteAsyncResource.runInAsyncScope(() => {
629
- testSuiteStartCh.publish({ testSuiteAbsolutePath, frameworkVersion })
657
+ testSuiteStartCh.publish({
658
+ testSuiteAbsolutePath,
659
+ frameworkVersion,
660
+ isFlakyTestRetriesEnabled,
661
+ isEarlyFlakeDetectionEnabled
662
+ })
630
663
  })
631
664
  const startTestsResponse = await startTests.apply(this, arguments)
632
665
 
@@ -651,7 +684,8 @@ addHook({
651
684
  testSkipCh.publish({
652
685
  testName: getTestName(task),
653
686
  testSuiteAbsolutePath: task.file.filepath,
654
- isNew: newTasks.has(task)
687
+ isNew: newTasks.has(task),
688
+ isDisabled: disabledTasks.has(task)
655
689
  })
656
690
  } else if (state === 'pass' && !isSwitchedStatus) {
657
691
  if (testAsyncResource) {
@@ -681,7 +715,8 @@ addHook({
681
715
  testSkipCh.publish({
682
716
  testName: getTestName(task),
683
717
  testSuiteAbsolutePath: task.file.filepath,
684
- isNew: newTasks.has(task)
718
+ isNew: newTasks.has(task),
719
+ isDisabled: disabledTasks.has(task)
685
720
  })
686
721
  }
687
722
  })
@@ -29,7 +29,8 @@ const {
29
29
  CUCUMBER_IS_PARALLEL,
30
30
  TEST_RETRY_REASON,
31
31
  TEST_MANAGEMENT_ENABLED,
32
- TEST_MANAGEMENT_IS_QUARANTINED
32
+ TEST_MANAGEMENT_IS_QUARANTINED,
33
+ TEST_MANAGEMENT_IS_DISABLED
33
34
  } = require('../../dd-trace/src/plugins/util/test')
34
35
  const { RESOURCE_NAME } = require('../../../ext/tags')
35
36
  const { COMPONENT, ERROR_MESSAGE } = require('../../dd-trace/src/constants')
@@ -86,7 +87,7 @@ class CucumberPlugin extends CiPlugin {
86
87
  hasForcedToRunSuites,
87
88
  isEarlyFlakeDetectionEnabled,
88
89
  isEarlyFlakeDetectionFaulty,
89
- isQuarantinedTestsEnabled,
90
+ isTestManagementTestsEnabled,
90
91
  isParallel
91
92
  }) => {
92
93
  const { isSuitesSkippingEnabled, isCodeCoverageEnabled } = this.libraryConfig || {}
@@ -113,7 +114,7 @@ class CucumberPlugin extends CiPlugin {
113
114
  if (isParallel) {
114
115
  this.testSessionSpan.setTag(CUCUMBER_IS_PARALLEL, 'true')
115
116
  }
116
- if (isQuarantinedTestsEnabled) {
117
+ if (isTestManagementTestsEnabled) {
117
118
  this.testSessionSpan.setTag(TEST_MANAGEMENT_ENABLED, 'true')
118
119
  }
119
120
 
@@ -124,7 +125,10 @@ class CucumberPlugin extends CiPlugin {
124
125
  this.testSessionSpan.finish()
125
126
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
126
127
  finishAllTraceSpans(this.testSessionSpan)
127
- this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
128
+ this.telemetry.count(TELEMETRY_TEST_SESSION, {
129
+ provider: this.ciProviderName,
130
+ autoInjected: !!process.env.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER
131
+ })
128
132
 
129
133
  this.libraryConfig = null
130
134
  this.tracer._exporter.flush()
@@ -324,6 +328,7 @@ class CucumberPlugin extends CiPlugin {
324
328
  isNew,
325
329
  isEfdRetry,
326
330
  isFlakyRetry,
331
+ isDisabled,
327
332
  isQuarantined
328
333
  }) => {
329
334
  const span = storage('legacy').getStore().span
@@ -353,6 +358,10 @@ class CucumberPlugin extends CiPlugin {
353
358
  span.setTag(TEST_IS_RETRY, 'true')
354
359
  }
355
360
 
361
+ if (isDisabled) {
362
+ span.setTag(TEST_MANAGEMENT_IS_DISABLED, 'true')
363
+ }
364
+
356
365
  if (isQuarantined) {
357
366
  span.setTag(TEST_MANAGEMENT_IS_QUARANTINED, 'true')
358
367
  }
@@ -35,7 +35,11 @@ const {
35
35
  TEST_RETRY_REASON,
36
36
  DD_TEST_IS_USER_PROVIDED_SERVICE,
37
37
  TEST_MANAGEMENT_IS_QUARANTINED,
38
- TEST_MANAGEMENT_ENABLED
38
+ TEST_MANAGEMENT_ENABLED,
39
+ TEST_MANAGEMENT_IS_DISABLED,
40
+ DD_CAPABILITIES_EARLY_FLAKE_DETECTION,
41
+ DD_CAPABILITIES_AUTO_TEST_RETRIES,
42
+ DD_CAPABILITIES_TEST_IMPACT_ANALYSIS
39
43
  } = require('../../dd-trace/src/plugins/util/test')
40
44
  const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
41
45
  const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
@@ -154,15 +158,15 @@ function getKnownTests (tracer, testConfiguration) {
154
158
  })
155
159
  }
156
160
 
157
- function getQuarantinedTests (tracer, testConfiguration) {
161
+ function getTestManagementTests (tracer, testConfiguration) {
158
162
  return new Promise(resolve => {
159
- if (!tracer._tracer._exporter?.getQuarantinedTests) {
163
+ if (!tracer._tracer._exporter?.getTestManagementTests) {
160
164
  return resolve({ err: new Error('Test Optimization was not initialized correctly') })
161
165
  }
162
- tracer._tracer._exporter.getQuarantinedTests(testConfiguration, (err, quarantinedTests) => {
166
+ tracer._tracer._exporter.getTestManagementTests(testConfiguration, (err, testManagementTests) => {
163
167
  resolve({
164
168
  err,
165
- quarantinedTests
169
+ testManagementTests
166
170
  })
167
171
  })
168
172
  })
@@ -257,7 +261,7 @@ class CypressPlugin {
257
261
  isFlakyTestRetriesEnabled,
258
262
  flakyTestRetriesCount,
259
263
  isKnownTestsEnabled,
260
- isQuarantinedTestsEnabled
264
+ isTestManagementEnabled
261
265
  }
262
266
  } = libraryConfigurationResponse
263
267
  this.isSuitesSkippingEnabled = isSuitesSkippingEnabled
@@ -268,22 +272,18 @@ class CypressPlugin {
268
272
  if (isFlakyTestRetriesEnabled) {
269
273
  this.cypressConfig.retries.runMode = flakyTestRetriesCount
270
274
  }
271
- this.isQuarantinedTestsEnabled = isQuarantinedTestsEnabled
275
+ this.isTestManagementTestsEnabled = isTestManagementEnabled
272
276
  }
273
277
  return this.cypressConfig
274
278
  })
275
279
  return this.libraryConfigurationPromise
276
280
  }
277
281
 
278
- getIsQuarantinedTest (testSuite, testName) {
279
- return this.quarantinedTests
280
- ?.cypress
281
- ?.suites
282
- ?.[testSuite]
283
- ?.tests
284
- ?.[testName]
285
- ?.properties
286
- ?.quarantined
282
+ getTestProperties (testSuite, testName) {
283
+ const { disabled: isDisabled, quarantined: isQuarantined } =
284
+ this.testManagementTests?.cypress?.suites?.[testSuite]?.tests?.[testName]?.properties || {}
285
+
286
+ return { isDisabled, isQuarantined }
287
287
  }
288
288
 
289
289
  getTestSuiteSpan ({ testSuite, testSuiteAbsolutePath }) {
@@ -418,16 +418,16 @@ class CypressPlugin {
418
418
  }
419
419
  }
420
420
 
421
- if (this.isQuarantinedTestsEnabled) {
422
- const quarantinedTestsResponse = await getQuarantinedTests(
421
+ if (this.isTestManagementTestsEnabled) {
422
+ const testManagementTestsResponse = await getTestManagementTests(
423
423
  this.tracer,
424
424
  this.testConfiguration
425
425
  )
426
- if (quarantinedTestsResponse.err) {
427
- log.error('Cypress quarantined tests response error', quarantinedTestsResponse.err)
428
- this.isQuarantinedTestsEnabled = false
426
+ if (testManagementTestsResponse.err) {
427
+ log.error('Cypress test management tests response error', testManagementTestsResponse.err)
428
+ this.isTestManagementTestsEnabled = false
429
429
  } else {
430
- this.quarantinedTests = quarantinedTestsResponse.quarantinedTests
430
+ this.testManagementTests = testManagementTestsResponse.testManagementTests
431
431
  }
432
432
  }
433
433
 
@@ -452,14 +452,21 @@ class CypressPlugin {
452
452
 
453
453
  const testSessionName = getTestSessionName(this.tracer._tracer._config, this.command, this.testEnvironmentMetadata)
454
454
 
455
- if (this.tracer._tracer._exporter?.setMetadataTags) {
455
+ if (this.tracer._tracer._exporter?.addMetadataTags) {
456
456
  const metadataTags = {}
457
457
  for (const testLevel of TEST_LEVEL_EVENT_TYPES) {
458
458
  metadataTags[testLevel] = {
459
459
  [TEST_SESSION_NAME]: testSessionName
460
460
  }
461
461
  }
462
- this.tracer._tracer._exporter.setMetadataTags(metadataTags)
462
+ metadataTags.test = {
463
+ ...metadataTags.test,
464
+ [DD_CAPABILITIES_TEST_IMPACT_ANALYSIS]: this.isSuitesSkippingEnabled ? 'true' : 'false',
465
+ [DD_CAPABILITIES_EARLY_FLAKE_DETECTION]: this.isEarlyFlakeDetectionEnabled ? 'true' : 'false',
466
+ [DD_CAPABILITIES_AUTO_TEST_RETRIES]: this.isFlakyTestRetriesEnabled ? 'true' : 'false'
467
+ }
468
+
469
+ this.tracer._tracer._exporter.addMetadataTags(metadataTags)
463
470
  }
464
471
 
465
472
  this.testSessionSpan = this.tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_session`, {
@@ -509,7 +516,7 @@ class CypressPlugin {
509
516
  }
510
517
  )
511
518
 
512
- if (this.isQuarantinedTestsEnabled) {
519
+ if (this.isTestManagementTestsEnabled) {
513
520
  this.testSessionSpan.setTag(TEST_MANAGEMENT_ENABLED, 'true')
514
521
  }
515
522
 
@@ -518,7 +525,8 @@ class CypressPlugin {
518
525
  this.testSessionSpan.finish()
519
526
  this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
520
527
  incrementCountMetric(TELEMETRY_TEST_SESSION, {
521
- provider: this.ciProviderName
528
+ provider: this.ciProviderName,
529
+ autoInjected: !!process.env.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER
522
530
  })
523
531
 
524
532
  finishAllTraceSpans(this.testSessionSpan)
@@ -588,9 +596,11 @@ class CypressPlugin {
588
596
  skippedTestSpan.setTag(ITR_CORRELATION_ID, this.itrCorrelationId)
589
597
  }
590
598
 
591
- const isQuarantined = this.getIsQuarantinedTest(spec.relative, cypressTestName)
599
+ const { isDisabled, isQuarantined } = this.getTestProperties(spec.relative, cypressTestName)
592
600
 
593
- if (isQuarantined) {
601
+ if (isDisabled) {
602
+ skippedTestSpan.setTag(TEST_MANAGEMENT_IS_DISABLED, 'true')
603
+ } else if (isQuarantined) {
594
604
  skippedTestSpan.setTag(TEST_MANAGEMENT_IS_QUARANTINED, 'true')
595
605
  }
596
606
 
@@ -697,7 +707,7 @@ class CypressPlugin {
697
707
  })
698
708
  const isUnskippable = this.unskippableSuites.includes(testSuite)
699
709
  const isForcedToRun = shouldSkip && isUnskippable
700
- const isQuarantined = this.getIsQuarantinedTest(testSuite, testName)
710
+ const { isDisabled, isQuarantined } = this.getTestProperties(testSuite, testName)
701
711
 
702
712
  // skip test
703
713
  if (shouldSkip && !isUnskippable) {
@@ -708,7 +718,7 @@ class CypressPlugin {
708
718
 
709
719
  // TODO: I haven't found a way to trick cypress into ignoring a test
710
720
  // The way we'll implement quarantine in cypress is by skipping the test altogether
711
- if (isQuarantined) {
721
+ if (isDisabled || isQuarantined) {
712
722
  return { shouldSkip: true }
713
723
  }
714
724
 
@@ -737,8 +747,7 @@ class CypressPlugin {
737
747
  testSuiteAbsolutePath,
738
748
  testName,
739
749
  isNew,
740
- isEfdRetry,
741
- isQuarantined
750
+ isEfdRetry
742
751
  } = test
743
752
  if (coverage && this.isCodeCoverageEnabled && this.tracer._tracer._exporter?.exportCoverage) {
744
753
  const coverageFiles = getCoveredFilenamesFromCoverage(coverage)
@@ -777,9 +786,6 @@ class CypressPlugin {
777
786
  this.activeTestSpan.setTag(TEST_RETRY_REASON, 'efd')
778
787
  }
779
788
  }
780
- if (isQuarantined) {
781
- this.activeTestSpan.setTag(TEST_MANAGEMENT_IS_QUARANTINED, 'true')
782
- }
783
789
  const finishedTest = {
784
790
  testName,
785
791
  testStatus,
@@ -1,5 +1,6 @@
1
1
  const NoopTracer = require('../../dd-trace/src/noop/tracer')
2
2
  const cypressPlugin = require('./cypress-plugin')
3
+ const satisfies = require('semifies')
3
4
 
4
5
  const noopTask = {
5
6
  'dd:testSuiteStart': () => {
@@ -19,6 +20,15 @@ const noopTask = {
19
20
  module.exports = (on, config) => {
20
21
  const tracer = require('../../dd-trace')
21
22
 
23
+ if (satisfies(config.version, '<10.2.0')) {
24
+ // console.warn does not seem to work in cypress, so using console.log instead
25
+ // eslint-disable-next-line no-console
26
+ console.log(
27
+ 'WARNING: dd-trace support for Cypress<10.2.0 is deprecated' +
28
+ ' and will not be supported in future versions of dd-trace.'
29
+ )
30
+ }
31
+
22
32
  // The tracer was not init correctly for whatever reason (such as invalid DD_SITE)
23
33
  if (tracer._tracer instanceof NoopTracer) {
24
34
  // We still need to register these tasks or the support file will fail