dd-trace 6.10.0 → 6.12.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.
- package/LICENSE-3rdparty.csv +5 -0
- package/README.md +0 -17
- package/index.d.ts +128 -6
- package/initialize.mjs +28 -17
- package/openfeature.js +2 -2
- package/package.json +27 -23
- package/packages/datadog-esbuild/index.js +0 -34
- package/packages/datadog-instrumentations/src/anthropic.js +210 -15
- package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
- package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
- package/packages/datadog-instrumentations/src/bunyan.js +3 -16
- package/packages/datadog-instrumentations/src/cucumber.js +30 -15
- package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
- package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
- package/packages/datadog-instrumentations/src/cypress.js +2 -0
- package/packages/datadog-instrumentations/src/fastify.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +9 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
- package/packages/datadog-instrumentations/src/jest.js +25 -17
- package/packages/datadog-instrumentations/src/mariadb.js +278 -21
- package/packages/datadog-instrumentations/src/mocha/main.js +539 -55
- package/packages/datadog-instrumentations/src/mocha/utils.js +135 -19
- package/packages/datadog-instrumentations/src/playwright-reporter.js +247 -0
- package/packages/datadog-instrumentations/src/playwright.js +182 -35
- package/packages/datadog-instrumentations/src/router.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +6 -8
- package/packages/datadog-instrumentations/src/vitest-main.js +11 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -8
- package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
- package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
- package/packages/datadog-plugin-bunyan/src/index.js +5 -8
- package/packages/datadog-plugin-cucumber/src/index.js +11 -0
- package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
- package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +81 -29
- package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
- package/packages/datadog-plugin-cypress/src/index.js +12 -6
- package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
- package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
- package/packages/datadog-plugin-electron/src/index.js +2 -0
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +6 -0
- package/packages/datadog-plugin-mocha/src/index.js +56 -1
- package/packages/datadog-plugin-nats/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +41 -30
- package/packages/datadog-plugin-openai-agents/src/integration.js +1 -0
- package/packages/datadog-plugin-playwright/src/index.js +46 -13
- package/packages/datadog-plugin-vitest/src/index.js +6 -0
- package/packages/datadog-webpack/index.js +0 -11
- package/packages/dd-trace/index.js +0 -1
- package/packages/dd-trace/src/agent/info.js +6 -5
- package/packages/dd-trace/src/aiguard/client.js +100 -1
- package/packages/dd-trace/src/aiguard/errors.js +41 -0
- package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
- package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
- package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
- package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
- package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
- package/packages/dd-trace/src/aiguard/sdk.js +22 -278
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
- package/packages/dd-trace/src/appsec/reporter.js +2 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +13 -0
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -0
- package/packages/dd-trace/src/appsec/telemetry/waf.js +24 -0
- package/packages/dd-trace/src/carrier.js +107 -48
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +5 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +29 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +27 -9
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +26 -8
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +10 -4
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +5 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
- package/packages/dd-trace/src/config/index.js +13 -2
- package/packages/dd-trace/src/config/major-overrides.js +7 -0
- package/packages/dd-trace/src/config/supported-configurations.json +14 -0
- package/packages/dd-trace/src/datastreams/index.js +2 -0
- package/packages/dd-trace/src/datastreams/manager.js +9 -2
- package/packages/dd-trace/src/datastreams/processor.js +15 -13
- package/packages/dd-trace/src/datastreams/size.js +5 -0
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +5 -11
- package/packages/dd-trace/src/debugger/index.js +4 -2
- package/packages/dd-trace/src/debugger/inspect-segment.js +154 -0
- package/packages/dd-trace/src/evp_proxy/constants.js +8 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +64 -0
- package/packages/dd-trace/src/evp_proxy/discovery.js +133 -0
- package/packages/dd-trace/src/evp_proxy/path.js +22 -0
- package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
- package/packages/dd-trace/src/exporters/common/request.js +5 -2
- package/packages/dd-trace/src/exporters/common/writer.js +11 -6
- package/packages/dd-trace/src/llmobs/experiments/client.js +167 -5
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +484 -92
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +302 -29
- package/packages/dd-trace/src/llmobs/experiments/index.js +75 -64
- package/packages/dd-trace/src/llmobs/experiments/noop.js +135 -7
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +101 -9
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
- package/packages/dd-trace/src/noop/proxy.js +3 -4
- package/packages/dd-trace/src/openfeature/constants/constants.js +0 -18
- package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
- package/packages/dd-trace/src/openfeature/index.js +7 -4
- package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/base.js +153 -11
- package/packages/dd-trace/src/openfeature/writers/exposures.js +62 -14
- package/packages/dd-trace/src/openfeature/writers/util.js +97 -15
- package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +22 -13
- package/packages/dd-trace/src/opentracing/tracer.js +5 -2
- package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
- package/packages/dd-trace/src/plugin_manager.js +3 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/jest.js +4 -3
- package/packages/dd-trace/src/plugins/util/test.js +9 -9
- package/packages/dd-trace/src/plugins/util/web.js +3 -0
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
- package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
- package/packages/dd-trace/src/proxy.js +38 -29
- package/packages/dd-trace/src/ritm.js +9 -2
- package/packages/dd-trace/src/serverless.js +37 -0
- package/packages/dd-trace/src/span_format.js +1 -0
- package/packages/dd-trace/src/span_stats.js +30 -3
- package/packages/dd-trace/src/storage-channels.js +86 -0
- package/packages/dd-trace/src/telemetry/metrics.js +62 -8
- package/packages/dd-trace/src/telemetry/send-data.js +1 -0
- package/packages/dd-trace/src/tracer.js +9 -2
- package/packages/dd-trace/src/tracer_metadata.js +14 -1
- package/packages/dd-trace/src/web-tags-cache.js +132 -0
- package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/https-proxy-agent/LICENSE +22 -0
- package/vendor/dist/https-proxy-agent/index.js +4 -0
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/proxy-from-env/LICENSE +20 -0
- package/vendor/dist/proxy-from-env/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
- package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
- package/packages/dd-trace/src/feature-registry.js +0 -29
- package/packages/dd-trace/src/openfeature/register.js +0 -35
- package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
|
@@ -7,9 +7,18 @@ const { pathToFileURL } = require('url')
|
|
|
7
7
|
|
|
8
8
|
const log = require('../../dd-trace/src/log')
|
|
9
9
|
const { getSegment } = require('../../dd-trace/src/util')
|
|
10
|
+
const {
|
|
11
|
+
finalizeAfterUserHandlers,
|
|
12
|
+
manualPluginOwner,
|
|
13
|
+
runUserHandler,
|
|
14
|
+
} = require('../../datadog-plugin-cypress/src/finalization')
|
|
10
15
|
const { channel } = require('./helpers/instrument')
|
|
11
16
|
|
|
12
17
|
const DD_CONFIG_WRAPPED = Symbol.for('dd-trace.cypress.config.wrapped')
|
|
18
|
+
const DD_CYPRESS_AFTER_SPEC_HANDLER = Symbol.for('dd-trace.cypress.after-spec.handler')
|
|
19
|
+
const DD_CYPRESS_AFTER_RUN_HANDLER = Symbol.for('dd-trace.cypress.after-run.handler')
|
|
20
|
+
const DD_CYPRESS_TASK_HANDLER = Symbol.for('dd-trace.cypress.task.handler')
|
|
21
|
+
const DD_CYPRESS_NOOP_TASK_HANDLER = Symbol.for('dd-trace.cypress.noop-task.handler')
|
|
13
22
|
const BROWSER_INSTRUMENTATION_NOT_INSTALLED =
|
|
14
23
|
'Browser-side Cypress Test Optimization instrumentation was not installed.'
|
|
15
24
|
const CONFIG_INSTRUMENTATION_NOT_INSTALLED =
|
|
@@ -184,6 +193,47 @@ function isDatadogTaskRegistration (handler) {
|
|
|
184
193
|
typeof handler['dd:addTags'] === 'function'
|
|
185
194
|
}
|
|
186
195
|
|
|
196
|
+
/**
|
|
197
|
+
* @param {unknown} handler Cypress after:run handler
|
|
198
|
+
* @returns {boolean} whether this is the handler registered by the manual Datadog plugin
|
|
199
|
+
*/
|
|
200
|
+
function isDatadogAfterRunHandler (handler) {
|
|
201
|
+
return typeof handler === 'function' && handler[DD_CYPRESS_AFTER_RUN_HANDLER] === true
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @param {unknown} handler Cypress after:spec handler
|
|
206
|
+
* @returns {boolean} whether this is the handler registered by the manual Datadog plugin
|
|
207
|
+
*/
|
|
208
|
+
function isDatadogAfterSpecHandler (handler) {
|
|
209
|
+
return typeof handler === 'function' && handler[DD_CYPRESS_AFTER_SPEC_HANDLER] === true
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @param {object} manualPlugin manual plugin registration state
|
|
214
|
+
* @returns {boolean} whether the manual plugin supports error-aware finalization
|
|
215
|
+
*/
|
|
216
|
+
function supportsErrorAwareFinalization (manualPlugin) {
|
|
217
|
+
return isDatadogAfterSpecHandler(manualPlugin.afterSpecHandler) &&
|
|
218
|
+
isDatadogAfterRunHandler(manualPlugin.afterRunHandler)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* @param {unknown} handler Cypress task handler map
|
|
223
|
+
* @returns {boolean} whether the current manual Datadog plugin owns the task map
|
|
224
|
+
*/
|
|
225
|
+
function isCurrentDatadogTaskRegistration (handler) {
|
|
226
|
+
return !!handler && handler[DD_CYPRESS_TASK_HANDLER] === manualPluginOwner
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* @param {unknown} handler Cypress task handler map
|
|
231
|
+
* @returns {boolean} whether the manual plugin registered only fallback tasks
|
|
232
|
+
*/
|
|
233
|
+
function isDatadogNoopTaskRegistration (handler) {
|
|
234
|
+
return !!handler && handler[DD_CYPRESS_NOOP_TASK_HANDLER] === true
|
|
235
|
+
}
|
|
236
|
+
|
|
187
237
|
/**
|
|
188
238
|
* @param {unknown} value
|
|
189
239
|
* @returns {boolean}
|
|
@@ -393,15 +443,61 @@ function registerManualAfterScreenshotHandlers (on, handlers, datadogHandler) {
|
|
|
393
443
|
*
|
|
394
444
|
* @param {Function} on Cypress event registration function
|
|
395
445
|
* @param {Function[]} handlers collected after:spec handlers
|
|
446
|
+
* @param {Function} [datadogHandler] manual Datadog after:spec handler
|
|
447
|
+
* @param {Function} [cleanup] removes generated support files after an error
|
|
396
448
|
* @returns {void}
|
|
397
449
|
*/
|
|
398
|
-
function registerAfterSpecHandlers (on, handlers) {
|
|
399
|
-
|
|
450
|
+
function registerAfterSpecHandlers (on, handlers, datadogHandler, cleanup) {
|
|
451
|
+
const userHandlers = datadogHandler
|
|
452
|
+
? handlers.filter(handler => handler !== datadogHandler)
|
|
453
|
+
: handlers
|
|
400
454
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
455
|
+
if (userHandlers.length === 0) {
|
|
456
|
+
if (datadogHandler) {
|
|
457
|
+
if (cleanup) {
|
|
458
|
+
on('after:spec', (...args) => Promise.resolve().then(() => datadogHandler(...args)).catch((error) => {
|
|
459
|
+
cleanup()
|
|
460
|
+
throw error
|
|
461
|
+
}))
|
|
462
|
+
} else {
|
|
463
|
+
on('after:spec', datadogHandler)
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
on('after:spec', (spec, results) => {
|
|
470
|
+
const callHandler = datadogHandler
|
|
471
|
+
? handler => runUserHandler(() => handler(spec, results))
|
|
472
|
+
: handler => handler(spec, results)
|
|
473
|
+
const chain = userHandlers.reduce(
|
|
474
|
+
(promise, handler) => promise.then(() => callHandler(handler)),
|
|
475
|
+
Promise.resolve()
|
|
476
|
+
)
|
|
477
|
+
if (!datadogHandler) return chain
|
|
478
|
+
const finalization = finalizeAfterUserHandlers(chain, (...args) => datadogHandler(spec, results, ...args))
|
|
479
|
+
if (!cleanup) return finalization
|
|
480
|
+
return finalization.catch((error) => {
|
|
481
|
+
cleanup()
|
|
482
|
+
throw error
|
|
483
|
+
})
|
|
484
|
+
})
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Enables the Cypress lifecycle events needed to finish Test Optimization
|
|
489
|
+
* sessions in interactive mode.
|
|
490
|
+
*
|
|
491
|
+
* @param {object} config Cypress resolved config object
|
|
492
|
+
* @returns {void}
|
|
493
|
+
*/
|
|
494
|
+
function enableInteractiveRunEvents (config) {
|
|
495
|
+
if (config.isInteractive && config.experimentalInteractiveRunEvents !== true) {
|
|
496
|
+
config.experimentalInteractiveRunEvents = true
|
|
497
|
+
log.warn(
|
|
498
|
+
'Datadog enabled Cypress experimentalInteractiveRunEvents so Test Optimization can finish the test session.'
|
|
499
|
+
)
|
|
500
|
+
}
|
|
405
501
|
}
|
|
406
502
|
|
|
407
503
|
/**
|
|
@@ -412,6 +508,7 @@ function registerAfterSpecHandlers (on, handlers) {
|
|
|
412
508
|
*
|
|
413
509
|
* @param {Function} on Cypress event registration function
|
|
414
510
|
* @param {object} config Cypress resolved config object
|
|
511
|
+
* @param {Function[]} userBeforeRunHandlers user's before:run handlers collected from wrappedOn
|
|
415
512
|
* @param {Function[]} userAfterSpecHandlers user's after:spec handlers collected from wrappedOn
|
|
416
513
|
* @param {Function[]} userAfterRunHandlers user's after:run handlers collected from wrappedOn
|
|
417
514
|
* @param {Function[]} userAfterScreenshotHandlers user's after:screenshot handlers collected from wrappedOn
|
|
@@ -421,6 +518,7 @@ function registerAfterSpecHandlers (on, handlers) {
|
|
|
421
518
|
function registerDdTraceHooks (
|
|
422
519
|
on,
|
|
423
520
|
config,
|
|
521
|
+
userBeforeRunHandlers,
|
|
424
522
|
userAfterSpecHandlers,
|
|
425
523
|
userAfterRunHandlers,
|
|
426
524
|
userAfterScreenshotHandlers,
|
|
@@ -433,13 +531,23 @@ function registerDdTraceHooks (
|
|
|
433
531
|
if (generatedSupportFiles) cleanupGeneratedFiles(generatedSupportFiles)
|
|
434
532
|
}
|
|
435
533
|
|
|
436
|
-
const registerAfterRunWithCleanup = () => {
|
|
534
|
+
const registerAfterRunWithCleanup = (datadogHandler) => {
|
|
535
|
+
const handlers = datadogHandler
|
|
536
|
+
? userAfterRunHandlers.filter(handler => handler !== datadogHandler)
|
|
537
|
+
: userAfterRunHandlers
|
|
538
|
+
|
|
437
539
|
on('after:run', (results) => {
|
|
438
|
-
const
|
|
439
|
-
|
|
540
|
+
const callHandler = datadogHandler
|
|
541
|
+
? handler => runUserHandler(() => handler(results))
|
|
542
|
+
: handler => handler(results)
|
|
543
|
+
const chain = handlers.reduce(
|
|
544
|
+
(promise, handler) => promise.then(() => callHandler(handler)),
|
|
440
545
|
Promise.resolve()
|
|
441
546
|
)
|
|
442
|
-
return chain.finally(cleanupWrapper)
|
|
547
|
+
if (!datadogHandler) return chain.finally(cleanupWrapper)
|
|
548
|
+
|
|
549
|
+
return finalizeAfterUserHandlers(chain, (...args) => datadogHandler(results, ...args))
|
|
550
|
+
.finally(cleanupWrapper)
|
|
443
551
|
})
|
|
444
552
|
}
|
|
445
553
|
|
|
@@ -450,13 +558,36 @@ function registerDdTraceHooks (
|
|
|
450
558
|
on('task', noopTask)
|
|
451
559
|
}
|
|
452
560
|
|
|
453
|
-
if (manualPlugin.detected
|
|
454
|
-
|
|
561
|
+
if (manualPlugin.detected &&
|
|
562
|
+
(manualPlugin.isNoop ||
|
|
563
|
+
manualPlugin.ownsCurrentPlugin ||
|
|
564
|
+
supportsErrorAwareFinalization(manualPlugin) ||
|
|
565
|
+
!setupNodeEventsCh.hasSubscribers)) {
|
|
566
|
+
if (manualPlugin.afterRunHandler) {
|
|
567
|
+
enableInteractiveRunEvents(config)
|
|
568
|
+
if (manualPlugin.initialConfig !== config) {
|
|
569
|
+
manualPlugin.initialConfig.experimentalInteractiveRunEvents = config.experimentalInteractiveRunEvents
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
for (const handler of userBeforeRunHandlers) on('before:run', handler)
|
|
573
|
+
registerAfterSpecHandlers(on, userAfterSpecHandlers, manualPlugin.afterSpecHandler, cleanupWrapper)
|
|
455
574
|
registerManualAfterScreenshotHandlers(on, userAfterScreenshotHandlers, manualPlugin.afterScreenshotHandler)
|
|
456
|
-
registerAfterRunWithCleanup()
|
|
575
|
+
registerAfterRunWithCleanup(manualPlugin.afterRunHandler)
|
|
576
|
+
on('task', manualPlugin.taskHandler)
|
|
457
577
|
return config
|
|
458
578
|
}
|
|
459
579
|
|
|
580
|
+
if (manualPlugin.detected) {
|
|
581
|
+
userBeforeRunHandlers = userBeforeRunHandlers.filter(handler => handler !== manualPlugin.beforeRunHandler)
|
|
582
|
+
userAfterSpecHandlers = userAfterSpecHandlers.filter(handler => handler !== manualPlugin.afterSpecHandler)
|
|
583
|
+
userAfterRunHandlers = userAfterRunHandlers.filter(handler => handler !== manualPlugin.afterRunHandler)
|
|
584
|
+
userAfterScreenshotHandlers = userAfterScreenshotHandlers.filter(
|
|
585
|
+
handler => handler !== manualPlugin.afterScreenshotHandler
|
|
586
|
+
)
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
for (const handler of userBeforeRunHandlers) on('before:run', handler)
|
|
590
|
+
|
|
460
591
|
if (!setupNodeEventsCh.hasSubscribers) {
|
|
461
592
|
registerNoopHandlers()
|
|
462
593
|
return config
|
|
@@ -483,6 +614,7 @@ function registerDdTraceHooks (
|
|
|
483
614
|
return config
|
|
484
615
|
}
|
|
485
616
|
|
|
617
|
+
enableInteractiveRunEvents(config)
|
|
486
618
|
return payload.configPromise || config
|
|
487
619
|
}
|
|
488
620
|
|
|
@@ -492,28 +624,60 @@ function registerDdTraceHooks (
|
|
|
492
624
|
*/
|
|
493
625
|
function wrapSetupNodeEvents (originalSetupNodeEvents) {
|
|
494
626
|
return function ddSetupNodeEvents (on, config) {
|
|
627
|
+
const userBeforeRunHandlers = []
|
|
495
628
|
const userAfterSpecHandlers = []
|
|
496
629
|
const userAfterRunHandlers = []
|
|
497
630
|
const userAfterScreenshotHandlers = []
|
|
498
631
|
const manualPlugin = {
|
|
499
632
|
detected: false,
|
|
633
|
+
initialConfig: config,
|
|
634
|
+
beforeRunHandler: undefined,
|
|
635
|
+
afterSpecHandler: undefined,
|
|
636
|
+
afterRunHandler: undefined,
|
|
500
637
|
afterScreenshotHandler: undefined,
|
|
638
|
+
taskHandler: undefined,
|
|
639
|
+
ownsCurrentPlugin: false,
|
|
640
|
+
isNoop: false,
|
|
501
641
|
}
|
|
642
|
+
const recentRegistrations = []
|
|
502
643
|
|
|
503
644
|
const wrappedOn = (event, handler) => {
|
|
504
|
-
if (event === '
|
|
645
|
+
if (event === 'before:run') {
|
|
646
|
+
userBeforeRunHandlers.push(handler)
|
|
647
|
+
} else if (event === 'after:spec') {
|
|
505
648
|
userAfterSpecHandlers.push(handler)
|
|
649
|
+
if (isDatadogAfterSpecHandler(handler)) manualPlugin.afterSpecHandler = handler
|
|
506
650
|
} else if (event === 'after:run') {
|
|
507
651
|
userAfterRunHandlers.push(handler)
|
|
652
|
+
if (isDatadogAfterRunHandler(handler)) manualPlugin.afterRunHandler = handler
|
|
508
653
|
} else if (event === 'after:screenshot') {
|
|
509
654
|
userAfterScreenshotHandlers.push(handler)
|
|
510
655
|
} else {
|
|
511
656
|
if (event === 'task' && isDatadogTaskRegistration(handler)) {
|
|
512
657
|
manualPlugin.detected = true
|
|
513
|
-
manualPlugin.
|
|
658
|
+
manualPlugin.ownsCurrentPlugin = isCurrentDatadogTaskRegistration(handler)
|
|
659
|
+
manualPlugin.isNoop = isDatadogNoopTaskRegistration(handler)
|
|
660
|
+
const afterRun = recentRegistrations.at(-1)
|
|
661
|
+
const afterSpec = recentRegistrations.at(-2)
|
|
662
|
+
const possibleAfterScreenshot = recentRegistrations.at(-3)
|
|
663
|
+
const hasAfterScreenshot = possibleAfterScreenshot?.event === 'after:screenshot'
|
|
664
|
+
const beforeRun = hasAfterScreenshot ? recentRegistrations.at(-4) : possibleAfterScreenshot
|
|
665
|
+
if (!manualPlugin.isNoop &&
|
|
666
|
+
beforeRun?.event === 'before:run' &&
|
|
667
|
+
afterSpec?.event === 'after:spec' &&
|
|
668
|
+
afterRun?.event === 'after:run') {
|
|
669
|
+
manualPlugin.beforeRunHandler ||= beforeRun.handler
|
|
670
|
+
manualPlugin.afterSpecHandler ||= afterSpec.handler
|
|
671
|
+
manualPlugin.afterRunHandler ||= afterRun.handler
|
|
672
|
+
if (hasAfterScreenshot) manualPlugin.afterScreenshotHandler ||= possibleAfterScreenshot.handler
|
|
673
|
+
}
|
|
674
|
+
manualPlugin.taskHandler = handler
|
|
675
|
+
} else {
|
|
676
|
+
on(event, handler)
|
|
514
677
|
}
|
|
515
|
-
on(event, handler)
|
|
516
678
|
}
|
|
679
|
+
recentRegistrations.push({ event, handler })
|
|
680
|
+
if (recentRegistrations.length > 4) recentRegistrations.shift()
|
|
517
681
|
}
|
|
518
682
|
|
|
519
683
|
const maybePromise = originalSetupNodeEvents
|
|
@@ -525,6 +689,7 @@ function wrapSetupNodeEvents (originalSetupNodeEvents) {
|
|
|
525
689
|
return registerDdTraceHooks(
|
|
526
690
|
on,
|
|
527
691
|
mergeReturnedConfig(config, result),
|
|
692
|
+
userBeforeRunHandlers,
|
|
528
693
|
userAfterSpecHandlers,
|
|
529
694
|
userAfterRunHandlers,
|
|
530
695
|
userAfterScreenshotHandlers,
|
|
@@ -536,6 +701,7 @@ function wrapSetupNodeEvents (originalSetupNodeEvents) {
|
|
|
536
701
|
return registerDdTraceHooks(
|
|
537
702
|
on,
|
|
538
703
|
mergeReturnedConfig(config, maybePromise),
|
|
704
|
+
userBeforeRunHandlers,
|
|
539
705
|
userAfterSpecHandlers,
|
|
540
706
|
userAfterRunHandlers,
|
|
541
707
|
userAfterScreenshotHandlers,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { shouldDeferLegacyFinalization } = require('../../datadog-plugin-cypress/src/finalization')
|
|
4
|
+
const Hook = require('./helpers/hook')
|
|
5
|
+
|
|
6
|
+
const DD_CYPRESS_LEGACY_FINALIZER_WRAPPED = Symbol.for('dd-trace.cypress.legacy-finalizer.wrapped')
|
|
7
|
+
const LEGACY_FINALIZER_MODULES = new Set([
|
|
8
|
+
'dd-trace/packages/datadog-plugin-cypress/src/after-run.js',
|
|
9
|
+
'dd-trace/packages/datadog-plugin-cypress/src/after-spec.js',
|
|
10
|
+
])
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {Function} finalizer standalone Datadog Cypress finalizer
|
|
14
|
+
* @returns {Function} context-aware finalizer
|
|
15
|
+
*/
|
|
16
|
+
function wrapLegacyFinalizer (finalizer) {
|
|
17
|
+
if (finalizer[DD_CYPRESS_LEGACY_FINALIZER_WRAPPED]) return finalizer
|
|
18
|
+
|
|
19
|
+
function wrappedLegacyFinalizer () {
|
|
20
|
+
if (shouldDeferLegacyFinalization()) return
|
|
21
|
+
return finalizer.apply(this, arguments)
|
|
22
|
+
}
|
|
23
|
+
wrappedLegacyFinalizer[DD_CYPRESS_LEGACY_FINALIZER_WRAPPED] = true
|
|
24
|
+
return wrappedLegacyFinalizer
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Hook(['dd-trace'], { internals: true }, (moduleExports, moduleName) => {
|
|
28
|
+
if (!LEGACY_FINALIZER_MODULES.has(moduleName.replaceAll('\\', '/'))) return moduleExports
|
|
29
|
+
return wrapLegacyFinalizer(moduleExports)
|
|
30
|
+
})
|
|
@@ -146,6 +146,7 @@ function wrapHookDone (ctx, request, reply, req, name, doneCallback) {
|
|
|
146
146
|
ctx.error = error
|
|
147
147
|
publishError(ctx)
|
|
148
148
|
|
|
149
|
+
// eslint-disable-next-line no-restricted-syntax -- arbitrary cookie names; publishing {} sets a WAF address
|
|
149
150
|
const hasCookies = request.cookies && Object.keys(request.cookies).length > 0
|
|
150
151
|
|
|
151
152
|
if (cookieParserReadCh.hasSubscribers && hasCookies && !cookiesPublished.has(req)) {
|
|
@@ -193,6 +194,7 @@ function preHandler (request, reply, done) {
|
|
|
193
194
|
const res = getRes(reply)
|
|
194
195
|
const ctx = { req, res }
|
|
195
196
|
|
|
197
|
+
// eslint-disable-next-line no-restricted-syntax -- arbitrary body keys; publishing {} sets a WAF address
|
|
196
198
|
const hasBody = request.body && Object.keys(request.body).length > 0
|
|
197
199
|
|
|
198
200
|
// For multipart/form-data, the body is not available until after preValidation hook
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../../datadog-shimmer')
|
|
4
|
+
const { channel } = require('./instrument')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {{ prototype: object }} Logger
|
|
8
|
+
* @param {string} id
|
|
9
|
+
*/
|
|
10
|
+
module.exports = function wrapLogger (Logger, id) {
|
|
11
|
+
const logCh = channel(`apm:${id}:log`)
|
|
12
|
+
shimmer.wrap(Logger.prototype, '_emit', emit => {
|
|
13
|
+
return function wrappedEmit (rec) {
|
|
14
|
+
if (logCh.hasSubscribers) {
|
|
15
|
+
const payload = { message: rec }
|
|
16
|
+
logCh.publish(payload)
|
|
17
|
+
arguments[0] = payload.message
|
|
18
|
+
}
|
|
19
|
+
return emit.apply(this, arguments)
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
}
|
|
@@ -70,6 +70,7 @@ module.exports = {
|
|
|
70
70
|
'aws-sdk': () => require('../aws-sdk'),
|
|
71
71
|
bluebird: () => require('../bluebird'),
|
|
72
72
|
'body-parser': () => require('../body-parser'),
|
|
73
|
+
'browser-bunyan': () => require('../browser-bunyan'),
|
|
73
74
|
bullmq: () => require('../bullmq'),
|
|
74
75
|
bunyan: () => require('../bunyan'),
|
|
75
76
|
'cassandra-driver': () => require('../cassandra-driver'),
|
|
@@ -110,7 +111,7 @@ module.exports = {
|
|
|
110
111
|
'light-my-request': () => require('../light-my-request'),
|
|
111
112
|
'limitd-client': () => require('../limitd-client'),
|
|
112
113
|
lodash: () => require('../lodash'),
|
|
113
|
-
mariadb: () => require('../mariadb'),
|
|
114
|
+
mariadb: { esmFirst: true, fn: () => require('../mariadb') },
|
|
114
115
|
memcached: () => require('../memcached'),
|
|
115
116
|
mercurius: () => require('../mercurius'),
|
|
116
117
|
'microgateway-core': () => require('../microgateway-core'),
|
|
@@ -518,10 +518,11 @@ function runPoolQueryConnectionCallback (
|
|
|
518
518
|
* @param {unknown} error
|
|
519
519
|
* @param {Record<string, unknown>} acquireCtx
|
|
520
520
|
* @param {AcquireErrorChannels} channels
|
|
521
|
+
* @param {number} [poolWaitTime]
|
|
521
522
|
*/
|
|
522
|
-
function reportPoolAcquireError (start, error, acquireCtx, channels) {
|
|
523
|
+
function reportPoolAcquireError (start, error, acquireCtx, channels, poolWaitTime) {
|
|
523
524
|
acquireCtx.error = error
|
|
524
|
-
acquireCtx.poolWaitTime = acquireWait(start)
|
|
525
|
+
acquireCtx.poolWaitTime = poolWaitTime ?? acquireWait(start)
|
|
525
526
|
if (start !== undefined) acquireCtx.startTime = performance.timeOrigin + start
|
|
526
527
|
channels.acquireStartCh.publish(acquireCtx)
|
|
527
528
|
channels.acquireFinishCh.publish(acquireCtx)
|
|
@@ -536,11 +537,14 @@ function reportPoolAcquireError (start, error, acquireCtx, channels) {
|
|
|
536
537
|
* @param {Function} callback
|
|
537
538
|
* @param {unknown} thisArg
|
|
538
539
|
* @param {ArgumentsLike} args
|
|
540
|
+
* @param {number} [poolWaitTime]
|
|
539
541
|
* @returns {unknown}
|
|
540
542
|
*/
|
|
541
|
-
function runPoolAcquireError (
|
|
543
|
+
function runPoolAcquireError (
|
|
544
|
+
start, error, acquireCtx, channels, connectionCtx, callback, thisArg, args, poolWaitTime
|
|
545
|
+
) {
|
|
542
546
|
return channels.connectionFinishCh.runStores(connectionCtx, () => {
|
|
543
|
-
reportPoolAcquireError(start, error, acquireCtx, channels)
|
|
547
|
+
reportPoolAcquireError(start, error, acquireCtx, channels, poolWaitTime)
|
|
544
548
|
return callback.apply(thisArg, args)
|
|
545
549
|
})
|
|
546
550
|
}
|
|
@@ -613,6 +617,7 @@ function takeClusterAcquire (key) {
|
|
|
613
617
|
}
|
|
614
618
|
|
|
615
619
|
module.exports = {
|
|
620
|
+
acquireWait,
|
|
616
621
|
clearPoolWaitTime,
|
|
617
622
|
dispatchesAcquireSynchronously,
|
|
618
623
|
isPoolQueryAcquire,
|
|
@@ -112,14 +112,6 @@ for (const name of names) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
for (const { file, versions, hook, filePattern, patchDefault } of instrumentations[name]) {
|
|
115
|
-
if (isIitm && patchDefault === !!moduleExports.default) {
|
|
116
|
-
if (patchDefault) {
|
|
117
|
-
moduleExports = moduleExports.default
|
|
118
|
-
} else {
|
|
119
|
-
return moduleExports
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
115
|
const fullFilename = filename(name, file)
|
|
124
116
|
|
|
125
117
|
let matchesFile = moduleName === fullFilename
|
|
@@ -134,6 +126,16 @@ for (const name of names) {
|
|
|
134
126
|
}
|
|
135
127
|
|
|
136
128
|
if (matchesFile && matchVersion(moduleVersion, versions)) {
|
|
129
|
+
// IITM invokes this callback for every module in the package. Only unwrap the namespace after its file and
|
|
130
|
+
// version match, otherwise a default export from an unrelated internal module can replace that module.
|
|
131
|
+
if (isIitm && patchDefault === !!moduleExports.default) {
|
|
132
|
+
if (patchDefault) {
|
|
133
|
+
moduleExports = moduleExports.default
|
|
134
|
+
} else {
|
|
135
|
+
return moduleExports
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
137
139
|
// Do not log in case of an error to prevent duplicate telemetry for the same integration version.
|
|
138
140
|
instrumentedIntegrationsSuccess.set(`${name}@${moduleVersion}`, true)
|
|
139
141
|
try {
|
|
@@ -97,7 +97,9 @@ const itrSkippedSuitesCh = channel('ci:jest:itr:skipped-suites')
|
|
|
97
97
|
const CHILD_MESSAGE_CALL = 1
|
|
98
98
|
|
|
99
99
|
// Maximum time we'll wait for the tracer to flush
|
|
100
|
-
|
|
100
|
+
// The exporter has a 10-second bounded final-flush deadline. Leave enough time
|
|
101
|
+
// for its completion callback before Jest's --forceExit fallback takes over.
|
|
102
|
+
const FLUSH_TIMEOUT = 12_000
|
|
101
103
|
const JEST_SESSION_STATE = Symbol.for('dd-trace:jest:session')
|
|
102
104
|
const JEST_BAIL_REPORTER_PATH = require.resolve('./jest/bail-reporter')
|
|
103
105
|
const DD_JEST_HANDLE_TEST_EVENT_WRAPPED = Symbol('dd-trace:jest:handle-test-event-wrapped')
|
|
@@ -110,7 +112,7 @@ const jestSessionState = (globalThis[JEST_SESSION_STATE] ||= {})
|
|
|
110
112
|
const RETRY_TIMES = Symbol.for('RETRY_TIMES')
|
|
111
113
|
|
|
112
114
|
let skippableSuites = []
|
|
113
|
-
let skippableSuitesCoverage
|
|
115
|
+
let skippableSuitesCoverage
|
|
114
116
|
let skippedSuitesCoverage = {}
|
|
115
117
|
let knownTests = {}
|
|
116
118
|
let isCodeCoverageEnabled = false
|
|
@@ -131,7 +133,7 @@ let isTestManagementTestsEnabled = false
|
|
|
131
133
|
let testManagementTests = {}
|
|
132
134
|
let testManagementAttemptToFixRetries = 0
|
|
133
135
|
let isImpactedTestsEnabled = false
|
|
134
|
-
let modifiedFiles
|
|
136
|
+
let modifiedFiles
|
|
135
137
|
let repositoryRoot
|
|
136
138
|
let lastCoverageMap
|
|
137
139
|
let lastCoverageMapRootDir
|
|
@@ -688,8 +690,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
688
690
|
|
|
689
691
|
if (this.isImpactedTestsEnabled) {
|
|
690
692
|
try {
|
|
691
|
-
|
|
692
|
-
this.modifiedFiles = hasImpactedTests ? modifiedFiles : this.testEnvironmentOptions._ddModifiedFiles
|
|
693
|
+
this.modifiedFiles = modifiedFiles ?? this.testEnvironmentOptions._ddModifiedFiles
|
|
693
694
|
} catch (e) {
|
|
694
695
|
log.error('Error parsing impacted tests', e)
|
|
695
696
|
this.isImpactedTestsEnabled = false
|
|
@@ -2489,12 +2490,6 @@ function getRepositoryRootFromTest (test, fallbackRootDir) {
|
|
|
2489
2490
|
return getRepositoryRootFromConfig(test?.context?.config, fallbackRootDir)
|
|
2490
2491
|
}
|
|
2491
2492
|
|
|
2492
|
-
function hasSkippableSuitesCoverage () {
|
|
2493
|
-
return skippableSuitesCoverage &&
|
|
2494
|
-
typeof skippableSuitesCoverage === 'object' &&
|
|
2495
|
-
Object.keys(skippableSuitesCoverage).length > 0
|
|
2496
|
-
}
|
|
2497
|
-
|
|
2498
2493
|
function shouldCollectJestCoverageForTia () {
|
|
2499
2494
|
return shouldReportJestSuiteCoverageForTia() ||
|
|
2500
2495
|
(isJestCoverageBackfillSupported && isItrEnabled && isCoverageReportUploadEnabled)
|
|
@@ -2605,7 +2600,7 @@ function resetLibraryConfiguration () {
|
|
|
2605
2600
|
testManagementTests = {}
|
|
2606
2601
|
testManagementAttemptToFixRetries = 0
|
|
2607
2602
|
isImpactedTestsEnabled = false
|
|
2608
|
-
modifiedFiles =
|
|
2603
|
+
modifiedFiles = undefined
|
|
2609
2604
|
repositoryRoot = undefined
|
|
2610
2605
|
}
|
|
2611
2606
|
|
|
@@ -2627,13 +2622,14 @@ function applySuiteSkipping (originalTests, rootDir, frameworkVersion) {
|
|
|
2627
2622
|
|
|
2628
2623
|
isSuitesSkipped ||= jestSuitesToRun.suitesToRun.length !== originalTests.length
|
|
2629
2624
|
numSkippedSuites += jestSuitesToRun.skippedSuites.length
|
|
2630
|
-
|
|
2625
|
+
const hasSkippableSuitesCoverage = skippableSuitesCoverage !== undefined
|
|
2626
|
+
skippedSuitesCoverage = isSuitesSkipped && isTiaCoverageBackfillEnabled() && hasSkippableSuitesCoverage
|
|
2631
2627
|
? skippableSuitesCoverage
|
|
2632
2628
|
: {}
|
|
2633
2629
|
coverageBackfillContexts = isSuitesSkipped && isTiaCoverageBackfillEnabled()
|
|
2634
2630
|
? getTestContexts(originalTests)
|
|
2635
2631
|
: undefined
|
|
2636
|
-
coverageBackfillFiles = isSuitesSkipped && isTiaCoverageBackfillEnabled() && hasSkippableSuitesCoverage
|
|
2632
|
+
coverageBackfillFiles = isSuitesSkipped && isTiaCoverageBackfillEnabled() && hasSkippableSuitesCoverage
|
|
2637
2633
|
? getCoverageBackfillFiles(skippableSuitesCoverage, repositoryRoot, getTestSuitePath)
|
|
2638
2634
|
: undefined
|
|
2639
2635
|
|
|
@@ -3022,10 +3018,10 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
3022
3018
|
skippableSuitesCoverage: receivedSkippableSuitesCoverage,
|
|
3023
3019
|
} = skippableSuitesResponse || await getChannelPromise(skippableSuitesCh)
|
|
3024
3020
|
if (err) {
|
|
3025
|
-
skippableSuitesCoverage =
|
|
3021
|
+
skippableSuitesCoverage = undefined
|
|
3026
3022
|
} else {
|
|
3027
3023
|
skippableSuites = receivedSkippableSuites
|
|
3028
|
-
skippableSuitesCoverage = receivedSkippableSuitesCoverage
|
|
3024
|
+
skippableSuitesCoverage = receivedSkippableSuitesCoverage
|
|
3029
3025
|
}
|
|
3030
3026
|
skippedSuitesCoverage = {}
|
|
3031
3027
|
} catch (err) {
|
|
@@ -3066,7 +3062,19 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
3066
3062
|
frameworkVersion: jestVersion,
|
|
3067
3063
|
})
|
|
3068
3064
|
|
|
3069
|
-
|
|
3065
|
+
let result
|
|
3066
|
+
try {
|
|
3067
|
+
result = await runCLI.apply(this, arguments)
|
|
3068
|
+
} catch (error) {
|
|
3069
|
+
try {
|
|
3070
|
+
await waitForTestSessionFinish(getTestSessionFinishPayload('fail', error, {
|
|
3071
|
+
isTestSessionFinalizationError: true,
|
|
3072
|
+
}))
|
|
3073
|
+
} catch (finalizationError) {
|
|
3074
|
+
log.error('Jest test session finalization error: %s', finalizationError)
|
|
3075
|
+
}
|
|
3076
|
+
throw error
|
|
3077
|
+
}
|
|
3070
3078
|
|
|
3071
3079
|
const {
|
|
3072
3080
|
results: {
|