dd-trace 5.101.0 → 5.103.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 (235) hide show
  1. package/ext/exporters.js +1 -0
  2. package/package.json +20 -17
  3. package/packages/datadog-esbuild/src/utils.js +2 -2
  4. package/packages/datadog-instrumentations/src/aerospike.js +2 -2
  5. package/packages/datadog-instrumentations/src/ai.js +9 -9
  6. package/packages/datadog-instrumentations/src/amqplib.js +6 -7
  7. package/packages/datadog-instrumentations/src/anthropic.js +10 -10
  8. package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
  9. package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
  10. package/packages/datadog-instrumentations/src/avsc.js +6 -6
  11. package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
  12. package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
  13. package/packages/datadog-instrumentations/src/bluebird.js +2 -2
  14. package/packages/datadog-instrumentations/src/body-parser.js +2 -2
  15. package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
  16. package/packages/datadog-instrumentations/src/child_process.js +12 -12
  17. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +41 -24
  18. package/packages/datadog-instrumentations/src/connect.js +7 -7
  19. package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
  20. package/packages/datadog-instrumentations/src/cookie.js +2 -2
  21. package/packages/datadog-instrumentations/src/couchbase.js +73 -238
  22. package/packages/datadog-instrumentations/src/crypto.js +4 -4
  23. package/packages/datadog-instrumentations/src/cucumber.js +78 -17
  24. package/packages/datadog-instrumentations/src/dns.js +0 -3
  25. package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
  26. package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
  27. package/packages/datadog-instrumentations/src/electron.js +240 -0
  28. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
  29. package/packages/datadog-instrumentations/src/express-session.js +4 -4
  30. package/packages/datadog-instrumentations/src/express.js +10 -11
  31. package/packages/datadog-instrumentations/src/fastify.js +2 -2
  32. package/packages/datadog-instrumentations/src/fetch.js +5 -5
  33. package/packages/datadog-instrumentations/src/fs.js +14 -14
  34. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
  35. package/packages/datadog-instrumentations/src/google-genai.js +4 -4
  36. package/packages/datadog-instrumentations/src/graphql.js +13 -12
  37. package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
  38. package/packages/datadog-instrumentations/src/hapi.js +2 -2
  39. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +9 -9
  40. package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
  41. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  42. package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
  43. package/packages/datadog-instrumentations/src/helpers/kafka.js +41 -0
  44. package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
  45. package/packages/datadog-instrumentations/src/hono.js +2 -2
  46. package/packages/datadog-instrumentations/src/http/client.js +6 -6
  47. package/packages/datadog-instrumentations/src/http/server.js +9 -9
  48. package/packages/datadog-instrumentations/src/ioredis.js +16 -12
  49. package/packages/datadog-instrumentations/src/jest.js +382 -81
  50. package/packages/datadog-instrumentations/src/kafkajs.js +165 -174
  51. package/packages/datadog-instrumentations/src/knex.js +17 -17
  52. package/packages/datadog-instrumentations/src/koa.js +12 -12
  53. package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
  54. package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
  55. package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
  56. package/packages/datadog-instrumentations/src/lodash.js +4 -4
  57. package/packages/datadog-instrumentations/src/mariadb.js +13 -13
  58. package/packages/datadog-instrumentations/src/memcached.js +2 -2
  59. package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
  60. package/packages/datadog-instrumentations/src/mocha/common.js +3 -3
  61. package/packages/datadog-instrumentations/src/mocha/main.js +85 -11
  62. package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
  63. package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
  64. package/packages/datadog-instrumentations/src/mongodb-core.js +42 -30
  65. package/packages/datadog-instrumentations/src/mongodb.js +5 -5
  66. package/packages/datadog-instrumentations/src/mongoose.js +21 -21
  67. package/packages/datadog-instrumentations/src/mquery.js +5 -5
  68. package/packages/datadog-instrumentations/src/multer.js +4 -4
  69. package/packages/datadog-instrumentations/src/mysql.js +16 -16
  70. package/packages/datadog-instrumentations/src/mysql2.js +4 -4
  71. package/packages/datadog-instrumentations/src/net.js +14 -8
  72. package/packages/datadog-instrumentations/src/nyc.js +5 -5
  73. package/packages/datadog-instrumentations/src/openai.js +19 -19
  74. package/packages/datadog-instrumentations/src/oracledb.js +6 -6
  75. package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
  76. package/packages/datadog-instrumentations/src/pg.js +39 -25
  77. package/packages/datadog-instrumentations/src/pino.js +6 -10
  78. package/packages/datadog-instrumentations/src/playwright.js +445 -68
  79. package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
  80. package/packages/datadog-instrumentations/src/redis.js +20 -12
  81. package/packages/datadog-instrumentations/src/restify.js +2 -2
  82. package/packages/datadog-instrumentations/src/router.js +12 -12
  83. package/packages/datadog-instrumentations/src/stripe.js +12 -12
  84. package/packages/datadog-instrumentations/src/vitest.js +107 -26
  85. package/packages/datadog-instrumentations/src/winston.js +4 -4
  86. package/packages/datadog-instrumentations/src/ws.js +7 -7
  87. package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
  88. package/packages/datadog-plugin-aws-sdk/src/base.js +70 -28
  89. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
  90. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +20 -13
  91. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +46 -36
  92. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +34 -23
  93. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
  94. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
  95. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +14 -15
  96. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +74 -55
  97. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +20 -18
  98. package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
  99. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
  100. package/packages/datadog-plugin-couchbase/src/index.js +58 -52
  101. package/packages/datadog-plugin-cucumber/src/index.js +5 -0
  102. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +215 -26
  103. package/packages/datadog-plugin-cypress/src/support.js +13 -1
  104. package/packages/datadog-plugin-electron/src/index.js +17 -0
  105. package/packages/datadog-plugin-electron/src/ipc.js +143 -0
  106. package/packages/datadog-plugin-electron/src/net.js +82 -0
  107. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
  108. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
  109. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
  110. package/packages/datadog-plugin-graphql/src/execute.js +6 -28
  111. package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
  112. package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
  113. package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
  114. package/packages/datadog-plugin-graphql/src/utils.js +29 -0
  115. package/packages/datadog-plugin-grpc/src/client.js +6 -7
  116. package/packages/datadog-plugin-grpc/src/util.js +57 -22
  117. package/packages/datadog-plugin-http/src/client.js +3 -7
  118. package/packages/datadog-plugin-jest/src/index.js +92 -50
  119. package/packages/datadog-plugin-jest/src/util.js +1 -2
  120. package/packages/datadog-plugin-mocha/src/index.js +5 -0
  121. package/packages/datadog-plugin-mongodb-core/src/index.js +36 -69
  122. package/packages/datadog-plugin-mysql/src/index.js +1 -1
  123. package/packages/datadog-plugin-openai/src/services.js +2 -1
  124. package/packages/datadog-plugin-openai/src/tracing.js +12 -23
  125. package/packages/datadog-plugin-pg/src/index.js +3 -3
  126. package/packages/datadog-plugin-playwright/src/index.js +5 -1
  127. package/packages/datadog-plugin-redis/src/index.js +18 -23
  128. package/packages/datadog-plugin-vitest/src/index.js +8 -1
  129. package/packages/datadog-shimmer/src/shimmer.js +7 -1
  130. package/packages/dd-trace/src/aiguard/index.js +3 -1
  131. package/packages/dd-trace/src/aiguard/sdk.js +36 -30
  132. package/packages/dd-trace/src/aiguard/tags.js +20 -11
  133. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
  134. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
  135. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
  136. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
  137. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +4 -4
  138. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
  139. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
  140. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
  141. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
  142. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  143. package/packages/dd-trace/src/appsec/index.js +21 -24
  144. package/packages/dd-trace/src/appsec/reporter.js +3 -1
  145. package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
  146. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
  147. package/packages/dd-trace/src/azure_metadata.js +17 -6
  148. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
  149. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
  150. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
  151. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
  152. package/packages/dd-trace/src/config/defaults.js +3 -14
  153. package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -1
  154. package/packages/dd-trace/src/config/git_properties.js +2 -2
  155. package/packages/dd-trace/src/config/helper.js +4 -0
  156. package/packages/dd-trace/src/config/index.js +2 -2
  157. package/packages/dd-trace/src/config/major-overrides.js +98 -0
  158. package/packages/dd-trace/src/config/parsers.js +7 -1
  159. package/packages/dd-trace/src/config/supported-configurations.json +51 -38
  160. package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
  161. package/packages/dd-trace/src/datastreams/index.js +2 -1
  162. package/packages/dd-trace/src/datastreams/manager.js +1 -1
  163. package/packages/dd-trace/src/datastreams/processor.js +3 -4
  164. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
  165. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
  166. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  167. package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
  168. package/packages/dd-trace/src/debugger/index.js +7 -7
  169. package/packages/dd-trace/src/dogstatsd.js +2 -2
  170. package/packages/dd-trace/src/encode/0.4.js +748 -232
  171. package/packages/dd-trace/src/encode/0.5.js +47 -10
  172. package/packages/dd-trace/src/encode/agentless-json.js +1 -1
  173. package/packages/dd-trace/src/exporter.js +2 -0
  174. package/packages/dd-trace/src/exporters/agent/index.js +2 -1
  175. package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
  176. package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
  177. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
  178. package/packages/dd-trace/src/exporters/common/request.js +1 -1
  179. package/packages/dd-trace/src/exporters/electron/index.js +49 -0
  180. package/packages/dd-trace/src/external-logger/src/index.js +2 -1
  181. package/packages/dd-trace/src/git_metadata.js +10 -8
  182. package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
  183. package/packages/dd-trace/src/lambda/index.js +62 -14
  184. package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
  185. package/packages/dd-trace/src/llmobs/index.js +13 -2
  186. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
  187. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
  188. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +6 -3
  189. package/packages/dd-trace/src/llmobs/sdk.js +24 -26
  190. package/packages/dd-trace/src/llmobs/span_processor.js +25 -5
  191. package/packages/dd-trace/src/llmobs/util.js +1 -0
  192. package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
  193. package/packages/dd-trace/src/msgpack/chunk.js +6 -3
  194. package/packages/dd-trace/src/openfeature/noop.js +40 -36
  195. package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
  196. package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
  197. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
  198. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
  199. package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
  200. package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
  201. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
  202. package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
  203. package/packages/dd-trace/src/plugins/ci_plugin.js +49 -4
  204. package/packages/dd-trace/src/plugins/database.js +54 -12
  205. package/packages/dd-trace/src/plugins/index.js +1 -0
  206. package/packages/dd-trace/src/plugins/plugin.js +2 -4
  207. package/packages/dd-trace/src/plugins/util/ci.js +9 -9
  208. package/packages/dd-trace/src/plugins/util/git-cache.js +23 -23
  209. package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
  210. package/packages/dd-trace/src/plugins/util/test.js +56 -12
  211. package/packages/dd-trace/src/plugins/util/url.js +1 -3
  212. package/packages/dd-trace/src/plugins/util/user-provided-git.js +18 -16
  213. package/packages/dd-trace/src/plugins/util/web.js +5 -7
  214. package/packages/dd-trace/src/priority_sampler.js +1 -1
  215. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  216. package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
  217. package/packages/dd-trace/src/profiling/profilers/wall.js +5 -6
  218. package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
  219. package/packages/dd-trace/src/rate_limiter.js +1 -1
  220. package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
  221. package/packages/dd-trace/src/ritm.js +2 -1
  222. package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
  223. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
  224. package/packages/dd-trace/src/scope.js +3 -10
  225. package/packages/dd-trace/src/serverless.js +6 -6
  226. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +27 -1
  227. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  228. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +24 -0
  229. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  230. package/packages/dd-trace/src/span_stats.js +1 -1
  231. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  232. package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
  233. package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
  234. package/packages/dd-trace/src/tracer.js +7 -7
  235. package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ const { performance } = require('node:perf_hooks')
4
+
3
5
  const { createCoverageMap } = require('../../../vendor/dist/istanbul-lib-coverage')
4
6
  const shimmer = require('../../datadog-shimmer')
5
7
  const log = require('../../dd-trace/src/log')
@@ -12,6 +14,7 @@ const {
12
14
  getTestSuitePath,
13
15
  CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
14
16
  getIsFaultyEarlyFlakeDetection,
17
+ getEfdRetryCount,
15
18
  recordAttemptToFixExecution,
16
19
  collectAttemptToFixExecutionsFromTraces,
17
20
  logAttemptToFixTestExecution,
@@ -62,6 +65,9 @@ const lastStatusByPickleId = new Map()
62
65
  /** For ATR: statuses keyed by stable scenario id (uri:name) so retries accumulate correctly */
63
66
  const atrStatusesByScenarioKey = new Map()
64
67
  const numRetriesByPickleId = new Map()
68
+ const efdRetryCountByPickleId = new Map()
69
+ const efdSlowAbortedPickleIds = new Set()
70
+ const testCaseStartedTimesById = new Map()
65
71
  const numAttemptToCtx = new Map()
66
72
  const newTestsByTestFullname = new Map()
67
73
  const attemptToFixTestsByTestFullname = new Map()
@@ -82,6 +88,7 @@ let isUnskippable = false
82
88
  let isSuitesSkippingEnabled = false
83
89
  let isEarlyFlakeDetectionEnabled = false
84
90
  let earlyFlakeDetectionNumRetries = 0
91
+ let earlyFlakeDetectionSlowTestRetries = {}
85
92
  let earlyFlakeDetectionFaultyThreshold = 0
86
93
  let isEarlyFlakeDetectionFaulty = false
87
94
  let isFlakyTestRetriesEnabled = false
@@ -290,9 +297,9 @@ function wrapRun (pl, isLatestVersion, version) {
290
297
 
291
298
  patched.add(pl)
292
299
 
293
- shimmer.wrap(pl.prototype, 'run', run => function () {
300
+ shimmer.wrap(pl.prototype, 'run', run => function (...args) {
294
301
  if (!testFinishCh.hasSubscribers) {
295
- return run.apply(this, arguments)
302
+ return run.apply(this, args)
296
303
  }
297
304
 
298
305
  let numAttempt = 0
@@ -360,9 +367,10 @@ function wrapRun (pl, isLatestVersion, version) {
360
367
  }
361
368
  this.eventBroadcaster.on('envelope', onEnvelope)
362
369
  let promise
370
+ const executionStart = performance.now()
363
371
 
364
372
  testFnCh.runStores(ctx, () => {
365
- promise = run.apply(this, arguments)
373
+ promise = run.apply(this, args)
366
374
  })
367
375
  promise.finally(async () => {
368
376
  this.eventBroadcaster.removeListener('envelope', onEnvelope)
@@ -424,15 +432,31 @@ function wrapRun (pl, isLatestVersion, version) {
424
432
  isEfdRetry = numRetries > 0
425
433
  }
426
434
 
435
+ if (
436
+ isEarlyFlakeDetectionEnabled &&
437
+ status !== 'skip' &&
438
+ (isNew || isModified) &&
439
+ !isEfdRetry &&
440
+ !efdRetryCountByPickleId.has(this.pickle.id)
441
+ ) {
442
+ const retryCount = getEfdRetryCount(performance.now() - executionStart, earlyFlakeDetectionSlowTestRetries)
443
+ efdRetryCountByPickleId.set(this.pickle.id, retryCount)
444
+ if (retryCount === 0) {
445
+ efdSlowAbortedPickleIds.add(this.pickle.id)
446
+ }
447
+ }
448
+
449
+ const efdRetryCount = efdRetryCountByPickleId.get(this.pickle.id) ?? earlyFlakeDetectionNumRetries
450
+
427
451
  // Check if all EFD retries failed
428
452
  if (isEfdRetry && (isNew || isModified)) {
429
453
  const statuses = lastStatusByPickleId.get(this.pickle.id)
430
- if (statuses.length === earlyFlakeDetectionNumRetries + 1) {
454
+ if (statuses.length === efdRetryCount + 1) {
431
455
  const { fail } = statuses.reduce((acc, status) => {
432
456
  acc[status]++
433
457
  return acc
434
458
  }, { pass: 0, fail: 0 })
435
- if (fail === earlyFlakeDetectionNumRetries + 1) {
459
+ if (fail === efdRetryCount + 1) {
436
460
  hasFailedAllRetries = true
437
461
  }
438
462
  }
@@ -480,7 +504,7 @@ function wrapRun (pl, isLatestVersion, version) {
480
504
  const isLastAtrRetry = isFlakyTestRetriesEnabled && !isAttemptToFix && !isEfdRetry && numTestRetries > 0
481
505
 
482
506
  const statuses = lastStatusByPickleId.get(this.pickle.id)
483
- const isLastEfdRetry = isEfdRetry && statuses?.length === earlyFlakeDetectionNumRetries + 1
507
+ const isLastEfdRetry = isEfdRetry && statuses?.length === efdRetryCount + 1
484
508
  const isLastAttemptToFixRetry = isAttemptToFix && statuses?.length === testManagementAttemptToFixRetries + 1
485
509
 
486
510
  // Intermediate (non-last EFD or ATF retries) executions do not report a final status
@@ -514,6 +538,7 @@ function wrapRun (pl, isLatestVersion, version) {
514
538
  isDisabled,
515
539
  isQuarantined,
516
540
  isModified,
541
+ earlyFlakeAbortReason: efdSlowAbortedPickleIds.has(this.pickle.id) ? 'slow' : undefined,
517
542
  ...attemptCtx.currentStore,
518
543
  finalStatus,
519
544
  })
@@ -526,11 +551,11 @@ function wrapRun (pl, isLatestVersion, version) {
526
551
  })
527
552
  }
528
553
  })
529
- shimmer.wrap(pl.prototype, 'runStep', runStep => function () {
554
+ shimmer.wrap(pl.prototype, 'runStep', runStep => function (...args) {
530
555
  if (!testFinishCh.hasSubscribers) {
531
- return runStep.apply(this, arguments)
556
+ return runStep.apply(this, args)
532
557
  }
533
- const testStep = arguments[0]
558
+ const testStep = args[0]
534
559
  let resource
535
560
 
536
561
  if (isLatestVersion) {
@@ -542,7 +567,7 @@ function wrapRun (pl, isLatestVersion, version) {
542
567
  const ctx = { resource }
543
568
  return testStepStartCh.runStores(ctx, () => {
544
569
  try {
545
- const promise = runStep.apply(this, arguments)
570
+ const promise = runStep.apply(this, args)
546
571
 
547
572
  promise.then((result) => {
548
573
  const finalResult = satisfies(version, '>=12.0.0') ? result.result : result
@@ -603,6 +628,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
603
628
 
604
629
  isEarlyFlakeDetectionEnabled = configurationResponse.libraryConfig?.isEarlyFlakeDetectionEnabled
605
630
  earlyFlakeDetectionNumRetries = configurationResponse.libraryConfig?.earlyFlakeDetectionNumRetries
631
+ earlyFlakeDetectionSlowTestRetries = configurationResponse.libraryConfig?.earlyFlakeDetectionSlowTestRetries ?? {}
606
632
  earlyFlakeDetectionFaultyThreshold = configurationResponse.libraryConfig?.earlyFlakeDetectionFaultyThreshold
607
633
  isSuitesSkippingEnabled = configurationResponse.libraryConfig?.isSuitesSkippingEnabled
608
634
  isFlakyTestRetriesEnabled = configurationResponse.libraryConfig?.isFlakyTestRetriesEnabled
@@ -627,7 +653,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
627
653
  const skippableResponse = await getChannelPromise(skippableSuitesCh)
628
654
 
629
655
  errorSkippableRequest = skippableResponse.err
630
- skippableSuites = skippableResponse.skippableSuites
656
+ skippableSuites = skippableResponse.skippableSuites ?? []
631
657
 
632
658
  if (!errorSkippableRequest) {
633
659
  const filteredPickles = isCoordinator
@@ -692,6 +718,10 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
692
718
 
693
719
  atrStatusesByScenarioKey.clear()
694
720
  attemptToFixTestsByTestFullname.clear()
721
+ efdRetryCountByPickleId.clear()
722
+ efdSlowAbortedPickleIds.clear()
723
+ testCaseStartedTimesById.clear()
724
+ newTestsByTestFullname.clear()
695
725
  sessionStartCh.publish({ command, frameworkVersion })
696
726
 
697
727
  if (!errorSkippableRequest && skippedSuites.length) {
@@ -816,7 +846,9 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
816
846
  }
817
847
  }
818
848
  // TODO: for >=11 we could use `runTestCaseResult` instead of accumulating results in `lastStatusByPickleId`
849
+ const firstExecutionStart = performance.now()
819
850
  let runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
851
+ const firstExecutionDurationMs = performance.now() - firstExecutionStart
820
852
 
821
853
  // Restore dryRun so it doesn't affect subsequent tests in the same worker
822
854
  this.options.dryRun = originalDryRun
@@ -835,7 +867,15 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
835
867
 
836
868
  // If it's a new test and it hasn't been skipped, we run it again
837
869
  if (isEarlyFlakeDetectionEnabled && lastTestStatus !== 'skip' && (isNew || isModified)) {
838
- for (let retryIndex = 0; retryIndex < earlyFlakeDetectionNumRetries; retryIndex++) {
870
+ let efdRetryCount = efdRetryCountByPickleId.get(pickle.id)
871
+ if (efdRetryCount === undefined) {
872
+ efdRetryCount = getEfdRetryCount(firstExecutionDurationMs, earlyFlakeDetectionSlowTestRetries)
873
+ efdRetryCountByPickleId.set(pickle.id, efdRetryCount)
874
+ if (efdRetryCount === 0) {
875
+ efdSlowAbortedPickleIds.add(pickle.id)
876
+ }
877
+ }
878
+ for (let retryIndex = 0; retryIndex < efdRetryCount; retryIndex++) {
839
879
  numRetriesByPickleId.set(pickle.id, retryIndex + 1)
840
880
  // eslint-disable-next-line no-await-in-loop
841
881
  runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
@@ -952,6 +992,9 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
952
992
  let pickle
953
993
 
954
994
  if (parsed.testCaseStarted) {
995
+ if (parsed.testCaseStarted.id) {
996
+ testCaseStartedTimesById.set(parsed.testCaseStarted.id, performance.now())
997
+ }
955
998
  if (isNewVersion) {
956
999
  pickle = this.inProgress[worker.id].pickle
957
1000
  } else {
@@ -973,6 +1016,10 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
973
1016
 
974
1017
  // after calling `parseWorkerMessageFunction`, the test status can already be read
975
1018
  if (parsed.testCaseFinished) {
1019
+ const testCaseStartedId = parsed.testCaseFinished.testCaseStartedId
1020
+ const testCaseStartedAt = testCaseStartedTimesById.get(testCaseStartedId)
1021
+ testCaseStartedTimesById.delete(testCaseStartedId)
1022
+
976
1023
  let worstTestStepResult
977
1024
  if (isNewVersion && eventDataCollector) {
978
1025
  pickle = this.inProgress[worker.id].pickle
@@ -1003,8 +1050,19 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
1003
1050
  testStatuses = [status]
1004
1051
  newTestsByTestFullname.set(testFullname, testStatuses)
1005
1052
  }
1053
+ let efdRetryCount = efdRetryCountByPickleId.get(pickle.id)
1054
+ if (efdRetryCount === undefined) {
1055
+ const firstExecutionDurationMs = testCaseStartedAt === undefined ? 0 : performance.now() - testCaseStartedAt
1056
+ efdRetryCount = status === 'skip'
1057
+ ? 0
1058
+ : getEfdRetryCount(firstExecutionDurationMs, earlyFlakeDetectionSlowTestRetries)
1059
+ efdRetryCountByPickleId.set(pickle.id, efdRetryCount)
1060
+ if (efdRetryCount === 0 && status !== 'skip') {
1061
+ efdSlowAbortedPickleIds.add(pickle.id)
1062
+ }
1063
+ }
1006
1064
  // We have finished all retries
1007
- if (testStatuses.length === earlyFlakeDetectionNumRetries + 1) {
1065
+ if (testStatuses.length === efdRetryCount + 1) {
1008
1066
  const newTestFinalStatus = getTestStatusFromRetries(testStatuses)
1009
1067
  // we only push to `finished` if the retries have finished
1010
1068
  finished.push(newTestFinalStatus)
@@ -1143,9 +1201,9 @@ addHook({
1143
1201
  versions: ['>=11.0.0'],
1144
1202
  file: 'lib/formatter/helpers/event_data_collector.js',
1145
1203
  }, (eventDataCollectorPackage) => {
1146
- shimmer.wrap(eventDataCollectorPackage.default.prototype, 'parseEnvelope', parseEnvelope => function () {
1204
+ shimmer.wrap(eventDataCollectorPackage.default.prototype, 'parseEnvelope', parseEnvelope => function (...args) {
1147
1205
  eventDataCollector = this
1148
- return parseEnvelope.apply(this, arguments)
1206
+ return parseEnvelope.apply(this, args)
1149
1207
  })
1150
1208
  return eventDataCollectorPackage
1151
1209
  })
@@ -1164,18 +1222,20 @@ addHook({
1164
1222
  parseWorkerMessage => getWrappedParseWorkerMessage(parseWorkerMessage, true)
1165
1223
  )
1166
1224
  // EFD in parallel mode only supported in >=11.0.0
1167
- shimmer.wrap(adapterPackage.ChildProcessAdapter.prototype, 'startWorker', startWorker => function () {
1225
+ shimmer.wrap(adapterPackage.ChildProcessAdapter.prototype, 'startWorker', startWorker => function (...args) {
1168
1226
  if (isKnownTestsEnabled && isValidKnownTests(knownTests)) {
1169
1227
  this.options.worldParameters._ddIsKnownTestsEnabled = true
1170
1228
  this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
1171
1229
  this.options.worldParameters._ddKnownTests = knownTests
1172
1230
  this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
1231
+ this.options.worldParameters._ddEarlyFlakeDetectionSlowTestRetries = earlyFlakeDetectionSlowTestRetries
1173
1232
  } else {
1174
1233
  isEarlyFlakeDetectionEnabled = false
1175
1234
  isKnownTestsEnabled = false
1176
1235
  this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled = false
1177
1236
  this.options.worldParameters._ddIsKnownTestsEnabled = false
1178
1237
  this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = 0
1238
+ this.options.worldParameters._ddEarlyFlakeDetectionSlowTestRetries = {}
1179
1239
  }
1180
1240
 
1181
1241
  if (isImpactedTestsEnabled) {
@@ -1192,7 +1252,7 @@ addHook({
1192
1252
  this.options.worldParameters._ddTestManagementAttemptToFixRetries = testManagementAttemptToFixRetries
1193
1253
  }
1194
1254
 
1195
- return startWorker.apply(this, arguments)
1255
+ return startWorker.apply(this, args)
1196
1256
  })
1197
1257
  return adapterPackage
1198
1258
  })
@@ -1222,6 +1282,7 @@ addHook({
1222
1282
  isEarlyFlakeDetectionEnabled = !!this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled
1223
1283
  if (isEarlyFlakeDetectionEnabled) {
1224
1284
  earlyFlakeDetectionNumRetries = this.options.worldParameters._ddEarlyFlakeDetectionNumRetries
1285
+ earlyFlakeDetectionSlowTestRetries = this.options.worldParameters._ddEarlyFlakeDetectionSlowTestRetries ?? {}
1225
1286
  }
1226
1287
  isImpactedTestsEnabled = !!this.options.worldParameters._ddImpactedTestsEnabled
1227
1288
  if (isImpactedTestsEnabled) {
@@ -18,8 +18,6 @@ const rrtypes = {
18
18
  resolveSoa: 'SOA',
19
19
  }
20
20
 
21
- const rrtypeMap = new WeakMap()
22
-
23
21
  addHook({ name: 'dns' }, dns => {
24
22
  const lookup = createCallbackInstrumentor('apm:dns:lookup', { captureResult: true })
25
23
  const lookupService = createCallbackInstrumentor('apm:dns:lookup_service', { captureResult: true })
@@ -46,7 +44,6 @@ addHook({ name: 'dns' }, dns => {
46
44
  function patchResolveShorthands (prototype, resolve) {
47
45
  for (const method of Object.keys(rrtypes)) {
48
46
  if (prototype[method]) {
49
- rrtypeMap.set(prototype[method], rrtypes[method])
50
47
  shimmer.wrap(prototype, method, resolve(buildArgsContext(rrtypes[method])))
51
48
  }
52
49
  }
@@ -24,24 +24,21 @@ function wrapTransportPrototype (Transport) {
24
24
  addHook({ name: '@elastic/elasticsearch', file: 'lib/Transport.js', versions: ['>=5.6.16 <8', '>=8'] }, Transport => {
25
25
  shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
26
26
  shimmer.wrap(Transport.prototype, 'getConnection', createWrapGetConnection('elasticsearch'))
27
- return Transport
28
27
  })
29
28
 
30
29
  addHook({ name: 'elasticsearch', file: 'src/lib/transport.js', versions: ['>=10'] }, Transport => {
31
30
  shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
32
- return Transport
33
31
  })
34
32
 
35
33
  addHook({ name: 'elasticsearch', file: 'src/lib/connection_pool.js', versions: ['>=10'] }, ConnectionPool => {
36
- shimmer.wrap(ConnectionPool.prototype, 'select', createWrapSelect('elasticsearch'))
37
- return ConnectionPool
34
+ shimmer.wrap(ConnectionPool.prototype, 'select', createWrapSelect())
38
35
  })
39
36
 
40
37
  function createWrapGetConnection (name) {
41
38
  const connectCh = channel(`apm:${name}:query:connect`)
42
39
  return function wrapRequest (request) {
43
- return function () {
44
- const connection = request.apply(this, arguments)
40
+ return function (...args) {
41
+ const connection = request.apply(this, args)
45
42
  if (connectCh.hasSubscribers && connection && connection.url) {
46
43
  connectCh.publish(connection.url)
47
44
  }
@@ -53,17 +50,17 @@ function createWrapGetConnection (name) {
53
50
  function createWrapSelect () {
54
51
  const connectCh = channel('apm:elasticsearch:query:connect')
55
52
  return function wrapRequest (request) {
56
- return function () {
57
- if (arguments.length === 1) {
58
- const cb = arguments[0]
59
- arguments[0] = shimmer.wrapFunction(cb, cb => function (err, connection) {
53
+ return function (...args) {
54
+ if (args.length === 1) {
55
+ const cb = args[0]
56
+ args[0] = shimmer.wrapFunction(cb, cb => function (err, connection) {
60
57
  if (connectCh.hasSubscribers && connection && connection.host) {
61
58
  connectCh.publish({ hostname: connection.host.host, port: connection.host.port })
62
59
  }
63
60
  cb(err, connection)
64
61
  })
65
62
  }
66
- return request.apply(this, arguments)
63
+ return request.apply(this, args)
67
64
  }
68
65
  }
69
66
  }
@@ -0,0 +1,42 @@
1
+ 'use strict'
2
+
3
+ // eslint-disable-next-line n/no-missing-require
4
+ const { contextBridge, ipcRenderer } = require('electron')
5
+
6
+ const BRIDGE_CHANNEL = 'datadog:bridge-send'
7
+ const CONFIG_CHANNEL = 'datadog:bridge-config'
8
+
9
+ // Privacy levels matching @datadog/browser-core DefaultPrivacyLevel
10
+ const MASK = 'mask'
11
+
12
+ const config = ipcRenderer.sendSync(CONFIG_CHANNEL)
13
+
14
+ const defaultPrivacyLevel = config?.defaultPrivacyLevel ?? MASK
15
+ const configuredHosts = config?.allowedWebViewHosts ?? []
16
+ // eslint-disable-next-line no-undef
17
+ const allowedHosts = [...new Set([location.hostname, ...configuredHosts])]
18
+
19
+ const bridge = {
20
+ getCapabilities () {
21
+ return '[]'
22
+ },
23
+ getPrivacyLevel () {
24
+ return defaultPrivacyLevel
25
+ },
26
+ getAllowedWebViewHosts () {
27
+ return JSON.stringify(allowedHosts)
28
+ },
29
+ send (msg) {
30
+ ipcRenderer.send(BRIDGE_CHANNEL, msg)
31
+ },
32
+ }
33
+
34
+ // Support both contextIsolation enabled (default) and disabled
35
+
36
+ window.DatadogEventBridge = bridge
37
+
38
+ try {
39
+ contextBridge.exposeInMainWorld('DatadogEventBridge', bridge)
40
+ } catch {
41
+ // exposeInMainWorld throws when contextIsolation is disabled
42
+ }
@@ -0,0 +1,240 @@
1
+ 'use strict'
2
+
3
+ const { join } = require('path')
4
+ const { wrap } = require('../../datadog-shimmer')
5
+ const { addHook, channel, tracingChannel } = require('./helpers/instrument')
6
+
7
+ const requestCh = tracingChannel('apm:electron:net:request')
8
+ const mainReceiveCh = tracingChannel('apm:electron:ipc:main:receive')
9
+ const mainHandleCh = tracingChannel('apm:electron:ipc:main:handle')
10
+ const mainSendCh = tracingChannel('apm:electron:ipc:main:send')
11
+ const rendererPatchedCh = channel('apm:electron:ipc:renderer:patched')
12
+ const rendererReceiveCh = tracingChannel('apm:electron:ipc:renderer:receive')
13
+ const rendererSendCh = tracingChannel('apm:electron:ipc:renderer:send')
14
+
15
+ const listeners = {}
16
+ const handlers = {}
17
+
18
+ function createWrapRequest (ch) {
19
+ return function wrapRequest (request) {
20
+ return function (...args) {
21
+ if (!ch.start.hasSubscribers) return request.apply(this, arguments)
22
+
23
+ const ctx = { args }
24
+
25
+ return ch.start.runStores(ctx, () => {
26
+ try {
27
+ const req = request.apply(this, ctx.args)
28
+ const emit = req.emit
29
+
30
+ ctx.req = req
31
+
32
+ req.emit = function (eventName, arg) {
33
+ /* eslint-disable no-fallthrough */
34
+ switch (eventName) {
35
+ case 'response':
36
+ ctx.res = arg
37
+ ctx.res.on('error', error => {
38
+ ctx.error = error
39
+ ch.error.publish(ctx)
40
+ ch.asyncStart.publish(ctx)
41
+ })
42
+ ctx.res.on('end', () => ch.asyncStart.publish(ctx))
43
+ break
44
+ case 'error':
45
+ ctx.error = arg
46
+ ch.error.publish(ctx)
47
+ case 'abort':
48
+ ch.asyncStart.publish(ctx)
49
+ }
50
+
51
+ return emit.apply(this, arguments)
52
+ }
53
+
54
+ return req
55
+ } catch (e) {
56
+ ctx.error = e
57
+ ch.error.publish(ctx)
58
+ throw e
59
+ } finally {
60
+ ch.end.publish(ctx)
61
+ }
62
+ })
63
+ }
64
+ }
65
+ }
66
+
67
+ function createWrapAddListener (ch, mappings) {
68
+ return function wrapAddListener (addListener) {
69
+ return function (channel, listener) {
70
+ const wrappedListener = (event, ...args) => {
71
+ const ctx = { args, channel, event }
72
+
73
+ return ch.tracePromise(() => listener.call(this, event, ...args), ctx)
74
+ }
75
+
76
+ const mapping = mappings[channel] || new WeakMap()
77
+ const wrapper = mapping.get(listener) || wrappedListener
78
+
79
+ mapping.set(listener, wrapper)
80
+
81
+ return addListener.call(this, channel, wrappedListener)
82
+ }
83
+ }
84
+ }
85
+
86
+ function createWrapRemoveListener (mappings) {
87
+ return function wrapRemoveListener (removeListener) {
88
+ return function (channel, listener) {
89
+ const mapping = mappings[channel]
90
+
91
+ if (mapping) {
92
+ const wrapper = mapping.get(listener)
93
+
94
+ if (wrapper) {
95
+ return removeListener.call(this, channel, wrapper)
96
+ }
97
+ }
98
+
99
+ return removeListener.call(this, channel, listener)
100
+ }
101
+ }
102
+ }
103
+
104
+ function createWrapRemoveAllListeners (mappings) {
105
+ return function wrapRemoveAllListeners (removeAllListeners) {
106
+ return function (channel) {
107
+ if (channel) {
108
+ delete mappings[channel]
109
+ } else {
110
+ for (const key of Object.keys(mappings)) delete mappings[key]
111
+ }
112
+
113
+ return removeAllListeners.call(this, channel)
114
+ }
115
+ }
116
+ }
117
+
118
+ function createWrapSend (ch, promise = false) {
119
+ const trace = (promise ? ch.tracePromise : ch.traceSync).bind(ch)
120
+
121
+ return function wrapSend (send) {
122
+ return function (channel, ...args) {
123
+ const ctx = { args, channel, self: this }
124
+
125
+ return trace(() => send.call(this, channel, ...args), ctx)
126
+ }
127
+ }
128
+ }
129
+
130
+ function wrapSendToFrame (send) {
131
+ return function (frameId, channel, ...args) {
132
+ const ctx = { args, channel, frameId, self: this }
133
+
134
+ return mainSendCh.traceSync(() => send.call(this, frameId, channel, ...args), ctx)
135
+ }
136
+ }
137
+
138
+ function wrapBrowserWindow (electron) {
139
+ const moduleExports = {}
140
+
141
+ class DatadogBrowserWindow extends electron.BrowserWindow {
142
+ constructor (options = {}) {
143
+ const win = super(options)
144
+
145
+ win.webContents.session.registerPreloadScript({
146
+ type: 'frame', // TODO: service-worker
147
+ filePath: join(__dirname, 'electron', 'preload.js'),
148
+ })
149
+
150
+ // BrowserWindow doesn't support subclassing because it's all native code
151
+ // so we return an instance of it instead of the subclass.
152
+ return win
153
+ }
154
+ }
155
+
156
+ Object.defineProperty(moduleExports, 'BrowserWindow', {
157
+ enumerable: true,
158
+ get: () => DatadogBrowserWindow,
159
+ configurable: false,
160
+ })
161
+
162
+ for (const key of Reflect.ownKeys(electron)) {
163
+ const descriptor = Reflect.getOwnPropertyDescriptor(electron, key)
164
+
165
+ if (key === 'BrowserWindow') continue
166
+
167
+ Object.defineProperty(moduleExports, key, descriptor)
168
+ }
169
+
170
+ return moduleExports
171
+ }
172
+
173
+ function wrapWebContents (proto) {
174
+ const descriptor = Object.getOwnPropertyDescriptor(proto, 'webContents')
175
+ const wrapped = new WeakSet()
176
+ const wrapSend = createWrapSend(mainSendCh)
177
+
178
+ Object.defineProperty(proto, 'webContents', {
179
+ get () {
180
+ const webContents = descriptor.get.apply(this)
181
+
182
+ if (!wrapped.has(webContents)) {
183
+ // wrap(webContents, 'postMessage', wrapSend)
184
+ wrap(webContents, 'send', wrapSend)
185
+ wrap(webContents, 'sendToFrame', wrapSendToFrame)
186
+
187
+ wrapped.add(webContents)
188
+ }
189
+
190
+ return webContents
191
+ },
192
+ })
193
+ }
194
+
195
+ addHook({ name: 'electron', versions: ['>=37.0.0'] }, electron => {
196
+ // Electron exports a string in Node and an object in Electron.
197
+ if (typeof electron === 'string') return electron
198
+
199
+ const { BrowserWindow, ipcMain, ipcRenderer, net } = electron
200
+
201
+ if (net) {
202
+ // This also covers `fetch` as it uses `request` under the hood.
203
+ wrap(net, 'request', createWrapRequest(requestCh))
204
+ }
205
+
206
+ if (ipcRenderer) {
207
+ wrap(ipcRenderer, 'invoke', createWrapSend(rendererSendCh, true))
208
+ // wrap(ipcRenderer, 'postMessage', createWrapSend(rendererSendCh))
209
+ wrap(ipcRenderer, 'send', createWrapSend(rendererSendCh))
210
+ wrap(ipcRenderer, 'sendSync', createWrapSend(rendererSendCh))
211
+ wrap(ipcRenderer, 'sendToHost', createWrapSend(rendererSendCh))
212
+
213
+ wrap(ipcRenderer, 'addListener', createWrapAddListener(rendererReceiveCh, listeners))
214
+ wrap(ipcRenderer, 'off', createWrapRemoveListener(listeners))
215
+ wrap(ipcRenderer, 'on', createWrapAddListener(rendererReceiveCh, listeners))
216
+ wrap(ipcRenderer, 'once', createWrapAddListener(rendererReceiveCh, listeners))
217
+ wrap(ipcRenderer, 'removeListener', createWrapRemoveListener(listeners))
218
+ wrap(ipcRenderer, 'removeAllListeners', createWrapRemoveAllListeners(listeners))
219
+
220
+ ipcRenderer.send('datadog:apm:renderer:patched')
221
+ } else {
222
+ wrap(ipcMain, 'addListener', createWrapAddListener(mainReceiveCh, listeners))
223
+ wrap(ipcMain, 'handle', createWrapAddListener(mainHandleCh, handlers))
224
+ wrap(ipcMain, 'handleOnce', createWrapAddListener(mainHandleCh, handlers))
225
+ wrap(ipcMain, 'off', createWrapRemoveListener(listeners))
226
+ wrap(ipcMain, 'on', createWrapAddListener(mainReceiveCh, listeners))
227
+ wrap(ipcMain, 'once', createWrapAddListener(mainReceiveCh, listeners))
228
+ wrap(ipcMain, 'removeAllListeners', createWrapRemoveAllListeners(listeners))
229
+ wrap(ipcMain, 'removeHandler', createWrapRemoveAllListeners(handlers))
230
+ wrap(ipcMain, 'removeListener', createWrapRemoveListener(listeners))
231
+
232
+ ipcMain.once('datadog:apm:renderer:patched', event => rendererPatchedCh.publish(event))
233
+
234
+ wrapWebContents(BrowserWindow.prototype)
235
+
236
+ electron = wrapBrowserWindow(electron)
237
+ }
238
+
239
+ return electron
240
+ })
@@ -12,8 +12,8 @@ const sanitizeMiddlewareFinished = channel('datadog:express-mongo-sanitize:filte
12
12
  const propertiesToSanitize = ['body', 'params', 'headers', 'query']
13
13
 
14
14
  addHook({ name: 'express-mongo-sanitize', versions: ['>=1.0.0'] }, expressMongoSanitize => {
15
- shimmer.wrap(expressMongoSanitize, 'sanitize', sanitize => function () {
16
- const sanitizedObject = sanitize.apply(this, arguments)
15
+ shimmer.wrap(expressMongoSanitize, 'sanitize', sanitize => function (...args) {
16
+ const sanitizedObject = sanitize.apply(this, args)
17
17
 
18
18
  if (sanitizeMethodFinished.hasSubscribers) {
19
19
  sanitizeMethodFinished.publish({ sanitizedObject })
@@ -22,21 +22,21 @@ addHook({ name: 'express-mongo-sanitize', versions: ['>=1.0.0'] }, expressMongoS
22
22
  return sanitizedObject
23
23
  })
24
24
 
25
- return shimmer.wrapFunction(expressMongoSanitize, expressMongoSanitize => function () {
26
- const middleware = expressMongoSanitize.apply(this, arguments)
25
+ return shimmer.wrapFunction(expressMongoSanitize, expressMongoSanitize => function (...args) {
26
+ const middleware = expressMongoSanitize.apply(this, args)
27
27
 
28
28
  return shimmer.wrapFunction(middleware, middleware => function (req, res, next) {
29
29
  if (!sanitizeMiddlewareFinished.hasSubscribers) {
30
30
  return middleware.apply(this, arguments)
31
31
  }
32
32
 
33
- const wrappedNext = shimmer.wrapFunction(next, next => function () {
33
+ const wrappedNext = shimmer.wrapFunction(next, next => function (...args) {
34
34
  sanitizeMiddlewareFinished.publish({
35
35
  sanitizedProperties: propertiesToSanitize,
36
36
  req,
37
37
  })
38
38
 
39
- return next.apply(this, arguments)
39
+ return next.apply(this, args)
40
40
  })
41
41
 
42
42
  return middleware.call(this, req, res, wrappedNext)