dd-trace 5.124.0 → 5.126.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 +3 -1
- package/ci/init.js +8 -3
- package/ci/test-optimization-validation/ci-package-scripts.js +2 -2
- package/ci/test-optimization-validation/ci-remediation.js +6 -6
- package/ci/test-optimization-validation/command-blocker.js +7 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +1 -1
- package/ci/test-optimization-validation/framework-adapters/vitest.js +3 -3
- package/ci/test-optimization-validation/package-check.js +1 -1
- package/ci/test-optimization-validation/report-writer.js +7 -5
- package/ci/vitest-no-worker-init-runner-setup.mjs +8 -0
- package/ci/vitest-no-worker-init-setup.mjs +13 -13
- package/ci/vitest-no-worker-init-v5-setup.mjs +4 -0
- package/index.d.ts +8 -0
- package/package.json +13 -10
- package/packages/datadog-esbuild/index.js +3 -1
- package/packages/datadog-instrumentations/src/cypress-config.js +19 -17
- package/packages/datadog-instrumentations/src/fs.js +24 -20
- package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +2 -2
- package/packages/datadog-instrumentations/src/graphql.js +16 -16
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +504 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +265 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +95 -30
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +0 -25
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +83 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +85 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/mercurius.js +30 -12
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +14 -5
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +251 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +11 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +562 -27
- package/packages/datadog-instrumentations/src/jest.js +166 -45
- package/packages/datadog-instrumentations/src/knex.js +76 -0
- package/packages/datadog-instrumentations/src/mariadb.js +6 -0
- package/packages/datadog-instrumentations/src/mocha/common.js +59 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +66 -20
- package/packages/datadog-instrumentations/src/mocha/utils.js +2 -1
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +98 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -8
- package/packages/datadog-instrumentations/src/net.js +14 -17
- package/packages/datadog-instrumentations/src/next.js +212 -62
- package/packages/datadog-instrumentations/src/openai.js +42 -40
- package/packages/datadog-instrumentations/src/pg.js +15 -0
- package/packages/datadog-instrumentations/src/playwright.js +113 -13
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +40 -0
- package/packages/datadog-instrumentations/src/sequelize.js +94 -2
- package/packages/datadog-instrumentations/src/undici.js +53 -4
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +37 -3
- package/packages/datadog-instrumentations/src/vitest-main.js +92 -9
- package/packages/datadog-instrumentations/src/vitest-worker.js +71 -14
- package/packages/datadog-instrumentations/src/webdriverio.js +965 -6
- package/packages/datadog-plugin-amqp10/src/consumer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/producer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/util.js +2 -1
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +6 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +16 -5
- package/packages/datadog-plugin-cassandra-driver/src/index.js +8 -3
- package/packages/datadog-plugin-cucumber/src/index.js +0 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +262 -48
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +4 -1
- package/packages/datadog-plugin-graphql/src/execute.js +998 -196
- package/packages/datadog-plugin-graphql/src/index.js +27 -7
- package/packages/datadog-plugin-graphql/src/jit.js +136 -0
- package/packages/datadog-plugin-graphql/src/request.js +18 -27
- package/packages/datadog-plugin-graphql/src/resolve-error.js +108 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -2
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +45 -3
- package/packages/datadog-plugin-graphql/src/utils.js +208 -120
- package/packages/datadog-plugin-graphql/src/validate.js +10 -23
- package/packages/datadog-plugin-jest/src/index.js +0 -6
- package/packages/datadog-plugin-langchain/src/tracing.js +7 -0
- package/packages/datadog-plugin-mocha/src/index.js +403 -75
- package/packages/datadog-plugin-mongodb-core/src/query.js +6 -0
- package/packages/datadog-plugin-mysql/src/index.js +41 -15
- package/packages/datadog-plugin-net/src/tcp.js +3 -1
- package/packages/datadog-plugin-next/src/index.js +63 -29
- package/packages/datadog-plugin-playwright/src/index.js +167 -27
- package/packages/datadog-plugin-undici/src/index.js +27 -41
- package/packages/datadog-plugin-vitest/src/index.js +6 -12
- package/packages/dd-trace/src/aiguard/evaluation.js +2 -1
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +8 -1
- package/packages/dd-trace/src/aiguard/messages/openai.js +8 -1
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +20 -6
- package/packages/dd-trace/src/appsec/api_security/index.js +23 -6
- package/packages/dd-trace/src/appsec/api_security/sampler.js +99 -40
- package/packages/dd-trace/src/appsec/graphql.js +6 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +8 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +3 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +531 -95
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/lambda.js +44 -26
- package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +32 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +8 -8
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +20 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +5 -173
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +7 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agents.js +54 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +1 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +394 -225
- package/packages/dd-trace/src/ci-visibility/exporters/limits.js +9 -0
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +323 -31
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +42 -0
- package/packages/dd-trace/src/ci-visibility/final-flush.js +2 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +57 -18
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +0 -3
- package/packages/dd-trace/src/ci-visibility/requests/request.js +11 -0
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +164 -71
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +180 -0
- package/packages/dd-trace/src/ci-visibility/telemetry.js +10 -7
- package/packages/dd-trace/src/ci-visibility/test-video.js +61 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
- package/packages/dd-trace/src/config/index.js +73 -13
- package/packages/dd-trace/src/config/parsers.js +11 -1
- package/packages/dd-trace/src/config/stable.js +3 -3
- package/packages/dd-trace/src/config/supported-configurations.json +22 -2
- package/packages/dd-trace/src/crashtracking/crashtracker.js +82 -18
- package/packages/dd-trace/src/debugger/config.js +12 -1
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/request-options.js +28 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +7 -40
- package/packages/dd-trace/src/debugger/devtools_client/status.js +11 -6
- package/packages/dd-trace/src/debugger/devtools_client/tags.js +41 -0
- package/packages/dd-trace/src/debugger/index.js +23 -3
- package/packages/dd-trace/src/dogstatsd.js +510 -76
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +170 -0
- package/packages/dd-trace/src/encode/0.4.js +5 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -8
- package/packages/dd-trace/src/evp_proxy/direct.js +3 -25
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +24 -7
- package/packages/dd-trace/src/exporters/agentless/index.js +7 -9
- package/packages/dd-trace/src/exporters/agentless/writer.js +103 -119
- package/packages/dd-trace/src/exporters/common/agents.js +28 -6
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -2
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +191 -0
- package/packages/dd-trace/src/exporters/common/proxy.js +52 -0
- package/packages/dd-trace/src/exporters/common/request.js +42 -14
- package/packages/dd-trace/src/exporters/common/url.js +40 -1
- package/packages/dd-trace/src/exporters/common/writer.js +9 -7
- package/packages/dd-trace/src/flush.js +6 -3
- package/packages/dd-trace/src/id.js +14 -0
- package/packages/dd-trace/src/index.js +5 -2
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +2 -1
- package/packages/dd-trace/src/llmobs/index.js +32 -32
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +22 -71
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +23 -13
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +7 -0
- package/packages/dd-trace/src/llmobs/util.js +0 -33
- package/packages/dd-trace/src/llmobs/writers/base.js +49 -32
- package/packages/dd-trace/src/log/index.js +7 -1
- package/packages/dd-trace/src/{ci-visibility/log-submission → log-submission}/log-submission-plugin.js +48 -19
- package/packages/dd-trace/src/openfeature/writers/base.js +14 -12
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/index.js +5 -24
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +14 -4
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +15 -22
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +14 -4
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +10 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +5 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +19 -4
- package/packages/dd-trace/src/opentelemetry/resource-attributes.js +55 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +6 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +10 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +101 -20
- package/packages/dd-trace/src/payload-tagging/index.js +2 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -6
- package/packages/dd-trace/src/plugins/tracing.js +12 -10
- package/packages/dd-trace/src/plugins/util/ci.js +3 -1
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +16 -15
- package/packages/dd-trace/src/plugins/util/test.js +83 -20
- package/packages/dd-trace/src/plugins/util/url.js +2 -2
- package/packages/dd-trace/src/plugins/util/web.js +4 -9
- package/packages/dd-trace/src/priority_sampler.js +4 -0
- package/packages/dd-trace/src/profiling/config.js +1 -0
- package/packages/dd-trace/src/profiling/oom.js +7 -2
- package/packages/dd-trace/src/profiling/profiler.js +23 -13
- package/packages/dd-trace/src/profiling/profilers/space.js +38 -11
- package/packages/dd-trace/src/profiling/webspan-utils.js +7 -4
- package/packages/dd-trace/src/proxy.js +75 -5
- package/packages/dd-trace/src/remote_config/index.js +319 -101
- package/packages/dd-trace/src/remote_config/scheduler.js +37 -12
- package/packages/dd-trace/src/runtime_metrics/client.js +37 -8
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +5 -1
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -1
- package/packages/dd-trace/src/sampling_rule.js +39 -10
- package/packages/dd-trace/src/serverless/telemetry-delivery-tracker.js +4 -8
- package/packages/dd-trace/src/serverless/vercel.js +53 -20
- package/packages/dd-trace/src/serverless.js +10 -3
- package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
- package/packages/dd-trace/src/span_processor.js +18 -3
- package/packages/dd-trace/src/span_stats.js +24 -28
- package/packages/dd-trace/src/startup-log.js +3 -2
- package/packages/dd-trace/src/telemetry/agentless-url.js +28 -0
- package/packages/dd-trace/src/telemetry/send-data.js +23 -20
- package/packages/dd-trace/src/telemetry/session-propagation.js +3 -2
- package/packages/dd-trace/src/tracer.js +4 -5
- package/packages/dd-trace/src/tracer_metadata.js +11 -3
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +0 -27
- package/packages/dd-trace/src/encode/agentless-json.js +0 -210
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { AsyncResource } = require('node:async_hooks')
|
|
4
|
+
|
|
3
5
|
const { createCoverageMap } = require('../../../../vendor/dist/istanbul-lib-coverage')
|
|
4
6
|
const satisfies = require('../../../../vendor/dist/semifies')
|
|
5
7
|
const { DD_MAJOR } = require('../../../../version')
|
|
@@ -35,6 +37,7 @@ const {
|
|
|
35
37
|
isMarkedAsUnskippable,
|
|
36
38
|
} = require('../../../dd-trace/src/plugins/util/test')
|
|
37
39
|
|
|
40
|
+
const { addMochaRunHooks } = require('./common')
|
|
38
41
|
const {
|
|
39
42
|
isNewTest,
|
|
40
43
|
getTestProperties,
|
|
@@ -60,8 +63,6 @@ const {
|
|
|
60
63
|
adjustRunnerFailuresForTestOptimization,
|
|
61
64
|
} = require('./utils')
|
|
62
65
|
|
|
63
|
-
require('./common')
|
|
64
|
-
|
|
65
66
|
const MINIMUM_MOCHA_VERSION = DD_MAJOR >= 6 ? '>=8.0.0' : '>=5.2.0'
|
|
66
67
|
|
|
67
68
|
/**
|
|
@@ -81,6 +82,8 @@ const runnerTestEndHandlers = new WeakMap()
|
|
|
81
82
|
const runnerFailuresAdjusted = new WeakSet()
|
|
82
83
|
const runnerFrameworkErrors = new WeakMap()
|
|
83
84
|
const runnerStarted = new WeakSet()
|
|
85
|
+
const readyRunners = new WeakSet()
|
|
86
|
+
const pendingRunnerStarts = new WeakMap()
|
|
84
87
|
const runnerRecoveryStates = new WeakMap()
|
|
85
88
|
const runnersWithPendingCoverageReset = new WeakSet()
|
|
86
89
|
const parallelRunners = new WeakSet()
|
|
@@ -536,7 +539,10 @@ function stopCurrentHook (runner, hook) {
|
|
|
536
539
|
if (test) {
|
|
537
540
|
if (hook.parent?._afterEach?.includes(hook) || hook.parent?._afterAll?.includes(hook)) {
|
|
538
541
|
markTestTerminal(runner, test)
|
|
539
|
-
if (!test._ddTestFinishStarted)
|
|
542
|
+
if (!test._ddTestFinishStarted) {
|
|
543
|
+
const onTestEnd = runnerTestEndHandlers.get(runner)
|
|
544
|
+
onTestEnd?.(test)
|
|
545
|
+
}
|
|
540
546
|
} else {
|
|
541
547
|
markTestPending(runner, test)
|
|
542
548
|
}
|
|
@@ -763,14 +769,18 @@ function wrapRunnerEmit (Runner) {
|
|
|
763
769
|
const test = hook.ctx?.currentTest
|
|
764
770
|
if (test && hook.parent?._afterEach?.includes(hook)) {
|
|
765
771
|
markTestTerminal(this, test)
|
|
766
|
-
if (!test._ddTestFinishStarted)
|
|
772
|
+
if (!test._ddTestFinishStarted) {
|
|
773
|
+
const onTestEnd = runnerTestEndHandlers.get(this)
|
|
774
|
+
onTestEnd?.(test)
|
|
775
|
+
}
|
|
767
776
|
}
|
|
768
777
|
} else if (event === 'pending' || event === 'pass' || event === 'fail' || event === 'retry' ||
|
|
769
778
|
event === 'test end') {
|
|
770
779
|
const test = arguments[1]
|
|
771
780
|
stopAfterEachHooks(this, test)
|
|
772
781
|
if (event === 'test end' && !test._ddTestFinishStarted) {
|
|
773
|
-
runnerTestEndHandlers.get(this)
|
|
782
|
+
const onTestEnd = runnerTestEndHandlers.get(this)
|
|
783
|
+
onTestEnd?.(test)
|
|
774
784
|
}
|
|
775
785
|
}
|
|
776
786
|
}
|
|
@@ -1060,16 +1070,50 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
|
|
|
1060
1070
|
runStoresWithCompletion(libraryConfigurationCh, ctx, onReceivedConfiguration)
|
|
1061
1071
|
}
|
|
1062
1072
|
|
|
1073
|
+
/**
|
|
1074
|
+
* @param {import('mocha').Runner} runner
|
|
1075
|
+
* @returns {void}
|
|
1076
|
+
*/
|
|
1077
|
+
function startMochaRunner (runner) {
|
|
1078
|
+
if (readyRunners.has(runner)) {
|
|
1079
|
+
runner.suite.run()
|
|
1080
|
+
} else {
|
|
1081
|
+
// Global setup can finish after configuration. Preserve the configuration
|
|
1082
|
+
// context until Runner#run has installed its delayed-start listener.
|
|
1083
|
+
pendingRunnerStarts.set(runner, AsyncResource.bind(() => runner.suite.run()))
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
/**
|
|
1088
|
+
* @param {import('mocha').Runner['run']} run
|
|
1089
|
+
* @param {import('mocha').Runner} runner
|
|
1090
|
+
* @param {Parameters<import('mocha').Runner['run']>} args
|
|
1091
|
+
* @returns {import('mocha').Runner}
|
|
1092
|
+
*/
|
|
1093
|
+
function runMochaRunner (run, runner, args) {
|
|
1094
|
+
const result = run.apply(runner, args)
|
|
1095
|
+
// Once delay mode is enabled, startup must complete even if the plugin is disabled during global setup.
|
|
1096
|
+
readyRunners.add(runner)
|
|
1097
|
+
const start = pendingRunnerStarts.get(runner)
|
|
1098
|
+
if (start) {
|
|
1099
|
+
pendingRunnerStarts.delete(runner)
|
|
1100
|
+
start()
|
|
1101
|
+
}
|
|
1102
|
+
return result
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1063
1105
|
// In this hook we delay the execution with options.delay to grab library configuration,
|
|
1064
1106
|
// skippable and known tests.
|
|
1065
1107
|
// It is called but skipped in parallel mode.
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1108
|
+
/**
|
|
1109
|
+
* @param {Function} Mocha
|
|
1110
|
+
* @param {string} frameworkVersion
|
|
1111
|
+
* @returns {Function}
|
|
1112
|
+
*/
|
|
1113
|
+
function wrapMochaRun (Mocha, frameworkVersion) {
|
|
1071
1114
|
warnDeprecatedMochaVersion(frameworkVersion)
|
|
1072
1115
|
|
|
1116
|
+
// Shimmer is required because run must return its Runner while execution is paused and resumed after configuration.
|
|
1073
1117
|
shimmer.wrap(Mocha.prototype, 'run', run => function (...args) {
|
|
1074
1118
|
// Workers do not need to request any data, just run the tests
|
|
1075
1119
|
if (!testFinishCh.hasSubscribers || getEnvironmentVariable('MOCHA_WORKER_ID') || this.options.parallel) {
|
|
@@ -1110,23 +1154,25 @@ addHook({
|
|
|
1110
1154
|
getCodeCoverageCh.publish({
|
|
1111
1155
|
onDone: (receivedCodeCoverage) => {
|
|
1112
1156
|
untestedCoverage = receivedCodeCoverage
|
|
1113
|
-
|
|
1157
|
+
startMochaRunner(runner)
|
|
1114
1158
|
},
|
|
1115
1159
|
})
|
|
1116
1160
|
} else {
|
|
1117
|
-
|
|
1161
|
+
startMochaRunner(runner)
|
|
1118
1162
|
}
|
|
1119
1163
|
})
|
|
1120
1164
|
|
|
1121
1165
|
return runner
|
|
1122
1166
|
})
|
|
1123
1167
|
return Mocha
|
|
1124
|
-
}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
addMochaRunHooks([MINIMUM_MOCHA_VERSION], wrapMochaRun)
|
|
1125
1171
|
|
|
1126
1172
|
addHook({
|
|
1127
1173
|
name: 'mocha',
|
|
1128
1174
|
versions: [MINIMUM_MOCHA_VERSION],
|
|
1129
|
-
|
|
1175
|
+
filePattern: String.raw`lib/cli/run-helpers\.(?:c?js)$`,
|
|
1130
1176
|
}, (run) => {
|
|
1131
1177
|
// `runMocha` is an async function
|
|
1132
1178
|
shimmer.wrap(run, 'runMocha', runMocha => function (...args) {
|
|
@@ -1136,7 +1182,7 @@ addHook({
|
|
|
1136
1182
|
const mocha = args[0]
|
|
1137
1183
|
|
|
1138
1184
|
/**
|
|
1139
|
-
* This
|
|
1185
|
+
* This enables the delayed root suite, which we'll release after
|
|
1140
1186
|
* our configuration and skippable suites requests.
|
|
1141
1187
|
* You need this both here and in Mocha#run hook: the programmatic API
|
|
1142
1188
|
* does not call `runMocha`, so it needs to be in Mocha#run. When using
|
|
@@ -1157,7 +1203,7 @@ addHook({
|
|
|
1157
1203
|
addHook({
|
|
1158
1204
|
name: 'mocha',
|
|
1159
1205
|
versions: [MINIMUM_MOCHA_VERSION],
|
|
1160
|
-
|
|
1206
|
+
filePattern: String.raw`lib/runner\.(?:c?js)$`,
|
|
1161
1207
|
}, function (Runner, frameworkVersion) {
|
|
1162
1208
|
if (patched.has(Runner)) return Runner
|
|
1163
1209
|
|
|
@@ -1168,7 +1214,7 @@ addHook({
|
|
|
1168
1214
|
|
|
1169
1215
|
shimmer.wrap(Runner.prototype, 'run', run => function (...args) {
|
|
1170
1216
|
if (!testFinishCh.hasSubscribers) {
|
|
1171
|
-
return run
|
|
1217
|
+
return runMochaRunner(run, this, args)
|
|
1172
1218
|
}
|
|
1173
1219
|
|
|
1174
1220
|
const { onRunDone, onFlushDone } = getRunCompletionCallbacks(args[0])
|
|
@@ -1501,7 +1547,7 @@ addHook({
|
|
|
1501
1547
|
}
|
|
1502
1548
|
})
|
|
1503
1549
|
|
|
1504
|
-
return run
|
|
1550
|
+
return runMochaRunner(run, this, args)
|
|
1505
1551
|
})
|
|
1506
1552
|
|
|
1507
1553
|
return Runner
|
|
@@ -1588,7 +1634,7 @@ addHook({
|
|
|
1588
1634
|
addHook({
|
|
1589
1635
|
name: 'mocha',
|
|
1590
1636
|
versions: ['>=8.0.0'],
|
|
1591
|
-
|
|
1637
|
+
filePattern: String.raw`lib/nodejs/parallel-buffered-runner\.(?:c?js)$`,
|
|
1592
1638
|
}, (ParallelBufferedRunner, frameworkVersion) => {
|
|
1593
1639
|
shimmer.wrap(ParallelBufferedRunner.prototype, 'run', run => function (cb, { files, options = {} }) {
|
|
1594
1640
|
if (!testFinishCh.hasSubscribers) {
|
|
@@ -1667,7 +1713,7 @@ addHook({
|
|
|
1667
1713
|
addHook({
|
|
1668
1714
|
name: 'mocha',
|
|
1669
1715
|
versions: ['>=8.0.0'],
|
|
1670
|
-
|
|
1716
|
+
filePattern: String.raw`lib/nodejs/buffered-worker-pool\.(?:c?js)$`,
|
|
1671
1717
|
}, (BufferedWorkerPoolPackage, frameworkVersion) => {
|
|
1672
1718
|
const { BufferedWorkerPool } = BufferedWorkerPoolPackage
|
|
1673
1719
|
|
|
@@ -507,7 +507,8 @@ function inheritDatadogPropertiesFromRetriedTest (test) {
|
|
|
507
507
|
}
|
|
508
508
|
|
|
509
509
|
function runnableWrapper (RunnablePackage, libraryConfig) {
|
|
510
|
-
|
|
510
|
+
const Runnable = RunnablePackage.Runnable ?? RunnablePackage
|
|
511
|
+
shimmer.wrap(Runnable.prototype, 'run', run => function (...args) {
|
|
511
512
|
if (!testFinishCh.hasSubscribers) {
|
|
512
513
|
return run.apply(this, args)
|
|
513
514
|
}
|
|
@@ -6,6 +6,11 @@ const {
|
|
|
6
6
|
WEBDRIVERIO_WORKER_EVENT,
|
|
7
7
|
WEBDRIVERIO_WORKER_ORIGIN,
|
|
8
8
|
} = require('../../../dd-trace/src/ci-visibility/exporters/test-worker/webdriverio')
|
|
9
|
+
const { FINAL_FLUSH_TIMEOUT } = require('../../../dd-trace/src/ci-visibility/final-flush')
|
|
10
|
+
|
|
11
|
+
const SCREENSHOT_UPLOAD = 'dd:test-optimization:webdriverio:screenshot:upload'
|
|
12
|
+
const SCREENSHOT_UPLOAD_RESPONSE = 'dd:test-optimization:webdriverio:screenshot:upload:response'
|
|
13
|
+
const SCREENSHOT_UPLOAD_TIMEOUT_MS = FINAL_FLUSH_TIMEOUT + 5000
|
|
9
14
|
|
|
10
15
|
/**
|
|
11
16
|
* Sends a message over WebdriverIO's worker IPC envelope.
|
|
@@ -30,10 +35,103 @@ function sendWebdriverioWorkerMessage (message, onError, onDone) {
|
|
|
30
35
|
})
|
|
31
36
|
}
|
|
32
37
|
|
|
38
|
+
let screenshotUploadRequestId = 0
|
|
39
|
+
const screenshotUploadRequests = new Map()
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Removes shared screenshot response listeners when there are no pending requests.
|
|
43
|
+
*
|
|
44
|
+
* @returns {void}
|
|
45
|
+
*/
|
|
46
|
+
function removeScreenshotUploadListeners () {
|
|
47
|
+
if (screenshotUploadRequests.size !== 0) return
|
|
48
|
+
|
|
49
|
+
process.off('message', onScreenshotUploadResponse)
|
|
50
|
+
process.off('disconnect', onScreenshotUploadDisconnect)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Completes one pending screenshot upload request.
|
|
55
|
+
*
|
|
56
|
+
* @param {string} requestId
|
|
57
|
+
* @param {Error} [error]
|
|
58
|
+
* @returns {void}
|
|
59
|
+
*/
|
|
60
|
+
function finishScreenshotUploadRequest (requestId, error) {
|
|
61
|
+
const request = screenshotUploadRequests.get(requestId)
|
|
62
|
+
if (!request) return
|
|
63
|
+
|
|
64
|
+
screenshotUploadRequests.delete(requestId)
|
|
65
|
+
clearTimeout(request.timeout)
|
|
66
|
+
removeScreenshotUploadListeners()
|
|
67
|
+
request.onDone(error)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Dispatches one coordinator screenshot response to its pending request.
|
|
72
|
+
*
|
|
73
|
+
* @param {object} message
|
|
74
|
+
* @returns {void}
|
|
75
|
+
*/
|
|
76
|
+
function onScreenshotUploadResponse (message) {
|
|
77
|
+
if (message?.name !== SCREENSHOT_UPLOAD_RESPONSE) return
|
|
78
|
+
|
|
79
|
+
const { error: errorMessage, requestId } = message.content || {}
|
|
80
|
+
if (!requestId) return
|
|
81
|
+
|
|
82
|
+
finishScreenshotUploadRequest(requestId, errorMessage ? new Error(errorMessage) : undefined)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Fails every pending screenshot upload after coordinator disconnect.
|
|
87
|
+
*
|
|
88
|
+
* @returns {void}
|
|
89
|
+
*/
|
|
90
|
+
function onScreenshotUploadDisconnect () {
|
|
91
|
+
for (const requestId of screenshotUploadRequests.keys()) {
|
|
92
|
+
finishScreenshotUploadRequest(
|
|
93
|
+
requestId,
|
|
94
|
+
new Error('WebdriverIO coordinator disconnected during screenshot upload')
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Requests one screenshot upload from the WebdriverIO coordinator.
|
|
101
|
+
*
|
|
102
|
+
* @param {object} content - Screenshot upload metadata
|
|
103
|
+
* @param {(error?: Error) => void} onDone - Upload completion callback
|
|
104
|
+
* @returns {void}
|
|
105
|
+
*/
|
|
106
|
+
function requestWebdriverioScreenshotUpload (content, onDone) {
|
|
107
|
+
const requestId = `${process.pid}-${++screenshotUploadRequestId}`
|
|
108
|
+
const timeout = setTimeout(() => {
|
|
109
|
+
finishScreenshotUploadRequest(requestId, new Error('WebdriverIO screenshot upload timed out'))
|
|
110
|
+
}, SCREENSHOT_UPLOAD_TIMEOUT_MS)
|
|
111
|
+
timeout.unref?.()
|
|
112
|
+
if (screenshotUploadRequests.size === 0) {
|
|
113
|
+
process.on('message', onScreenshotUploadResponse)
|
|
114
|
+
process.once('disconnect', onScreenshotUploadDisconnect)
|
|
115
|
+
}
|
|
116
|
+
screenshotUploadRequests.set(requestId, { onDone, timeout })
|
|
117
|
+
sendWebdriverioWorkerMessage({
|
|
118
|
+
origin: 'datadog',
|
|
119
|
+
name: SCREENSHOT_UPLOAD,
|
|
120
|
+
content: { ...content, requestId },
|
|
121
|
+
}, error => finishScreenshotUploadRequest(
|
|
122
|
+
requestId,
|
|
123
|
+
error || new Error('WebdriverIO screenshot upload IPC failed')
|
|
124
|
+
))
|
|
125
|
+
}
|
|
126
|
+
|
|
33
127
|
module.exports = {
|
|
34
128
|
CONFIGURATION_REQUEST: 'dd:test-optimization:webdriverio:configuration:request',
|
|
35
129
|
CONFIGURATION_RESPONSE: 'dd:test-optimization:webdriverio:configuration:response',
|
|
36
130
|
createWebdriverioWorkerMessage,
|
|
131
|
+
requestWebdriverioScreenshotUpload,
|
|
132
|
+
SCREENSHOT_UPLOAD,
|
|
133
|
+
SCREENSHOT_UPLOAD_RESPONSE,
|
|
134
|
+
SCREENSHOT_UPLOAD_TIMEOUT_MS,
|
|
37
135
|
sendWebdriverioWorkerMessage,
|
|
38
136
|
SUITE_FINISH: 'dd:test-optimization:webdriverio:test-suite:finish',
|
|
39
137
|
WORKER_READY: 'dd:test-optimization:webdriverio:worker:ready',
|
|
@@ -7,6 +7,7 @@ const { getEnvironmentVariable } = require('../../../dd-trace/src/config/helper'
|
|
|
7
7
|
const log = require('../../../dd-trace/src/log')
|
|
8
8
|
const { DD_MAJOR } = require('../../../../version')
|
|
9
9
|
|
|
10
|
+
const { addMochaRunHooks } = require('./common')
|
|
10
11
|
const {
|
|
11
12
|
runnableWrapper,
|
|
12
13
|
getOnTestHandler,
|
|
@@ -29,7 +30,6 @@ const {
|
|
|
29
30
|
WEBDRIVERIO_WORKER_ENV,
|
|
30
31
|
WORKER_READY,
|
|
31
32
|
} = require('./webdriverio-protocol')
|
|
32
|
-
require('./common')
|
|
33
33
|
|
|
34
34
|
const MINIMUM_MOCHA_VERSION = DD_MAJOR >= 6 ? '>=8.0.0' : '>=5.2.0'
|
|
35
35
|
|
|
@@ -360,13 +360,15 @@ function isFailedTestReplayEnabled () {
|
|
|
360
360
|
return config.isTestDynamicInstrumentationEnabled && config.isDiEnabled
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
363
|
+
/**
|
|
364
|
+
* @param {Function} Mocha
|
|
365
|
+
* @param {string} frameworkVersion
|
|
366
|
+
* @returns {Function}
|
|
367
|
+
*/
|
|
368
|
+
function wrapMochaRun (Mocha, frameworkVersion) {
|
|
368
369
|
reportWebdriverioWorkerReady(frameworkVersion)
|
|
369
370
|
|
|
371
|
+
// Shimmer is required because run must return its Runner while execution is paused and resumed after configuration.
|
|
370
372
|
shimmer.wrap(Mocha.prototype, 'run', run => function (...args) {
|
|
371
373
|
applyMochaOptions(this.options)
|
|
372
374
|
if (!isWebdriverioWorker || !workerFinishCh.hasSubscribers) {
|
|
@@ -438,13 +440,15 @@ addHook({
|
|
|
438
440
|
})
|
|
439
441
|
|
|
440
442
|
return Mocha
|
|
441
|
-
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
addMochaRunHooks(['>=8.0.0'], wrapMochaRun)
|
|
442
446
|
|
|
443
447
|
// Runner is also hooked in mocha/main.js, but in here we only generate test events.
|
|
444
448
|
addHook({
|
|
445
449
|
name: 'mocha',
|
|
446
450
|
versions: [MINIMUM_MOCHA_VERSION],
|
|
447
|
-
|
|
451
|
+
filePattern: String.raw`lib/runner\.(?:c?js)$`,
|
|
448
452
|
}, function (Runner) {
|
|
449
453
|
shimmer.wrap(Runner.prototype, 'runTests', runTests => getRunTestsWrapper(runTests, config))
|
|
450
454
|
|
|
@@ -27,8 +27,6 @@ addHook({ name: 'net' }, (net) => {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const options = getOptions(args)
|
|
30
|
-
const lastIndex = args.length - 1
|
|
31
|
-
const callback = args[lastIndex]
|
|
32
30
|
|
|
33
31
|
if (!options) return connect.apply(this, args)
|
|
34
32
|
|
|
@@ -38,42 +36,39 @@ addHook({ name: 'net' }, (net) => {
|
|
|
38
36
|
const errorCh = protocol === 'ipc' ? errorICPCh : errorTCPCh
|
|
39
37
|
const ctx = { options }
|
|
40
38
|
|
|
41
|
-
if (typeof callback === 'function') {
|
|
42
|
-
args[lastIndex] = function (...args) {
|
|
43
|
-
return finishCh.runStores(ctx, callback, this, ...args)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
39
|
return startCh.runStores(ctx, () => {
|
|
48
|
-
setupListeners(this, protocol, ctx, finishCh, errorCh)
|
|
40
|
+
const cleanup = setupListeners(this, protocol, ctx, finishCh, errorCh)
|
|
49
41
|
|
|
50
|
-
const
|
|
42
|
+
const originalEmit = this.emit
|
|
51
43
|
let pendingReadyEvents = 2
|
|
52
44
|
// Named `emit`/arity-1 mirrors the socket method so the per-socket wrap
|
|
53
45
|
// skips its name/length rewrite.
|
|
54
|
-
this.emit = shimmer.wrapFunction(
|
|
46
|
+
this.emit = shimmer.wrapFunction(originalEmit, wrappedEmit => function emit (eventName) {
|
|
55
47
|
switch (eventName) {
|
|
56
48
|
case 'ready':
|
|
57
49
|
case 'connect':
|
|
58
50
|
if (--pendingReadyEvents === 0) this.emit = originalEmit
|
|
59
51
|
return readyCh.runStores(ctx, () => {
|
|
60
|
-
return Reflect.apply(
|
|
52
|
+
return Reflect.apply(wrappedEmit, this, arguments)
|
|
61
53
|
})
|
|
62
54
|
case 'error':
|
|
63
55
|
case 'close':
|
|
64
56
|
this.emit = originalEmit
|
|
65
|
-
return Reflect.apply(
|
|
57
|
+
return Reflect.apply(wrappedEmit, this, arguments)
|
|
66
58
|
default:
|
|
67
|
-
return Reflect.apply(
|
|
59
|
+
return Reflect.apply(wrappedEmit, this, arguments)
|
|
68
60
|
}
|
|
69
61
|
})
|
|
70
62
|
|
|
71
63
|
try {
|
|
72
64
|
return connect.apply(this, args)
|
|
73
|
-
} catch (
|
|
74
|
-
|
|
65
|
+
} catch (error) {
|
|
66
|
+
cleanup()
|
|
67
|
+
this.emit = originalEmit
|
|
68
|
+
errorCh.publish(error)
|
|
69
|
+
finishCh.runStores(ctx, () => {})
|
|
75
70
|
|
|
76
|
-
throw
|
|
71
|
+
throw error
|
|
77
72
|
}
|
|
78
73
|
})
|
|
79
74
|
})
|
|
@@ -142,4 +137,6 @@ function setupListeners (socket, protocol, ctx, finishCh, errorCh) {
|
|
|
142
137
|
for (const event of events) {
|
|
143
138
|
socket.once(event, wrapListener)
|
|
144
139
|
}
|
|
140
|
+
|
|
141
|
+
return cleanupOtherListeners
|
|
145
142
|
}
|