dd-trace 5.22.0 → 5.23.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 +2 -0
- package/index.d.ts +20 -8
- package/package.json +9 -3
- package/packages/datadog-instrumentations/src/cucumber.js +290 -53
- package/packages/datadog-instrumentations/src/jest.js +3 -1
- package/packages/datadog-instrumentations/src/kafkajs.js +67 -31
- package/packages/datadog-instrumentations/src/microgateway-core.js +3 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +139 -54
- package/packages/datadog-instrumentations/src/mocha/utils.js +35 -15
- package/packages/datadog-instrumentations/src/mocha/worker.js +29 -1
- package/packages/datadog-instrumentations/src/openai.js +4 -2
- package/packages/datadog-instrumentations/src/pg.js +59 -4
- package/packages/datadog-instrumentations/src/vitest.js +184 -9
- package/packages/datadog-plugin-amqplib/src/consumer.js +1 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +33 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
- package/packages/datadog-plugin-cucumber/src/index.js +24 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +36 -6
- package/packages/datadog-plugin-cypress/src/support.js +4 -1
- package/packages/datadog-plugin-http/src/client.js +1 -42
- package/packages/datadog-plugin-http2/src/client.js +1 -26
- package/packages/datadog-plugin-jest/src/index.js +17 -1
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +20 -0
- package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -2
- package/packages/datadog-plugin-kafkajs/src/index.js +3 -1
- package/packages/datadog-plugin-mocha/src/index.js +18 -0
- package/packages/datadog-plugin-openai/src/index.js +27 -18
- package/packages/datadog-plugin-playwright/src/index.js +9 -0
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -3
- package/packages/datadog-plugin-vitest/src/index.js +68 -3
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/channels.js +4 -2
- package/packages/dd-trace/src/appsec/rasp/index.js +103 -0
- package/packages/dd-trace/src/appsec/rasp/sql_injection.js +86 -0
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +37 -0
- package/packages/dd-trace/src/appsec/rasp/utils.js +63 -0
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -0
- package/packages/dd-trace/src/appsec/remote_config/index.js +16 -7
- package/packages/dd-trace/src/appsec/remote_config/manager.js +89 -51
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +33 -14
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +4 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +13 -0
- package/packages/dd-trace/src/config.js +61 -10
- package/packages/dd-trace/src/constants.js +11 -1
- package/packages/dd-trace/src/data_streams_context.js +3 -0
- package/packages/dd-trace/src/datastreams/fnv.js +23 -0
- package/packages/dd-trace/src/datastreams/pathway.js +12 -5
- package/packages/dd-trace/src/datastreams/processor.js +35 -0
- package/packages/dd-trace/src/datastreams/schemas/schema.js +8 -0
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +125 -0
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +29 -0
- package/packages/dd-trace/src/debugger/devtools_client/config.js +24 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +57 -0
- package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +23 -0
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +164 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +28 -0
- package/packages/dd-trace/src/debugger/devtools_client/session.js +7 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +47 -0
- package/packages/dd-trace/src/debugger/devtools_client/status.js +109 -0
- package/packages/dd-trace/src/debugger/index.js +92 -0
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +29 -2
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/payload-tagging/config/aws.json +30 -0
- package/packages/dd-trace/src/payload-tagging/config/index.js +30 -0
- package/packages/dd-trace/src/payload-tagging/index.js +93 -0
- package/packages/dd-trace/src/payload-tagging/tagging.js +83 -0
- package/packages/dd-trace/src/plugin_manager.js +11 -10
- package/packages/dd-trace/src/plugins/ci_plugin.js +33 -8
- package/packages/dd-trace/src/plugins/util/env.js +5 -2
- package/packages/dd-trace/src/plugins/util/test.js +26 -2
- package/packages/dd-trace/src/profiling/config.js +5 -0
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns.js +13 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +16 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +16 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +24 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +16 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +48 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/net.js +24 -0
- package/packages/dd-trace/src/profiling/profilers/events.js +108 -32
- package/packages/dd-trace/src/profiling/profilers/shared.js +5 -0
- package/packages/dd-trace/src/profiling/profilers/wall.js +9 -3
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +10 -2
- package/packages/dd-trace/src/proxy.js +10 -3
- package/packages/dd-trace/src/span_stats.js +4 -2
- package/packages/dd-trace/src/appsec/rasp.js +0 -176
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -14,6 +14,7 @@ require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
|
|
|
14
14
|
require,int64-buffer,MIT,Copyright 2015-2016 Yusuke Kawasaki
|
|
15
15
|
require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
|
|
16
16
|
require,jest-docblock,MIT,Copyright Meta Platforms, Inc. and affiliates.
|
|
17
|
+
require,jsonpath-plus,MIT,Copyright (c) 2011-2019 Stefan Goessner, Subbu Allamaraju, Mike Brevoort, Robert Krahn, Brett Zamir, Richard Schneider
|
|
17
18
|
require,koalas,MIT,Copyright 2013-2017 Brian Woodward
|
|
18
19
|
require,limiter,MIT,Copyright 2011 John Hurliman
|
|
19
20
|
require,lodash.sortby,MIT,Copyright JS Foundation and other contributors
|
|
@@ -26,6 +27,7 @@ require,pprof-format,MIT,Copyright 2022 Stephen Belanger
|
|
|
26
27
|
require,protobufjs,BSD-3-Clause,Copyright 2016 Daniel Wirtz
|
|
27
28
|
require,tlhunter-sorted-set,MIT,Copyright (c) 2023 Datadog Inc.
|
|
28
29
|
require,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
|
|
30
|
+
require,rfdc,MIT,Copyright 2019 David Mark Clements
|
|
29
31
|
require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
|
|
30
32
|
require,shell-quote,mit,Copyright (c) 2013 James Halliday
|
|
31
33
|
dev,@types/node,MIT,Copyright Authors
|
package/index.d.ts
CHANGED
|
@@ -729,6 +729,26 @@ declare namespace tracer {
|
|
|
729
729
|
* The selection and priority order of context propagation injection and extraction mechanisms.
|
|
730
730
|
*/
|
|
731
731
|
propagationStyle?: string[] | PropagationStyle
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Cloud payload report as tags
|
|
735
|
+
*/
|
|
736
|
+
cloudPayloadTagging?: {
|
|
737
|
+
/**
|
|
738
|
+
* Additional JSONPath queries to replace with `redacted` in request payloads
|
|
739
|
+
* Undefined or invalid JSONPath queries disable the feature for requests.
|
|
740
|
+
*/
|
|
741
|
+
request?: string,
|
|
742
|
+
/**
|
|
743
|
+
* Additional JSONPath queries to replace with `redacted` in response payloads
|
|
744
|
+
* Undefined or invalid JSONPath queries disable the feature for responses.
|
|
745
|
+
*/
|
|
746
|
+
response?: string,
|
|
747
|
+
/**
|
|
748
|
+
* Maximum depth of payload traversal for tags
|
|
749
|
+
*/
|
|
750
|
+
maxDepth?: number
|
|
751
|
+
}
|
|
732
752
|
}
|
|
733
753
|
|
|
734
754
|
/**
|
|
@@ -1010,14 +1030,6 @@ declare namespace tracer {
|
|
|
1010
1030
|
* @default code => code < 500
|
|
1011
1031
|
*/
|
|
1012
1032
|
validateStatus?: (code: number) => boolean;
|
|
1013
|
-
|
|
1014
|
-
/**
|
|
1015
|
-
* Enable injection of tracing headers into requests signed with AWS IAM headers.
|
|
1016
|
-
* Disable this if you get AWS signature errors (HTTP 403).
|
|
1017
|
-
*
|
|
1018
|
-
* @default false
|
|
1019
|
-
*/
|
|
1020
|
-
enablePropagationWithAmazonHeaders?: boolean;
|
|
1021
1033
|
}
|
|
1022
1034
|
|
|
1023
1035
|
/** @hidden */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.23.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -13,12 +13,15 @@
|
|
|
13
13
|
"type:doc": "cd docs && yarn && yarn build",
|
|
14
14
|
"type:test": "cd docs && yarn && yarn test",
|
|
15
15
|
"lint": "node scripts/check_licenses.js && eslint . && yarn audit --groups dependencies",
|
|
16
|
+
"lint-fix": "node scripts/check_licenses.js && eslint . --fix && yarn audit --groups dependencies",
|
|
16
17
|
"services": "node ./scripts/install_plugin_modules && node packages/dd-trace/test/setup/services",
|
|
17
18
|
"test": "SERVICES=* yarn services && mocha --expose-gc 'packages/dd-trace/test/setup/node.js' 'packages/*/test/**/*.spec.js'",
|
|
18
19
|
"test:appsec": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" \"packages/dd-trace/test/appsec/**/*.spec.js\"",
|
|
19
20
|
"test:appsec:ci": "nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" -- npm run test:appsec",
|
|
20
21
|
"test:appsec:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/appsec/**/*.@($(echo $PLUGINS)).plugin.spec.js\"",
|
|
21
22
|
"test:appsec:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" -- npm run test:appsec:plugins",
|
|
23
|
+
"test:debugger": "tap packages/dd-trace/test/debugger/**/*.spec.js",
|
|
24
|
+
"test:debugger:ci": "npm run test:debugger -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/debugger/**/*.js\"",
|
|
22
25
|
"test:trace:core": "tap packages/dd-trace/test/*.spec.js \"packages/dd-trace/test/{ci-visibility,datastreams,encode,exporters,opentelemetry,opentracing,plugins,service-naming,telemetry}/**/*.spec.js\"",
|
|
23
26
|
"test:trace:core:ci": "npm run test:trace:core -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/**/*.js\"",
|
|
24
27
|
"test:instrumentations": "mocha -r 'packages/dd-trace/test/setup/mocha.js' 'packages/datadog-instrumentations/test/**/*.spec.js'",
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
"test:integration:appsec": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/appsec/*.spec.js\"",
|
|
37
40
|
"test:integration:cucumber": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/cucumber/*.spec.js\"",
|
|
38
41
|
"test:integration:cypress": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/cypress/*.spec.js\"",
|
|
42
|
+
"test:integration:debugger": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/debugger/*.spec.js\"",
|
|
39
43
|
"test:integration:jest": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/jest/*.spec.js\"",
|
|
40
44
|
"test:integration:mocha": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/mocha/*.spec.js\"",
|
|
41
45
|
"test:integration:playwright": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/playwright/*.spec.js\"",
|
|
@@ -83,10 +87,11 @@
|
|
|
83
87
|
"crypto-randomuuid": "^1.0.0",
|
|
84
88
|
"dc-polyfill": "^0.1.4",
|
|
85
89
|
"ignore": "^5.2.4",
|
|
86
|
-
"import-in-the-middle": "
|
|
90
|
+
"import-in-the-middle": "1.11.2",
|
|
87
91
|
"int64-buffer": "^0.1.9",
|
|
88
92
|
"istanbul-lib-coverage": "3.2.0",
|
|
89
93
|
"jest-docblock": "^29.7.0",
|
|
94
|
+
"jsonpath-plus": "^9.0.0",
|
|
90
95
|
"koalas": "^1.0.2",
|
|
91
96
|
"limiter": "1.1.5",
|
|
92
97
|
"lodash.sortby": "^4.7.0",
|
|
@@ -94,10 +99,11 @@
|
|
|
94
99
|
"module-details-from-path": "^1.0.3",
|
|
95
100
|
"msgpack-lite": "^0.1.26",
|
|
96
101
|
"opentracing": ">=0.12.1",
|
|
97
|
-
"path-to-regexp": "^0.1.
|
|
102
|
+
"path-to-regexp": "^0.1.10",
|
|
98
103
|
"pprof-format": "^2.1.0",
|
|
99
104
|
"protobufjs": "^7.2.5",
|
|
100
105
|
"retry": "^0.13.1",
|
|
106
|
+
"rfdc": "^1.3.1",
|
|
101
107
|
"semver": "^7.5.4",
|
|
102
108
|
"shell-quote": "^1.8.1",
|
|
103
109
|
"tlhunter-sorted-set": "^0.1.0"
|
|
@@ -35,7 +35,8 @@ const {
|
|
|
35
35
|
mergeCoverage,
|
|
36
36
|
fromCoverageMapToCoverage,
|
|
37
37
|
getTestSuitePath,
|
|
38
|
-
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE
|
|
38
|
+
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
|
|
39
|
+
getIsFaultyEarlyFlakeDetection
|
|
39
40
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
40
41
|
|
|
41
42
|
const isMarkedAsUnskippable = (pickle) => {
|
|
@@ -51,7 +52,9 @@ const patched = new WeakSet()
|
|
|
51
52
|
const lastStatusByPickleId = new Map()
|
|
52
53
|
const numRetriesByPickleId = new Map()
|
|
53
54
|
const numAttemptToAsyncResource = new Map()
|
|
55
|
+
const newTestsByTestFullname = new Map()
|
|
54
56
|
|
|
57
|
+
let eventDataCollector = null
|
|
55
58
|
let pickleByFile = {}
|
|
56
59
|
const pickleResultByFile = {}
|
|
57
60
|
|
|
@@ -64,6 +67,8 @@ let isUnskippable = false
|
|
|
64
67
|
let isSuitesSkippingEnabled = false
|
|
65
68
|
let isEarlyFlakeDetectionEnabled = false
|
|
66
69
|
let earlyFlakeDetectionNumRetries = 0
|
|
70
|
+
let earlyFlakeDetectionFaultyThreshold = 0
|
|
71
|
+
let isEarlyFlakeDetectionFaulty = false
|
|
67
72
|
let isFlakyTestRetriesEnabled = false
|
|
68
73
|
let numTestRetries = 0
|
|
69
74
|
let knownTests = []
|
|
@@ -129,15 +134,35 @@ function getChannelPromise (channelToPublishTo) {
|
|
|
129
134
|
})
|
|
130
135
|
}
|
|
131
136
|
|
|
137
|
+
function getShouldBeSkippedSuite (pickle, suitesToSkip) {
|
|
138
|
+
const testSuitePath = getTestSuitePath(pickle.uri, process.cwd())
|
|
139
|
+
const isUnskippable = isMarkedAsUnskippable(pickle)
|
|
140
|
+
const isSkipped = suitesToSkip.includes(testSuitePath)
|
|
141
|
+
|
|
142
|
+
return [isSkipped && !isUnskippable, testSuitePath]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// From cucumber@>=11
|
|
146
|
+
function getFilteredPicklesNew (coordinator, suitesToSkip) {
|
|
147
|
+
return coordinator.sourcedPickles.reduce((acc, sourcedPickle) => {
|
|
148
|
+
const { pickle } = sourcedPickle
|
|
149
|
+
const [shouldBeSkipped, testSuitePath] = getShouldBeSkippedSuite(pickle, suitesToSkip)
|
|
150
|
+
|
|
151
|
+
if (shouldBeSkipped) {
|
|
152
|
+
acc.skippedSuites.add(testSuitePath)
|
|
153
|
+
} else {
|
|
154
|
+
acc.picklesToRun.push(sourcedPickle)
|
|
155
|
+
}
|
|
156
|
+
return acc
|
|
157
|
+
}, { skippedSuites: new Set(), picklesToRun: [] })
|
|
158
|
+
}
|
|
159
|
+
|
|
132
160
|
function getFilteredPickles (runtime, suitesToSkip) {
|
|
133
161
|
return runtime.pickleIds.reduce((acc, pickleId) => {
|
|
134
|
-
const
|
|
135
|
-
const testSuitePath =
|
|
136
|
-
|
|
137
|
-
const isUnskippable = isMarkedAsUnskippable(test)
|
|
138
|
-
const isSkipped = suitesToSkip.includes(testSuitePath)
|
|
162
|
+
const pickle = runtime.eventDataCollector.getPickle(pickleId)
|
|
163
|
+
const [shouldBeSkipped, testSuitePath] = getShouldBeSkippedSuite(pickle, suitesToSkip)
|
|
139
164
|
|
|
140
|
-
if (
|
|
165
|
+
if (shouldBeSkipped) {
|
|
141
166
|
acc.skippedSuites.add(testSuitePath)
|
|
142
167
|
} else {
|
|
143
168
|
acc.picklesToRun.push(pickleId)
|
|
@@ -146,9 +171,21 @@ function getFilteredPickles (runtime, suitesToSkip) {
|
|
|
146
171
|
}, { skippedSuites: new Set(), picklesToRun: [] })
|
|
147
172
|
}
|
|
148
173
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
174
|
+
// From cucumber@>=11
|
|
175
|
+
function getPickleByFileNew (coordinator) {
|
|
176
|
+
return coordinator.sourcedPickles.reduce((acc, { pickle }) => {
|
|
177
|
+
if (acc[pickle.uri]) {
|
|
178
|
+
acc[pickle.uri].push(pickle)
|
|
179
|
+
} else {
|
|
180
|
+
acc[pickle.uri] = [pickle]
|
|
181
|
+
}
|
|
182
|
+
return acc
|
|
183
|
+
}, {})
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function getPickleByFile (runtimeOrCoodinator) {
|
|
187
|
+
return runtimeOrCoodinator.pickleIds.reduce((acc, pickleId) => {
|
|
188
|
+
const test = runtimeOrCoodinator.eventDataCollector.getPickle(pickleId)
|
|
152
189
|
if (acc[test.uri]) {
|
|
153
190
|
acc[test.uri].push(test)
|
|
154
191
|
} else {
|
|
@@ -294,17 +331,31 @@ function testCaseHook (TestCaseRunner) {
|
|
|
294
331
|
return TestCaseRunner
|
|
295
332
|
}
|
|
296
333
|
|
|
297
|
-
|
|
334
|
+
// Valid for old and new cucumber versions
|
|
335
|
+
function getCucumberOptions (adapterOrCoordinator) {
|
|
336
|
+
if (adapterOrCoordinator.adapter) {
|
|
337
|
+
return adapterOrCoordinator.adapter.worker?.options || adapterOrCoordinator.adapter.options
|
|
338
|
+
}
|
|
339
|
+
return adapterOrCoordinator.options
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordinator = false) {
|
|
298
343
|
return async function () {
|
|
299
344
|
if (!libraryConfigurationCh.hasSubscribers) {
|
|
300
345
|
return start.apply(this, arguments)
|
|
301
346
|
}
|
|
347
|
+
const options = getCucumberOptions(this)
|
|
348
|
+
|
|
349
|
+
if (!isParallel && this.adapter?.options) {
|
|
350
|
+
isParallel = options.parallel > 0
|
|
351
|
+
}
|
|
302
352
|
let errorSkippableRequest
|
|
303
353
|
|
|
304
354
|
const configurationResponse = await getChannelPromise(libraryConfigurationCh)
|
|
305
355
|
|
|
306
356
|
isEarlyFlakeDetectionEnabled = configurationResponse.libraryConfig?.isEarlyFlakeDetectionEnabled
|
|
307
357
|
earlyFlakeDetectionNumRetries = configurationResponse.libraryConfig?.earlyFlakeDetectionNumRetries
|
|
358
|
+
earlyFlakeDetectionFaultyThreshold = configurationResponse.libraryConfig?.earlyFlakeDetectionFaultyThreshold
|
|
308
359
|
isSuitesSkippingEnabled = configurationResponse.libraryConfig?.isSuitesSkippingEnabled
|
|
309
360
|
isFlakyTestRetriesEnabled = configurationResponse.libraryConfig?.isFlakyTestRetriesEnabled
|
|
310
361
|
numTestRetries = configurationResponse.libraryConfig?.flakyTestRetriesCount
|
|
@@ -325,28 +376,49 @@ function getWrappedStart (start, frameworkVersion, isParallel = false) {
|
|
|
325
376
|
skippableSuites = skippableResponse.skippableSuites
|
|
326
377
|
|
|
327
378
|
if (!errorSkippableRequest) {
|
|
328
|
-
const filteredPickles =
|
|
379
|
+
const filteredPickles = isCoordinator
|
|
380
|
+
? getFilteredPicklesNew(this, skippableSuites)
|
|
381
|
+
: getFilteredPickles(this, skippableSuites)
|
|
382
|
+
|
|
329
383
|
const { picklesToRun } = filteredPickles
|
|
330
|
-
|
|
384
|
+
const oldPickles = isCoordinator ? this.sourcedPickles : this.pickleIds
|
|
385
|
+
|
|
386
|
+
isSuitesSkipped = picklesToRun.length !== oldPickles.length
|
|
331
387
|
|
|
332
388
|
log.debug(
|
|
333
|
-
() => `${picklesToRun.length} out of ${
|
|
389
|
+
() => `${picklesToRun.length} out of ${oldPickles.length} suites are going to run.`
|
|
334
390
|
)
|
|
335
391
|
|
|
336
|
-
|
|
392
|
+
if (isCoordinator) {
|
|
393
|
+
this.sourcedPickles = picklesToRun
|
|
394
|
+
} else {
|
|
395
|
+
this.pickleIds = picklesToRun
|
|
396
|
+
}
|
|
337
397
|
|
|
338
398
|
skippedSuites = Array.from(filteredPickles.skippedSuites)
|
|
339
399
|
itrCorrelationId = skippableResponse.itrCorrelationId
|
|
340
400
|
}
|
|
341
401
|
}
|
|
342
402
|
|
|
343
|
-
pickleByFile = getPickleByFile(this)
|
|
403
|
+
pickleByFile = isCoordinator ? getPickleByFileNew(this) : getPickleByFile(this)
|
|
404
|
+
|
|
405
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
406
|
+
const isFaulty = getIsFaultyEarlyFlakeDetection(
|
|
407
|
+
Object.keys(pickleByFile),
|
|
408
|
+
knownTests.cucumber || {},
|
|
409
|
+
earlyFlakeDetectionFaultyThreshold
|
|
410
|
+
)
|
|
411
|
+
if (isFaulty) {
|
|
412
|
+
isEarlyFlakeDetectionEnabled = false
|
|
413
|
+
isEarlyFlakeDetectionFaulty = true
|
|
414
|
+
}
|
|
415
|
+
}
|
|
344
416
|
|
|
345
417
|
const processArgv = process.argv.slice(2).join(' ')
|
|
346
418
|
const command = process.env.npm_lifecycle_script || `cucumber-js ${processArgv}`
|
|
347
419
|
|
|
348
|
-
if (isFlakyTestRetriesEnabled && !
|
|
349
|
-
|
|
420
|
+
if (isFlakyTestRetriesEnabled && !options.retry && numTestRetries > 0) {
|
|
421
|
+
options.retry = numTestRetries
|
|
350
422
|
}
|
|
351
423
|
|
|
352
424
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
@@ -388,48 +460,65 @@ function getWrappedStart (start, frameworkVersion, isParallel = false) {
|
|
|
388
460
|
hasUnskippableSuites: isUnskippable,
|
|
389
461
|
hasForcedToRunSuites: isForcedToRun,
|
|
390
462
|
isEarlyFlakeDetectionEnabled,
|
|
463
|
+
isEarlyFlakeDetectionFaulty,
|
|
391
464
|
isParallel
|
|
392
465
|
})
|
|
393
466
|
})
|
|
467
|
+
eventDataCollector = null
|
|
394
468
|
return success
|
|
395
469
|
}
|
|
396
470
|
}
|
|
397
471
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
472
|
+
// Generates suite start and finish events in the main process.
|
|
473
|
+
// Handles EFD in both the main process and the worker process.
|
|
474
|
+
function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = false, isWorker = false) {
|
|
475
|
+
return async function () {
|
|
476
|
+
let pickle
|
|
477
|
+
if (isNewerCucumberVersion) {
|
|
478
|
+
pickle = arguments[0].pickle
|
|
479
|
+
} else {
|
|
480
|
+
pickle = this.eventDataCollector.getPickle(arguments[0])
|
|
481
|
+
}
|
|
401
482
|
|
|
402
|
-
const testFileAbsolutePath =
|
|
483
|
+
const testFileAbsolutePath = pickle.uri
|
|
403
484
|
const testSuitePath = getTestSuitePath(testFileAbsolutePath, process.cwd())
|
|
404
485
|
|
|
405
|
-
|
|
406
|
-
|
|
486
|
+
// If it's a worker, suite events are handled in `getWrappedParseWorkerMessage`
|
|
487
|
+
if (!isWorker && !pickleResultByFile[testFileAbsolutePath]) { // first test in suite
|
|
488
|
+
isUnskippable = isMarkedAsUnskippable(pickle)
|
|
407
489
|
isForcedToRun = isUnskippable && skippableSuites.includes(testSuitePath)
|
|
408
490
|
|
|
409
|
-
testSuiteStartCh.publish({
|
|
491
|
+
testSuiteStartCh.publish({
|
|
492
|
+
testFileAbsolutePath,
|
|
493
|
+
isUnskippable,
|
|
494
|
+
isForcedToRun,
|
|
495
|
+
itrCorrelationId
|
|
496
|
+
})
|
|
410
497
|
}
|
|
411
498
|
|
|
412
499
|
let isNew = false
|
|
413
500
|
|
|
414
501
|
if (isEarlyFlakeDetectionEnabled) {
|
|
415
|
-
isNew = isNewTest(testSuitePath,
|
|
502
|
+
isNew = isNewTest(testSuitePath, pickle.name)
|
|
416
503
|
if (isNew) {
|
|
417
|
-
numRetriesByPickleId.set(
|
|
504
|
+
numRetriesByPickleId.set(pickle.id, 0)
|
|
418
505
|
}
|
|
419
506
|
}
|
|
420
|
-
|
|
507
|
+
// TODO: for >=11 we could use `runTestCaseResult` instead of accumulating results in `lastStatusByPickleId`
|
|
508
|
+
let runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
|
|
421
509
|
|
|
422
|
-
const testStatuses = lastStatusByPickleId.get(
|
|
510
|
+
const testStatuses = lastStatusByPickleId.get(pickle.id)
|
|
423
511
|
const lastTestStatus = testStatuses[testStatuses.length - 1]
|
|
424
512
|
// If it's a new test and it hasn't been skipped, we run it again
|
|
425
513
|
if (isEarlyFlakeDetectionEnabled && lastTestStatus !== 'skip' && isNew) {
|
|
426
514
|
for (let retryIndex = 0; retryIndex < earlyFlakeDetectionNumRetries; retryIndex++) {
|
|
427
|
-
numRetriesByPickleId.set(
|
|
428
|
-
await
|
|
515
|
+
numRetriesByPickleId.set(pickle.id, retryIndex + 1)
|
|
516
|
+
runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
|
|
429
517
|
}
|
|
430
518
|
}
|
|
431
519
|
let testStatus = lastTestStatus
|
|
432
|
-
|
|
520
|
+
let shouldBePassedByEFD = false
|
|
521
|
+
if (isNew && isEarlyFlakeDetectionEnabled) {
|
|
433
522
|
/**
|
|
434
523
|
* If Early Flake Detection (EFD) is enabled the logic is as follows:
|
|
435
524
|
* - If all attempts for a test are failing, the test has failed and we will let the test process fail.
|
|
@@ -439,6 +528,8 @@ function getWrappedRunTest (runTestFunction) {
|
|
|
439
528
|
*/
|
|
440
529
|
testStatus = getTestStatusFromRetries(testStatuses)
|
|
441
530
|
if (testStatus === 'pass') {
|
|
531
|
+
// for cucumber@>=11, setting `this.success` does not work, so we have to change the returned value
|
|
532
|
+
shouldBePassedByEFD = true
|
|
442
533
|
this.success = true
|
|
443
534
|
}
|
|
444
535
|
}
|
|
@@ -449,8 +540,9 @@ function getWrappedRunTest (runTestFunction) {
|
|
|
449
540
|
pickleResultByFile[testFileAbsolutePath].push(testStatus)
|
|
450
541
|
}
|
|
451
542
|
|
|
452
|
-
//
|
|
453
|
-
if (pickleResultByFile[testFileAbsolutePath].length === pickleByFile[testFileAbsolutePath].length) {
|
|
543
|
+
// If it's a worker, suite events are handled in `getWrappedParseWorkerMessage`
|
|
544
|
+
if (!isWorker && pickleResultByFile[testFileAbsolutePath].length === pickleByFile[testFileAbsolutePath].length) {
|
|
545
|
+
// last test in suite
|
|
454
546
|
const testSuiteStatus = getSuiteStatusFromTestStatuses(pickleResultByFile[testFileAbsolutePath])
|
|
455
547
|
if (global.__coverage__) {
|
|
456
548
|
const coverageFiles = getCoveredFilenamesFromCoverage(global.__coverage__)
|
|
@@ -469,11 +561,15 @@ function getWrappedRunTest (runTestFunction) {
|
|
|
469
561
|
testSuiteFinishCh.publish({ status: testSuiteStatus, testSuitePath })
|
|
470
562
|
}
|
|
471
563
|
|
|
564
|
+
if (isNewerCucumberVersion && isEarlyFlakeDetectionEnabled && isNew) {
|
|
565
|
+
return shouldBePassedByEFD
|
|
566
|
+
}
|
|
567
|
+
|
|
472
568
|
return runTestCaseResult
|
|
473
569
|
}
|
|
474
570
|
}
|
|
475
571
|
|
|
476
|
-
function getWrappedParseWorkerMessage (parseWorkerMessageFunction) {
|
|
572
|
+
function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion) {
|
|
477
573
|
return function (worker, message) {
|
|
478
574
|
// If the message is an array, it's a dd-trace message, so we need to stop cucumber processing,
|
|
479
575
|
// or cucumber will throw an error
|
|
@@ -488,29 +584,43 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction) {
|
|
|
488
584
|
}
|
|
489
585
|
}
|
|
490
586
|
|
|
491
|
-
|
|
492
|
-
|
|
587
|
+
let envelope
|
|
588
|
+
|
|
589
|
+
if (isNewVersion) {
|
|
590
|
+
envelope = message.envelope
|
|
591
|
+
} else {
|
|
592
|
+
envelope = message.jsonEnvelope
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if (!envelope) {
|
|
493
596
|
return parseWorkerMessageFunction.apply(this, arguments)
|
|
494
597
|
}
|
|
495
|
-
let parsed =
|
|
598
|
+
let parsed = envelope
|
|
496
599
|
|
|
497
600
|
if (typeof parsed === 'string') {
|
|
498
601
|
try {
|
|
499
|
-
parsed = JSON.parse(
|
|
602
|
+
parsed = JSON.parse(envelope)
|
|
500
603
|
} catch (e) {
|
|
501
604
|
// ignore errors and continue
|
|
502
605
|
return parseWorkerMessageFunction.apply(this, arguments)
|
|
503
606
|
}
|
|
504
607
|
}
|
|
608
|
+
let pickle
|
|
609
|
+
|
|
505
610
|
if (parsed.testCaseStarted) {
|
|
506
|
-
|
|
507
|
-
|
|
611
|
+
if (isNewVersion) {
|
|
612
|
+
pickle = this.inProgress[worker.id].pickle
|
|
613
|
+
} else {
|
|
614
|
+
const { pickleId } = this.eventDataCollector.testCaseMap[parsed.testCaseStarted.testCaseId]
|
|
615
|
+
pickle = this.eventDataCollector.getPickle(pickleId)
|
|
616
|
+
}
|
|
617
|
+
// THIS FAILS IN PARALLEL MODE
|
|
508
618
|
const testFileAbsolutePath = pickle.uri
|
|
509
619
|
// First test in suite
|
|
510
620
|
if (!pickleResultByFile[testFileAbsolutePath]) {
|
|
511
621
|
pickleResultByFile[testFileAbsolutePath] = []
|
|
512
622
|
testSuiteStartCh.publish({
|
|
513
|
-
|
|
623
|
+
testFileAbsolutePath
|
|
514
624
|
})
|
|
515
625
|
}
|
|
516
626
|
}
|
|
@@ -519,14 +629,47 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction) {
|
|
|
519
629
|
|
|
520
630
|
// after calling `parseWorkerMessageFunction`, the test status can already be read
|
|
521
631
|
if (parsed.testCaseFinished) {
|
|
522
|
-
|
|
523
|
-
|
|
632
|
+
let worstTestStepResult
|
|
633
|
+
if (isNewVersion && eventDataCollector) {
|
|
634
|
+
pickle = this.inProgress[worker.id].pickle
|
|
635
|
+
worstTestStepResult =
|
|
636
|
+
eventDataCollector.getTestCaseAttempt(parsed.testCaseFinished.testCaseStartedId).worstTestStepResult
|
|
637
|
+
} else {
|
|
638
|
+
const testCase = this.eventDataCollector.getTestCaseAttempt(parsed.testCaseFinished.testCaseStartedId)
|
|
639
|
+
worstTestStepResult = testCase.worstTestStepResult
|
|
640
|
+
pickle = testCase.pickle
|
|
641
|
+
}
|
|
524
642
|
|
|
525
643
|
const { status } = getStatusFromResultLatest(worstTestStepResult)
|
|
644
|
+
let isNew = false
|
|
645
|
+
|
|
646
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
647
|
+
isNew = isNewTest(pickle.uri, pickle.name)
|
|
648
|
+
}
|
|
526
649
|
|
|
527
650
|
const testFileAbsolutePath = pickle.uri
|
|
528
651
|
const finished = pickleResultByFile[testFileAbsolutePath]
|
|
529
|
-
|
|
652
|
+
|
|
653
|
+
if (isNew) {
|
|
654
|
+
const testFullname = `${pickle.uri}:${pickle.name}`
|
|
655
|
+
let testStatuses = newTestsByTestFullname.get(testFullname)
|
|
656
|
+
if (!testStatuses) {
|
|
657
|
+
testStatuses = [status]
|
|
658
|
+
newTestsByTestFullname.set(testFullname, testStatuses)
|
|
659
|
+
} else {
|
|
660
|
+
testStatuses.push(status)
|
|
661
|
+
}
|
|
662
|
+
// We have finished all retries
|
|
663
|
+
if (testStatuses.length === earlyFlakeDetectionNumRetries + 1) {
|
|
664
|
+
const newTestFinalStatus = getTestStatusFromRetries(testStatuses)
|
|
665
|
+
// we only push to `finished` if the retries have finished
|
|
666
|
+
finished.push(newTestFinalStatus)
|
|
667
|
+
}
|
|
668
|
+
} else {
|
|
669
|
+
// TODO: can we get error message?
|
|
670
|
+
const finished = pickleResultByFile[testFileAbsolutePath]
|
|
671
|
+
finished.push(status)
|
|
672
|
+
}
|
|
530
673
|
|
|
531
674
|
if (finished.length === pickleByFile[testFileAbsolutePath].length) {
|
|
532
675
|
testSuiteFinishCh.publish({
|
|
@@ -556,13 +699,16 @@ addHook({
|
|
|
556
699
|
|
|
557
700
|
// From 7.3.0 onwards, runPickle becomes runTestCase. Not executed in parallel mode.
|
|
558
701
|
// `getWrappedStart` generates session start and finish events
|
|
559
|
-
// `
|
|
702
|
+
// `getWrappedRunTestCase` generates suite start and finish events and handles EFD.
|
|
703
|
+
// TODO (fix): there is a lib/runtime/index in >=11.0.0, but we don't instrument it because it's not useful for us
|
|
704
|
+
// This causes a info log saying "Found incompatible integration version".
|
|
560
705
|
addHook({
|
|
561
706
|
name: '@cucumber/cucumber',
|
|
562
|
-
versions: ['>=7.3.0'],
|
|
707
|
+
versions: ['>=7.3.0 <11.0.0'],
|
|
563
708
|
file: 'lib/runtime/index.js'
|
|
564
709
|
}, (runtimePackage, frameworkVersion) => {
|
|
565
|
-
shimmer.wrap(runtimePackage.default.prototype, 'runTestCase', runTestCase =>
|
|
710
|
+
shimmer.wrap(runtimePackage.default.prototype, 'runTestCase', runTestCase => getWrappedRunTestCase(runTestCase))
|
|
711
|
+
|
|
566
712
|
shimmer.wrap(runtimePackage.default.prototype, 'start', start => getWrappedStart(start, frameworkVersion))
|
|
567
713
|
|
|
568
714
|
return runtimePackage
|
|
@@ -570,13 +716,13 @@ addHook({
|
|
|
570
716
|
|
|
571
717
|
// Not executed in parallel mode.
|
|
572
718
|
// `getWrappedStart` generates session start and finish events
|
|
573
|
-
// `
|
|
719
|
+
// `getWrappedRunTestCase` generates suite start and finish events and handles EFD.
|
|
574
720
|
addHook({
|
|
575
721
|
name: '@cucumber/cucumber',
|
|
576
722
|
versions: ['>=7.0.0 <7.3.0'],
|
|
577
723
|
file: 'lib/runtime/index.js'
|
|
578
724
|
}, (runtimePackage, frameworkVersion) => {
|
|
579
|
-
shimmer.wrap(runtimePackage.default.prototype, 'runPickle', runPickle =>
|
|
725
|
+
shimmer.wrap(runtimePackage.default.prototype, 'runPickle', runPickle => getWrappedRunTestCase(runPickle))
|
|
580
726
|
shimmer.wrap(runtimePackage.default.prototype, 'start', start => getWrappedStart(start, frameworkVersion))
|
|
581
727
|
|
|
582
728
|
return runtimePackage
|
|
@@ -584,11 +730,10 @@ addHook({
|
|
|
584
730
|
|
|
585
731
|
// Only executed in parallel mode.
|
|
586
732
|
// `getWrappedStart` generates session start and finish events
|
|
587
|
-
// `
|
|
588
|
-
// `getWrappedParseWorkerMessage` generates suite finish events
|
|
733
|
+
// `getWrappedParseWorkerMessage` generates suite start and finish events
|
|
589
734
|
addHook({
|
|
590
735
|
name: '@cucumber/cucumber',
|
|
591
|
-
versions: ['>=8.0.0'],
|
|
736
|
+
versions: ['>=8.0.0 <11.0.0'],
|
|
592
737
|
file: 'lib/runtime/parallel/coordinator.js'
|
|
593
738
|
}, (coordinatorPackage, frameworkVersion) => {
|
|
594
739
|
shimmer.wrap(coordinatorPackage.default.prototype, 'start', start => getWrappedStart(start, frameworkVersion, true))
|
|
@@ -599,3 +744,95 @@ addHook({
|
|
|
599
744
|
)
|
|
600
745
|
return coordinatorPackage
|
|
601
746
|
})
|
|
747
|
+
|
|
748
|
+
// >=11.0.0 hooks
|
|
749
|
+
// `getWrappedRunTestCase` does two things:
|
|
750
|
+
// - generates suite start and finish events in the main process,
|
|
751
|
+
// - handles EFD in both the main process and the worker process.
|
|
752
|
+
addHook({
|
|
753
|
+
name: '@cucumber/cucumber',
|
|
754
|
+
versions: ['>=11.0.0'],
|
|
755
|
+
file: 'lib/runtime/worker.js'
|
|
756
|
+
}, (workerPackage) => {
|
|
757
|
+
shimmer.wrap(
|
|
758
|
+
workerPackage.Worker.prototype,
|
|
759
|
+
'runTestCase',
|
|
760
|
+
runTestCase => getWrappedRunTestCase(runTestCase, true, !!process.env.CUCUMBER_WORKER_ID)
|
|
761
|
+
)
|
|
762
|
+
return workerPackage
|
|
763
|
+
})
|
|
764
|
+
|
|
765
|
+
// `getWrappedStart` generates session start and finish events
|
|
766
|
+
addHook({
|
|
767
|
+
name: '@cucumber/cucumber',
|
|
768
|
+
versions: ['>=11.0.0'],
|
|
769
|
+
file: 'lib/runtime/coordinator.js'
|
|
770
|
+
}, (coordinatorPackage, frameworkVersion) => {
|
|
771
|
+
shimmer.wrap(
|
|
772
|
+
coordinatorPackage.Coordinator.prototype,
|
|
773
|
+
'run',
|
|
774
|
+
run => getWrappedStart(run, frameworkVersion, false, true)
|
|
775
|
+
)
|
|
776
|
+
return coordinatorPackage
|
|
777
|
+
})
|
|
778
|
+
|
|
779
|
+
// Necessary because `eventDataCollector` is no longer available in the runtime instance
|
|
780
|
+
addHook({
|
|
781
|
+
name: '@cucumber/cucumber',
|
|
782
|
+
versions: ['>=11.0.0'],
|
|
783
|
+
file: 'lib/formatter/helpers/event_data_collector.js'
|
|
784
|
+
}, (eventDataCollectorPackage) => {
|
|
785
|
+
shimmer.wrap(eventDataCollectorPackage.default.prototype, 'parseEnvelope', parseEnvelope => function () {
|
|
786
|
+
eventDataCollector = this
|
|
787
|
+
return parseEnvelope.apply(this, arguments)
|
|
788
|
+
})
|
|
789
|
+
return eventDataCollectorPackage
|
|
790
|
+
})
|
|
791
|
+
|
|
792
|
+
// Only executed in parallel mode for >=11, in the main process.
|
|
793
|
+
// `getWrappedParseWorkerMessage` generates suite start and finish events
|
|
794
|
+
// In `startWorker` we pass early flake detection info to the worker.
|
|
795
|
+
addHook({
|
|
796
|
+
name: '@cucumber/cucumber',
|
|
797
|
+
versions: ['>=11.0.0'],
|
|
798
|
+
file: 'lib/runtime/parallel/adapter.js'
|
|
799
|
+
}, (adapterPackage) => {
|
|
800
|
+
shimmer.wrap(
|
|
801
|
+
adapterPackage.ChildProcessAdapter.prototype,
|
|
802
|
+
'parseWorkerMessage',
|
|
803
|
+
parseWorkerMessage => getWrappedParseWorkerMessage(parseWorkerMessage, true)
|
|
804
|
+
)
|
|
805
|
+
// EFD in parallel mode only supported in >=11.0.0
|
|
806
|
+
shimmer.wrap(adapterPackage.ChildProcessAdapter.prototype, 'startWorker', startWorker => function () {
|
|
807
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
808
|
+
this.options.worldParameters._ddKnownTests = knownTests
|
|
809
|
+
this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
return startWorker.apply(this, arguments)
|
|
813
|
+
})
|
|
814
|
+
return adapterPackage
|
|
815
|
+
})
|
|
816
|
+
|
|
817
|
+
// Hook executed in the worker process when in parallel mode.
|
|
818
|
+
// In this hook we read the information passed in `worldParameters` and make it available for
|
|
819
|
+
// `getWrappedRunTestCase`.
|
|
820
|
+
addHook({
|
|
821
|
+
name: '@cucumber/cucumber',
|
|
822
|
+
versions: ['>=11.0.0'],
|
|
823
|
+
file: 'lib/runtime/parallel/worker.js'
|
|
824
|
+
}, (workerPackage) => {
|
|
825
|
+
shimmer.wrap(
|
|
826
|
+
workerPackage.ChildProcessWorker.prototype,
|
|
827
|
+
'initialize',
|
|
828
|
+
initialize => async function () {
|
|
829
|
+
await initialize.apply(this, arguments)
|
|
830
|
+
isEarlyFlakeDetectionEnabled = !!this.options.worldParameters._ddKnownTests
|
|
831
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
832
|
+
knownTests = this.options.worldParameters._ddKnownTests
|
|
833
|
+
earlyFlakeDetectionNumRetries = this.options.worldParameters._ddEarlyFlakeDetectionNumRetries
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
)
|
|
837
|
+
return workerPackage
|
|
838
|
+
})
|