dd-trace 6.12.0 → 6.14.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/cypress.js +9 -11
- 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/test-optimization-validation/scenarios/ci-wiring.js +5 -4
- 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 +127 -26
- package/package.json +22 -19
- package/packages/datadog-esbuild/index.js +3 -1
- package/packages/datadog-instrumentations/src/bunyan.js +4 -2
- 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/bunyan.js +12 -3
- 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 +266 -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 +13 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +279 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +12 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +562 -27
- package/packages/datadog-instrumentations/src/jest.js +165 -38
- package/packages/datadog-instrumentations/src/knex.js +76 -0
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +1597 -0
- package/packages/datadog-instrumentations/src/mariadb.js +13 -0
- package/packages/datadog-instrumentations/src/mocha/common.js +59 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +25 -15
- 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/pino.js +15 -4
- package/packages/datadog-instrumentations/src/playwright.js +137 -27
- 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 +44 -7
- package/packages/datadog-instrumentations/src/vitest-main.js +92 -9
- package/packages/datadog-instrumentations/src/vitest-worker.js +82 -14
- package/packages/datadog-instrumentations/src/webdriverio.js +986 -1
- package/packages/datadog-instrumentations/src/winston.js +6 -3
- 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-cypress/src/support.js +1 -0
- 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-http/src/client.js +2 -15
- package/packages/datadog-plugin-http2/src/client.js +2 -15
- 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-openai-agents/src/integration.js +15 -11
- package/packages/datadog-plugin-playwright/src/index.js +176 -28
- package/packages/datadog-plugin-undici/src/index.js +29 -56
- package/packages/datadog-plugin-vitest/src/index.js +6 -12
- package/packages/dd-trace/src/aiguard/evaluation.js +96 -21
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +2 -3
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +29 -10
- 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/aiguard/noop.js +9 -1
- package/packages/dd-trace/src/aiguard/redaction.js +183 -0
- package/packages/dd-trace/src/aiguard/sdk.js +7 -2
- package/packages/dd-trace/src/aiguard/tags.js +2 -0
- 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/sql-sensitive-analyzer.js +11 -36
- 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/iast/vulnerabilities-formatter/utils.js +10 -9
- package/packages/dd-trace/src/appsec/lambda.js +44 -26
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -0
- 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 +7 -150
- 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 +397 -234
- 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 +21 -0
- 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/upload-test-screenshot.js +164 -71
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +176 -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 +10 -0
- package/packages/dd-trace/src/config/index.js +75 -14
- 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 +47 -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 +33 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +7 -39
- 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 +532 -71
- 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 +27 -23
- package/packages/dd-trace/src/exporters/agent/index.js +24 -3
- package/packages/dd-trace/src/exporters/agent/writer.js +28 -11
- package/packages/dd-trace/src/exporters/agentless/index.js +7 -9
- package/packages/dd-trace/src/exporters/agentless/writer.js +100 -118
- 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/request.js +31 -11
- package/packages/dd-trace/src/exporters/common/url.js +40 -1
- package/packages/dd-trace/src/exporters/common/writer.js +31 -7
- package/packages/dd-trace/src/exporters/span-stats/index.js +23 -4
- package/packages/dd-trace/src/external-logger/src/index.js +4 -3
- package/packages/dd-trace/src/flush.js +105 -0
- 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/client.js +4 -0
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +52 -2
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +420 -105
- package/packages/dd-trace/src/llmobs/experiments/index.js +54 -42
- package/packages/dd-trace/src/llmobs/experiments/noop.js +39 -8
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +21 -0
- package/packages/dd-trace/src/llmobs/index.js +111 -48
- package/packages/dd-trace/src/llmobs/noop.js +2 -1
- 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/anthropic/util.js +8 -4
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +6 -3
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +7 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +13 -6
- package/packages/dd-trace/src/llmobs/plugins/openai-agents/utils.js +5 -7
- package/packages/dd-trace/src/llmobs/util.js +0 -33
- package/packages/dd-trace/src/llmobs/writers/base.js +106 -53
- package/packages/dd-trace/src/log/index.js +7 -1
- package/packages/dd-trace/src/log-submission/log-submission-plugin.js +249 -0
- package/packages/dd-trace/src/noop/span.js +5 -0
- package/packages/dd-trace/src/openfeature/writers/base.js +14 -12
- package/packages/dd-trace/src/openfeature/writers/exposures.js +8 -1
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +45 -3
- package/packages/dd-trace/src/opentelemetry/logs/index.js +9 -25
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +7 -4
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +14 -4
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +18 -23
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +8 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +18 -6
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +14 -2
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +25 -5
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +61 -25
- 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/opentelemetry/tracer.js +26 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +494 -351
- package/packages/dd-trace/src/opentracing/span.js +28 -0
- package/packages/dd-trace/src/otel-thread-ctx.js +23 -5
- package/packages/dd-trace/src/payload-tagging/index.js +2 -1
- package/packages/dd-trace/src/plugin_manager.js +2 -0
- 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/status-validator.js +98 -0
- package/packages/dd-trace/src/plugins/util/test.js +157 -41
- package/packages/dd-trace/src/plugins/util/url.js +2 -2
- package/packages/dd-trace/src/plugins/util/web.js +6 -74
- package/packages/dd-trace/src/profiling/config.js +1 -0
- package/packages/dd-trace/src/profiling/oom.js +11 -5
- package/packages/dd-trace/src/profiling/profiler.js +30 -13
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/space.js +38 -11
- package/packages/dd-trace/src/profiling/profilers/wall.js +14 -14
- package/packages/dd-trace/src/profiling/webspan-utils.js +7 -4
- package/packages/dd-trace/src/proxy.js +108 -10
- 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/index.js +5 -0
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +10 -1
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +22 -7
- package/packages/dd-trace/src/sampling_rule.js +36 -9
- package/packages/dd-trace/src/serverless/telemetry-delivery-tracker.js +51 -0
- package/packages/dd-trace/src/serverless/vercel.js +155 -0
- package/packages/dd-trace/src/serverless.js +45 -21
- package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
- package/packages/dd-trace/src/span_stats.js +64 -31
- 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 +18 -16
- package/packages/dd-trace/src/telemetry/session-propagation.js +3 -2
- package/packages/dd-trace/src/tracer.js +26 -5
- package/packages/dd-trace/src/tracer_metadata.js +11 -3
- package/packages/dd-trace/src/web-tags-cache.js +67 -13
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- 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/ci-visibility/log-submission/log-submission-plugin.js +0 -53
- package/packages/dd-trace/src/encode/agentless-json.js +0 -209
|
@@ -59,6 +59,7 @@ const testSuiteStartCh = channel('ci:playwright:test-suite:start')
|
|
|
59
59
|
const testSuiteFinishCh = channel('ci:playwright:test-suite:finish')
|
|
60
60
|
|
|
61
61
|
const workerReportCh = channel('ci:playwright:worker:report')
|
|
62
|
+
const logSubmissionFlushCh = channel('ci:log-submission:flush')
|
|
62
63
|
const workerReportTelemetryCh = channel('ci:playwright:worker-report:telemetry')
|
|
63
64
|
const testPageGotoCh = channel('ci:playwright:test:page-goto')
|
|
64
65
|
|
|
@@ -69,6 +70,7 @@ const createRootSuiteCh = tracingChannel('orchestrion:playwright:createRootSuite
|
|
|
69
70
|
const artifactsRecorderScreenshotPathCh =
|
|
70
71
|
tracingChannel('orchestrion:playwright:ArtifactsRecorder_createScreenshotAttachmentPath')
|
|
71
72
|
const snapshotRecorderScreenshotPathCh = tracingChannel('orchestrion:playwright:SnapshotRecorder_createAttachmentPath')
|
|
73
|
+
const saveAutomaticVideoCh = tracingChannel('orchestrion:playwright:saveAutomaticVideo')
|
|
72
74
|
const pageGotoCh = tracingChannel('orchestrion:playwright-core:Page_goto')
|
|
73
75
|
|
|
74
76
|
const testToCtx = new WeakMap()
|
|
@@ -82,6 +84,8 @@ const RUM_FLUSH_WAIT_TIME = getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WA
|
|
|
82
84
|
const DD_PROPERTIES_TIMEOUT = 5000
|
|
83
85
|
const isFailureScreenshotUploadEnabled =
|
|
84
86
|
getValueFromEnvSources('DD_TEST_FAILURE_SCREENSHOTS_ENABLED') === true
|
|
87
|
+
const isFailureVideoUploadEnabled =
|
|
88
|
+
getValueFromEnvSources('DD_TEST_FAILURE_VIDEOS_ENABLED') === true
|
|
85
89
|
|
|
86
90
|
let applyRepeatEachIndex = null
|
|
87
91
|
let reporterError
|
|
@@ -90,7 +94,7 @@ let hasReporterError = false
|
|
|
90
94
|
let startedSuites = []
|
|
91
95
|
|
|
92
96
|
// Browser-side callbacks live in a coverage-excluded file so coverage counters can't reach chromium.
|
|
93
|
-
const { detectRum, stopRumSession } = require('./
|
|
97
|
+
const { detectRum, stopRumSession } = require('./rum-browser-scripts')
|
|
94
98
|
|
|
95
99
|
const STATUS_TO_TEST_STATUS = {
|
|
96
100
|
passed: 'pass',
|
|
@@ -133,18 +137,22 @@ let rootDir = ''
|
|
|
133
137
|
let sessionProjects = []
|
|
134
138
|
|
|
135
139
|
const MINIMUM_SUPPORTED_VERSION_RANGE_EFD = '>=1.38.0' // TODO: remove this once we drop support for v5
|
|
140
|
+
const MINIMUM_FAILURE_VIDEO_UPLOAD_VERSION_RANGE = '>=1.38.0'
|
|
136
141
|
const EFD_RETRY_COUNT_REQUEST = 'ddEfdRetryCountRequest'
|
|
137
142
|
const EFD_RETRY_COUNT_RESPONSE = 'ddEfdRetryCountResponse'
|
|
138
143
|
const DD_PROPERTIES_REQUEST = 'ddPropertiesRequest'
|
|
139
144
|
const DD_PROPERTIES_RESPONSE = 'ddProperties'
|
|
140
145
|
const kDdPlaywrightDisabledTestIds = Symbol('ddPlaywrightDisabledTestIds')
|
|
141
146
|
const kDdPlaywrightFailureScreenshots = Symbol('ddPlaywrightFailureScreenshots')
|
|
147
|
+
const kDdPlaywrightFailureVideos = Symbol('ddPlaywrightFailureVideos')
|
|
142
148
|
const kDdPlaywrightReporterConfigured = Symbol('ddPlaywrightReporterConfigured')
|
|
143
149
|
const kDdPlaywrightWorkerHostInstrumented = Symbol('ddPlaywrightWorkerHostInstrumented')
|
|
144
150
|
const kDdPlaywrightWorkerInstrumented = Symbol('ddPlaywrightWorkerInstrumented')
|
|
145
151
|
const instrumentedPlaywrightReporters = new WeakSet()
|
|
146
152
|
const PLAYWRIGHT_FAILURE_SCREENSHOT_PATH_RE = /(?:^|[\\/])test-failed-\d+\.png$/
|
|
153
|
+
const PLAYWRIGHT_FAILURE_VIDEO_PATH_RE = /(?:^|[\\/])video(?:-\d+)?\.webm$/
|
|
147
154
|
const automaticFailureScreenshotPaths = new Set()
|
|
155
|
+
const automaticFailureVideoPaths = new Set()
|
|
148
156
|
|
|
149
157
|
/**
|
|
150
158
|
* Returns whether Playwright's internal screenshot recorder created an attachment.
|
|
@@ -156,6 +164,16 @@ function isAutomaticFailureScreenshotAttachment (attachment) {
|
|
|
156
164
|
return typeof attachment?.path === 'string' && automaticFailureScreenshotPaths.delete(attachment.path)
|
|
157
165
|
}
|
|
158
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Returns whether Playwright's internal video recorder created an attachment.
|
|
169
|
+
*
|
|
170
|
+
* @param {object} attachment - Playwright attachment payload
|
|
171
|
+
* @returns {boolean}
|
|
172
|
+
*/
|
|
173
|
+
function isAutomaticFailureVideoAttachment (attachment) {
|
|
174
|
+
return typeof attachment?.path === 'string' && automaticFailureVideoPaths.delete(attachment.path)
|
|
175
|
+
}
|
|
176
|
+
|
|
159
177
|
function isValidKnownTests (receivedKnownTests) {
|
|
160
178
|
return !!receivedKnownTests.playwright
|
|
161
179
|
}
|
|
@@ -552,6 +570,21 @@ function isFailureScreenshotCaptureEnabled (projects) {
|
|
|
552
570
|
return false
|
|
553
571
|
}
|
|
554
572
|
|
|
573
|
+
/**
|
|
574
|
+
* Returns whether at least one Playwright project records videos that can be retained for failures.
|
|
575
|
+
*
|
|
576
|
+
* @param {Array<object>} projects - Playwright projects with resolved use options
|
|
577
|
+
* @returns {boolean} Whether video capture is enabled
|
|
578
|
+
*/
|
|
579
|
+
function isFailureVideoCaptureEnabled (projects) {
|
|
580
|
+
for (const project of projects) {
|
|
581
|
+
const video = project.use?.video
|
|
582
|
+
const mode = typeof video === 'object' && video !== null ? video.mode : video
|
|
583
|
+
if (mode === 'on' || mode === 'retain-on-failure') return true
|
|
584
|
+
}
|
|
585
|
+
return false
|
|
586
|
+
}
|
|
587
|
+
|
|
555
588
|
function getProjectsFromDispatcher (dispatcher) {
|
|
556
589
|
const bundledConfig = dispatcher._testRun?.config?.config?.projects
|
|
557
590
|
if (bundledConfig) {
|
|
@@ -613,7 +646,15 @@ function getTestSuiteError (testSuiteAbsolutePath) {
|
|
|
613
646
|
if (errors.length === 1) {
|
|
614
647
|
return errors[0]
|
|
615
648
|
}
|
|
616
|
-
|
|
649
|
+
let errorMessages = ''
|
|
650
|
+
let isFirstError = true
|
|
651
|
+
for (const error of errors) {
|
|
652
|
+
if (!isFirstError) errorMessages += '\n------\n'
|
|
653
|
+
errorMessages += error.message || error.value || ''
|
|
654
|
+
isFirstError = false
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
return new Error(`${errors.length} errors in this test suite:\n${errorMessages}`)
|
|
617
658
|
}
|
|
618
659
|
|
|
619
660
|
function getTestByTestId (dispatcher, testId) {
|
|
@@ -1085,7 +1126,8 @@ function onDispatcherCreateWorker (dispatcher, worker) {
|
|
|
1085
1126
|
|
|
1086
1127
|
const projects = getProjectsFromDispatcher(dispatcher)
|
|
1087
1128
|
sessionProjects = projects
|
|
1088
|
-
const
|
|
1129
|
+
const automaticFailureScreenshotsByTestId = new Map()
|
|
1130
|
+
const failureVideosByTestId = new Map()
|
|
1089
1131
|
|
|
1090
1132
|
if (disabledTestIds.size && !worker[kDdPlaywrightWorkerHostInstrumented] &&
|
|
1091
1133
|
typeof worker.runTestGroup === 'function') {
|
|
@@ -1110,19 +1152,29 @@ function onDispatcherCreateWorker (dispatcher, worker) {
|
|
|
1110
1152
|
const test = getTestByTestId(dispatcher, testId)
|
|
1111
1153
|
if (!test) return
|
|
1112
1154
|
|
|
1155
|
+
automaticFailureScreenshotsByTestId.clear()
|
|
1156
|
+
failureVideosByTestId.clear()
|
|
1113
1157
|
const browser = getBrowserNameFromProjects(projects, test)
|
|
1114
1158
|
const shouldCreateTestSpan = test.expectedStatus === 'skipped'
|
|
1115
1159
|
testBeginHandler(test, browser, shouldCreateTestSpan)
|
|
1116
1160
|
})
|
|
1117
|
-
worker.on('attach', (
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1161
|
+
worker.on('attach', (attachment) => {
|
|
1162
|
+
const { testId, _ddIsAutomaticFailureScreenshot, _ddIsAutomaticFailureVideo } = attachment
|
|
1163
|
+
if (_ddIsAutomaticFailureScreenshot) {
|
|
1164
|
+
let screenshots = automaticFailureScreenshotsByTestId.get(testId)
|
|
1165
|
+
if (!screenshots) {
|
|
1166
|
+
screenshots = []
|
|
1167
|
+
automaticFailureScreenshotsByTestId.set(testId, screenshots)
|
|
1168
|
+
}
|
|
1169
|
+
screenshots.push(attachment)
|
|
1170
|
+
} else if (isFailureVideoUploadEnabled && _ddIsAutomaticFailureVideo) {
|
|
1171
|
+
let videos = failureVideosByTestId.get(testId)
|
|
1172
|
+
if (!videos) {
|
|
1173
|
+
videos = []
|
|
1174
|
+
failureVideosByTestId.set(testId, videos)
|
|
1175
|
+
}
|
|
1176
|
+
videos.push(attachment)
|
|
1124
1177
|
}
|
|
1125
|
-
screenshotPaths.add(path)
|
|
1126
1178
|
})
|
|
1127
1179
|
worker.on('testEnd', ({ testId, status, errors, annotations }) => {
|
|
1128
1180
|
const test = getTestByTestId(dispatcher, testId)
|
|
@@ -1146,19 +1198,28 @@ function onDispatcherCreateWorker (dispatcher, worker) {
|
|
|
1146
1198
|
}
|
|
1147
1199
|
)
|
|
1148
1200
|
const testResult = test.results.at(-1)
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1201
|
+
if (isFailureScreenshotUploadEnabled &&
|
|
1202
|
+
!shouldCreateTestSpan &&
|
|
1203
|
+
!test._ddShouldSkipEfdRetry &&
|
|
1204
|
+
!disabledTestIds.has(testId)) {
|
|
1205
|
+
let screenshots
|
|
1206
|
+
if (testStatus === 'fail') {
|
|
1207
|
+
screenshots = automaticFailureScreenshotsByTestId.get(testId)
|
|
1208
|
+
if (!screenshots) {
|
|
1209
|
+
screenshots = []
|
|
1210
|
+
automaticFailureScreenshotsByTestId.set(testId, screenshots)
|
|
1156
1211
|
}
|
|
1157
1212
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1213
|
+
worker[kDdPlaywrightFailureScreenshots] ??= []
|
|
1214
|
+
worker[kDdPlaywrightFailureScreenshots].push(screenshots)
|
|
1215
|
+
}
|
|
1216
|
+
if (isFailureVideoUploadEnabled &&
|
|
1217
|
+
!shouldCreateTestSpan &&
|
|
1218
|
+
!test._ddShouldSkipEfdRetry &&
|
|
1219
|
+
!disabledTestIds.has(testId)) {
|
|
1220
|
+
const videos = testStatus === 'fail' ? failureVideosByTestId.get(testId) : undefined
|
|
1221
|
+
worker[kDdPlaywrightFailureVideos] ??= []
|
|
1222
|
+
worker[kDdPlaywrightFailureVideos].push(videos)
|
|
1162
1223
|
}
|
|
1163
1224
|
const isAtrRetry = testResult?.retry > 0 &&
|
|
1164
1225
|
isFlakyTestRetriesEnabled &&
|
|
@@ -1274,6 +1335,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1274
1335
|
rootDir = getRootDir(this, config)
|
|
1275
1336
|
const projects = getProjectsFromRunner(this, config)
|
|
1276
1337
|
const isFailureScreenshotEnabled = isFailureScreenshotCaptureEnabled(projects)
|
|
1338
|
+
const isFailureVideoEnabled = isFailureVideoCaptureEnabled(projects)
|
|
1339
|
+
const isFailureVideoUploadSupported = satisfies(playwrightVersion, MINIMUM_FAILURE_VIDEO_UPLOAD_VERSION_RANGE)
|
|
1277
1340
|
const processArgv = process.argv.slice(2).join(' ')
|
|
1278
1341
|
const command = `playwright ${processArgv}`
|
|
1279
1342
|
testSessionStartCh.publish({
|
|
@@ -1281,6 +1344,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1281
1344
|
frameworkVersion: playwrightVersion,
|
|
1282
1345
|
rootDir,
|
|
1283
1346
|
isFailureScreenshotEnabled,
|
|
1347
|
+
isFailureVideoEnabled,
|
|
1348
|
+
isFailureVideoUploadSupported,
|
|
1284
1349
|
})
|
|
1285
1350
|
|
|
1286
1351
|
try {
|
|
@@ -1307,7 +1372,11 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1307
1372
|
log.error('Playwright session start error', e)
|
|
1308
1373
|
}
|
|
1309
1374
|
|
|
1310
|
-
testSessionConfigurationCh.publish({
|
|
1375
|
+
testSessionConfigurationCh.publish({
|
|
1376
|
+
isFailureScreenshotEnabled,
|
|
1377
|
+
isFailureVideoEnabled,
|
|
1378
|
+
isFailureVideoUploadSupported,
|
|
1379
|
+
})
|
|
1311
1380
|
|
|
1312
1381
|
const isTestOptimizationSupported = satisfies(playwrightVersion, MINIMUM_SUPPORTED_VERSION_RANGE_EFD)
|
|
1313
1382
|
const shouldGetKnownTests = isKnownTestsEnabled && isTestOptimizationSupported
|
|
@@ -1693,8 +1762,33 @@ function recordAutomaticFailureScreenshotPath (ctx) {
|
|
|
1693
1762
|
}
|
|
1694
1763
|
}
|
|
1695
1764
|
|
|
1765
|
+
/**
|
|
1766
|
+
* Records only the destination used by Playwright's automatic video recorder.
|
|
1767
|
+
*
|
|
1768
|
+
* @param {object} ctx - Orchestrion context
|
|
1769
|
+
* @returns {void}
|
|
1770
|
+
*/
|
|
1771
|
+
function recordAutomaticFailureVideoPath (ctx) {
|
|
1772
|
+
const video = ctx.arguments?.[0]
|
|
1773
|
+
if (!isFailureVideoUploadEnabled || typeof video?.saveAs !== 'function') return
|
|
1774
|
+
|
|
1775
|
+
const saveAs = video.saveAs
|
|
1776
|
+
ctx.arguments[0] = new Proxy(video, {
|
|
1777
|
+
get (target, property, receiver) {
|
|
1778
|
+
if (property !== 'saveAs') return Reflect.get(target, property, receiver)
|
|
1779
|
+
return function (filePath) {
|
|
1780
|
+
if (typeof filePath === 'string' && PLAYWRIGHT_FAILURE_VIDEO_PATH_RE.test(filePath)) {
|
|
1781
|
+
automaticFailureVideoPaths.add(filePath)
|
|
1782
|
+
}
|
|
1783
|
+
return Reflect.apply(saveAs, target, arguments)
|
|
1784
|
+
}
|
|
1785
|
+
},
|
|
1786
|
+
})
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1696
1789
|
artifactsRecorderScreenshotPathCh.subscribe({ end: recordAutomaticFailureScreenshotPath })
|
|
1697
1790
|
snapshotRecorderScreenshotPathCh.subscribe({ end: recordAutomaticFailureScreenshotPath })
|
|
1791
|
+
saveAutomaticVideoCh.subscribe({ start: recordAutomaticFailureVideoPath })
|
|
1698
1792
|
|
|
1699
1793
|
if (DD_MAJOR < 6) { // <1.38.0 is only supported up to version 5
|
|
1700
1794
|
addHook({
|
|
@@ -2057,6 +2151,7 @@ function finishProcessHostStartRunner (processHost) {
|
|
|
2057
2151
|
workerReportCh.publish({
|
|
2058
2152
|
serializedTraces: message[1],
|
|
2059
2153
|
screenshots: processHost[kDdPlaywrightFailureScreenshots]?.shift(),
|
|
2154
|
+
videos: processHost[kDdPlaywrightFailureVideos]?.shift(),
|
|
2060
2155
|
})
|
|
2061
2156
|
} else if (Array.isArray(message) && message[0] === PLAYWRIGHT_WORKER_TELEMETRY_PAYLOAD_CODE) {
|
|
2062
2157
|
workerReportTelemetryCh.publish(message[1])
|
|
@@ -2212,7 +2307,8 @@ addHook({
|
|
|
2212
2307
|
|
|
2213
2308
|
function instrumentWorkerMainMethods (workerMain) {
|
|
2214
2309
|
if (!workerMain || workerMain[kDdPlaywrightWorkerInstrumented] ||
|
|
2215
|
-
typeof workerMain._runTest !== 'function' || typeof workerMain.dispatchEvent !== 'function'
|
|
2310
|
+
typeof workerMain._runTest !== 'function' || typeof workerMain.dispatchEvent !== 'function' ||
|
|
2311
|
+
typeof workerMain.gracefullyClose !== 'function') {
|
|
2216
2312
|
return workerMain
|
|
2217
2313
|
}
|
|
2218
2314
|
|
|
@@ -2228,6 +2324,15 @@ function instrumentWorkerMainMethods (workerMain) {
|
|
|
2228
2324
|
return runTestGroup.apply(this, arguments)
|
|
2229
2325
|
})
|
|
2230
2326
|
|
|
2327
|
+
// Playwright >=1.60 creates WorkerMain through a runtime factory, which Orchestrion cannot wrap statically.
|
|
2328
|
+
shimmer.wrap(workerMain, 'gracefullyClose', gracefullyClose => async function () {
|
|
2329
|
+
try {
|
|
2330
|
+
return await gracefullyClose.apply(this, arguments)
|
|
2331
|
+
} finally {
|
|
2332
|
+
await getChannelPromise(logSubmissionFlushCh)
|
|
2333
|
+
}
|
|
2334
|
+
})
|
|
2335
|
+
|
|
2231
2336
|
shimmer.wrap(workerMain, '_runTest', _runTest => async function (test) {
|
|
2232
2337
|
if (this[kDdPlaywrightDisabledTestIds]?.has(test.id)) {
|
|
2233
2338
|
test._ddIsDisabled = true
|
|
@@ -2393,8 +2498,9 @@ function instrumentWorkerMainMethods (workerMain) {
|
|
|
2393
2498
|
// We reproduce what happens in `Dispatcher#_onStepBegin` and `Dispatcher#_onStepEnd`,
|
|
2394
2499
|
// since `startTime` and `duration` are not available directly in the worker process
|
|
2395
2500
|
shimmer.wrap(workerMain, 'dispatchEvent', dispatchEvent => function (event, payload) {
|
|
2396
|
-
if (event === 'testBegin'
|
|
2501
|
+
if (event === 'testBegin') {
|
|
2397
2502
|
automaticFailureScreenshotPaths.clear()
|
|
2503
|
+
automaticFailureVideoPaths.clear()
|
|
2398
2504
|
} else if (event === 'stepBegin') {
|
|
2399
2505
|
stepInfoByStepId[payload.stepId] = {
|
|
2400
2506
|
startTime: payload.wallTime,
|
|
@@ -2411,8 +2517,12 @@ function instrumentWorkerMainMethods (workerMain) {
|
|
|
2411
2517
|
duration: payload.wallTime - stepInfo.startTime,
|
|
2412
2518
|
error: payload.error,
|
|
2413
2519
|
})
|
|
2414
|
-
} else if (event === 'attach'
|
|
2415
|
-
payload
|
|
2520
|
+
} else if (event === 'attach') {
|
|
2521
|
+
if (isAutomaticFailureScreenshotAttachment(payload)) {
|
|
2522
|
+
payload._ddIsAutomaticFailureScreenshot = true
|
|
2523
|
+
} else if (isAutomaticFailureVideoAttachment(payload)) {
|
|
2524
|
+
payload._ddIsAutomaticFailureVideo = true
|
|
2525
|
+
}
|
|
2416
2526
|
}
|
|
2417
2527
|
return dispatchEvent.apply(this, arguments)
|
|
2418
2528
|
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Serialized into browsers by browser-test integrations. Excluded from coverage by filename.
|
|
4
|
+
|
|
5
|
+
/** @returns {{ isRumInstrumented: boolean, isRumActive: boolean, rumSamplingRate: number | null }} */
|
|
6
|
+
function detectRum () {
|
|
7
|
+
const isRumInstrumented = !!window.DD_RUM
|
|
8
|
+
const isRumActive = window.DD_RUM && window.DD_RUM.getInternalContext
|
|
9
|
+
? !!window.DD_RUM.getInternalContext()
|
|
10
|
+
: false
|
|
11
|
+
const rumInitConfiguration = window.DD_RUM && window.DD_RUM.getInitConfiguration
|
|
12
|
+
? window.DD_RUM.getInitConfiguration()
|
|
13
|
+
: undefined
|
|
14
|
+
const rumSamplingRate = rumInitConfiguration ? rumInitConfiguration.sessionSampleRate : null
|
|
15
|
+
|
|
16
|
+
return { isRumInstrumented, isRumActive, rumSamplingRate }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @returns {boolean} */
|
|
20
|
+
function stopRumSession () {
|
|
21
|
+
if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
22
|
+
window.DD_RUM.stopSession()
|
|
23
|
+
return true
|
|
24
|
+
}
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @returns {boolean} */
|
|
29
|
+
function stopRumSessionAndReportActivity () {
|
|
30
|
+
if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
31
|
+
const isRumActive = window.DD_RUM.getInternalContext
|
|
32
|
+
? !!window.DD_RUM.getInternalContext()
|
|
33
|
+
: false
|
|
34
|
+
window.DD_RUM.stopSession()
|
|
35
|
+
return isRumActive
|
|
36
|
+
}
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = { detectRum, stopRumSession, stopRumSessionAndReportActivity }
|
|
@@ -5,15 +5,45 @@ const {
|
|
|
5
5
|
channel,
|
|
6
6
|
addHook,
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
|
+
const {
|
|
9
|
+
wrapPoolRelease,
|
|
10
|
+
wrapPromisePoolAcquire,
|
|
11
|
+
wrapPromisePoolQueryMethod,
|
|
12
|
+
} = require('./helpers/pool-acquire')
|
|
13
|
+
|
|
14
|
+
addHook({
|
|
15
|
+
name: 'sequelize',
|
|
16
|
+
versions: ['>=4'],
|
|
17
|
+
file: 'lib/dialects/abstract/connection-manager.js',
|
|
18
|
+
}, ConnectionManager => {
|
|
19
|
+
shimmer.wrap(ConnectionManager.prototype, 'getConnection', getConnection => wrapPromisePoolAcquire(
|
|
20
|
+
getConnection,
|
|
21
|
+
resolveSequelizeDriver,
|
|
22
|
+
resolveSequelizeConfig,
|
|
23
|
+
sequelizeHasIdleConnection
|
|
24
|
+
))
|
|
25
|
+
shimmer.wrap(ConnectionManager.prototype, 'releaseConnection', wrapPoolRelease)
|
|
26
|
+
if (typeof ConnectionManager.prototype.destroyConnection === 'function') {
|
|
27
|
+
shimmer.wrap(ConnectionManager.prototype, 'destroyConnection', wrapPoolRelease)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return ConnectionManager
|
|
31
|
+
})
|
|
8
32
|
|
|
9
33
|
addHook({ name: 'sequelize', versions: ['>=4'], file: 'lib/sequelize.js' }, Sequelize => {
|
|
10
34
|
const startCh = channel('datadog:sequelize:query:start')
|
|
11
35
|
const finishCh = channel('datadog:sequelize:query:finish')
|
|
12
36
|
|
|
13
37
|
shimmer.wrap(Sequelize.prototype, 'query', query => {
|
|
38
|
+
const queryWithPool = wrapPromisePoolQueryMethod(
|
|
39
|
+
query,
|
|
40
|
+
(sequelize, args) => args[1]?.transaction ? undefined : sequelize.connectionManager,
|
|
41
|
+
sequelize => resolveSequelizeDriver(sequelize.connectionManager)
|
|
42
|
+
)
|
|
43
|
+
|
|
14
44
|
return function (sql, options) {
|
|
15
45
|
if (!startCh.hasSubscribers) {
|
|
16
|
-
return
|
|
46
|
+
return queryWithPool.apply(this, arguments)
|
|
17
47
|
}
|
|
18
48
|
|
|
19
49
|
let dialect
|
|
@@ -33,7 +63,7 @@ addHook({ name: 'sequelize', versions: ['>=4'], file: 'lib/sequelize.js' }, Sequ
|
|
|
33
63
|
}
|
|
34
64
|
|
|
35
65
|
return startCh.runStores({ sql, dialect }, () => {
|
|
36
|
-
const promise =
|
|
66
|
+
const promise = queryWithPool.apply(this, arguments)
|
|
37
67
|
promise.then(onFinish, () => { onFinish() })
|
|
38
68
|
|
|
39
69
|
return promise
|
|
@@ -43,3 +73,65 @@ addHook({ name: 'sequelize', versions: ['>=4'], file: 'lib/sequelize.js' }, Sequ
|
|
|
43
73
|
|
|
44
74
|
return Sequelize
|
|
45
75
|
})
|
|
76
|
+
|
|
77
|
+
addHook({ name: 'sequelize', versions: ['>=4'], file: 'lib/transaction.js' }, Transaction => {
|
|
78
|
+
shimmer.wrap(Transaction.prototype, 'prepareEnvironment', prepareEnvironment => wrapPromisePoolQueryMethod(
|
|
79
|
+
prepareEnvironment,
|
|
80
|
+
transaction => transaction.parent ? undefined : transaction.sequelize.connectionManager,
|
|
81
|
+
transaction => resolveSequelizeDriver(transaction.sequelize.connectionManager)
|
|
82
|
+
))
|
|
83
|
+
|
|
84
|
+
return Transaction
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @typedef {{
|
|
89
|
+
* available: number,
|
|
90
|
+
* pending?: number,
|
|
91
|
+
* waiting?: number,
|
|
92
|
+
* }} SequelizePool
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {{ pool: SequelizePool & { read?: SequelizePool, write?: SequelizePool } }} manager
|
|
97
|
+
* @param {[{ type?: string, useMaster?: boolean }?]} args
|
|
98
|
+
* @returns {boolean}
|
|
99
|
+
*/
|
|
100
|
+
function sequelizeHasIdleConnection (manager, args) {
|
|
101
|
+
const pool = manager.pool
|
|
102
|
+
const options = args[0]
|
|
103
|
+
const selected = pool?.read === undefined
|
|
104
|
+
? pool
|
|
105
|
+
: options?.type === 'SELECT' && !options?.useMaster ? pool.read : pool.write
|
|
106
|
+
const waiting = selected.waiting ?? selected.pending
|
|
107
|
+
return selected.available > waiting
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {{ dialectName?: string }|undefined} manager
|
|
112
|
+
* @returns {'mariadb'|'mysql2'|'pg'|undefined}
|
|
113
|
+
*/
|
|
114
|
+
function resolveSequelizeDriver (manager) {
|
|
115
|
+
switch (manager?.dialectName) {
|
|
116
|
+
case 'mariadb':
|
|
117
|
+
return 'mariadb'
|
|
118
|
+
case 'mysql':
|
|
119
|
+
return 'mysql2'
|
|
120
|
+
case 'postgres':
|
|
121
|
+
return 'pg'
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @param {{ config: Record<string, unknown> & { username?: string } }} manager
|
|
127
|
+
* @returns {Record<string, unknown>}
|
|
128
|
+
*/
|
|
129
|
+
function resolveSequelizeConfig (manager) {
|
|
130
|
+
const config = manager.config
|
|
131
|
+
return {
|
|
132
|
+
database: config.database,
|
|
133
|
+
host: config.host,
|
|
134
|
+
port: config.port,
|
|
135
|
+
user: config.username,
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const tracingChannel = require('dc-polyfill')
|
|
3
|
+
const { channel, tracingChannel } = require('dc-polyfill')
|
|
4
4
|
|
|
5
5
|
const shimmer = require('../../datadog-shimmer')
|
|
6
6
|
const satisfies = require('../../../vendor/dist/semifies')
|
|
7
|
-
const {
|
|
8
|
-
addHook,
|
|
9
|
-
} = require('./helpers/instrument')
|
|
7
|
+
const { addHook } = require('./helpers/instrument')
|
|
10
8
|
const { createWrapFetch } = require('./helpers/fetch')
|
|
11
9
|
|
|
12
10
|
const ch = tracingChannel('apm:undici:fetch')
|
|
11
|
+
const upgradeCh = channel('apm:undici:request:upgrade')
|
|
13
12
|
|
|
14
13
|
// Undici 5.0.x has a bug where fetch doesn't preserve AggregateError in the error cause chain
|
|
15
14
|
// Use native DC only for versions where error handling works correctly
|
|
16
15
|
const NATIVE_DC_VERSION = '>=4.7.0 <5.0.0 || >=5.1.0'
|
|
17
16
|
|
|
17
|
+
addHook({
|
|
18
|
+
name: 'undici',
|
|
19
|
+
versions: ['>=4.4.1 <8.0.0', '>=8.0.0'],
|
|
20
|
+
file: 'lib/core/request.js',
|
|
21
|
+
}, wrapRequestUpgrade)
|
|
22
|
+
|
|
18
23
|
addHook({
|
|
19
24
|
name: 'undici',
|
|
20
25
|
versions: ['^4.4.1', '5', '>=6.0.0'],
|
|
@@ -27,3 +32,47 @@ addHook({
|
|
|
27
32
|
// For older versions or those with buggy error handling, wrap fetch
|
|
28
33
|
return shimmer.wrap(undici, 'fetch', createWrapFetch(undici.Request, ch))
|
|
29
34
|
})
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {Function & { prototype: Record<string, Function> }} Request
|
|
38
|
+
* @returns {Function}
|
|
39
|
+
*/
|
|
40
|
+
function wrapRequestUpgrade (Request) {
|
|
41
|
+
const requestSource = Function.prototype.toString.call(Request)
|
|
42
|
+
const methodName = typeof Request.prototype.onRequestUpgrade === 'function'
|
|
43
|
+
? 'onRequestUpgrade'
|
|
44
|
+
: 'onUpgrade'
|
|
45
|
+
const method = Request.prototype[methodName]
|
|
46
|
+
|
|
47
|
+
// Orchestrion cannot leave fixed source byte-for-byte untouched after a conditional AST match.
|
|
48
|
+
if (typeof method !== 'function' ||
|
|
49
|
+
!requestSource.includes('channels.trailers.publish') ||
|
|
50
|
+
Function.prototype.toString.call(method).includes('channels.trailers.publish')) {
|
|
51
|
+
return Request
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
shimmer.wrap(Request.prototype, methodName, createWrapUpgrade)
|
|
55
|
+
return Request
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {Function} upgrade
|
|
60
|
+
* @returns {Function}
|
|
61
|
+
*/
|
|
62
|
+
function createWrapUpgrade (upgrade) {
|
|
63
|
+
return function (statusCode, headers, socket) {
|
|
64
|
+
if (!upgradeCh.hasSubscribers) return upgrade.apply(this, arguments)
|
|
65
|
+
|
|
66
|
+
let result
|
|
67
|
+
try {
|
|
68
|
+
result = upgrade.apply(this, arguments)
|
|
69
|
+
} catch (error) {
|
|
70
|
+
upgradeCh.publish({ error, headers, request: this, statusCode })
|
|
71
|
+
throw error
|
|
72
|
+
}
|
|
73
|
+
if (!this.aborted) {
|
|
74
|
+
upgradeCh.publish({ headers, request: this, statusCode })
|
|
75
|
+
}
|
|
76
|
+
return result
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -56,6 +56,22 @@ const VITEST_NO_WORKER_INIT_SETUP_FILE = path.join(
|
|
|
56
56
|
'ci',
|
|
57
57
|
'vitest-no-worker-init-setup.mjs'
|
|
58
58
|
)
|
|
59
|
+
const VITEST_NO_WORKER_INIT_RUNNER_SETUP_FILE = path.join(
|
|
60
|
+
__dirname,
|
|
61
|
+
'..',
|
|
62
|
+
'..',
|
|
63
|
+
'..',
|
|
64
|
+
'ci',
|
|
65
|
+
'vitest-no-worker-init-runner-setup.mjs'
|
|
66
|
+
)
|
|
67
|
+
const VITEST_NO_WORKER_INIT_V5_SETUP_FILE = path.join(
|
|
68
|
+
__dirname,
|
|
69
|
+
'..',
|
|
70
|
+
'..',
|
|
71
|
+
'..',
|
|
72
|
+
'ci',
|
|
73
|
+
'vitest-no-worker-init-v5-setup.mjs'
|
|
74
|
+
)
|
|
59
75
|
const VITEST_BROWSER_SETUP_FILE_PLUGIN = {
|
|
60
76
|
name: 'datadog:vitest-browser-setup-file',
|
|
61
77
|
config: configureVitestBrowserSetupFile,
|
|
@@ -325,7 +341,10 @@ function isEarlyFlakeDetectionActive (state) {
|
|
|
325
341
|
function configure (ctx, frameworkVersion, testSpecifications, setupData, options) {
|
|
326
342
|
const { shouldReportTestModule, state } = options
|
|
327
343
|
reserveEarlyFlakeDetectionSuite = options.reserveEarlyFlakeDetectionSuite
|
|
328
|
-
|
|
344
|
+
const setupFile = satisfies(frameworkVersion, '>=5.0.0')
|
|
345
|
+
? VITEST_NO_WORKER_INIT_V5_SETUP_FILE
|
|
346
|
+
: VITEST_NO_WORKER_INIT_RUNNER_SETUP_FILE
|
|
347
|
+
addSetupFileToVitestConfigs(ctx, setupFile, testSpecifications)
|
|
329
348
|
addVitestBrowserSetupFileAccess(testSpecifications)
|
|
330
349
|
|
|
331
350
|
const {
|
|
@@ -470,8 +489,15 @@ function allowVitestBrowserSetupFile (viteConfig) {
|
|
|
470
489
|
const allow = viteConfig.server?.fs?.allow
|
|
471
490
|
if (!allow) return
|
|
472
491
|
|
|
473
|
-
|
|
474
|
-
|
|
492
|
+
const setupFiles = [
|
|
493
|
+
VITEST_NO_WORKER_INIT_SETUP_FILE,
|
|
494
|
+
VITEST_NO_WORKER_INIT_RUNNER_SETUP_FILE,
|
|
495
|
+
VITEST_NO_WORKER_INIT_V5_SETUP_FILE,
|
|
496
|
+
]
|
|
497
|
+
for (const setupFile of setupFiles) {
|
|
498
|
+
if (!allow.includes(setupFile)) {
|
|
499
|
+
allow.push(setupFile)
|
|
500
|
+
}
|
|
475
501
|
}
|
|
476
502
|
}
|
|
477
503
|
|
|
@@ -493,6 +519,7 @@ function addVitestBrowserSetupFileAccess (testSpecifications) {
|
|
|
493
519
|
if (!browserServerProject) continue
|
|
494
520
|
|
|
495
521
|
addVitestBrowserCommand(safeConfig(project))
|
|
522
|
+
addVitestBrowserRuntimeCommand(project)
|
|
496
523
|
if (configuredProjects.has(browserServerProject)) continue
|
|
497
524
|
|
|
498
525
|
configuredProjects.add(browserServerProject)
|
|
@@ -507,6 +534,13 @@ function addVitestBrowserSetupFileAccess (testSpecifications) {
|
|
|
507
534
|
}
|
|
508
535
|
}
|
|
509
536
|
|
|
537
|
+
function addVitestBrowserRuntimeCommand (project) {
|
|
538
|
+
const parentBrowser = project?._parentBrowser || project?._parent?._parentBrowser
|
|
539
|
+
if (parentBrowser?.commands) {
|
|
540
|
+
parentBrowser.commands[VITEST_BROWSER_EFD_SUITE_ADMISSION_COMMAND] = handleBrowserEfdSuiteAdmission
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
510
544
|
/**
|
|
511
545
|
* Adds the private EFD admission command to a Vitest Browser Mode configuration.
|
|
512
546
|
*
|
|
@@ -1602,15 +1636,18 @@ function splitNodeOptions (nodeOptions) {
|
|
|
1602
1636
|
}
|
|
1603
1637
|
|
|
1604
1638
|
function serializeNodeOptions (tokens) {
|
|
1605
|
-
|
|
1639
|
+
let serializedTokens = ''
|
|
1640
|
+
let hasSerializedToken = false
|
|
1606
1641
|
for (const token of tokens) {
|
|
1642
|
+
if (hasSerializedToken) serializedTokens += ' '
|
|
1607
1643
|
if (NODE_OPTIONS_QUOTE_RE.test(token)) {
|
|
1608
|
-
serializedTokens
|
|
1644
|
+
serializedTokens += JSON.stringify(token)
|
|
1609
1645
|
} else {
|
|
1610
|
-
serializedTokens
|
|
1646
|
+
serializedTokens += token
|
|
1611
1647
|
}
|
|
1648
|
+
hasSerializedToken = true
|
|
1612
1649
|
}
|
|
1613
|
-
return serializedTokens
|
|
1650
|
+
return serializedTokens
|
|
1614
1651
|
}
|
|
1615
1652
|
|
|
1616
1653
|
function getTestSpecificationProject (testSpecification) {
|