dd-trace 6.13.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/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/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 +13 -0
- 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 +25 -20
- 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 +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/playwright.js +109 -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/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/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/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 +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 +20 -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 -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 +27 -23
- 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 +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 +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_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 +93 -18
- 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/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 +36 -9
- 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_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 +18 -16
- 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
|
@@ -12,9 +12,11 @@ class Amqp10ConsumerPlugin extends ConsumerPlugin {
|
|
|
12
12
|
|
|
13
13
|
const source = getShortName(link)
|
|
14
14
|
const address = getAddress(link)
|
|
15
|
+
let resource = 'receive'
|
|
16
|
+
if (source) resource += ` ${source}`
|
|
15
17
|
|
|
16
18
|
this.startSpan({
|
|
17
|
-
resource
|
|
19
|
+
resource,
|
|
18
20
|
type: 'worker',
|
|
19
21
|
meta: {
|
|
20
22
|
'amqp.link.source.address': source,
|
|
@@ -14,9 +14,11 @@ class Amqp10ProducerPlugin extends ProducerPlugin {
|
|
|
14
14
|
|
|
15
15
|
const address = getAddress(link)
|
|
16
16
|
const target = getShortName(link)
|
|
17
|
+
let resource = 'send'
|
|
18
|
+
if (target) resource += ` ${target}`
|
|
17
19
|
|
|
18
20
|
this.startSpan({
|
|
19
|
-
resource
|
|
21
|
+
resource,
|
|
20
22
|
meta: {
|
|
21
23
|
'amqp.link.target.address': target,
|
|
22
24
|
'amqp.link.role': 'sender',
|
|
@@ -9,7 +9,8 @@ function getAddress (link) {
|
|
|
9
9
|
function getShortName (link) {
|
|
10
10
|
if (!link || !link.name) return null
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
const lastUnderscorePosition = link.name.lastIndexOf('_')
|
|
13
|
+
return lastUnderscorePosition === -1 ? link.name : link.name.slice(0, lastUnderscorePosition)
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
module.exports = { getAddress, getShortName }
|
|
@@ -50,7 +50,12 @@ class SchemaExtractor {
|
|
|
50
50
|
|
|
51
51
|
if (Array.isArray(fieldType)) {
|
|
52
52
|
// Union Type
|
|
53
|
-
type = 'union['
|
|
53
|
+
type = 'union['
|
|
54
|
+
for (const typeDefinition of fieldType) {
|
|
55
|
+
if (type !== 'union[') type += ','
|
|
56
|
+
type += SchemaExtractor.getType(typeDefinition.type || typeDefinition)
|
|
57
|
+
}
|
|
58
|
+
type += ']'
|
|
54
59
|
} else if (fieldType === 'array') {
|
|
55
60
|
// Array Type
|
|
56
61
|
array = true
|
|
@@ -265,8 +265,11 @@ function extractRequestParams (params, provider) {
|
|
|
265
265
|
for (const message of requestBody.messages) {
|
|
266
266
|
const textBlocks = message.content?.filter(block => block.text) || []
|
|
267
267
|
if (textBlocks.length > 0) {
|
|
268
|
+
let content = ''
|
|
269
|
+
for (const block of textBlocks) content += block.text
|
|
270
|
+
|
|
268
271
|
messages.push({
|
|
269
|
-
content
|
|
272
|
+
content,
|
|
270
273
|
role: message.role,
|
|
271
274
|
})
|
|
272
275
|
}
|
|
@@ -288,9 +291,14 @@ function extractRequestParams (params, provider) {
|
|
|
288
291
|
for (let idx = requestBody.messages.length - 1; idx >= 0; idx--) {
|
|
289
292
|
const message = requestBody.messages[idx]
|
|
290
293
|
if (message.role === 'user') {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
+
const content = message.content
|
|
295
|
+
prompt = undefined
|
|
296
|
+
if (content) {
|
|
297
|
+
prompt = ''
|
|
298
|
+
for (const block of content) {
|
|
299
|
+
if (block.type === 'text') prompt += block.text
|
|
300
|
+
}
|
|
301
|
+
}
|
|
294
302
|
break
|
|
295
303
|
}
|
|
296
304
|
}
|
|
@@ -546,7 +554,10 @@ function parseToolInput (inputStr) {
|
|
|
546
554
|
}
|
|
547
555
|
|
|
548
556
|
function buildToolResult ({ toolUseId, content }) {
|
|
549
|
-
|
|
557
|
+
let result = ''
|
|
558
|
+
if (content) {
|
|
559
|
+
for (const item of content) result += resolveToolResultItem(item)
|
|
560
|
+
}
|
|
550
561
|
return { name: '', result, toolId: toolUseId ?? '', type: 'tool_result' }
|
|
551
562
|
}
|
|
552
563
|
|
|
@@ -33,9 +33,14 @@ class CassandraDriverPlugin extends DatabasePlugin {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function combine (queries) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
let combined = ''
|
|
37
|
+
let isFirstQuery = true
|
|
38
|
+
for (const query of queries) {
|
|
39
|
+
if (!isFirstQuery) combined += ' '
|
|
40
|
+
combined += (query.query || query).replace(/;?$/, ';')
|
|
41
|
+
isFirstQuery = false
|
|
42
|
+
}
|
|
43
|
+
return combined
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
function trim (str, size) {
|
|
@@ -124,7 +124,6 @@ class CucumberPlugin extends CiPlugin {
|
|
|
124
124
|
this.testSessionSpan.setTag('error', error)
|
|
125
125
|
this.testModuleSpan.setTag('error', error)
|
|
126
126
|
}
|
|
127
|
-
this.tracer._exporter.exportDeferredTestSuiteSpans?.()
|
|
128
127
|
this.testModuleSpan.finish()
|
|
129
128
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
130
129
|
this.testSessionSpan.finish()
|
|
@@ -202,7 +201,6 @@ class CucumberPlugin extends CiPlugin {
|
|
|
202
201
|
this.addSub('ci:cucumber:test-suite:finish', ({ status, testSuitePath }) => {
|
|
203
202
|
const testSuiteSpan = this._testSuiteSpansByTestSuite.get(testSuitePath)
|
|
204
203
|
testSuiteSpan.setTag(TEST_STATUS, status)
|
|
205
|
-
this.tracer._exporter.deferTestSuiteSpan?.(testSuiteSpan)
|
|
206
204
|
testSuiteSpan.finish()
|
|
207
205
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
208
206
|
})
|
|
@@ -97,6 +97,12 @@ const {
|
|
|
97
97
|
getScreenshotUploadResult,
|
|
98
98
|
setScreenshotUploadTags,
|
|
99
99
|
} = require('../../dd-trace/src/ci-visibility/test-screenshot')
|
|
100
|
+
const {
|
|
101
|
+
VIDEO_UPLOAD_RESULT_ERROR,
|
|
102
|
+
VIDEO_UPLOAD_RESULT_UPLOADED,
|
|
103
|
+
VIDEO_UPLOAD_SCOPE_TEST_SUITE,
|
|
104
|
+
setVideoUploadTags,
|
|
105
|
+
} = require('../../dd-trace/src/ci-visibility/test-video')
|
|
100
106
|
const { appClosing: appClosingTelemetry } = require('../../dd-trace/src/telemetry')
|
|
101
107
|
const log = require('../../dd-trace/src/log')
|
|
102
108
|
|
|
@@ -491,6 +497,8 @@ class CypressPlugin {
|
|
|
491
497
|
attemptToFixExecutions = new Map()
|
|
492
498
|
loggedAttemptToFixTests = new Set()
|
|
493
499
|
uploadedScreenshotPaths = new Set()
|
|
500
|
+
uploadedVideoPaths = new Set()
|
|
501
|
+
pendingVideoUploads = []
|
|
494
502
|
screenshotUploadPromisesByTraceId = new Map()
|
|
495
503
|
screenshotUploadAbortControllers = new Set()
|
|
496
504
|
afterScreenshotHandler = undefined
|
|
@@ -581,13 +589,14 @@ class CypressPlugin {
|
|
|
581
589
|
this.attemptToFixExecutions = new Map()
|
|
582
590
|
this.loggedAttemptToFixTests = new Set()
|
|
583
591
|
this.uploadedScreenshotPaths = new Set()
|
|
592
|
+
this.uploadedVideoPaths = new Set()
|
|
593
|
+
this.pendingVideoUploads = []
|
|
584
594
|
this.screenshotUploadPromisesByTraceId = new Map()
|
|
585
595
|
this.screenshotUploadAbortControllers = new Set()
|
|
586
596
|
this.lastFinishedTest = null
|
|
587
597
|
this.pendingScreenshotUploads = []
|
|
588
598
|
this.activeTestSpan = null
|
|
589
599
|
this.testSuiteSpan = null
|
|
590
|
-
this.finishedTestSuiteSpans = []
|
|
591
600
|
this.testModuleSpan = null
|
|
592
601
|
this.testSessionSpan = null
|
|
593
602
|
this.command = undefined
|
|
@@ -801,6 +810,35 @@ class CypressPlugin {
|
|
|
801
810
|
}
|
|
802
811
|
}
|
|
803
812
|
|
|
813
|
+
/**
|
|
814
|
+
* Warns when video upload is enabled but Cypress cannot produce or send videos.
|
|
815
|
+
*
|
|
816
|
+
* @param {object} cypressConfig - Cypress resolved config
|
|
817
|
+
* @param {object} tracer - dd-trace proxy tracer
|
|
818
|
+
* @param {object} testOptimizationConfig - Test Optimization config
|
|
819
|
+
* @returns {void}
|
|
820
|
+
*/
|
|
821
|
+
warnIfMisconfiguredTestFailureVideos (cypressConfig, tracer, testOptimizationConfig) {
|
|
822
|
+
if (!testOptimizationConfig.DD_TEST_FAILURE_VIDEOS_ENABLED) return
|
|
823
|
+
|
|
824
|
+
if (cypressConfig.video === false) {
|
|
825
|
+
log.warn(
|
|
826
|
+
'%s %s',
|
|
827
|
+
'DD_TEST_FAILURE_VIDEOS_ENABLED is true, but Cypress video capture is disabled.',
|
|
828
|
+
'Datadog cannot upload failure videos unless Cypress is configured to record videos.'
|
|
829
|
+
)
|
|
830
|
+
return
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
if (!tracer?._tracer?._exporter?.canUploadTestVideos?.()) {
|
|
834
|
+
log.warn(
|
|
835
|
+
'%s %s',
|
|
836
|
+
'DD_TEST_FAILURE_VIDEOS_ENABLED is true, but Cypress failure video upload is not supported',
|
|
837
|
+
'by the active Test Optimization transport.'
|
|
838
|
+
)
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
804
842
|
// Init function returns a promise that resolves with the Cypress configuration
|
|
805
843
|
// Depending on the received configuration, the Cypress configuration can be modified:
|
|
806
844
|
// for example, to enable retries for failed tests.
|
|
@@ -827,6 +865,7 @@ class CypressPlugin {
|
|
|
827
865
|
const testOptimizationConfig = getConfig().testOptimization
|
|
828
866
|
this.rumFlushWaitMillis = testOptimizationConfig.DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS
|
|
829
867
|
this.warnIfMisconfiguredTestFailureScreenshots(cypressConfig, tracer, testOptimizationConfig)
|
|
868
|
+
this.warnIfMisconfiguredTestFailureVideos(cypressConfig, tracer, testOptimizationConfig)
|
|
830
869
|
|
|
831
870
|
if (!this.isTestIsolationEnabled) {
|
|
832
871
|
log.warn('Test isolation is disabled, retries will not be enabled')
|
|
@@ -1272,11 +1311,34 @@ class CypressPlugin {
|
|
|
1272
1311
|
return details
|
|
1273
1312
|
}
|
|
1274
1313
|
|
|
1275
|
-
afterRun (suiteStats, error
|
|
1314
|
+
afterRun (suiteStats, error) {
|
|
1315
|
+
const hasPendingVideoSpans = this.pendingVideoUploads.length > 0
|
|
1316
|
+
const videoUploadsPromise = this.uploadPendingTestSuiteVideos()
|
|
1276
1317
|
if (!this._isInit) {
|
|
1277
1318
|
log.warn('Attemping to call afterRun without initializating the plugin first')
|
|
1319
|
+
if (videoUploadsPromise) {
|
|
1320
|
+
return Promise.all([videoUploadsPromise, this.#flushExporter(false)])
|
|
1321
|
+
.then(() => this.#flushExporter(false))
|
|
1322
|
+
}
|
|
1278
1323
|
return
|
|
1279
1324
|
}
|
|
1325
|
+
const finalizationPromise = this.#finalizeRun(suiteStats, error, hasPendingVideoSpans)
|
|
1326
|
+
if (videoUploadsPromise) {
|
|
1327
|
+
return Promise.all([videoUploadsPromise, finalizationPromise])
|
|
1328
|
+
.then(() => this.#flushExporter(false))
|
|
1329
|
+
}
|
|
1330
|
+
return finalizationPromise
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
/**
|
|
1334
|
+
* Finalizes Cypress run state without starting queued video uploads.
|
|
1335
|
+
*
|
|
1336
|
+
* @param {object|undefined} suiteStats - Cypress run statistics
|
|
1337
|
+
* @param {Error|undefined} error - Run finalization error
|
|
1338
|
+
* @param {boolean} [hasPendingVideoSpans] - Whether video-owned spans will finish during finalization
|
|
1339
|
+
* @returns {Promise<null>}
|
|
1340
|
+
*/
|
|
1341
|
+
#finalizeRun (suiteStats, error, hasPendingVideoSpans = false) {
|
|
1280
1342
|
if (this.testSessionSpan && this.testModuleSpan) {
|
|
1281
1343
|
const testStatus = error ? 'fail' : getSessionStatus(suiteStats)
|
|
1282
1344
|
const hasBackfilledCoverage = this.applySkippedCoverageToTestSessionCoverage()
|
|
@@ -1284,13 +1346,6 @@ class CypressPlugin {
|
|
|
1284
1346
|
|
|
1285
1347
|
this.testModuleSpan.setTag(TEST_STATUS, testStatus)
|
|
1286
1348
|
this.testSessionSpan.setTag(TEST_STATUS, testStatus)
|
|
1287
|
-
for (const span of this.finishedTestSuiteSpans) {
|
|
1288
|
-
if (error && shouldFailFinishedSuites) {
|
|
1289
|
-
span.setTag(TEST_STATUS, 'fail')
|
|
1290
|
-
span.setTag('error', error)
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
this.finishedTestSuiteSpans = []
|
|
1294
1349
|
if (error) {
|
|
1295
1350
|
this.testModuleSpan.setTag('error', error)
|
|
1296
1351
|
this.testSessionSpan.setTag('error', error)
|
|
@@ -1331,14 +1386,28 @@ class CypressPlugin {
|
|
|
1331
1386
|
autoInjected: !!getConfig().testOptimization.DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER,
|
|
1332
1387
|
})
|
|
1333
1388
|
|
|
1334
|
-
|
|
1335
|
-
|
|
1389
|
+
// Cypress finishes suite videos in after:run, so their spans must remain open until the upload result is known.
|
|
1390
|
+
if (!hasPendingVideoSpans) {
|
|
1391
|
+
finishAllTraceSpans(this.testSessionSpan)
|
|
1392
|
+
}
|
|
1336
1393
|
}
|
|
1337
1394
|
|
|
1395
|
+
return this.#flushExporter(true)
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* Flushes Test Optimization data after Cypress finalization work.
|
|
1400
|
+
*
|
|
1401
|
+
* @param {boolean} closeRun - Whether to close the Cypress run and telemetry lifecycle
|
|
1402
|
+
* @returns {Promise<null>}
|
|
1403
|
+
*/
|
|
1404
|
+
#flushExporter (closeRun) {
|
|
1338
1405
|
return new Promise(resolve => {
|
|
1339
1406
|
const finishAfterRun = () => {
|
|
1340
|
-
|
|
1341
|
-
|
|
1407
|
+
if (closeRun) {
|
|
1408
|
+
this._isInit = false
|
|
1409
|
+
appClosingTelemetry()
|
|
1410
|
+
}
|
|
1342
1411
|
resolve(null)
|
|
1343
1412
|
}
|
|
1344
1413
|
|
|
@@ -1391,12 +1460,12 @@ class CypressPlugin {
|
|
|
1391
1460
|
}
|
|
1392
1461
|
|
|
1393
1462
|
afterSpec (spec, results, error) {
|
|
1394
|
-
const { tests, stats, screenshots } = results || {}
|
|
1463
|
+
const { tests, stats, screenshots, video } = results || {}
|
|
1395
1464
|
const cypressTests = tests || []
|
|
1396
1465
|
const specScreenshots = screenshots || []
|
|
1397
1466
|
const finishedTests = this.finishedTestsByFile[spec.relative] || []
|
|
1398
1467
|
const screenshotUploadPromises = []
|
|
1399
|
-
const
|
|
1468
|
+
const testSpanFinishes = []
|
|
1400
1469
|
|
|
1401
1470
|
if (!this.testSuiteSpan) {
|
|
1402
1471
|
// dd:testSuiteStart hasn't been triggered for whatever reason
|
|
@@ -1463,7 +1532,7 @@ class CypressPlugin {
|
|
|
1463
1532
|
})
|
|
1464
1533
|
}
|
|
1465
1534
|
|
|
1466
|
-
skippedTestSpan.
|
|
1535
|
+
testSpanFinishes.push({ testSpan: skippedTestSpan, finishTime: this._now() })
|
|
1467
1536
|
}
|
|
1468
1537
|
|
|
1469
1538
|
// Make sure that reported test statuses are the same as Cypress reports.
|
|
@@ -1604,36 +1673,46 @@ class CypressPlugin {
|
|
|
1604
1673
|
const screenshotUploadResultPromise = failedTestTraceId
|
|
1605
1674
|
? this.getScreenshotUploadResultPromise(failedTestTraceId)
|
|
1606
1675
|
: undefined
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
} else {
|
|
1614
|
-
if (screenshotUploadResultPromise) {
|
|
1615
|
-
this.screenshotUploadPromisesByTraceId.delete(failedTestTraceId)
|
|
1616
|
-
}
|
|
1617
|
-
finishedTest.testSpan.finish(finishedTest.finishTime)
|
|
1618
|
-
}
|
|
1676
|
+
testSpanFinishes.push({
|
|
1677
|
+
testSpan: finishedTest.testSpan,
|
|
1678
|
+
finishTime: finishedTest.finishTime,
|
|
1679
|
+
screenshotUploadResultPromise: error ? undefined : screenshotUploadResultPromise,
|
|
1680
|
+
failedTestTraceId,
|
|
1681
|
+
})
|
|
1619
1682
|
}
|
|
1620
1683
|
}
|
|
1621
1684
|
|
|
1622
|
-
const
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1685
|
+
const testSuiteFinishTime = this._now()
|
|
1686
|
+
const suiteFailed = error || latestError || getSuiteStatus(stats) === 'fail'
|
|
1687
|
+
const testSuiteSpan = this.testSuiteSpan
|
|
1688
|
+
const uploadOptions = {
|
|
1689
|
+
filePath: video,
|
|
1690
|
+
testSessionId: typeof this.testSessionSpan?.context === 'function'
|
|
1691
|
+
? this.testSessionSpan.context().toTraceId()
|
|
1692
|
+
: undefined,
|
|
1693
|
+
testSuiteId: typeof testSuiteSpan?.context === 'function'
|
|
1694
|
+
? testSuiteSpan.context().toSpanId()
|
|
1695
|
+
: undefined,
|
|
1696
|
+
}
|
|
1697
|
+
const shouldUploadVideo = suiteFailed && this.#canUploadTestSuiteVideo(uploadOptions)
|
|
1698
|
+
if (testSuiteSpan) {
|
|
1699
|
+
testSuiteSpan.setTag(TEST_STATUS, error ? 'fail' : getSuiteStatus(stats))
|
|
1700
|
+
if (error || latestError) testSuiteSpan.setTag('error', error || latestError)
|
|
1701
|
+
this.testSuiteSpan = null
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
let testSpansPromise
|
|
1705
|
+
if (shouldUploadVideo) {
|
|
1706
|
+
this.pendingVideoUploads.push({
|
|
1707
|
+
...uploadOptions,
|
|
1708
|
+
testSpanFinishes,
|
|
1709
|
+
testSuiteSpan,
|
|
1710
|
+
testSuiteFinishTime,
|
|
1711
|
+
})
|
|
1712
|
+
} else {
|
|
1713
|
+
testSpansPromise = this.finishTestSpans(testSpanFinishes)
|
|
1714
|
+
if (testSuiteSpan) {
|
|
1715
|
+
testSuiteSpan.finish(testSuiteFinishTime)
|
|
1637
1716
|
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
1638
1717
|
}
|
|
1639
1718
|
}
|
|
@@ -1646,17 +1725,19 @@ class CypressPlugin {
|
|
|
1646
1725
|
}
|
|
1647
1726
|
}
|
|
1648
1727
|
|
|
1649
|
-
finishSuite()
|
|
1650
|
-
|
|
1651
1728
|
if (error) {
|
|
1652
1729
|
this.abortPendingScreenshotUploads(error)
|
|
1653
|
-
|
|
1730
|
+
const videoSpansPromise = this.#finishPendingTestSuiteVideos(VIDEO_UPLOAD_RESULT_ERROR)
|
|
1731
|
+
const finalizationPromise = this.#finalizeRun(undefined, error)
|
|
1732
|
+
if (videoSpansPromise) {
|
|
1733
|
+
return Promise.all([videoSpansPromise, finalizationPromise]).then(() => null)
|
|
1734
|
+
}
|
|
1735
|
+
return finalizationPromise
|
|
1654
1736
|
}
|
|
1655
1737
|
|
|
1656
1738
|
const screenshotUploadsPromise = waitForScreenshotUploads()
|
|
1657
1739
|
let afterSpecPromise = screenshotUploadsPromise
|
|
1658
|
-
if (
|
|
1659
|
-
const testSpansPromise = Promise.all(testSpanFinishPromises).then(() => null)
|
|
1740
|
+
if (testSpansPromise) {
|
|
1660
1741
|
if (screenshotUploadsPromise) {
|
|
1661
1742
|
afterSpecPromise = Promise.all([testSpansPromise, screenshotUploadsPromise]).then(() => null)
|
|
1662
1743
|
} else {
|
|
@@ -1667,6 +1748,36 @@ class CypressPlugin {
|
|
|
1667
1748
|
return afterSpecPromise
|
|
1668
1749
|
}
|
|
1669
1750
|
|
|
1751
|
+
/**
|
|
1752
|
+
* Applies media outcome tags and finishes test spans from one Cypress suite.
|
|
1753
|
+
*
|
|
1754
|
+
* @param {Array<object>} testSpanFinishes - Test spans and deferred screenshot outcomes
|
|
1755
|
+
* @param {string|undefined} videoUploadResult - Test suite video upload outcome
|
|
1756
|
+
* @returns {Promise<null>|undefined}
|
|
1757
|
+
*/
|
|
1758
|
+
finishTestSpans (testSpanFinishes, videoUploadResult) {
|
|
1759
|
+
const finishPromises = []
|
|
1760
|
+
for (const {
|
|
1761
|
+
testSpan,
|
|
1762
|
+
finishTime,
|
|
1763
|
+
screenshotUploadResultPromise,
|
|
1764
|
+
failedTestTraceId,
|
|
1765
|
+
} of testSpanFinishes) {
|
|
1766
|
+
const finishTestSpan = (screenshotUploadResult) => {
|
|
1767
|
+
setScreenshotUploadTags(testSpan, screenshotUploadResult)
|
|
1768
|
+
setVideoUploadTags(testSpan, videoUploadResult, VIDEO_UPLOAD_SCOPE_TEST_SUITE)
|
|
1769
|
+
if (failedTestTraceId) this.screenshotUploadPromisesByTraceId.delete(failedTestTraceId)
|
|
1770
|
+
testSpan.finish(finishTime)
|
|
1771
|
+
}
|
|
1772
|
+
if (screenshotUploadResultPromise) {
|
|
1773
|
+
finishPromises.push(screenshotUploadResultPromise.then(finishTestSpan))
|
|
1774
|
+
} else {
|
|
1775
|
+
finishTestSpan()
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
if (finishPromises.length > 0) return Promise.all(finishPromises).then(() => null)
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1670
1781
|
/**
|
|
1671
1782
|
* Uploads failure screenshots for a Cypress test attempt.
|
|
1672
1783
|
*
|
|
@@ -1720,6 +1831,109 @@ class CypressPlugin {
|
|
|
1720
1831
|
}
|
|
1721
1832
|
}
|
|
1722
1833
|
|
|
1834
|
+
/**
|
|
1835
|
+
* Returns whether a Cypress test suite video can be uploaded.
|
|
1836
|
+
*
|
|
1837
|
+
* @param {object} options - Upload options
|
|
1838
|
+
* @param {string|undefined} options.filePath - Cypress video path
|
|
1839
|
+
* @param {string|undefined} options.testSessionId - Test session id
|
|
1840
|
+
* @param {string|undefined} options.testSuiteId - Test suite id
|
|
1841
|
+
* @returns {boolean}
|
|
1842
|
+
*/
|
|
1843
|
+
#canUploadTestSuiteVideo ({ filePath, testSessionId, testSuiteId }) {
|
|
1844
|
+
const exporter = this.tracer?._tracer?._exporter
|
|
1845
|
+
return Boolean(filePath && testSessionId && testSuiteId && !this.uploadedVideoPaths.has(filePath) &&
|
|
1846
|
+
exporter?.canUploadTestVideos?.() && exporter.uploadTestSuiteVideo)
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
/**
|
|
1850
|
+
* Uploads the Cypress spec video for a failed test suite.
|
|
1851
|
+
*
|
|
1852
|
+
* @param {object} options - Upload options
|
|
1853
|
+
* @param {string|undefined} options.filePath - Cypress video path
|
|
1854
|
+
* @param {string|undefined} options.testSessionId - Test session id
|
|
1855
|
+
* @param {string|undefined} options.testSuiteId - Test suite id
|
|
1856
|
+
* @returns {Promise<string>|undefined} Promise resolving to the upload outcome
|
|
1857
|
+
*/
|
|
1858
|
+
uploadTestSuiteVideo ({ filePath, testSessionId, testSuiteId }) {
|
|
1859
|
+
const exporter = this.tracer?._tracer?._exporter
|
|
1860
|
+
if (!this.#canUploadTestSuiteVideo({ filePath, testSessionId, testSuiteId })) return
|
|
1861
|
+
|
|
1862
|
+
this.uploadedVideoPaths.add(filePath)
|
|
1863
|
+
|
|
1864
|
+
return new Promise(resolve => {
|
|
1865
|
+
exporter.uploadTestSuiteVideo({
|
|
1866
|
+
filePath,
|
|
1867
|
+
testSessionId,
|
|
1868
|
+
testSuiteId,
|
|
1869
|
+
idempotencyKey: `${testSessionId}:${testSuiteId}:${basename(filePath)}`,
|
|
1870
|
+
capturedAtMs: Date.now(),
|
|
1871
|
+
}, (error) => {
|
|
1872
|
+
resolve(error ? VIDEO_UPLOAD_RESULT_ERROR : VIDEO_UPLOAD_RESULT_UPLOADED)
|
|
1873
|
+
})
|
|
1874
|
+
})
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
/**
|
|
1878
|
+
* Tags and finishes every event that references one Cypress test suite video.
|
|
1879
|
+
*
|
|
1880
|
+
* @param {object} pendingVideoUpload - Pending video upload and owning spans
|
|
1881
|
+
* @param {Array<object>} pendingVideoUpload.testSpanFinishes - Deferred test span finishes
|
|
1882
|
+
* @param {object|undefined} pendingVideoUpload.testSuiteSpan - Owning test suite span
|
|
1883
|
+
* @param {number} pendingVideoUpload.testSuiteFinishTime - Suite completion time captured by after:spec
|
|
1884
|
+
* @param {string|undefined} uploadResult - Video upload outcome
|
|
1885
|
+
* @returns {Promise<null>|undefined}
|
|
1886
|
+
*/
|
|
1887
|
+
#finishPendingTestSuiteVideo ({ testSpanFinishes, testSuiteSpan, testSuiteFinishTime }, uploadResult) {
|
|
1888
|
+
const testSpansPromise = this.finishTestSpans(testSpanFinishes, uploadResult)
|
|
1889
|
+
if (testSuiteSpan) {
|
|
1890
|
+
setVideoUploadTags(testSuiteSpan, uploadResult, VIDEO_UPLOAD_SCOPE_TEST_SUITE)
|
|
1891
|
+
testSuiteSpan.finish(testSuiteFinishTime)
|
|
1892
|
+
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
1893
|
+
}
|
|
1894
|
+
return testSpansPromise
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
/**
|
|
1898
|
+
* Finishes queued video-owned spans when Cypress will not reach after:run.
|
|
1899
|
+
*
|
|
1900
|
+
* @param {string} uploadResult - Video upload outcome applied to every queued span
|
|
1901
|
+
* @returns {Promise<null>|undefined}
|
|
1902
|
+
*/
|
|
1903
|
+
#finishPendingTestSuiteVideos (uploadResult) {
|
|
1904
|
+
const pendingVideoUploads = this.pendingVideoUploads
|
|
1905
|
+
this.pendingVideoUploads = []
|
|
1906
|
+
const finishPromises = []
|
|
1907
|
+
for (const pendingVideoUpload of pendingVideoUploads) {
|
|
1908
|
+
const finishPromise = this.#finishPendingTestSuiteVideo(pendingVideoUpload, uploadResult)
|
|
1909
|
+
if (finishPromise) finishPromises.push(finishPromise)
|
|
1910
|
+
}
|
|
1911
|
+
if (finishPromises.length > 0) return Promise.all(finishPromises).then(() => null)
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
/**
|
|
1915
|
+
* Starts queued Cypress video uploads after Cypress has compressed the source files.
|
|
1916
|
+
*
|
|
1917
|
+
* @returns {Promise<null>|undefined}
|
|
1918
|
+
*/
|
|
1919
|
+
uploadPendingTestSuiteVideos () {
|
|
1920
|
+
const pendingVideoUploads = this.pendingVideoUploads
|
|
1921
|
+
this.pendingVideoUploads = []
|
|
1922
|
+
const finishPromises = []
|
|
1923
|
+
for (const pendingVideoUpload of pendingVideoUploads) {
|
|
1924
|
+
const { filePath, testSessionId, testSuiteId } = pendingVideoUpload
|
|
1925
|
+
const uploadPromise = this.uploadTestSuiteVideo({ filePath, testSessionId, testSuiteId })
|
|
1926
|
+
if (uploadPromise) {
|
|
1927
|
+
finishPromises.push(uploadPromise.then(uploadResult =>
|
|
1928
|
+
this.#finishPendingTestSuiteVideo(pendingVideoUpload, uploadResult)))
|
|
1929
|
+
} else {
|
|
1930
|
+
const finishPromise = this.#finishPendingTestSuiteVideo(pendingVideoUpload)
|
|
1931
|
+
if (finishPromise) finishPromises.push(finishPromise)
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
if (finishPromises.length > 0) return Promise.all(finishPromises).then(() => null)
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1723
1937
|
getTasks () {
|
|
1724
1938
|
return {
|
|
1725
1939
|
'dd:testSuiteStart': ({ testSuite, testSuiteAbsolutePath }) => {
|
|
@@ -12,9 +12,12 @@ class GoogleCloudPubsubClientPlugin extends ClientPlugin {
|
|
|
12
12
|
|
|
13
13
|
if (api === 'publish') return
|
|
14
14
|
|
|
15
|
+
let resource = api
|
|
16
|
+
if (request.name) resource += ` ${request.name}`
|
|
17
|
+
|
|
15
18
|
const spanOptions = {
|
|
16
19
|
service: this.config.service || this.serviceName(),
|
|
17
|
-
resource
|
|
20
|
+
resource,
|
|
18
21
|
kind: this.constructor.kind,
|
|
19
22
|
meta: {
|
|
20
23
|
'pubsub.method': api,
|