dd-trace 5.32.0 → 5.33.1

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 (43) hide show
  1. package/README.md +12 -11
  2. package/index.d.ts +11 -1
  3. package/package.json +2 -2
  4. package/packages/datadog-instrumentations/src/aws-sdk.js +3 -1
  5. package/packages/datadog-instrumentations/src/cucumber.js +17 -9
  6. package/packages/datadog-instrumentations/src/jest.js +36 -21
  7. package/packages/datadog-instrumentations/src/mocha/main.js +9 -4
  8. package/packages/datadog-instrumentations/src/mocha/utils.js +4 -2
  9. package/packages/datadog-instrumentations/src/mocha/worker.js +4 -2
  10. package/packages/datadog-instrumentations/src/playwright.js +8 -3
  11. package/packages/datadog-instrumentations/src/vitest.js +35 -11
  12. package/packages/datadog-plugin-amqplib/src/producer.js +9 -1
  13. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +16 -0
  14. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +63 -0
  15. package/packages/datadog-plugin-aws-sdk/src/services/{bedrockruntime.js → bedrockruntime/utils.js} +67 -75
  16. package/packages/datadog-plugin-cucumber/src/index.js +3 -1
  17. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +19 -8
  18. package/packages/datadog-plugin-cypress/src/support.js +6 -2
  19. package/packages/datadog-plugin-fetch/src/index.js +3 -3
  20. package/packages/datadog-plugin-http/src/client.js +5 -33
  21. package/packages/datadog-plugin-jest/src/index.js +4 -1
  22. package/packages/datadog-plugin-langchain/src/handlers/default.js +6 -30
  23. package/packages/datadog-plugin-langchain/src/tracing.js +5 -6
  24. package/packages/datadog-plugin-mocha/src/index.js +3 -1
  25. package/packages/datadog-plugin-openai/src/tracing.js +14 -33
  26. package/packages/datadog-plugin-playwright/src/index.js +3 -1
  27. package/packages/datadog-plugin-vitest/src/index.js +16 -4
  28. package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +3 -3
  29. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +41 -24
  30. package/packages/dd-trace/src/appsec/iast/iast-context.js +12 -0
  31. package/packages/dd-trace/src/appsec/iast/path-line.js +19 -23
  32. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -0
  33. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +75 -24
  34. package/packages/dd-trace/src/appsec/rasp/utils.js +10 -5
  35. package/packages/dd-trace/src/appsec/stack_trace.js +38 -28
  36. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +5 -4
  37. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +5 -3
  38. package/packages/dd-trace/src/config.js +6 -2
  39. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +59 -0
  40. package/packages/dd-trace/src/plugins/ci_plugin.js +1 -0
  41. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +0 -2
  42. package/packages/dd-trace/src/plugins/util/llm.js +35 -0
  43. package/packages/dd-trace/src/plugins/util/test.js +2 -0
package/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # `dd-trace`: Node.js APM Tracer Library
2
2
 
3
3
  [![npm v5](https://img.shields.io/npm/v/dd-trace/latest?color=blue&label=dd-trace%40v5&logo=npm)](https://www.npmjs.com/package/dd-trace)
4
- [![npm v4](https://img.shields.io/npm/v/dd-trace/latest-node16?color=blue&label=dd-trace%40v4&logo=npm)](https://www.npmjs.com/package/dd-trace/v/latest-node16)
5
4
  [![codecov](https://codecov.io/gh/DataDog/dd-trace-js/branch/master/graph/badge.svg)](https://codecov.io/gh/DataDog/dd-trace-js)
6
5
 
7
6
  <img align="right" src="https://user-images.githubusercontent.com/551402/208212084-1d0c07e2-4135-4c61-b2da-8f2fddbc66ed.png" alt="Bits the dog JavaScript" width="200px"/>
@@ -25,16 +24,16 @@ Most of the documentation for `dd-trace` is available on these webpages:
25
24
 
26
25
  | Release Line | Latest Version | Node.js | [SSI](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/single-step-apm/?tab=linuxhostorvm) | [K8s Injection](https://docs.datadoghq.com/tracing/trace_collection/library_injection_local/?tab=kubernetes) |Status |Initial Release | End of Life |
27
26
  | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
28
- | [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) | ![npm v1](https://img.shields.io/npm/v/dd-trace/legacy-v1?color=white&label=%20&style=flat-square) | `>= v12` | NO | NO | **End of Life** | 2021-07-13 | 2022-02-25 |
29
- | [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) | ![npm v2](https://img.shields.io/npm/v/dd-trace/latest-node12?color=white&label=%20&style=flat-square) | `>= v12` | NO | NO | **End of Life** | 2022-01-28 | 2023-08-15 |
30
- | [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) | ![npm v3](https://img.shields.io/npm/v/dd-trace/latest-node14?color=white&label=%20&style=flat-square) | `>= v14` | NO | YES | **End of Life** | 2022-08-15 | 2024-05-15 |
31
- | [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) | ![npm v4](https://img.shields.io/npm/v/dd-trace/latest-node16?color=white&label=%20&style=flat-square) | `>= v16` | YES | YES | **Maintenance** | 2023-05-12 | 2025-01-11 |
27
+ | [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) | ![npm v1](https://img.shields.io/npm/v/dd-trace/legacy-v1?color=white&label=%20&style=flat-square) | `>= v12` | NO | NO | **EOL** | 2021-07-13 | 2022-02-25 |
28
+ | [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) | ![npm v2](https://img.shields.io/npm/v/dd-trace/latest-node12?color=white&label=%20&style=flat-square) | `>= v12` | NO | NO | **EOL** | 2022-01-28 | 2023-08-15 |
29
+ | [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) | ![npm v3](https://img.shields.io/npm/v/dd-trace/latest-node14?color=white&label=%20&style=flat-square) | `>= v14` | NO | YES | **EOL** | 2022-08-15 | 2024-05-15 |
30
+ | [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) | ![npm v4](https://img.shields.io/npm/v/dd-trace/latest-node16?color=white&label=%20&style=flat-square) | `>= v16` | YES | YES | **EOL** | 2023-05-12 | 2025-01-11 |
32
31
  | [`v5`](https://github.com/DataDog/dd-trace-js/tree/v5.x) | ![npm v5](https://img.shields.io/npm/v/dd-trace/latest?color=white&label=%20&style=flat-square) | `>= v18` | YES | YES | **Current** | 2024-01-11 | Unknown |
33
32
 
33
+ * EOL = End-of-life
34
34
  * SSI = Single-Step Install
35
35
 
36
- We currently maintain two release lines, namely `v5`, and `v4`.
37
- Features and bug fixes that are merged are released to the `v5` line and, if appropriate, also `v4`.
36
+ We currently maintain one release line, namely `v5`.
38
37
 
39
38
  For any new projects it is recommended to use the `v5` release line:
40
39
 
@@ -43,20 +42,22 @@ $ npm install dd-trace
43
42
  $ yarn add dd-trace
44
43
  ```
45
44
 
46
- However, existing projects that already use the `v4` release line, or projects that need to support EOL versions of Node.js, may continue to use these release lines.
45
+ Existing projects that need to use EOL versions of Node.js may continue to use these older release lines.
47
46
  This is done by specifying the version when installing the package.
48
47
 
49
48
  ```sh
50
- $ npm install dd-trace@4
51
- $ yarn add dd-trace@4
49
+ $ npm install dd-trace@4 # or whatever version you need
50
+ $ yarn add dd-trace@4 # or whatever version you need
52
51
  ```
53
52
 
53
+ Note, however, that the end-of-life release lines are no longer maintained and will not receive updates.
54
+
54
55
  Any backwards-breaking functionality that is introduced into the library will result in an increase of the major version of the library and therefore a new release line.
55
56
  Such releases are kept to a minimum to reduce the pain of upgrading the library.
56
57
 
57
58
  When a new release line is introduced the previous release line then enters maintenance mode where it will receive updates for the next year.
58
59
  Once that year is up the release line enters End of Life and will not receive new updates.
59
- The library also follows the Node.js LTS lifecycle wherein new release lines drop compatibility with Node.js versions that reach end of life (with the maintenance release line still receiving updates for a year).
60
+ The library also follows the Node.js LTS lifecycle wherein new release lines drop compatibility with Node.js versions that reach end-of-life (with the maintenance release line still receiving updates for a year).
60
61
 
61
62
  For more information about library versioning and compatibility, see the [NodeJS Compatibility Requirements](https://docs.datadoghq.com/tracing/trace_collection/compatibility/nodejs/#releases) page.
62
63
 
package/index.d.ts CHANGED
@@ -2233,7 +2233,17 @@ declare namespace tracer {
2233
2233
  /**
2234
2234
  * Specifies the verbosity of the sent telemetry. Default 'INFORMATION'
2235
2235
  */
2236
- telemetryVerbosity?: string
2236
+ telemetryVerbosity?: string,
2237
+
2238
+ /**
2239
+ * Configuration for stack trace reporting
2240
+ */
2241
+ stackTrace?: {
2242
+ /** Whether to enable stack trace reporting.
2243
+ * @default true
2244
+ */
2245
+ enabled?: boolean,
2246
+ }
2237
2247
  }
2238
2248
 
2239
2249
  export namespace llmobs {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "5.32.0",
3
+ "version": "5.33.1",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -86,7 +86,7 @@
86
86
  "@datadog/native-iast-rewriter": "2.6.1",
87
87
  "@datadog/native-iast-taint-tracking": "3.2.0",
88
88
  "@datadog/native-metrics": "^3.1.0",
89
- "@datadog/pprof": "5.4.1",
89
+ "@datadog/pprof": "5.5.1",
90
90
  "@datadog/sketches-js": "^2.1.0",
91
91
  "@isaacs/ttlcache": "^1.4.1",
92
92
  "@opentelemetry/api": ">=1.0.0 <1.9.0",
@@ -155,6 +155,8 @@ function getMessage (request, error, result) {
155
155
  }
156
156
 
157
157
  function getChannelSuffix (name) {
158
+ // some resource identifiers have spaces between ex: bedrock runtime
159
+ name = name.replaceAll(' ', '')
158
160
  return [
159
161
  'cloudwatchlogs',
160
162
  'dynamodb',
@@ -168,7 +170,7 @@ function getChannelSuffix (name) {
168
170
  'sqs',
169
171
  'states',
170
172
  'stepfunctions',
171
- 'bedrock runtime'
173
+ 'bedrockruntime'
172
174
  ].includes(name)
173
175
  ? name
174
176
  : 'default'
@@ -70,6 +70,7 @@ let earlyFlakeDetectionNumRetries = 0
70
70
  let earlyFlakeDetectionFaultyThreshold = 0
71
71
  let isEarlyFlakeDetectionFaulty = false
72
72
  let isFlakyTestRetriesEnabled = false
73
+ let isKnownTestsEnabled = false
73
74
  let numTestRetries = 0
74
75
  let knownTests = []
75
76
  let skippedSuites = []
@@ -292,7 +293,7 @@ function wrapRun (pl, isLatestVersion) {
292
293
  }
293
294
  let isNew = false
294
295
  let isEfdRetry = false
295
- if (isEarlyFlakeDetectionEnabled && status !== 'skip') {
296
+ if (isKnownTestsEnabled && status !== 'skip') {
296
297
  const numRetries = numRetriesByPickleId.get(this.pickle.id)
297
298
 
298
299
  isNew = numRetries !== undefined
@@ -394,13 +395,15 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
394
395
  isSuitesSkippingEnabled = configurationResponse.libraryConfig?.isSuitesSkippingEnabled
395
396
  isFlakyTestRetriesEnabled = configurationResponse.libraryConfig?.isFlakyTestRetriesEnabled
396
397
  numTestRetries = configurationResponse.libraryConfig?.flakyTestRetriesCount
398
+ isKnownTestsEnabled = configurationResponse.libraryConfig?.isKnownTestsEnabled
397
399
 
398
- if (isEarlyFlakeDetectionEnabled) {
400
+ if (isKnownTestsEnabled) {
399
401
  const knownTestsResponse = await getChannelPromise(knownTestsCh)
400
402
  if (!knownTestsResponse.err) {
401
403
  knownTests = knownTestsResponse.knownTests
402
404
  } else {
403
405
  isEarlyFlakeDetectionEnabled = false
406
+ isKnownTestsEnabled = false
404
407
  }
405
408
  }
406
409
 
@@ -437,7 +440,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
437
440
 
438
441
  pickleByFile = isCoordinator ? getPickleByFileNew(this) : getPickleByFile(this)
439
442
 
440
- if (isEarlyFlakeDetectionEnabled) {
443
+ if (isKnownTestsEnabled) {
441
444
  const isFaulty = getIsFaultyEarlyFlakeDetection(
442
445
  Object.keys(pickleByFile),
443
446
  knownTests.cucumber || {},
@@ -445,6 +448,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
445
448
  )
446
449
  if (isFaulty) {
447
450
  isEarlyFlakeDetectionEnabled = false
451
+ isKnownTestsEnabled = false
448
452
  isEarlyFlakeDetectionFaulty = true
449
453
  }
450
454
  }
@@ -533,7 +537,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
533
537
 
534
538
  let isNew = false
535
539
 
536
- if (isEarlyFlakeDetectionEnabled) {
540
+ if (isKnownTestsEnabled) {
537
541
  isNew = isNewTest(testSuitePath, pickle.name)
538
542
  if (isNew) {
539
543
  numRetriesByPickleId.set(pickle.id, 0)
@@ -678,14 +682,14 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
678
682
  const { status } = getStatusFromResultLatest(worstTestStepResult)
679
683
  let isNew = false
680
684
 
681
- if (isEarlyFlakeDetectionEnabled) {
685
+ if (isKnownTestsEnabled) {
682
686
  isNew = isNewTest(pickle.uri, pickle.name)
683
687
  }
684
688
 
685
689
  const testFileAbsolutePath = pickle.uri
686
690
  const finished = pickleResultByFile[testFileAbsolutePath]
687
691
 
688
- if (isNew) {
692
+ if (isEarlyFlakeDetectionEnabled && isNew) {
689
693
  const testFullname = `${pickle.uri}:${pickle.name}`
690
694
  let testStatuses = newTestsByTestFullname.get(testFullname)
691
695
  if (!testStatuses) {
@@ -839,7 +843,8 @@ addHook({
839
843
  )
840
844
  // EFD in parallel mode only supported in >=11.0.0
841
845
  shimmer.wrap(adapterPackage.ChildProcessAdapter.prototype, 'startWorker', startWorker => function () {
842
- if (isEarlyFlakeDetectionEnabled) {
846
+ if (isKnownTestsEnabled) {
847
+ this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
843
848
  this.options.worldParameters._ddKnownTests = knownTests
844
849
  this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
845
850
  }
@@ -862,9 +867,12 @@ addHook({
862
867
  'initialize',
863
868
  initialize => async function () {
864
869
  await initialize.apply(this, arguments)
865
- isEarlyFlakeDetectionEnabled = !!this.options.worldParameters._ddKnownTests
866
- if (isEarlyFlakeDetectionEnabled) {
870
+ isKnownTestsEnabled = !!this.options.worldParameters._ddKnownTests
871
+ if (isKnownTestsEnabled) {
867
872
  knownTests = this.options.worldParameters._ddKnownTests
873
+ }
874
+ isEarlyFlakeDetectionEnabled = !!this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled
875
+ if (isEarlyFlakeDetectionEnabled) {
868
876
  earlyFlakeDetectionNumRetries = this.options.worldParameters._ddEarlyFlakeDetectionNumRetries
869
877
  }
870
878
  }
@@ -69,6 +69,7 @@ let earlyFlakeDetectionNumRetries = 0
69
69
  let earlyFlakeDetectionFaultyThreshold = 30
70
70
  let isEarlyFlakeDetectionFaulty = false
71
71
  let hasFilteredSkippableSuites = false
72
+ let isKnownTestsEnabled = false
72
73
 
73
74
  const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
74
75
 
@@ -138,17 +139,19 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
138
139
  this.isFlakyTestRetriesEnabled = this.testEnvironmentOptions._ddIsFlakyTestRetriesEnabled
139
140
  this.flakyTestRetriesCount = this.testEnvironmentOptions._ddFlakyTestRetriesCount
140
141
  this.isDiEnabled = this.testEnvironmentOptions._ddIsDiEnabled
142
+ this.isKnownTestsEnabled = this.testEnvironmentOptions._ddIsKnownTestsEnabled
141
143
 
142
- if (this.isEarlyFlakeDetectionEnabled) {
143
- const hasKnownTests = !!knownTests.jest
144
- earlyFlakeDetectionNumRetries = this.testEnvironmentOptions._ddEarlyFlakeDetectionNumRetries
144
+ if (this.isKnownTestsEnabled) {
145
145
  try {
146
+ const hasKnownTests = !!knownTests.jest
147
+ earlyFlakeDetectionNumRetries = this.testEnvironmentOptions._ddEarlyFlakeDetectionNumRetries
146
148
  this.knownTestsForThisSuite = hasKnownTests
147
149
  ? (knownTests.jest[this.testSuite] || [])
148
150
  : this.getKnownTestsForSuite(this.testEnvironmentOptions._ddKnownTests)
149
151
  } catch (e) {
150
152
  // If there has been an error parsing the tests, we'll disable Early Flake Deteciton
151
153
  this.isEarlyFlakeDetectionEnabled = false
154
+ this.isKnownTestsEnabled = false
152
155
  }
153
156
  }
154
157
 
@@ -228,7 +231,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
228
231
  asyncResources.set(event.test, asyncResource)
229
232
  const testName = getJestTestName(event.test)
230
233
 
231
- if (this.isEarlyFlakeDetectionEnabled) {
234
+ if (this.isKnownTestsEnabled) {
232
235
  const originalTestName = removeEfdStringFromTestName(testName)
233
236
  isNewTest = retriedTestsToNumAttempts.has(originalTestName)
234
237
  if (isNewTest) {
@@ -254,24 +257,26 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
254
257
  })
255
258
  }
256
259
  if (event.name === 'add_test') {
257
- if (this.isEarlyFlakeDetectionEnabled) {
260
+ if (this.isKnownTestsEnabled) {
258
261
  const testName = this.getTestNameFromAddTestEvent(event, state)
259
262
  const isNew = !this.knownTestsForThisSuite?.includes(testName)
260
263
  const isSkipped = event.mode === 'todo' || event.mode === 'skip'
261
264
  if (isNew && !isSkipped && !retriedTestsToNumAttempts.has(testName)) {
262
265
  retriedTestsToNumAttempts.set(testName, 0)
263
- // Retrying snapshots has proven to be problematic, so we'll skip them for now
264
- // We'll still detect new tests, but we won't retry them.
265
- // TODO: do not bail out of EFD with the whole test suite
266
- if (this.getHasSnapshotTests()) {
267
- log.warn('Early flake detection is disabled for suites with snapshots')
268
- return
269
- }
270
- for (let retryIndex = 0; retryIndex < earlyFlakeDetectionNumRetries; retryIndex++) {
271
- if (this.global.test) {
272
- this.global.test(addEfdStringToTestName(event.testName, retryIndex), event.fn, event.timeout)
273
- } else {
274
- log.error('Early flake detection could not retry test because global.test is undefined')
266
+ if (this.isEarlyFlakeDetectionEnabled) {
267
+ // Retrying snapshots has proven to be problematic, so we'll skip them for now
268
+ // We'll still detect new tests, but we won't retry them.
269
+ // TODO: do not bail out of EFD with the whole test suite
270
+ if (this.getHasSnapshotTests()) {
271
+ log.warn('Early flake detection is disabled for suites with snapshots')
272
+ return
273
+ }
274
+ for (let retryIndex = 0; retryIndex < earlyFlakeDetectionNumRetries; retryIndex++) {
275
+ if (this.global.test) {
276
+ this.global.test(addEfdStringToTestName(event.testName, retryIndex), event.fn, event.timeout)
277
+ } else {
278
+ log.error('Early flake detection could not retry test because global.test is undefined')
279
+ }
275
280
  }
276
281
  }
277
282
  }
@@ -286,7 +291,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
286
291
  event.test.fn = originalTestFns.get(event.test)
287
292
 
288
293
  // We'll store the test statuses of the retries
289
- if (this.isEarlyFlakeDetectionEnabled) {
294
+ if (this.isKnownTestsEnabled) {
290
295
  const testName = getJestTestName(event.test)
291
296
  const originalTestName = removeEfdStringFromTestName(testName)
292
297
  const isNewTest = retriedTestsToNumAttempts.has(originalTestName)
@@ -483,12 +488,13 @@ function cliWrapper (cli, jestVersion) {
483
488
  isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
484
489
  earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
485
490
  earlyFlakeDetectionFaultyThreshold = libraryConfig.earlyFlakeDetectionFaultyThreshold
491
+ isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
486
492
  }
487
493
  } catch (err) {
488
494
  log.error('Jest library configuration error', err)
489
495
  }
490
496
 
491
- if (isEarlyFlakeDetectionEnabled) {
497
+ if (isKnownTestsEnabled) {
492
498
  const knownTestsPromise = new Promise((resolve) => {
493
499
  onDone = resolve
494
500
  })
@@ -504,6 +510,7 @@ function cliWrapper (cli, jestVersion) {
504
510
  } else {
505
511
  // We disable EFD if there has been an error in the known tests request
506
512
  isEarlyFlakeDetectionEnabled = false
513
+ isKnownTestsEnabled = false
507
514
  }
508
515
  } catch (err) {
509
516
  log.error('Jest known tests error', err)
@@ -821,6 +828,7 @@ addHook({
821
828
  _ddIsFlakyTestRetriesEnabled,
822
829
  _ddFlakyTestRetriesCount,
823
830
  _ddIsDiEnabled,
831
+ _ddIsKnownTestsEnabled,
824
832
  ...restOfTestEnvironmentOptions
825
833
  } = testEnvironmentOptions
826
834
 
@@ -848,17 +856,19 @@ addHook({
848
856
  const testPaths = await getTestPaths.apply(this, arguments)
849
857
  const [{ rootDir, shard }] = arguments
850
858
 
851
- if (isEarlyFlakeDetectionEnabled) {
859
+ if (isKnownTestsEnabled) {
852
860
  const projectSuites = testPaths.tests.map(test => getTestSuitePath(test.path, test.context.config.rootDir))
853
861
  const isFaulty =
854
862
  getIsFaultyEarlyFlakeDetection(projectSuites, knownTests.jest || {}, earlyFlakeDetectionFaultyThreshold)
855
863
  if (isFaulty) {
856
864
  log.error('Early flake detection is disabled because the number of new suites is too high.')
857
865
  isEarlyFlakeDetectionEnabled = false
866
+ isKnownTestsEnabled = false
858
867
  const testEnvironmentOptions = testPaths.tests[0]?.context?.config?.testEnvironmentOptions
859
868
  // Project config is shared among all tests, so we can modify it here
860
869
  if (testEnvironmentOptions) {
861
870
  testEnvironmentOptions._ddIsEarlyFlakeDetectionEnabled = false
871
+ testEnvironmentOptions._ddIsKnownTestsEnabled = false
862
872
  }
863
873
  isEarlyFlakeDetectionFaulty = true
864
874
  }
@@ -929,6 +939,11 @@ addHook({
929
939
  return runtimePackage
930
940
  })
931
941
 
942
+ /*
943
+ * This hook does two things:
944
+ * - Pass known tests to the workers.
945
+ * - Receive trace, coverage and logs payloads from the workers.
946
+ */
932
947
  addHook({
933
948
  name: 'jest-worker',
934
949
  versions: ['>=24.9.0'],
@@ -936,7 +951,7 @@ addHook({
936
951
  }, (childProcessWorker) => {
937
952
  const ChildProcessWorker = childProcessWorker.default
938
953
  shimmer.wrap(ChildProcessWorker.prototype, 'send', send => function (request) {
939
- if (!isEarlyFlakeDetectionEnabled) {
954
+ if (!isKnownTestsEnabled) {
940
955
  return send.apply(this, arguments)
941
956
  }
942
957
  const [type] = request
@@ -201,6 +201,7 @@ function getExecutionConfiguration (runner, isParallel, onFinishRequest) {
201
201
  if (err) {
202
202
  config.knownTests = []
203
203
  config.isEarlyFlakeDetectionEnabled = false
204
+ config.isKnownTestsEnabled = false
204
205
  } else {
205
206
  config.knownTests = knownTests
206
207
  }
@@ -222,12 +223,13 @@ function getExecutionConfiguration (runner, isParallel, onFinishRequest) {
222
223
  config.isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
223
224
  config.earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
224
225
  config.earlyFlakeDetectionFaultyThreshold = libraryConfig.earlyFlakeDetectionFaultyThreshold
226
+ config.isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
225
227
  // ITR and auto test retries are not supported in parallel mode yet
226
228
  config.isSuitesSkippingEnabled = !isParallel && libraryConfig.isSuitesSkippingEnabled
227
229
  config.isFlakyTestRetriesEnabled = !isParallel && libraryConfig.isFlakyTestRetriesEnabled
228
230
  config.flakyTestRetriesCount = !isParallel && libraryConfig.flakyTestRetriesCount
229
231
 
230
- if (config.isEarlyFlakeDetectionEnabled) {
232
+ if (config.isKnownTestsEnabled) {
231
233
  knownTestsCh.publish({
232
234
  onDone: mochaRunAsyncResource.bind(onReceivedKnownTests)
233
235
  })
@@ -273,7 +275,7 @@ addHook({
273
275
  })
274
276
 
275
277
  getExecutionConfiguration(runner, false, () => {
276
- if (config.isEarlyFlakeDetectionEnabled) {
278
+ if (config.isKnownTestsEnabled) {
277
279
  const testSuites = this.files.map(file => getTestSuitePath(file, process.cwd()))
278
280
  const isFaulty = getIsFaultyEarlyFlakeDetection(
279
281
  testSuites,
@@ -283,6 +285,7 @@ addHook({
283
285
  if (isFaulty) {
284
286
  config.isEarlyFlakeDetectionEnabled = false
285
287
  config.isEarlyFlakeDetectionFaulty = true
288
+ config.isKnownTestsEnabled = false
286
289
  }
287
290
  }
288
291
  if (getCodeCoverageCh.hasSubscribers) {
@@ -537,7 +540,7 @@ addHook({
537
540
  this.once('end', getOnEndHandler(true))
538
541
 
539
542
  getExecutionConfiguration(this, true, () => {
540
- if (config.isEarlyFlakeDetectionEnabled) {
543
+ if (config.isKnownTestsEnabled) {
541
544
  const testSuites = files.map(file => getTestSuitePath(file, process.cwd()))
542
545
  const isFaulty = getIsFaultyEarlyFlakeDetection(
543
546
  testSuites,
@@ -545,6 +548,7 @@ addHook({
545
548
  config.earlyFlakeDetectionFaultyThreshold
546
549
  )
547
550
  if (isFaulty) {
551
+ config.isKnownTestsEnabled = false
548
552
  config.isEarlyFlakeDetectionEnabled = false
549
553
  config.isEarlyFlakeDetectionFaulty = true
550
554
  }
@@ -569,7 +573,7 @@ addHook({
569
573
  const { BufferedWorkerPool } = BufferedWorkerPoolPackage
570
574
 
571
575
  shimmer.wrap(BufferedWorkerPool.prototype, 'run', run => async function (testSuiteAbsolutePath, workerArgs) {
572
- if (!testStartCh.hasSubscribers || !config.isEarlyFlakeDetectionEnabled) {
576
+ if (!testStartCh.hasSubscribers || !config.isKnownTestsEnabled) {
573
577
  return run.apply(this, arguments)
574
578
  }
575
579
 
@@ -584,6 +588,7 @@ addHook({
584
588
  {
585
589
  ...workerArgs,
586
590
  _ddEfdNumRetries: config.earlyFlakeDetectionNumRetries,
591
+ _ddIsEfdEnabled: config.isEarlyFlakeDetectionEnabled,
587
592
  _ddKnownTests: {
588
593
  mocha: {
589
594
  [testPath]: testSuiteKnownTests
@@ -349,12 +349,14 @@ function getOnPendingHandler () {
349
349
  // Hook to add retries to tests if EFD is enabled
350
350
  function getRunTestsWrapper (runTests, config) {
351
351
  return function (suite, fn) {
352
- if (config.isEarlyFlakeDetectionEnabled) {
352
+ if (config.isKnownTestsEnabled) {
353
353
  // by the time we reach `this.on('test')`, it is too late. We need to add retries here
354
354
  suite.tests.forEach(test => {
355
355
  if (!test.isPending() && isNewTest(test, config.knownTests)) {
356
356
  test._ddIsNew = true
357
- retryTest(test, config.earlyFlakeDetectionNumRetries)
357
+ if (config.isEarlyFlakeDetectionEnabled) {
358
+ retryTest(test, config.earlyFlakeDetectionNumRetries)
359
+ }
358
360
  }
359
361
  })
360
362
  }
@@ -25,10 +25,12 @@ addHook({
25
25
  }, (Mocha) => {
26
26
  shimmer.wrap(Mocha.prototype, 'run', run => function () {
27
27
  if (this.options._ddKnownTests) {
28
- // EFD is enabled if there's a list of known tests
29
- config.isEarlyFlakeDetectionEnabled = true
28
+ // If there are known tests, it means isKnownTestsEnabled should be true
29
+ config.isKnownTestsEnabled = true
30
+ config.isEarlyFlakeDetectionEnabled = this.options._ddIsEfdEnabled
30
31
  config.knownTests = this.options._ddKnownTests
31
32
  config.earlyFlakeDetectionNumRetries = this.options._ddEfdNumRetries
33
+ delete this.options._ddIsEfdEnabled
32
34
  delete this.options._ddKnownTests
33
35
  delete this.options._ddEfdNumRetries
34
36
  }
@@ -35,6 +35,7 @@ const STATUS_TO_TEST_STATUS = {
35
35
  }
36
36
 
37
37
  let remainingTestsByFile = {}
38
+ let isKnownTestsEnabled = false
38
39
  let isEarlyFlakeDetectionEnabled = false
39
40
  let earlyFlakeDetectionNumRetries = 0
40
41
  let isFlakyTestRetriesEnabled = false
@@ -418,6 +419,7 @@ function runnerHook (runnerExport, playwrightVersion) {
418
419
  try {
419
420
  const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh)
420
421
  if (!err) {
422
+ isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
421
423
  isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
422
424
  earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
423
425
  isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
@@ -425,19 +427,22 @@ function runnerHook (runnerExport, playwrightVersion) {
425
427
  }
426
428
  } catch (e) {
427
429
  isEarlyFlakeDetectionEnabled = false
430
+ isKnownTestsEnabled = false
428
431
  log.error('Playwright session start error', e)
429
432
  }
430
433
 
431
- if (isEarlyFlakeDetectionEnabled && semver.gte(playwrightVersion, MINIMUM_SUPPORTED_VERSION_EFD)) {
434
+ if (isKnownTestsEnabled && semver.gte(playwrightVersion, MINIMUM_SUPPORTED_VERSION_EFD)) {
432
435
  try {
433
436
  const { err, knownTests: receivedKnownTests } = await getChannelPromise(knownTestsCh)
434
437
  if (!err) {
435
438
  knownTests = receivedKnownTests
436
439
  } else {
437
440
  isEarlyFlakeDetectionEnabled = false
441
+ isKnownTestsEnabled = false
438
442
  }
439
443
  } catch (err) {
440
444
  isEarlyFlakeDetectionEnabled = false
445
+ isKnownTestsEnabled = false
441
446
  log.error('Playwright known tests error', err)
442
447
  }
443
448
  }
@@ -553,7 +558,7 @@ addHook({
553
558
 
554
559
  async function newCreateRootSuite () {
555
560
  const rootSuite = await oldCreateRootSuite.apply(this, arguments)
556
- if (!isEarlyFlakeDetectionEnabled) {
561
+ if (!isKnownTestsEnabled) {
557
562
  return rootSuite
558
563
  }
559
564
  const newTests = rootSuite
@@ -562,7 +567,7 @@ addHook({
562
567
 
563
568
  newTests.forEach(newTest => {
564
569
  newTest._ddIsNew = true
565
- if (newTest.expectedStatus !== 'skipped') {
570
+ if (isEarlyFlakeDetectionEnabled && newTest.expectedStatus !== 'skipped') {
566
571
  const fileSuite = getSuiteType(newTest, 'file')
567
572
  const projectSuite = getSuiteType(newTest, 'project')
568
573
  for (let repeatEachIndex = 0; repeatEachIndex < earlyFlakeDetectionNumRetries; repeatEachIndex++) {