dd-trace 6.2.0 → 6.4.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.md +1 -1
- package/index.electron.js +3 -0
- package/package.json +8 -5
- package/packages/datadog-instrumentations/src/ai.js +29 -24
- package/packages/datadog-instrumentations/src/cookie.js +7 -1
- package/packages/datadog-instrumentations/src/cucumber.js +4 -3
- package/packages/datadog-instrumentations/src/express.js +20 -2
- package/packages/datadog-instrumentations/src/grpc/server.js +18 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/modelcontextprotocol-sdk.js +30 -54
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +8 -8
- package/packages/datadog-instrumentations/src/http/server.js +27 -0
- package/packages/datadog-instrumentations/src/http2/server.js +143 -17
- package/packages/datadog-instrumentations/src/jest.js +10 -4
- package/packages/datadog-instrumentations/src/modelcontextprotocol-sdk.js +248 -1
- package/packages/datadog-instrumentations/src/playwright.js +40 -3
- package/packages/datadog-instrumentations/src/router.js +180 -105
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +41 -16
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +21 -21
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +14 -8
- package/packages/datadog-plugin-aws-sdk/src/util.js +0 -22
- package/packages/datadog-plugin-azure-functions/src/index.js +2 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +5 -5
- package/packages/datadog-plugin-graphql/src/execute.js +90 -14
- package/packages/datadog-plugin-graphql/src/parse.js +22 -1
- package/packages/datadog-plugin-graphql/src/request.js +33 -2
- package/packages/datadog-plugin-graphql/src/utils.js +42 -0
- package/packages/datadog-plugin-graphql/src/validate.js +13 -1
- package/packages/datadog-plugin-http2/src/server.js +38 -6
- package/packages/datadog-plugin-jest/src/util.js +21 -6
- package/packages/datadog-plugin-modelcontextprotocol-sdk/src/tracing.js +144 -26
- package/packages/datadog-plugin-modelcontextprotocol-sdk/src/utils.js +30 -0
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +4 -2
- package/packages/datadog-shimmer/src/shimmer.js +9 -2
- package/packages/dd-trace/index.electron.js +3 -0
- package/packages/dd-trace/index.js +2 -37
- package/packages/dd-trace/src/appsec/channels.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +6 -3
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +1 -1
- package/packages/dd-trace/src/bootstrap.js +39 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +23 -16
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +14 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +22 -6
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +5 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +55 -5
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +8 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
- package/packages/dd-trace/src/config/config-types.d.ts +8 -0
- package/packages/dd-trace/src/config/defaults.js +20 -15
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
- package/packages/dd-trace/src/config/index.js +13 -3
- package/packages/dd-trace/src/config/parsers.js +79 -0
- package/packages/dd-trace/src/config/supported-configurations.json +17 -0
- package/packages/dd-trace/src/constants.js +7 -0
- package/packages/dd-trace/src/datastreams/pathway.js +6 -4
- package/packages/dd-trace/src/feature-registry.js +22 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +2 -0
- package/packages/dd-trace/src/llmobs/index.js +10 -2
- package/packages/dd-trace/src/llmobs/tagger.js +19 -1
- package/packages/dd-trace/src/noop/proxy.js +5 -4
- package/packages/dd-trace/src/openfeature/register.js +46 -0
- package/packages/dd-trace/src/opentelemetry/span_processor.js +7 -5
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +32 -16
- package/packages/dd-trace/src/opentracing/propagation/log.js +11 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +80 -14
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +10 -1
- package/packages/dd-trace/src/opentracing/tracer.js +7 -1
- package/packages/dd-trace/src/plugins/util/test.js +9 -4
- package/packages/dd-trace/src/plugins/util/web.js +12 -0
- package/packages/dd-trace/src/proxy.js +21 -9
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +20 -11
- package/packages/dd-trace/src/standalone/index.js +0 -22
- 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
|
@@ -1861,10 +1861,16 @@ function resetSuiteSkippingRunState () {
|
|
|
1861
1861
|
function applySuiteSkipping (originalTests, rootDir, frameworkVersion) {
|
|
1862
1862
|
if (!isItrEnabled || !isSuitesSkippingEnabled) return originalTests
|
|
1863
1863
|
|
|
1864
|
-
const
|
|
1865
|
-
const jestSuitesToRun = getJestSuitesToRun(skippableSuites, originalTests,
|
|
1864
|
+
const repositoryRoot = getRepositoryRootFromTest(originalTests[0], rootDir)
|
|
1865
|
+
const jestSuitesToRun = getJestSuitesToRun(skippableSuites, originalTests, repositoryRoot, rootDir)
|
|
1866
1866
|
hasFilteredSkippableSuites = true
|
|
1867
|
-
log.debug(
|
|
1867
|
+
log.debug(
|
|
1868
|
+
'Jest discovered %d suites; skipped %d using %d skippable candidates; %d suites will run.',
|
|
1869
|
+
originalTests.length,
|
|
1870
|
+
jestSuitesToRun.skippedSuites.length,
|
|
1871
|
+
skippableSuites.length,
|
|
1872
|
+
jestSuitesToRun.suitesToRun.length
|
|
1873
|
+
)
|
|
1868
1874
|
hasUnskippableSuites = jestSuitesToRun.hasUnskippableSuites
|
|
1869
1875
|
hasForcedToRunSuites = jestSuitesToRun.hasForcedToRunSuites
|
|
1870
1876
|
|
|
@@ -1877,7 +1883,7 @@ function applySuiteSkipping (originalTests, rootDir, frameworkVersion) {
|
|
|
1877
1883
|
? getTestContexts(originalTests)
|
|
1878
1884
|
: undefined
|
|
1879
1885
|
coverageBackfillFiles = isSuitesSkipped && isTiaCoverageBackfillEnabled() && hasSkippableSuitesCoverage()
|
|
1880
|
-
? getCoverageBackfillFiles(skippableSuitesCoverage,
|
|
1886
|
+
? getCoverageBackfillFiles(skippableSuitesCoverage, repositoryRoot, getTestSuitePath)
|
|
1881
1887
|
: undefined
|
|
1882
1888
|
|
|
1883
1889
|
itrSkippedSuitesCh.publish({ skippedSuites: jestSuitesToRun.skippedSuites, frameworkVersion })
|
|
@@ -1,7 +1,254 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { tracingChannel } = require('dc-polyfill')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
const { addHook, channel, getHooks } = require('./helpers/instrument')
|
|
4
6
|
|
|
5
7
|
for (const hook of getHooks('@modelcontextprotocol/sdk')) {
|
|
6
8
|
addHook(hook, exports => exports)
|
|
7
9
|
}
|
|
10
|
+
|
|
11
|
+
const serverRequestCh = tracingChannel('apm:mcp:server:request')
|
|
12
|
+
const clientRequestInjectCh = channel('apm:mcp:client:request:inject')
|
|
13
|
+
const serverToolRegisteredCh = channel('apm:mcp:server:tool:registered')
|
|
14
|
+
|
|
15
|
+
const DISTRIBUTED_TRACE_META_KEY = '_dd_trace_context'
|
|
16
|
+
const TRACED_METHOD_PREFIX = /^(?:tools|resources|prompts)\//
|
|
17
|
+
|
|
18
|
+
// Maps Protocol instance → Map<requestId, ctx>. Shares the ctx object between
|
|
19
|
+
// _onrequest (span start, in the correct HTTP async context), the SDK request
|
|
20
|
+
// handler wrapper (result/error capture), and the SDK cleanup path (span finish).
|
|
21
|
+
const pendingContexts = new WeakMap()
|
|
22
|
+
const wrappedAbortControllerMaps = new WeakSet()
|
|
23
|
+
const wrappedRequestHandlerMaps = new WeakSet()
|
|
24
|
+
const wrappedRequestHandlers = new WeakSet()
|
|
25
|
+
|
|
26
|
+
function addTraceContextToRequest (request, traceContext) {
|
|
27
|
+
return {
|
|
28
|
+
...request,
|
|
29
|
+
params: {
|
|
30
|
+
...request.params,
|
|
31
|
+
_meta: {
|
|
32
|
+
...request.params?._meta,
|
|
33
|
+
[DISTRIBUTED_TRACE_META_KEY]: traceContext,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getPendingContext (protocol, requestId) {
|
|
40
|
+
return pendingContexts.get(protocol)?.get(requestId)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function finishServerRequest (protocol, requestId) {
|
|
44
|
+
const pending = pendingContexts.get(protocol)
|
|
45
|
+
const ctx = pending?.get(requestId)
|
|
46
|
+
if (!ctx) return
|
|
47
|
+
|
|
48
|
+
pending.delete(requestId)
|
|
49
|
+
serverRequestCh.asyncEnd.publish(ctx)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function wrapRequestHandler (protocol, handler) {
|
|
53
|
+
if (wrappedRequestHandlers.has(handler)) return handler
|
|
54
|
+
|
|
55
|
+
const wrappedHandler = function requestHandlerWithTrace (request, extra) {
|
|
56
|
+
const ctx = getPendingContext(protocol, extra?.requestId)
|
|
57
|
+
if (!ctx) return handler.apply(this, arguments)
|
|
58
|
+
|
|
59
|
+
let result
|
|
60
|
+
try {
|
|
61
|
+
result = handler.apply(this, arguments)
|
|
62
|
+
} catch (err) {
|
|
63
|
+
ctx.error = err
|
|
64
|
+
throw err
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (result && typeof result.then === 'function') {
|
|
68
|
+
result.then(result => {
|
|
69
|
+
ctx.result = result
|
|
70
|
+
}, err => {
|
|
71
|
+
ctx.error = err
|
|
72
|
+
})
|
|
73
|
+
return result
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
ctx.result = result
|
|
77
|
+
return result
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
wrappedRequestHandlers.add(wrappedHandler)
|
|
81
|
+
return wrappedHandler
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function wrapRequestHandlers (protocol) {
|
|
85
|
+
const handlers = protocol._requestHandlers
|
|
86
|
+
if (!handlers || wrappedRequestHandlerMaps.has(handlers)) return
|
|
87
|
+
|
|
88
|
+
wrappedRequestHandlerMaps.add(handlers)
|
|
89
|
+
shimmer.wrap(handlers, 'set', function (original) {
|
|
90
|
+
return function setRequestHandlerWithTrace (method, handler) {
|
|
91
|
+
if (typeof handler === 'function') {
|
|
92
|
+
return original.call(this, method, wrapRequestHandler(protocol, handler))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return original.apply(this, arguments)
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function wrapAbortControllers (protocol) {
|
|
101
|
+
const controllers = protocol._requestHandlerAbortControllers
|
|
102
|
+
if (!controllers || wrappedAbortControllerMaps.has(controllers)) return
|
|
103
|
+
|
|
104
|
+
wrappedAbortControllerMaps.add(controllers)
|
|
105
|
+
shimmer.wrap(controllers, 'delete', function (original) {
|
|
106
|
+
return function deleteAbortControllerWithTrace (requestId) {
|
|
107
|
+
finishServerRequest(protocol, requestId)
|
|
108
|
+
return original.apply(this, arguments)
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
shimmer.wrap(controllers, 'clear', function (original) {
|
|
112
|
+
return function clearAbortControllersWithTrace () {
|
|
113
|
+
for (const requestId of this.keys()) {
|
|
114
|
+
finishServerRequest(protocol, requestId)
|
|
115
|
+
}
|
|
116
|
+
return original.apply(this, arguments)
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function wrapProtocol (Protocol) {
|
|
122
|
+
// Inject trace context into MCP request metadata so out-of-process MCP servers
|
|
123
|
+
// can parent server spans to the client operation span.
|
|
124
|
+
shimmer.wrap(Protocol.prototype, 'request', function (original) {
|
|
125
|
+
return function requestWithTraceContext (request, resultSchema, options) {
|
|
126
|
+
if (!clientRequestInjectCh.hasSubscribers || !TRACED_METHOD_PREFIX.test(request?.method)) {
|
|
127
|
+
return original.apply(this, arguments)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const ctx = {}
|
|
131
|
+
clientRequestInjectCh.publish(ctx)
|
|
132
|
+
|
|
133
|
+
if (!ctx.traceContext) {
|
|
134
|
+
return original.apply(this, arguments)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return original.call(this, addTraceContextToRequest(request, ctx.traceContext), resultSchema, options)
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// Start spans in _onrequest — this runs inside the express POST /mcp handler's
|
|
142
|
+
// async context, so ALS correctly parents server spans under the HTTP span.
|
|
143
|
+
shimmer.wrap(Protocol.prototype, '_onrequest', function (original) {
|
|
144
|
+
return function _onrequestWithTrace (request, extra) {
|
|
145
|
+
if (!serverRequestCh.hasSubscribers || !TRACED_METHOD_PREFIX.test(request.method)) {
|
|
146
|
+
return original.call(this, request, extra)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
wrapAbortControllers(this)
|
|
150
|
+
const ctx = { request, extra }
|
|
151
|
+
serverRequestCh.start.runStores(ctx, () => {
|
|
152
|
+
let pending = pendingContexts.get(this)
|
|
153
|
+
if (!pending) {
|
|
154
|
+
pending = new Map()
|
|
155
|
+
pendingContexts.set(this, pending)
|
|
156
|
+
}
|
|
157
|
+
pending.set(request.id, ctx)
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
original.call(this, request, extra)
|
|
161
|
+
} catch (err) {
|
|
162
|
+
ctx.error = err
|
|
163
|
+
finishServerRequest(this, request.id)
|
|
164
|
+
throw err
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// The SDK registers an AbortController only when it actually dispatches a handler.
|
|
168
|
+
// If none was registered (MethodNotFound path), no handler will run and our
|
|
169
|
+
// SDK cleanup hook will never fire — finish the span immediately.
|
|
170
|
+
if (!this._requestHandlerAbortControllers?.has(request.id)) {
|
|
171
|
+
ctx.error = { name: 'McpError', message: 'Method not found' }
|
|
172
|
+
finishServerRequest(this, request.id)
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
// The SDK's handler closure Zod-parses the request, stripping the JSON-RPC `id`.
|
|
179
|
+
// Use `extra.requestId` (the SDK's fullExtra field) to correlate with the pending ctx.
|
|
180
|
+
shimmer.wrap(Protocol.prototype, 'setRequestHandler', function (original) {
|
|
181
|
+
return function setRequestHandlerWithTrace () {
|
|
182
|
+
wrapRequestHandlers(this)
|
|
183
|
+
return original.apply(this, arguments)
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
return Protocol
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function wrapMcpServer (McpServer) {
|
|
191
|
+
// Both public registration methods (tool/registerTool) delegate here — one hook covers both.
|
|
192
|
+
// Publishes to serverToolRegisteredCh so tracing.js can build a WeakMap of tool → name
|
|
193
|
+
// for O(1) lookup in McpServerToolCallPlugin (executeToolHandler receives the tool object,
|
|
194
|
+
// not the name string).
|
|
195
|
+
shimmer.wrap(McpServer.prototype, '_createRegisteredTool', function (original) {
|
|
196
|
+
return function (name) {
|
|
197
|
+
const result = original.apply(this, arguments)
|
|
198
|
+
if (serverToolRegisteredCh.hasSubscribers) {
|
|
199
|
+
const tool = this._registeredTools?.[name]
|
|
200
|
+
if (tool) {
|
|
201
|
+
serverToolRegisteredCh.publish({ tool, name })
|
|
202
|
+
shimmer.wrap(tool, 'update', function (update) {
|
|
203
|
+
return function updateWithTrace (updates) {
|
|
204
|
+
const result = update.apply(this, arguments)
|
|
205
|
+
if (updates && Object.hasOwn(updates, 'name')) {
|
|
206
|
+
serverToolRegisteredCh.publish({ tool, name: updates.name || undefined })
|
|
207
|
+
}
|
|
208
|
+
return result
|
|
209
|
+
}
|
|
210
|
+
})
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return result
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
return McpServer
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
addHook({
|
|
221
|
+
name: '@modelcontextprotocol/sdk',
|
|
222
|
+
versions: ['>=1.27.1'],
|
|
223
|
+
file: 'dist/cjs/shared/protocol.js',
|
|
224
|
+
}, exports => {
|
|
225
|
+
wrapProtocol(exports.Protocol)
|
|
226
|
+
return exports
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
addHook({
|
|
230
|
+
name: '@modelcontextprotocol/sdk',
|
|
231
|
+
versions: ['>=1.27.1'],
|
|
232
|
+
file: 'dist/esm/shared/protocol.js',
|
|
233
|
+
}, exports => {
|
|
234
|
+
wrapProtocol(exports.Protocol)
|
|
235
|
+
return exports
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
addHook({
|
|
239
|
+
name: '@modelcontextprotocol/sdk',
|
|
240
|
+
versions: ['>=1.27.1'],
|
|
241
|
+
file: 'dist/cjs/server/mcp.js',
|
|
242
|
+
}, exports => {
|
|
243
|
+
wrapMcpServer(exports.McpServer)
|
|
244
|
+
return exports
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
addHook({
|
|
248
|
+
name: '@modelcontextprotocol/sdk',
|
|
249
|
+
versions: ['>=1.27.1'],
|
|
250
|
+
file: 'dist/esm/server/mcp.js',
|
|
251
|
+
}, exports => {
|
|
252
|
+
wrapMcpServer(exports.McpServer)
|
|
253
|
+
return exports
|
|
254
|
+
})
|
|
@@ -105,6 +105,7 @@ const efdStartedOriginalTestKeys = new Set()
|
|
|
105
105
|
const efdSlowAbortedTests = new Set()
|
|
106
106
|
const ddPropertiesByTestId = new Map()
|
|
107
107
|
const ddPropertiesRequestsByTestId = new Map()
|
|
108
|
+
const disabledTestIds = new Set()
|
|
108
109
|
let rootDir = ''
|
|
109
110
|
let sessionProjects = []
|
|
110
111
|
|
|
@@ -113,6 +114,8 @@ const EFD_RETRY_COUNT_REQUEST = 'ddEfdRetryCountRequest'
|
|
|
113
114
|
const EFD_RETRY_COUNT_RESPONSE = 'ddEfdRetryCountResponse'
|
|
114
115
|
const DD_PROPERTIES_REQUEST = 'ddPropertiesRequest'
|
|
115
116
|
const DD_PROPERTIES_RESPONSE = 'ddProperties'
|
|
117
|
+
const kDdPlaywrightDisabledTestIds = Symbol('ddPlaywrightDisabledTestIds')
|
|
118
|
+
const kDdPlaywrightWorkerHostInstrumented = Symbol('ddPlaywrightWorkerHostInstrumented')
|
|
116
119
|
const kDdPlaywrightWorkerInstrumented = Symbol('ddPlaywrightWorkerInstrumented')
|
|
117
120
|
|
|
118
121
|
function isValidKnownTests (receivedKnownTests) {
|
|
@@ -991,14 +994,36 @@ function onDispatcherCreateWorker (dispatcher, worker) {
|
|
|
991
994
|
const projects = getProjectsFromDispatcher(dispatcher)
|
|
992
995
|
sessionProjects = projects
|
|
993
996
|
|
|
997
|
+
if (disabledTestIds.size && !worker[kDdPlaywrightWorkerHostInstrumented] &&
|
|
998
|
+
typeof worker.runTestGroup === 'function') {
|
|
999
|
+
Object.defineProperty(worker, kDdPlaywrightWorkerHostInstrumented, { value: true })
|
|
1000
|
+
shimmer.wrap(worker, 'runTestGroup', runTestGroup => function (runPayload) {
|
|
1001
|
+
// Serial retries can restore disabled tests that were filtered from the initial dispatcher groups.
|
|
1002
|
+
let disabledIds
|
|
1003
|
+
for (const { testId } of runPayload.entries) {
|
|
1004
|
+
if (disabledTestIds.has(testId)) {
|
|
1005
|
+
disabledIds ??= []
|
|
1006
|
+
disabledIds.push(testId)
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
if (disabledIds) {
|
|
1010
|
+
runPayload._ddDisabledTestIds = disabledIds
|
|
1011
|
+
}
|
|
1012
|
+
return runTestGroup.apply(this, arguments)
|
|
1013
|
+
})
|
|
1014
|
+
}
|
|
1015
|
+
|
|
994
1016
|
worker.on('testBegin', ({ testId }) => {
|
|
995
1017
|
const test = getTestByTestId(dispatcher, testId)
|
|
1018
|
+
if (!test) return
|
|
1019
|
+
|
|
996
1020
|
const browser = getBrowserNameFromProjects(projects, test)
|
|
997
1021
|
const shouldCreateTestSpan = test.expectedStatus === 'skipped'
|
|
998
1022
|
testBeginHandler(test, browser, shouldCreateTestSpan)
|
|
999
1023
|
})
|
|
1000
1024
|
worker.on('testEnd', ({ testId, status, errors, annotations }) => {
|
|
1001
1025
|
const test = getTestByTestId(dispatcher, testId)
|
|
1026
|
+
if (!test) return
|
|
1002
1027
|
|
|
1003
1028
|
const isTimeout = status === 'timedOut'
|
|
1004
1029
|
const testStatus = STATUS_TO_TEST_STATUS[status]
|
|
@@ -1308,6 +1333,7 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
|
|
|
1308
1333
|
efdSlowAbortedTests.clear()
|
|
1309
1334
|
ddPropertiesByTestId.clear()
|
|
1310
1335
|
ddPropertiesRequestsByTestId.clear()
|
|
1336
|
+
disabledTestIds.clear()
|
|
1311
1337
|
|
|
1312
1338
|
// TODO: we can trick playwright into thinking the session passed by returning
|
|
1313
1339
|
// 'passed' here. We might be able to use this for both EFD and Test Management tests.
|
|
@@ -1552,6 +1578,7 @@ function processRootSuite (createRootSuiteReturnValue) {
|
|
|
1552
1578
|
if (testProperties.disabled) {
|
|
1553
1579
|
test._ddIsDisabled = true
|
|
1554
1580
|
if (!testProperties.attemptToFix) {
|
|
1581
|
+
disabledTestIds.add(test.id)
|
|
1555
1582
|
test.expectedStatus = 'skipped'
|
|
1556
1583
|
// setting test.expectedStatus to 'skipped' does not work for every case,
|
|
1557
1584
|
// so we need to filter out disabled tests in dispatcherRunWrapperNew,
|
|
@@ -1795,7 +1822,17 @@ function instrumentWorkerMainMethods (workerMain) {
|
|
|
1795
1822
|
let steps = []
|
|
1796
1823
|
const stepInfoByStepId = {}
|
|
1797
1824
|
|
|
1825
|
+
shimmer.wrap(workerMain, 'runTestGroup', runTestGroup => function (runPayload) {
|
|
1826
|
+
const disabledIds = runPayload._ddDisabledTestIds
|
|
1827
|
+
this[kDdPlaywrightDisabledTestIds] = disabledIds ? new Set(disabledIds) : undefined
|
|
1828
|
+
return runTestGroup.apply(this, arguments)
|
|
1829
|
+
})
|
|
1830
|
+
|
|
1798
1831
|
shimmer.wrap(workerMain, '_runTest', _runTest => async function (test) {
|
|
1832
|
+
if (this[kDdPlaywrightDisabledTestIds]?.has(test.id)) {
|
|
1833
|
+
test._ddIsDisabled = true
|
|
1834
|
+
test.expectedStatus = 'skipped'
|
|
1835
|
+
}
|
|
1799
1836
|
await waitForEfdRetryCount(test)
|
|
1800
1837
|
if (shouldSkipEfdRetry(test)) {
|
|
1801
1838
|
test._ddShouldSkipEfdRetry = true
|
|
@@ -2042,9 +2079,9 @@ function generateSummaryWrapper (generateSummary) {
|
|
|
2042
2079
|
return function (...args) {
|
|
2043
2080
|
for (const test of this.suite.allTests()) {
|
|
2044
2081
|
// https://github.com/microsoft/playwright/blob/bf92ffecff6f30a292b53430dbaee0207e0c61ad/packages/playwright/src/reporters/base.ts#L279
|
|
2045
|
-
const
|
|
2046
|
-
(!test.results.length || test.expectedStatus !== 'skipped')
|
|
2047
|
-
if (
|
|
2082
|
+
const shouldReportAsSkipped = test.outcome() === 'skipped' &&
|
|
2083
|
+
(disabledTestIds.has(test.id) || !test.results.length || test.expectedStatus !== 'skipped')
|
|
2084
|
+
if (shouldReportAsSkipped && !testsReportedInGenerateSummary.has(test)) {
|
|
2048
2085
|
testsReportedInGenerateSummary.add(test)
|
|
2049
2086
|
const {
|
|
2050
2087
|
_requireFile: testSuiteAbsolutePath,
|