dd-trace 6.4.0 → 6.5.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/README.electron.md +7 -0
- package/README.md +17 -0
- package/ci/diagnose.js +2100 -0
- package/ci/init.js +23 -2
- package/ci/runbook.md +198 -0
- package/ci/test-optimization-validation/approval-artifacts.js +143 -0
- package/ci/test-optimization-validation/approval.js +299 -0
- package/ci/test-optimization-validation/artifact-id.js +20 -0
- package/ci/test-optimization-validation/bounded-json.js +121 -0
- package/ci/test-optimization-validation/ci-command-candidate.js +83 -0
- package/ci/test-optimization-validation/ci-discovery.js +181 -0
- package/ci/test-optimization-validation/ci-remediation.js +210 -0
- package/ci/test-optimization-validation/cli.js +903 -0
- package/ci/test-optimization-validation/command-blocker.js +81 -0
- package/ci/test-optimization-validation/command-output-policy.js +206 -0
- package/ci/test-optimization-validation/command-runner.js +707 -0
- package/ci/test-optimization-validation/command-suitability.js +471 -0
- package/ci/test-optimization-validation/executable-approval.js +48 -0
- package/ci/test-optimization-validation/executable.js +480 -0
- package/ci/test-optimization-validation/generated-file-policy.js +63 -0
- package/ci/test-optimization-validation/generated-files.js +351 -0
- package/ci/test-optimization-validation/generated-verifier.js +196 -0
- package/ci/test-optimization-validation/init-probe-preload.js +163 -0
- package/ci/test-optimization-validation/init-probe.js +246 -0
- package/ci/test-optimization-validation/late-initialization.js +63 -0
- package/ci/test-optimization-validation/local-command.js +163 -0
- package/ci/test-optimization-validation/manifest-loader.js +133 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +738 -0
- package/ci/test-optimization-validation/manifest-schema.js +862 -0
- package/ci/test-optimization-validation/offline-fixtures.js +327 -0
- package/ci/test-optimization-validation/offline-output.js +406 -0
- package/ci/test-optimization-validation/payload-normalizer.js +72 -0
- package/ci/test-optimization-validation/plan-writer.js +1120 -0
- package/ci/test-optimization-validation/preflight-runner.js +114 -0
- package/ci/test-optimization-validation/redaction.js +331 -0
- package/ci/test-optimization-validation/report-writer.js +1508 -0
- package/ci/test-optimization-validation/safe-files.js +203 -0
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +159 -0
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +657 -0
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +780 -0
- package/ci/test-optimization-validation/scenarios/early-flake-detection.js +141 -0
- package/ci/test-optimization-validation/scenarios/helpers.js +539 -0
- package/ci/test-optimization-validation/scenarios/test-management.js +218 -0
- package/ci/test-optimization-validation/setup-runner.js +97 -0
- package/ci/test-optimization-validation/static-diagnosis.js +159 -0
- package/ci/test-optimization-validation/test-output.js +129 -0
- package/ci/test-optimization-validation-manifest.schema.json +1 -0
- package/ci/validate-test-optimization.js +3 -0
- package/ext/exporters.js +1 -0
- package/index.d.ts +121 -8
- package/init.js +18 -0
- package/initialize.mjs +1 -1
- package/loader-hook.mjs +28 -18
- package/openfeature.d.ts +1 -0
- package/openfeature.js +4 -0
- package/package.json +10 -7
- package/packages/datadog-instrumentations/src/ai.js +8 -2
- package/packages/datadog-instrumentations/src/child_process.js +1 -1
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber-worker-threads.js +9 -3
- package/packages/datadog-instrumentations/src/cucumber.js +20 -7
- package/packages/datadog-instrumentations/src/cypress-config.js +398 -52
- package/packages/datadog-instrumentations/src/fastify.js +7 -11
- package/packages/datadog-instrumentations/src/helpers/hook.js +27 -6
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +8 -8
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +28 -2
- package/packages/datadog-instrumentations/src/jest.js +26 -0
- package/packages/datadog-instrumentations/src/mariadb.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +0 -2
- package/packages/datadog-instrumentations/src/mocha/utils.js +0 -4
- package/packages/datadog-instrumentations/src/mongodb.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +3 -3
- package/packages/datadog-instrumentations/src/mquery.js +2 -2
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +24 -0
- package/packages/datadog-instrumentations/src/nyc.js +0 -2
- package/packages/datadog-instrumentations/src/oracledb.js +2 -2
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/playwright.js +159 -22
- package/packages/datadog-instrumentations/src/process.js +3 -0
- package/packages/datadog-instrumentations/src/router.js +18 -8
- package/packages/datadog-instrumentations/src/selenium.js +52 -26
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +2 -2
- package/packages/datadog-instrumentations/src/vitest-main.js +0 -2
- package/packages/datadog-instrumentations/src/ws.js +2 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +2 -2
- package/packages/datadog-plugin-cucumber/src/index.js +1 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +19 -57
- package/packages/datadog-plugin-cypress/src/index.js +6 -1
- package/packages/datadog-plugin-cypress/src/support.js +92 -26
- package/packages/datadog-plugin-electron/src/ipc.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +87 -45
- package/packages/datadog-plugin-graphql/src/validate.js +2 -2
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -1
- package/packages/datadog-plugin-langchain/src/handlers/language_models.js +2 -1
- package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +177 -64
- package/packages/datadog-plugin-router/src/index.js +11 -2
- package/packages/datadog-plugin-selenium/src/index.js +5 -36
- package/packages/datadog-plugin-ws/src/close.js +2 -1
- package/packages/datadog-plugin-ws/src/producer.js +2 -1
- package/packages/datadog-plugin-ws/src/receiver.js +2 -1
- package/packages/datadog-plugin-ws/src/server.js +2 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +3 -1
- package/packages/dd-trace/src/azure_metadata.js +2 -1
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +93 -28
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +160 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +288 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/payload-projection.js +84 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +369 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +60 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +41 -3
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -2
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +1 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +6 -2
- package/packages/dd-trace/src/ci-visibility/rum.js +7 -0
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +4 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +137 -9
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +168 -8
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +90 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +16 -0
- package/packages/dd-trace/src/config/helper.js +1 -0
- package/packages/dd-trace/src/config/index.js +10 -0
- package/packages/dd-trace/src/config/supported-configurations.json +66 -0
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/common/client-library-headers.js +21 -0
- package/packages/dd-trace/src/exporters/common/request.js +59 -30
- package/packages/dd-trace/src/exporters/common/url.js +15 -1
- package/packages/dd-trace/src/feature-registry.js +10 -3
- package/packages/dd-trace/src/llmobs/experiments/client.js +113 -0
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +154 -0
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +283 -0
- package/packages/dd-trace/src/llmobs/experiments/index.js +152 -0
- package/packages/dd-trace/src/llmobs/experiments/noop.js +30 -0
- package/packages/dd-trace/src/llmobs/experiments/result.js +34 -0
- package/packages/dd-trace/src/llmobs/noop.js +6 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +20 -3
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +2 -2
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +8 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +48 -14
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +43 -0
- package/packages/dd-trace/src/llmobs/sdk.js +17 -0
- package/packages/dd-trace/src/llmobs/tagger.js +68 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +2 -1
- package/packages/dd-trace/src/llmobs/util.js +32 -0
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +322 -0
- package/packages/dd-trace/src/openfeature/configuration_source.js +90 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +14 -23
- package/packages/dd-trace/src/openfeature/index.js +0 -2
- package/packages/dd-trace/src/openfeature/noop.js +1 -28
- package/packages/dd-trace/src/openfeature/register.js +16 -27
- package/packages/dd-trace/src/openfeature/remote_config.js +15 -18
- package/packages/dd-trace/src/openfeature/require-provider.js +18 -0
- package/packages/dd-trace/src/opentelemetry/span-ending-hook.js +10 -0
- package/packages/dd-trace/src/opentelemetry/span.js +5 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +20 -6
- package/packages/dd-trace/src/plugins/util/git.js +3 -2
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +29 -5
- package/packages/dd-trace/src/plugins/util/test.js +56 -4
- package/packages/dd-trace/src/proxy.js +84 -7
- package/packages/dd-trace/src/span_processor.js +5 -0
- package/packages/dd-trace/src/standalone/index.js +0 -14
- package/packages/dd-trace/src/telemetry/send-data.js +2 -2
- package/packages/dd-trace/src/util.js +26 -0
- package/vendor/dist/@apm-js-collab/code-transformer/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/vendor/dist/shell-quote/index.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/require-optional-peer.js +0 -17
|
@@ -86,26 +86,36 @@ function createLayerDispatchWrappers (name) {
|
|
|
86
86
|
const finishChannel = channel(`apm:${name}:middleware:finish`)
|
|
87
87
|
const errorChannel = channel(`apm:${name}:middleware:error`)
|
|
88
88
|
const nextChannel = channel(`apm:${name}:middleware:next`)
|
|
89
|
+
const repeatChannel = channel(`apm:${name}:middleware:repeat`)
|
|
89
90
|
// Bound per name so express and a bare router keep independent guards.
|
|
90
91
|
const publishError = createErrorPublisher(errorChannel)
|
|
91
92
|
|
|
92
|
-
|
|
93
|
+
/**
|
|
94
|
+
* @param {import('node:http').IncomingMessage} req
|
|
95
|
+
* @param {string | undefined} layerName
|
|
96
|
+
* @param {(error?: unknown) => void} originalNext
|
|
97
|
+
*/
|
|
98
|
+
function wrapNext (req, layerName, originalNext) {
|
|
93
99
|
// Per layer dispatch, N per request. Named `next`/arity-1 mirrors the
|
|
94
100
|
// router continuation so wrapCallback skips its name/length rewrite.
|
|
95
|
-
let
|
|
101
|
+
let calls = 0
|
|
96
102
|
return shimmer.wrapCallback(originalNext, original => function next (error) {
|
|
97
103
|
// A handler that calls `next()` and then rejects (`next(); await bg()`)
|
|
98
104
|
// makes the host call this continuation twice. Publish once so the second
|
|
99
105
|
// pass cannot tag the already-finished span's parent with a late error.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
calls++
|
|
107
|
+
if (calls === 1) {
|
|
103
108
|
if (error && error !== 'route' && error !== 'router') {
|
|
104
109
|
publishError({ req, error })
|
|
105
110
|
}
|
|
106
111
|
|
|
107
112
|
nextChannel.publish({ req })
|
|
108
113
|
finishChannel.publish({ req })
|
|
114
|
+
} else if (calls === 2) {
|
|
115
|
+
// Surface the repeat as a diagnostic on the still-live request span. The
|
|
116
|
+
// host cannot tell a legitimate `next(); await bg()` from a buggy double
|
|
117
|
+
// `next()`, so this only records that it happened, not that it is wrong.
|
|
118
|
+
repeatChannel.publish({ req, name: layerName, error })
|
|
109
119
|
}
|
|
110
120
|
|
|
111
121
|
original.apply(this, arguments)
|
|
@@ -125,7 +135,7 @@ function createLayerDispatchWrappers (name) {
|
|
|
125
135
|
const meta = getLayerMeta(this)
|
|
126
136
|
if (meta === undefined || this.handle.length > 3) return originalRequest.call(this, req, res, next)
|
|
127
137
|
|
|
128
|
-
const wrappedNext = typeof next === 'function' ? wrapNext(req, next) : next
|
|
138
|
+
const wrappedNext = typeof next === 'function' ? wrapNext(req, meta.name, next) : next
|
|
129
139
|
enterChannel.publish({ name: meta.name, req, route: resolveLayerRoute(meta, this), layer: this })
|
|
130
140
|
|
|
131
141
|
try {
|
|
@@ -143,7 +153,7 @@ function createLayerDispatchWrappers (name) {
|
|
|
143
153
|
const meta = getLayerMeta(this)
|
|
144
154
|
if (meta === undefined || this.handle.length !== 4) return originalError.call(this, error, req, res, next)
|
|
145
155
|
|
|
146
|
-
const wrappedNext = typeof next === 'function' ? wrapNext(req, next) : next
|
|
156
|
+
const wrappedNext = typeof next === 'function' ? wrapNext(req, meta.name, next) : next
|
|
147
157
|
enterChannel.publish({ name: meta.name, req, route: resolveLayerRoute(meta, this), layer: this })
|
|
148
158
|
|
|
149
159
|
try {
|
|
@@ -170,7 +180,7 @@ function createLayerDispatchWrappers (name) {
|
|
|
170
180
|
const isErrorHandler = original.length === 4
|
|
171
181
|
const req = args[isErrorHandler ? 1 : 0]
|
|
172
182
|
const nextIndex = isErrorHandler ? 3 : 2
|
|
173
|
-
if (typeof args[nextIndex] === 'function') args[nextIndex] = wrapNext(req, args[nextIndex])
|
|
183
|
+
if (typeof args[nextIndex] === 'function') args[nextIndex] = wrapNext(req, meta.name, args[nextIndex])
|
|
174
184
|
|
|
175
185
|
enterChannel.publish({ name: meta.name, req, route: resolveLayerRoute(meta, layer), layer })
|
|
176
186
|
|
|
@@ -5,6 +5,10 @@ const realSetTimeout = setTimeout
|
|
|
5
5
|
|
|
6
6
|
const shimmer = require('../../datadog-shimmer')
|
|
7
7
|
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
8
|
+
const {
|
|
9
|
+
RUM_TEST_EXECUTION_ID_COOKIE_NAME: DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME,
|
|
10
|
+
} = require('../../dd-trace/src/ci-visibility/rum')
|
|
11
|
+
const log = require('../../dd-trace/src/log')
|
|
8
12
|
const { addHook, channel } = require('./helpers/instrument')
|
|
9
13
|
|
|
10
14
|
const ciSeleniumDriverGetStartCh = channel('ci:selenium:driver:get')
|
|
@@ -20,7 +24,6 @@ if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
|
20
24
|
const IS_RUM_ACTIVE_SCRIPT = 'return !!window.DD_RUM'
|
|
21
25
|
|
|
22
26
|
const DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS = getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')
|
|
23
|
-
const DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME = 'datadog-ci-visibility-test-execution-id'
|
|
24
27
|
|
|
25
28
|
// TODO: can we increase the supported version range?
|
|
26
29
|
addHook({
|
|
@@ -32,28 +35,47 @@ addHook({
|
|
|
32
35
|
if (!ciSeleniumDriverGetStartCh.hasSubscribers) {
|
|
33
36
|
return get.apply(this, arguments)
|
|
34
37
|
}
|
|
35
|
-
let traceId
|
|
36
|
-
const setTraceId = (inputTraceId) => {
|
|
37
|
-
traceId = inputTraceId
|
|
38
|
-
}
|
|
39
38
|
const getResult = await get.apply(this, arguments)
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
let isRumActive
|
|
41
|
+
try {
|
|
42
|
+
isRumActive = await this.executeScript(IS_RUM_ACTIVE_SCRIPT)
|
|
43
|
+
} catch (error) {
|
|
44
|
+
log.error('Selenium RUM detection error', error)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let browserName
|
|
48
|
+
let browserVersion
|
|
49
|
+
try {
|
|
50
|
+
const capabilities = await this.getCapabilities()
|
|
51
|
+
browserName = capabilities.getBrowserName()
|
|
52
|
+
browserVersion = capabilities.getBrowserVersion()
|
|
53
|
+
} catch (error) {
|
|
54
|
+
log.error('Selenium browser metadata error', error)
|
|
55
|
+
}
|
|
43
56
|
|
|
44
|
-
|
|
45
|
-
setTraceId,
|
|
57
|
+
const context = {
|
|
46
58
|
seleniumVersion,
|
|
47
|
-
browserName
|
|
48
|
-
browserVersion
|
|
59
|
+
browserName,
|
|
60
|
+
browserVersion,
|
|
49
61
|
isRumActive,
|
|
50
|
-
|
|
62
|
+
testExecutionId: undefined,
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
ciSeleniumDriverGetStartCh.publish(context)
|
|
66
|
+
} catch (error) {
|
|
67
|
+
log.error('Selenium RUM correlation channel error', error)
|
|
68
|
+
}
|
|
51
69
|
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
70
|
+
if (context.testExecutionId && isRumActive) {
|
|
71
|
+
try {
|
|
72
|
+
await this.manage().addCookie({
|
|
73
|
+
name: DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME,
|
|
74
|
+
value: context.testExecutionId,
|
|
75
|
+
})
|
|
76
|
+
} catch (error) {
|
|
77
|
+
log.error('Selenium RUM correlation cookie error', error)
|
|
78
|
+
}
|
|
57
79
|
}
|
|
58
80
|
|
|
59
81
|
return getResult
|
|
@@ -63,16 +85,20 @@ addHook({
|
|
|
63
85
|
if (!ciSeleniumDriverGetStartCh.hasSubscribers) {
|
|
64
86
|
return quit.apply(this, arguments)
|
|
65
87
|
}
|
|
66
|
-
|
|
88
|
+
try {
|
|
89
|
+
const isRumActive = await this.executeScript(RUM_STOP_SESSION_SCRIPT)
|
|
67
90
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
91
|
+
if (isRumActive) {
|
|
92
|
+
// We'll have time for RUM to flush the events (there's no callback to know when it's done)
|
|
93
|
+
await new Promise(resolve => {
|
|
94
|
+
realSetTimeout(() => {
|
|
95
|
+
resolve()
|
|
96
|
+
}, DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS)
|
|
97
|
+
})
|
|
98
|
+
await this.manage().deleteCookie(DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME)
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
log.error('Selenium RUM cleanup error', error)
|
|
76
102
|
}
|
|
77
103
|
|
|
78
104
|
return quit.apply(this, arguments)
|
|
@@ -784,7 +784,7 @@ function getRepeatedTestReport (task, testName, testSuiteAbsolutePath, testPrope
|
|
|
784
784
|
|
|
785
785
|
return {
|
|
786
786
|
errors,
|
|
787
|
-
finalAttempt: attempts
|
|
787
|
+
finalAttempt: attempts.at(-1),
|
|
788
788
|
nonFinalAttempts: attempts.slice(0, -1),
|
|
789
789
|
state,
|
|
790
790
|
status,
|
|
@@ -880,7 +880,7 @@ function reportFinalTestAttempt (testReport) {
|
|
|
880
880
|
const finalAttempt = testReport.finalAttempt
|
|
881
881
|
|
|
882
882
|
if (status === 'fail') {
|
|
883
|
-
const error = errors
|
|
883
|
+
const error = errors.at(-1) || errors[0]
|
|
884
884
|
reportTestAttempt(testReport, finalAttempt || {
|
|
885
885
|
error,
|
|
886
886
|
finalStatus,
|
|
@@ -1343,10 +1343,8 @@ function wrapTinyPoolRun (TinyPool) {
|
|
|
1343
1343
|
|
|
1344
1344
|
shimmer.wrap(TinyPool.prototype, 'run', run => async function () {
|
|
1345
1345
|
// We have to do this before and after because the threads list gets recycled, that is, the processes are re-created
|
|
1346
|
-
// eslint-disable-next-line unicorn/no-array-for-each
|
|
1347
1346
|
this.threads.forEach(threadHandler)
|
|
1348
1347
|
const runResult = await run.apply(this, arguments)
|
|
1349
|
-
// eslint-disable-next-line unicorn/no-array-for-each
|
|
1350
1348
|
this.threads.forEach(threadHandler)
|
|
1351
1349
|
return runResult
|
|
1352
1350
|
})
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { tracingChannel } = /** @type {import('node:diagnostics_channel')} */ (require('dc-polyfill'))
|
|
4
4
|
|
|
5
5
|
const shimmer = require('../../datadog-shimmer')
|
|
6
|
+
const { getSegment } = require('../../dd-trace/src/util')
|
|
6
7
|
const {
|
|
7
8
|
addHook,
|
|
8
9
|
channel,
|
|
@@ -106,7 +107,7 @@ function createWrapEmit (emit) {
|
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
const ctx = { req }
|
|
109
|
-
ctx.req.resStatus = headers[0]
|
|
110
|
+
ctx.req.resStatus = getSegment(headers[0], ' ', 1)
|
|
110
111
|
|
|
111
112
|
emitCh.runStores(ctx, () => {
|
|
112
113
|
try {
|
|
@@ -94,7 +94,7 @@ class RunInChildContextPlugin extends BaseContextPlugin {
|
|
|
94
94
|
static retryable = false
|
|
95
95
|
|
|
96
96
|
bindStart (ctx) {
|
|
97
|
-
if (SUPPRESSED_CHILD_CONTEXT_SUBTYPES.has(
|
|
97
|
+
if (SUPPRESSED_CHILD_CONTEXT_SUBTYPES.has(getRunInChildContextSubtype(ctx))) {
|
|
98
98
|
// Pass the active store through unchanged so any nested spans
|
|
99
99
|
// remain parented to the surrounding map/parallel span
|
|
100
100
|
ctx.suppressed = true
|
|
@@ -105,7 +105,7 @@ class RunInChildContextPlugin extends BaseContextPlugin {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
// runInChildContext has two overloads: `(name, fn, options)` and `(fn, options)`.
|
|
108
|
-
function
|
|
108
|
+
function getRunInChildContextSubtype (ctx) {
|
|
109
109
|
const args = ctx.arguments || []
|
|
110
110
|
const opts = typeof args[0] === 'function' ? args[1] : args[2]
|
|
111
111
|
return opts?.subType
|
|
@@ -16,7 +16,8 @@ const REPLAYED_STATUSES = new Set(['SUCCEEDED', 'FAILED'])
|
|
|
16
16
|
* @returns {{ stepId: string | undefined, stepData: object | undefined }}
|
|
17
17
|
*/
|
|
18
18
|
function getStepDataForNext (ctxImpl) {
|
|
19
|
-
|
|
19
|
+
// @aws/durable-execution-sdk-js@2.2.0 renames .getNextStepId() to .peekStepId()
|
|
20
|
+
const stepId = ctxImpl?.peekStepId?.() ?? ctxImpl?.getNextStepId?.()
|
|
20
21
|
const stepData = stepId ? ctxImpl?._executionContext?.getStepData?.(stepId) : undefined
|
|
21
22
|
return { stepId, stepData }
|
|
22
23
|
}
|
|
@@ -120,8 +120,8 @@ const extractQueueMetadata = queueURL => {
|
|
|
120
120
|
|
|
121
121
|
if (parts.length < minParts) return null
|
|
122
122
|
|
|
123
|
-
const accountId = parts
|
|
124
|
-
const queueName = parts
|
|
123
|
+
const accountId = parts.at(-2)
|
|
124
|
+
const queueName = parts.at(-1)
|
|
125
125
|
const host = hasScheme ? parts[1] : parts[0]
|
|
126
126
|
|
|
127
127
|
let region = 'us-east-1' // Default region if not found in URL
|
|
@@ -438,7 +438,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
438
438
|
const isModified = isModifiedTest(
|
|
439
439
|
testScenarioPath,
|
|
440
440
|
scenario.location.line,
|
|
441
|
-
scenario.steps
|
|
441
|
+
scenario.steps.at(-1).location.line,
|
|
442
442
|
modifiedFiles,
|
|
443
443
|
'cucumber'
|
|
444
444
|
)
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
// Capture real timers at module load, before any test can install fake timers.
|
|
4
4
|
const { performance } = require('perf_hooks')
|
|
5
|
-
const { statSync } = require('node:fs')
|
|
6
5
|
const { basename } = require('node:path')
|
|
7
6
|
const dateNow = Date.now
|
|
8
7
|
|
|
9
8
|
const { createCoverageMap } = require('../../../vendor/dist/istanbul-lib-coverage')
|
|
10
9
|
const satisfies = require('../../../vendor/dist/semifies')
|
|
10
|
+
const { RUM_TEST_EXECUTION_ID_COOKIE_NAME } = require('../../dd-trace/src/ci-visibility/rum')
|
|
11
11
|
const {
|
|
12
12
|
TEST_STATUS,
|
|
13
|
-
|
|
13
|
+
setRumTestTags,
|
|
14
14
|
TEST_CODE_OWNERS,
|
|
15
15
|
getTestEnvironmentMetadata,
|
|
16
16
|
getTestLevelsMetadataTags,
|
|
@@ -79,14 +79,19 @@ const {
|
|
|
79
79
|
getMaxEfdRetryCount,
|
|
80
80
|
getPullRequestBaseBranch,
|
|
81
81
|
TEST_FINAL_STATUS,
|
|
82
|
-
TEST_FAILURE_SCREENSHOT_UPLOADED,
|
|
83
|
-
TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR,
|
|
84
82
|
getTestOptimizationRequestResults,
|
|
85
83
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
86
84
|
const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
|
|
87
85
|
const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
|
|
88
86
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
89
87
|
const getConfig = require('../../dd-trace/src/config')
|
|
88
|
+
const {
|
|
89
|
+
SCREENSHOT_UPLOAD_RESULT_ERROR,
|
|
90
|
+
SCREENSHOT_UPLOAD_RESULT_UPLOADED,
|
|
91
|
+
getScreenshotCapturedAtMs,
|
|
92
|
+
getScreenshotUploadResult,
|
|
93
|
+
setScreenshotUploadTags,
|
|
94
|
+
} = require('../../dd-trace/src/ci-visibility/test-screenshot')
|
|
90
95
|
const { appClosing: appClosingTelemetry } = require('../../dd-trace/src/telemetry')
|
|
91
96
|
const log = require('../../dd-trace/src/log')
|
|
92
97
|
|
|
@@ -141,8 +146,6 @@ const CYPRESS_STATUS_TO_TEST_STATUS = {
|
|
|
141
146
|
}
|
|
142
147
|
|
|
143
148
|
const SCREENSHOT_ATTEMPT_RE = /\(attempt \d+\)/
|
|
144
|
-
const SCREENSHOT_UPLOAD_RESULT_UPLOADED = 'uploaded'
|
|
145
|
-
const SCREENSHOT_UPLOAD_RESULT_ERROR = 'error'
|
|
146
149
|
|
|
147
150
|
function getScreenshotFilePath (screenshot) {
|
|
148
151
|
return typeof screenshot === 'string' ? screenshot : screenshot?.path
|
|
@@ -155,31 +158,6 @@ function isFailureScreenshotByMetadata (screenshot, screenshotFilePath) {
|
|
|
155
158
|
return screenshotFilePath.includes('(failed)')
|
|
156
159
|
}
|
|
157
160
|
|
|
158
|
-
/**
|
|
159
|
-
* Resolves a screenshot's capture time (epoch ms) for the media upload. Cypress
|
|
160
|
-
* screenshot objects carry an ISO `takenAt`; falls back to the file's mtime, then
|
|
161
|
-
* to the current time. Stamped once here and reused on retry via the idempotency
|
|
162
|
-
* key, so the stored object is overwritten rather than duplicated.
|
|
163
|
-
*
|
|
164
|
-
* @param {object|string} screenshot - Cypress screenshot object or path
|
|
165
|
-
* @param {string} filePath - Resolved screenshot file path
|
|
166
|
-
* @returns {number} Capture time in epoch milliseconds
|
|
167
|
-
*/
|
|
168
|
-
function getScreenshotCapturedAtMs (screenshot, filePath) {
|
|
169
|
-
const takenAt = screenshot !== null && typeof screenshot === 'object' ? screenshot.takenAt : undefined
|
|
170
|
-
if (takenAt) {
|
|
171
|
-
const parsedMs = new Date(takenAt).getTime()
|
|
172
|
-
if (Number.isInteger(parsedMs) && parsedMs > 0) {
|
|
173
|
-
return parsedMs
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
return Math.floor(statSync(filePath).mtimeMs)
|
|
178
|
-
} catch {
|
|
179
|
-
return dateNow()
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
161
|
function isFailureScreenshotForUpload (screenshot) {
|
|
184
162
|
const screenshotFilePath = getScreenshotFilePath(screenshot)
|
|
185
163
|
if (!screenshotFilePath) {
|
|
@@ -240,27 +218,6 @@ function getTestScreenshots (cypressTest, attemptIndex, specScreenshots) {
|
|
|
240
218
|
return specScreenshots.filter(screenshot => isScreenshotForTestAttempt(screenshot, titleParts, attemptIndex))
|
|
241
219
|
}
|
|
242
220
|
|
|
243
|
-
function getScreenshotUploadResult (uploadResults) {
|
|
244
|
-
let hasUploaded = false
|
|
245
|
-
for (const uploadResult of uploadResults) {
|
|
246
|
-
if (uploadResult === SCREENSHOT_UPLOAD_RESULT_ERROR) {
|
|
247
|
-
return SCREENSHOT_UPLOAD_RESULT_ERROR
|
|
248
|
-
}
|
|
249
|
-
if (uploadResult === SCREENSHOT_UPLOAD_RESULT_UPLOADED) {
|
|
250
|
-
hasUploaded = true
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
return hasUploaded ? SCREENSHOT_UPLOAD_RESULT_UPLOADED : undefined
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
function setScreenshotUploadTags (testSpan, uploadResult) {
|
|
257
|
-
if (uploadResult === SCREENSHOT_UPLOAD_RESULT_ERROR) {
|
|
258
|
-
testSpan.setTag(TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR, 'true')
|
|
259
|
-
} else if (uploadResult === SCREENSHOT_UPLOAD_RESULT_UPLOADED) {
|
|
260
|
-
testSpan.setTag(TEST_FAILURE_SCREENSHOT_UPLOADED, 'true')
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
221
|
function getSessionStatus (summary) {
|
|
265
222
|
if (summary.totalFailed !== undefined && summary.totalFailed > 0) {
|
|
266
223
|
return 'fail'
|
|
@@ -901,6 +858,12 @@ class CypressPlugin {
|
|
|
901
858
|
if (isFlakyTestRetriesEnabled && this.isTestIsolationEnabled) {
|
|
902
859
|
this.isFlakyTestRetriesEnabled = true
|
|
903
860
|
this.flakyTestRetriesCount = flakyTestRetriesCount ?? 0
|
|
861
|
+
if (typeof this.cypressConfig.retries === 'number') {
|
|
862
|
+
this.cypressConfig.retries = {
|
|
863
|
+
openMode: this.cypressConfig.retries,
|
|
864
|
+
runMode: this.cypressConfig.retries,
|
|
865
|
+
}
|
|
866
|
+
}
|
|
904
867
|
this.cypressConfig.retries.runMode = this.flakyTestRetriesCount
|
|
905
868
|
} else {
|
|
906
869
|
this.flakyTestRetriesCount = 0
|
|
@@ -1444,13 +1407,13 @@ class CypressPlugin {
|
|
|
1444
1407
|
// and create a skipped test span for each of them
|
|
1445
1408
|
for (const { title } of cypressTests) {
|
|
1446
1409
|
const cypressTestName = title.join(' ')
|
|
1447
|
-
const isTestFinished = finishedTests.
|
|
1410
|
+
const isTestFinished = finishedTests.some(({ testName }) => cypressTestName === testName)
|
|
1448
1411
|
|
|
1449
1412
|
if (isTestFinished) {
|
|
1450
1413
|
continue
|
|
1451
1414
|
}
|
|
1452
1415
|
|
|
1453
|
-
const isSkippedByItr = this.testsToSkip.
|
|
1416
|
+
const isSkippedByItr = this.testsToSkip.some(test =>
|
|
1454
1417
|
cypressTestName === test.name && spec.relative === test.suite
|
|
1455
1418
|
)
|
|
1456
1419
|
const testSourceFile = spec.absolute && this.repositoryRoot
|
|
@@ -1721,6 +1684,7 @@ class CypressPlugin {
|
|
|
1721
1684
|
repositoryRoot: this.repositoryRoot,
|
|
1722
1685
|
isTestIsolationEnabled: this.isTestIsolationEnabled,
|
|
1723
1686
|
rumFlushWaitMillis: this.rumFlushWaitMillis,
|
|
1687
|
+
rumTestExecutionIdCookieName: RUM_TEST_EXECUTION_ID_COOKIE_NAME,
|
|
1724
1688
|
}
|
|
1725
1689
|
|
|
1726
1690
|
this.testSuiteSpan ||= this.getTestSuiteSpan({ testSuite, testSuiteAbsolutePath })
|
|
@@ -1847,9 +1811,7 @@ class CypressPlugin {
|
|
|
1847
1811
|
if (error) {
|
|
1848
1812
|
this.activeTestSpan.setTag('error', error)
|
|
1849
1813
|
}
|
|
1850
|
-
|
|
1851
|
-
this.activeTestSpan.setTag(TEST_IS_RUM_ACTIVE, 'true')
|
|
1852
|
-
}
|
|
1814
|
+
setRumTestTags(this.activeTestSpan, isRUMActive)
|
|
1853
1815
|
// Source-line resolution strategy:
|
|
1854
1816
|
// 1. If plain JS and no source map, trust invocationDetails.line directly.
|
|
1855
1817
|
// 2. Otherwise, try invocationDetails.stack line mapped through source map.
|
|
@@ -80,7 +80,12 @@ class CypressPlugin extends Plugin {
|
|
|
80
80
|
// Already initialized by manual plugin call — just chain user handlers.
|
|
81
81
|
// Pass the plugin's afterScreenshot so chaining a user handler doesn't drop the upload
|
|
82
82
|
// (the chained registration replaces the one plugin.js set, so it must include it).
|
|
83
|
-
|
|
83
|
+
if (userAfterSpecHandlers.length > 0) {
|
|
84
|
+
on('after:spec', (spec, results) => userAfterSpecHandlers.reduce(
|
|
85
|
+
(chain, handler) => chain.then(() => handler(spec, results)),
|
|
86
|
+
Promise.resolve()
|
|
87
|
+
))
|
|
88
|
+
}
|
|
84
89
|
registerAfterScreenshot(datadogAfterScreenshotHandler)
|
|
85
90
|
registerAfterRunWithCleanup()
|
|
86
91
|
payload.registered = true
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME = 'datadog-ci-visibility-test-execution-id'
|
|
4
3
|
let rumFlushWaitMillis = 500
|
|
4
|
+
let rumTestExecutionIdCookieName
|
|
5
5
|
|
|
6
6
|
let isEarlyFlakeDetectionEnabled = false
|
|
7
7
|
let isKnownTestsEnabled = false
|
|
@@ -129,6 +129,89 @@ function runBeforeEachTask (test) {
|
|
|
129
129
|
})
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
/**
|
|
133
|
+
* @param {string} message
|
|
134
|
+
* @param {unknown} error
|
|
135
|
+
* @returns {false}
|
|
136
|
+
*/
|
|
137
|
+
function logRumCorrelationCookieError (message, error) {
|
|
138
|
+
try {
|
|
139
|
+
Cypress.log({
|
|
140
|
+
name: 'dd-trace',
|
|
141
|
+
message,
|
|
142
|
+
consoleProps: () => ({ Error: error }),
|
|
143
|
+
})
|
|
144
|
+
} catch (loggingError) {
|
|
145
|
+
// eslint-disable-next-line no-console
|
|
146
|
+
console.error(message, error, loggingError)
|
|
147
|
+
}
|
|
148
|
+
return false
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @param {unknown} error
|
|
153
|
+
* @returns {false}
|
|
154
|
+
*/
|
|
155
|
+
function handleRumCorrelationCookieError (error) {
|
|
156
|
+
return logRumCorrelationCookieError('Could not set the RUM correlation cookie', error)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @param {unknown} error
|
|
161
|
+
* @returns {false}
|
|
162
|
+
*/
|
|
163
|
+
function handleRumCorrelationCookieCleanupError (error) {
|
|
164
|
+
return logRumCorrelationCookieError('Could not clear the previous RUM correlation cookie', error)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param {string} traceId
|
|
169
|
+
* @returns {Promise<boolean>}
|
|
170
|
+
*/
|
|
171
|
+
function setRumCorrelationCookie (traceId) {
|
|
172
|
+
if (typeof cy.now !== 'function') {
|
|
173
|
+
return Cypress.Promise.resolve(handleRumCorrelationCookieError(new Error('Cypress cy.now is not available')))
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
let clearCookiePromise = Cypress.Promise.resolve()
|
|
177
|
+
if (!isTestIsolationEnabled) {
|
|
178
|
+
clearCookiePromise = Cypress.Promise.try(() => {
|
|
179
|
+
return cy.now('clearCookie', rumTestExecutionIdCookieName, { log: false })
|
|
180
|
+
}).then(undefined, handleRumCorrelationCookieCleanupError)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return clearCookiePromise.then(() => {
|
|
184
|
+
return Cypress.Promise.try(() => {
|
|
185
|
+
return cy.now('setCookie', rumTestExecutionIdCookieName, traceId, { log: false })
|
|
186
|
+
})
|
|
187
|
+
}).then(() => true, handleRumCorrelationCookieError)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @param {boolean} isCookieSet
|
|
192
|
+
* @returns {void}
|
|
193
|
+
*/
|
|
194
|
+
function restartRumSession (isCookieSet) {
|
|
195
|
+
if (!isCookieSet || isTestIsolationEnabled || !originalWindow) {
|
|
196
|
+
return
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const rum = safeGetRum(originalWindow)
|
|
200
|
+
if (rum) {
|
|
201
|
+
try {
|
|
202
|
+
const evt = new originalWindow.MouseEvent('click', { bubbles: true, cancelable: true })
|
|
203
|
+
// The browser-sdk addEventListener wrapper filters out untrusted synthetic events
|
|
204
|
+
// unless __ddIsTrusted is set. Set it so the click triggers expandOrRenewSession().
|
|
205
|
+
// See: https://github.com/DataDog/browser-sdk/blob/v6.27.1/packages/core/src/browser/addEventListener.ts#L119
|
|
206
|
+
Object.defineProperty(evt, '__ddIsTrusted', { value: true })
|
|
207
|
+
originalWindow.dispatchEvent(evt)
|
|
208
|
+
} catch {}
|
|
209
|
+
if (rum.startView) {
|
|
210
|
+
rum.startView()
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
132
215
|
// Catch test failures for quarantined tests and suppress them
|
|
133
216
|
// By not re-throwing the error, Cypress marks the test as passed
|
|
134
217
|
// This allows quarantined tests to run but not affect the exit code
|
|
@@ -150,6 +233,8 @@ Cypress.on('fail', (err, runnable) => {
|
|
|
150
233
|
// If command:end fired for all commands (none in-flight) but the last command
|
|
151
234
|
// has no error, it means command:end fired before the error was attached to it.
|
|
152
235
|
if (!hadInFlightCommands && currentTestCommands.length > 0) {
|
|
236
|
+
// We have to support very old cypress versions in v5
|
|
237
|
+
// eslint-disable-next-line unicorn/prefer-at
|
|
153
238
|
const lastCommand = currentTestCommands[currentTestCommands.length - 1]
|
|
154
239
|
if (!lastCommand.error) {
|
|
155
240
|
lastCommand.error = { message: err.message, stack: err.stack, name: err.name }
|
|
@@ -316,36 +401,16 @@ beforeEach(function () {
|
|
|
316
401
|
if (shouldDiscard) {
|
|
317
402
|
this.currentTest._ddShouldDiscard = true
|
|
318
403
|
}
|
|
404
|
+
let rumCookiePromise
|
|
319
405
|
if (traceId) {
|
|
320
|
-
|
|
321
|
-
// When testIsolation:false, the page is not reset between tests, so the RUM session
|
|
322
|
-
// stopped in afterEach must be explicitly restarted so events in this test are
|
|
323
|
-
// associated with the new testExecutionId.
|
|
324
|
-
//
|
|
325
|
-
// After stopSession(), the RUM SDK creates a new session upon a user interaction
|
|
326
|
-
// (click, scroll, keydown, or touchstart). We dispatch a synthetic click on the window
|
|
327
|
-
// to trigger session renewal, then call startView() to establish a view boundary.
|
|
328
|
-
if (!isTestIsolationEnabled && originalWindow) {
|
|
329
|
-
const rum = safeGetRum(originalWindow)
|
|
330
|
-
if (rum) {
|
|
331
|
-
try {
|
|
332
|
-
const evt = new originalWindow.MouseEvent('click', { bubbles: true, cancelable: true })
|
|
333
|
-
// The browser-sdk addEventListener wrapper filters out untrusted synthetic events
|
|
334
|
-
// unless __ddIsTrusted is set. Set it so the click triggers expandOrRenewSession().
|
|
335
|
-
// See: https://github.com/DataDog/browser-sdk/blob/v6.27.1/packages/core/src/browser/addEventListener.ts#L119
|
|
336
|
-
Object.defineProperty(evt, '__ddIsTrusted', { value: true })
|
|
337
|
-
originalWindow.dispatchEvent(evt)
|
|
338
|
-
} catch {}
|
|
339
|
-
if (rum.startView) {
|
|
340
|
-
rum.startView()
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
})
|
|
406
|
+
rumCookiePromise = setRumCorrelationCookie(traceId)
|
|
345
407
|
}
|
|
346
408
|
if (shouldSkip) {
|
|
347
409
|
this.skip()
|
|
348
410
|
}
|
|
411
|
+
if (rumCookiePromise) {
|
|
412
|
+
return rumCookiePromise.then(restartRumSession)
|
|
413
|
+
}
|
|
349
414
|
}).then(() => {
|
|
350
415
|
// Clear any commands accumulated during DD-owned setup (e.g. setCookie, RUM restart)
|
|
351
416
|
// so they are not reported as user test steps.
|
|
@@ -370,6 +435,7 @@ before(function () {
|
|
|
370
435
|
isImpactedTestsEnabled = suiteConfig.isImpactedTestsEnabled
|
|
371
436
|
isModifiedTest = suiteConfig.isModifiedTest
|
|
372
437
|
isTestIsolationEnabled = suiteConfig.isTestIsolationEnabled
|
|
438
|
+
rumTestExecutionIdCookieName = suiteConfig.rumTestExecutionIdCookieName
|
|
373
439
|
if (Number.isFinite(suiteConfig.rumFlushWaitMillis)) {
|
|
374
440
|
rumFlushWaitMillis = suiteConfig.rumFlushWaitMillis
|
|
375
441
|
}
|
|
@@ -46,7 +46,7 @@ class ElectronRendererReceivePlugin extends ConsumerPlugin {
|
|
|
46
46
|
|
|
47
47
|
if (channel?.startsWith('datadog:')) return
|
|
48
48
|
|
|
49
|
-
const childOf = this._tracer.extract('text_map', args
|
|
49
|
+
const childOf = this._tracer.extract('text_map', args.at(-1))
|
|
50
50
|
|
|
51
51
|
if (childOf) {
|
|
52
52
|
args.pop()
|