dd-trace 5.116.0 → 5.118.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/ci/diagnose.js +162 -21
- package/ci/init.js +0 -1
- package/ci/runbook.md +187 -180
- package/ci/test-optimization-validation/approval-artifacts.js +3 -1
- package/ci/test-optimization-validation/approval.js +52 -15
- package/ci/test-optimization-validation/ci-command-candidate.js +26 -32
- package/ci/test-optimization-validation/ci-discovery.js +1 -1
- package/ci/test-optimization-validation/ci-package-scripts.js +141 -0
- package/ci/test-optimization-validation/ci-remediation.js +112 -39
- package/ci/test-optimization-validation/cli.js +516 -681
- package/ci/test-optimization-validation/command-blocker.js +188 -33
- package/ci/test-optimization-validation/command-output-policy.js +3 -26
- package/ci/test-optimization-validation/command-runner.js +189 -245
- package/ci/test-optimization-validation/environment.js +90 -0
- package/ci/test-optimization-validation/executable.js +159 -388
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +119 -0
- package/ci/test-optimization-validation/framework-adapters/cypress.js +107 -0
- package/ci/test-optimization-validation/framework-adapters/playwright.js +181 -0
- package/ci/test-optimization-validation/generated-files.js +75 -13
- package/ci/test-optimization-validation/generated-test-contract.js +283 -0
- package/ci/test-optimization-validation/generated-verifier.js +49 -16
- package/ci/test-optimization-validation/literal-environment.js +57 -0
- package/ci/test-optimization-validation/manifest-loader.js +2 -22
- package/ci/test-optimization-validation/manifest-scaffold.js +816 -515
- package/ci/test-optimization-validation/manifest-schema.js +494 -702
- package/ci/test-optimization-validation/offline-fixtures.js +4 -1
- package/ci/test-optimization-validation/plan-writer.js +243 -984
- package/ci/test-optimization-validation/preflight-runner.js +49 -55
- package/ci/test-optimization-validation/redaction.js +2 -1
- package/ci/test-optimization-validation/report-writer.js +391 -1357
- package/ci/test-optimization-validation/result-semantics.js +86 -0
- package/ci/test-optimization-validation/runner-command.js +249 -0
- package/ci/test-optimization-validation/runner-contract.js +664 -0
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +29 -3
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +240 -543
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +450 -670
- package/ci/test-optimization-validation/scenarios/early-flake-detection.js +4 -3
- package/ci/test-optimization-validation/scenarios/helpers.js +67 -9
- package/ci/test-optimization-validation/scenarios/test-management.js +4 -3
- package/ci/test-optimization-validation/source-text.js +87 -0
- package/ci/test-optimization-validation/test-output.js +12 -22
- package/ext/tags.d.ts +1 -0
- package/index.d.ts +7 -0
- package/package.json +3 -3
- package/packages/datadog-instrumentations/src/cucumber.js +11 -12
- package/packages/datadog-instrumentations/src/helpers/channel.js +74 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/openai-agents.js +31 -0
- package/packages/datadog-instrumentations/src/jest.js +18 -17
- package/packages/datadog-instrumentations/src/mocha/main.js +79 -30
- package/packages/datadog-instrumentations/src/openai-agents.js +159 -0
- package/packages/datadog-instrumentations/src/playwright.js +3 -24
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +1 -1
- package/packages/datadog-instrumentations/src/vitest-main.js +14 -26
- package/packages/datadog-instrumentations/src/vitest-util.js +0 -7
- package/packages/datadog-instrumentations/src/vitest-worker.js +5 -8
- package/packages/datadog-plugin-cucumber/src/index.js +2 -1
- package/packages/datadog-plugin-mocha/src/index.js +2 -1
- package/packages/datadog-plugin-openai-agents/src/index.js +74 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +503 -0
- package/packages/datadog-plugin-openai-agents/src/processor.js +108 -0
- package/packages/datadog-plugin-openai-agents/src/util.js +60 -0
- package/packages/datadog-plugin-playwright/src/index.js +4 -1
- package/packages/datadog-plugin-vitest/src/index.js +5 -5
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +48 -49
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +161 -33
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +6 -4
- package/packages/dd-trace/src/config/generated-config-types.d.ts +2 -0
- package/packages/dd-trace/src/config/supported-configurations.json +7 -0
- package/packages/dd-trace/src/encode/span-stats.js +7 -1
- package/packages/dd-trace/src/exporter.js +16 -9
- package/packages/dd-trace/src/llmobs/index.js +9 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +104 -22
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +5 -9
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +20 -0
- package/packages/dd-trace/src/llmobs/plugins/openai-agents/utils.js +321 -0
- package/packages/dd-trace/src/llmobs/sdk.js +2 -1
- package/packages/dd-trace/src/llmobs/span_processor.js +7 -2
- package/packages/dd-trace/src/llmobs/tagger.js +23 -3
- package/packages/dd-trace/src/llmobs/util.js +56 -3
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +3 -6
- package/packages/dd-trace/src/openfeature/configuration_source.js +5 -8
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +5 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +9 -3
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/outbound.js +4 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -0
- package/packages/dd-trace/src/span_processor.js +1 -1
- package/packages/dd-trace/src/span_stats.js +22 -4
- package/ci/test-optimization-validation/command-suitability.js +0 -471
- package/ci/test-optimization-validation/init-probe-preload.js +0 -163
- package/ci/test-optimization-validation/init-probe.js +0 -246
- package/ci/test-optimization-validation/late-initialization.js +0 -63
- package/ci/test-optimization-validation/local-command.js +0 -163
- package/ci/test-optimization-validation/setup-runner.js +0 -97
- package/ci/test-optimization-validation-manifest.schema.json +0 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
function annotateResults (results) {
|
|
4
|
+
return results.map(result => ({
|
|
5
|
+
...result,
|
|
6
|
+
conclusion: result.evidence?.conclusion || getConclusion(result),
|
|
7
|
+
domain: result.evidence?.domain || getDomain(result),
|
|
8
|
+
evidenceStrength: result.evidence?.evidenceStrength || getEvidenceStrength(result),
|
|
9
|
+
}))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getExecutionStatus (results) {
|
|
13
|
+
if (results.some(isValidatorError)) return 'validator_error'
|
|
14
|
+
|
|
15
|
+
const conclusionResults = results.filter(result => {
|
|
16
|
+
const runLevelDomains = ['execution_environment', 'local_runtime', 'project_setup']
|
|
17
|
+
return result.scenario !== 'all' || runLevelDomains.includes(result.domain)
|
|
18
|
+
})
|
|
19
|
+
const allIncomplete = conclusionResults.length > 0 && conclusionResults.every(result => {
|
|
20
|
+
return result.domain === 'execution_environment' || ['not_checked', 'incomplete'].includes(result.conclusion)
|
|
21
|
+
})
|
|
22
|
+
if (!allIncomplete) return 'completed'
|
|
23
|
+
if (conclusionResults.some(result => ['execution_environment', 'local_runtime'].includes(result.domain))) {
|
|
24
|
+
return 'blocked'
|
|
25
|
+
}
|
|
26
|
+
if (conclusionResults.some(result => result.domain === 'project_setup')) return 'project_setup_required'
|
|
27
|
+
return 'completed'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getValidatorExitCode (results, executionStatus) {
|
|
31
|
+
if (executionStatus === 'validator_error') return 3
|
|
32
|
+
if (results.some(result => result.status === 'fail' && result.evidenceStrength.startsWith('confirmed_'))) return 1
|
|
33
|
+
const incomplete = results.some(result => {
|
|
34
|
+
return ['configured_propagation_unverified', 'incomplete', 'not_checked'].includes(result.conclusion)
|
|
35
|
+
})
|
|
36
|
+
if (executionStatus !== 'completed' || incomplete || !results.some(result => result.scenario !== 'all')) return 2
|
|
37
|
+
return 0
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getValidationCoverage (results) {
|
|
41
|
+
return results.some(result => result.conclusion === 'not_checked' ||
|
|
42
|
+
result.evidence?.validationIncomplete ||
|
|
43
|
+
result.evidence?.manifestIncomplete)
|
|
44
|
+
? 'partial'
|
|
45
|
+
: 'complete'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getConclusion (result) {
|
|
49
|
+
if (result.evidence?.validationIncomplete || result.evidence?.manifestIncomplete) return 'incomplete'
|
|
50
|
+
if (result.status === 'pass') return 'confirmed_working'
|
|
51
|
+
if (result.status === 'fail') {
|
|
52
|
+
return result.scenario === 'ci-wiring' ? 'confirmed_misconfigured' : 'confirmed_not_working'
|
|
53
|
+
}
|
|
54
|
+
if (result.status === 'skip') {
|
|
55
|
+
return result.evidence?.featureEligibility?.eligible === false ? 'not_checked' : 'not_eligible'
|
|
56
|
+
}
|
|
57
|
+
return 'incomplete'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getDomain (result) {
|
|
61
|
+
if (result.evidence?.blockedByProjectSetup) return 'project_setup'
|
|
62
|
+
if (result.evidence?.localRuntimeBlocked) return 'local_runtime'
|
|
63
|
+
if (result.evidence?.blockedByExecutionEnvironment) return 'execution_environment'
|
|
64
|
+
if (result.scenario === 'ci-wiring') return 'ci_configuration'
|
|
65
|
+
if (result.evidence?.staticDiagnosis) return 'project_setup'
|
|
66
|
+
if (result.status === 'blocked') return 'execution_environment'
|
|
67
|
+
if (result.evidence?.validatorAdapterUnavailable || result.evidence?.manifestIncomplete ||
|
|
68
|
+
result.frameworkId === 'validator' || result.frameworkId === 'validation-cleanup') return 'validator_adapter'
|
|
69
|
+
return 'test_optimization'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getEvidenceStrength (result) {
|
|
73
|
+
if (result.status === 'pass' || result.status === 'fail') {
|
|
74
|
+
return result.evidence?.staticDiagnosis ? 'confirmed_static' : 'confirmed_runtime'
|
|
75
|
+
}
|
|
76
|
+
if (result.status === 'blocked') return 'confirmed_runtime'
|
|
77
|
+
return result.evidence?.staticDiagnosis ? 'inferred_static' : 'unknown'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function isValidatorError (result) {
|
|
81
|
+
return result.evidence?.validationOrchestrationFailed === true ||
|
|
82
|
+
result.frameworkId === 'validator' ||
|
|
83
|
+
result.frameworkId === 'validation-cleanup'
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
module.exports = { annotateResults, getExecutionStatus, getValidationCoverage, getValidatorExitCode }
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs')
|
|
4
|
+
const path = require('node:path')
|
|
5
|
+
|
|
6
|
+
const cucumber = require('./framework-adapters/cucumber')
|
|
7
|
+
const cypress = require('./framework-adapters/cypress')
|
|
8
|
+
const playwright = require('./framework-adapters/playwright')
|
|
9
|
+
const { inheritApprovedExecutable } = require('./executable-approval')
|
|
10
|
+
|
|
11
|
+
const DEFAULT_TIMEOUT_MS = 180_000
|
|
12
|
+
const BROWSER_TIMEOUT_MS = 300_000
|
|
13
|
+
const GENERATED_SCENARIO_BY_FEATURE = {
|
|
14
|
+
atr: 'atr-fail-once',
|
|
15
|
+
efd: 'basic-pass',
|
|
16
|
+
'test-management': 'test-management-target',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Builds the validator-owned direct command for an existing representative test.
|
|
21
|
+
*
|
|
22
|
+
* @param {object} framework normalized framework manifest entry
|
|
23
|
+
* @returns {object} structured direct-runner command
|
|
24
|
+
*/
|
|
25
|
+
function getBasicCommand (framework) {
|
|
26
|
+
return buildCommand(framework, framework.validation.testFile, false)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Builds the validator-owned direct command for a generated scenario.
|
|
31
|
+
*
|
|
32
|
+
* @param {object} framework normalized framework manifest entry
|
|
33
|
+
* @param {object} scenario generated scenario
|
|
34
|
+
* @returns {object} structured direct-runner command
|
|
35
|
+
*/
|
|
36
|
+
function getGeneratedCommand (framework, scenario) {
|
|
37
|
+
return buildCommand(framework, scenario.testIdentities[0].file, true)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Returns every command the approval permits for one framework.
|
|
42
|
+
*
|
|
43
|
+
* @param {object} framework normalized framework manifest entry
|
|
44
|
+
* @param {string|null} [requestedScenario] selected validator scenario
|
|
45
|
+
* @returns {Array<[string, object]>} labeled direct-runner commands
|
|
46
|
+
*/
|
|
47
|
+
function getFrameworkCommands (framework, requestedScenario = null) {
|
|
48
|
+
if (framework.status !== 'runnable') return []
|
|
49
|
+
if (requestedScenario === 'ci-wiring') return []
|
|
50
|
+
|
|
51
|
+
const commands = [['basic-reporting', getBasicCommand(framework)]]
|
|
52
|
+
for (const scenario of framework.generatedTestStrategy?.scenarios || []) {
|
|
53
|
+
if (!shouldIncludeGeneratedScenario(scenario.id, requestedScenario)) continue
|
|
54
|
+
commands.push([`generated:${scenario.id}`, getGeneratedCommand(framework, scenario)])
|
|
55
|
+
}
|
|
56
|
+
return commands
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Returns every command covered by a validation manifest.
|
|
61
|
+
*
|
|
62
|
+
* @param {object} manifest normalized validation manifest
|
|
63
|
+
* @param {string|null} [requestedScenario] selected validator scenario
|
|
64
|
+
* @returns {Array<[string, object]>} labeled direct-runner commands
|
|
65
|
+
*/
|
|
66
|
+
function getManifestCommands (manifest, requestedScenario = null) {
|
|
67
|
+
const commands = []
|
|
68
|
+
for (const framework of manifest.frameworks || []) {
|
|
69
|
+
for (const [label, command] of getFrameworkCommands(framework, requestedScenario)) {
|
|
70
|
+
commands.push([`${framework.id}:${label}`, command])
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return commands
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Returns existing project files that affect direct validation.
|
|
78
|
+
*
|
|
79
|
+
* @param {object} manifest normalized validation manifest
|
|
80
|
+
* @param {object} [options] file selection options
|
|
81
|
+
* @param {boolean} [options.includeLocal] include local runner inputs
|
|
82
|
+
* @returns {string[]} sorted unique absolute paths
|
|
83
|
+
*/
|
|
84
|
+
function getManifestInputFiles (manifest, { includeLocal = true } = {}) {
|
|
85
|
+
const files = new Set()
|
|
86
|
+
for (const framework of manifest.frameworks || []) {
|
|
87
|
+
addExistingFile(files, framework.ciWiring?.configFile)
|
|
88
|
+
if (!includeLocal) {
|
|
89
|
+
addExistingFile(files, framework.project?.packageJson)
|
|
90
|
+
continue
|
|
91
|
+
}
|
|
92
|
+
if (framework.status !== 'runnable') continue
|
|
93
|
+
addExistingFile(files, framework.validation?.runner)
|
|
94
|
+
addExistingFile(files, framework.validation?.testFile)
|
|
95
|
+
addExistingFile(files, framework.project?.packageJson)
|
|
96
|
+
for (const filename of framework.project?.configFiles || []) addExistingFile(files, filename)
|
|
97
|
+
}
|
|
98
|
+
return [...files].sort()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Returns whether a generated scenario can execute for the selected feature.
|
|
103
|
+
*
|
|
104
|
+
* @param {string} scenarioId generated scenario id
|
|
105
|
+
* @param {string|null} requestedScenario selected validator scenario
|
|
106
|
+
* @returns {boolean} whether to include the command
|
|
107
|
+
*/
|
|
108
|
+
function shouldIncludeGeneratedScenario (scenarioId, requestedScenario) {
|
|
109
|
+
if (!requestedScenario) return true
|
|
110
|
+
return GENERATED_SCENARIO_BY_FEATURE[requestedScenario] === scenarioId
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Builds one direct Node.js runner invocation.
|
|
115
|
+
*
|
|
116
|
+
* @param {object} framework normalized framework manifest entry
|
|
117
|
+
* @param {string} testFile selected existing or generated test file
|
|
118
|
+
* @param {boolean} generated whether this is a validator-owned generated test
|
|
119
|
+
* @returns {object} structured command
|
|
120
|
+
*/
|
|
121
|
+
function buildCommand (framework, testFile, generated) {
|
|
122
|
+
const { runner, requiredEnvVars = [], timeoutMs } = framework.validation
|
|
123
|
+
const outputPaths = framework.framework === 'playwright'
|
|
124
|
+
? [playwright.getOutputPath(testFile)]
|
|
125
|
+
: []
|
|
126
|
+
|
|
127
|
+
return inheritApprovedExecutable(framework.validation, {
|
|
128
|
+
argv: [process.execPath, runner, ...getRunnerArgs(framework, testFile, generated)],
|
|
129
|
+
cwd: framework.project.root,
|
|
130
|
+
description: `${formatFrameworkName(framework.framework)} ${generated ? 'generated' : 'representative'} test`,
|
|
131
|
+
env: getRunnerEnv(framework),
|
|
132
|
+
outputPaths,
|
|
133
|
+
requiredEnvVars,
|
|
134
|
+
timeoutMs: timeoutMs || (framework.browserRequired ? BROWSER_TIMEOUT_MS : DEFAULT_TIMEOUT_MS),
|
|
135
|
+
usesShell: false,
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Returns adapter-owned arguments for one exact test file.
|
|
141
|
+
*
|
|
142
|
+
* @param {object} framework normalized framework manifest entry
|
|
143
|
+
* @param {string} testFile selected existing or generated test file
|
|
144
|
+
* @param {boolean} generated whether this is a validator-owned generated test
|
|
145
|
+
* @returns {string[]} runner arguments
|
|
146
|
+
*/
|
|
147
|
+
function getRunnerArgs (framework, testFile, generated) {
|
|
148
|
+
const name = framework.framework
|
|
149
|
+
const configuration = framework.validation.runnerArgs || []
|
|
150
|
+
if (name === 'cucumber') {
|
|
151
|
+
if (!generated) return [...configuration, ...cucumber.getFocusedTestArgs(testFile)]
|
|
152
|
+
return [
|
|
153
|
+
...configuration,
|
|
154
|
+
...cucumber.getGeneratedTestArgs(
|
|
155
|
+
testFile,
|
|
156
|
+
cucumber.getGeneratedStepsPath(framework.generatedTestStrategy.testDirectory)
|
|
157
|
+
),
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
if (name === 'cypress') {
|
|
161
|
+
if (generated) return cypress.getGeneratedTestArgs(testFile, configuration)
|
|
162
|
+
return [
|
|
163
|
+
'run',
|
|
164
|
+
...configuration,
|
|
165
|
+
...cypress.getFocusedTestArgs(testFile),
|
|
166
|
+
'--config',
|
|
167
|
+
'video=false,screenshotOnRunFailure=false',
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
if (name === 'playwright') {
|
|
171
|
+
if (generated) {
|
|
172
|
+
return playwright.getGeneratedTestArgs(
|
|
173
|
+
testFile,
|
|
174
|
+
playwright.getGeneratedConfigPath(framework.generatedTestStrategy.testDirectory)
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
return ['test', ...configuration, ...playwright.getFocusedTestArgs(testFile)]
|
|
178
|
+
}
|
|
179
|
+
if (name === 'jest') {
|
|
180
|
+
const generatedOverrides = []
|
|
181
|
+
if (generated && configuration.some(argument => {
|
|
182
|
+
return argument === '--detectLeaks' || argument === '--detectLeaks=true'
|
|
183
|
+
})) {
|
|
184
|
+
generatedOverrides.push('--detectLeaks=false')
|
|
185
|
+
}
|
|
186
|
+
return [
|
|
187
|
+
...configuration,
|
|
188
|
+
'--runTestsByPath',
|
|
189
|
+
testFile,
|
|
190
|
+
'--runInBand',
|
|
191
|
+
'--silent',
|
|
192
|
+
'--no-watchman',
|
|
193
|
+
...generatedOverrides,
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
if (name === 'mocha') {
|
|
197
|
+
return [...configuration, '--no-config', '--no-package', '--no-opts', '--reporter', 'spec', testFile]
|
|
198
|
+
}
|
|
199
|
+
if (name === 'vitest') {
|
|
200
|
+
const needsGlobals = generated && framework.generatedTestStrategy.moduleSystem === 'commonjs'
|
|
201
|
+
return ['run', ...configuration, testFile, ...(needsGlobals ? ['--globals'] : [])]
|
|
202
|
+
}
|
|
203
|
+
throw new Error(`No direct-runner adapter is available for ${name}.`)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Returns small deterministic environment adjustments owned by an adapter.
|
|
208
|
+
*
|
|
209
|
+
* @param {object} framework framework entry
|
|
210
|
+
* @returns {Record<string, string>} command environment
|
|
211
|
+
*/
|
|
212
|
+
function getRunnerEnv (framework) {
|
|
213
|
+
return {
|
|
214
|
+
...(framework.validation.environment || {}),
|
|
215
|
+
...(framework.framework === 'cucumber' ? { CUCUMBER_PUBLISH_QUIET: 'true' } : {}),
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Adds an existing regular file to an approval input set.
|
|
221
|
+
*
|
|
222
|
+
* @param {Set<string>} files collected files
|
|
223
|
+
* @param {string|undefined} filename candidate file
|
|
224
|
+
* @returns {void}
|
|
225
|
+
*/
|
|
226
|
+
function addExistingFile (files, filename) {
|
|
227
|
+
if (typeof filename !== 'string') return
|
|
228
|
+
try {
|
|
229
|
+
if (fs.statSync(filename).isFile()) files.add(path.resolve(filename))
|
|
230
|
+
} catch {}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Formats a framework name for command descriptions.
|
|
235
|
+
*
|
|
236
|
+
* @param {string} framework framework name
|
|
237
|
+
* @returns {string} display name
|
|
238
|
+
*/
|
|
239
|
+
function formatFrameworkName (framework) {
|
|
240
|
+
return framework.charAt(0).toUpperCase() + framework.slice(1)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
module.exports = {
|
|
244
|
+
getBasicCommand,
|
|
245
|
+
getFrameworkCommands,
|
|
246
|
+
getGeneratedCommand,
|
|
247
|
+
getManifestCommands,
|
|
248
|
+
getManifestInputFiles,
|
|
249
|
+
}
|