ui5-test-runner 6.0.0-beta.5 → 6.0.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 +20 -29
- package/dist/Command.js +52 -0
- package/dist/Npm.js +154 -74
- package/dist/browsers/RecoverableBrowserError.js +6 -0
- package/dist/browsers/chromeArguments.js +5 -0
- package/dist/browsers/chromeOptions.js +29 -0
- package/dist/browsers/consoleMessage.js +23 -0
- package/dist/browsers/factory.js +168 -3
- package/dist/browsers/networkResponse.js +15 -0
- package/dist/browsers/playwright.js +104 -0
- package/dist/browsers/puppeteer.js +54 -88
- package/dist/browsers/seleniumWebdriver.js +124 -0
- package/dist/browsers/webdriverio.js +85 -0
- package/dist/cli.js +18 -12
- package/dist/configuration/CommandLine.js +46 -26
- package/dist/configuration/ConfigurationValidator.js +132 -18
- package/dist/configuration/OptionValidationError.js +50 -2
- package/dist/configuration/derivations.js +8 -0
- package/dist/configuration/options.js +380 -23
- package/dist/configuration/validations.js +135 -0
- package/dist/configuration/validators/boolean.js +1 -1
- package/dist/configuration/validators/enumeration.js +7 -0
- package/dist/configuration/validators/fsEntry.js +12 -12
- package/dist/configuration/validators/index.js +8 -2
- package/dist/configuration/validators/integer.js +7 -1
- package/dist/configuration/validators/json.js +23 -0
- package/dist/configuration/validators/libraryMapping.js +28 -0
- package/dist/configuration/validators/percent.js +2 -2
- package/dist/configuration/validators/regexp.js +2 -2
- package/dist/configuration/validators/secret.js +8 -0
- package/dist/configuration/validators/string.js +1 -1
- package/dist/configuration/validators/timeout.js +2 -2
- package/dist/configuration/validators/url.js +3 -3
- package/dist/end.js +58 -0
- package/dist/if.js +22 -0
- package/dist/modes/Modes.js +2 -1
- package/dist/modes/batch/BatchItem.js +1 -0
- package/dist/modes/batch/batchTask.js +159 -0
- package/dist/modes/batch/index.js +98 -0
- package/dist/modes/batch/output.js +22 -0
- package/dist/modes/batch/report.js +45 -0
- package/dist/modes/batch/resolve.js +105 -0
- package/dist/modes/dumpConfig.js +6 -0
- package/dist/modes/execute.js +6 -5
- package/dist/modes/help.js +86 -2
- package/dist/modes/log/LogReader.js +3 -2
- package/dist/modes/log/LogStorage.js +31 -27
- package/dist/modes/log/index.js +38 -6
- package/dist/modes/log/{REserve.js → reserve.js} +25 -2
- package/dist/modes/mcp/IDocument.js +2 -0
- package/dist/modes/mcp/frontmatter.js +142 -0
- package/dist/modes/mcp/index.js +49 -0
- package/dist/modes/mcp/knowledgeBase.js +104 -0
- package/dist/modes/mcp/remoteKnowledgeBase.js +79 -0
- package/dist/modes/mcp/reserve.js +175 -0
- package/dist/modes/mcp/tools/getTopic.js +46 -0
- package/dist/modes/mcp/tools/index.js +6 -0
- package/dist/modes/mcp/tools/listTopics.js +14 -0
- package/dist/modes/test/PageContext.js +1 -0
- package/dist/modes/test/Server.js +99 -0
- package/dist/modes/test/browser.js +31 -17
- package/dist/modes/test/browserConfig.js +17 -0
- package/dist/modes/test/coverage/collect.js +38 -0
- package/dist/modes/test/coverage/index.js +3 -0
- package/dist/modes/test/coverage/instrument.js +70 -0
- package/dist/modes/test/coverage/nyc.js +15 -0
- package/dist/modes/test/coverage/report.js +71 -0
- package/dist/modes/test/coverage/settings.js +53 -0
- package/dist/modes/test/index.js +94 -34
- package/dist/modes/test/pageTask.js +293 -98
- package/dist/modes/test/report.js +20 -3
- package/dist/modes/test/reserve.js +76 -0
- package/dist/modes/test/screenshot.js +49 -0
- package/dist/platform/Crypto.js +9 -0
- package/dist/platform/Exit.js +33 -24
- package/dist/platform/FileSystem.js +6 -2
- package/dist/platform/Host.js +9 -1
- package/dist/platform/Http.js +54 -29
- package/dist/platform/Module.js +2 -1
- package/dist/platform/Path.js +5 -1
- package/dist/platform/Process.js +67 -13
- package/dist/platform/Terminal.js +12 -8
- package/dist/platform/Thread.js +1 -1
- package/dist/platform/assert.js +13 -12
- package/dist/platform/environment.js +9 -18
- package/dist/platform/index.js +1 -0
- package/dist/platform/logger/CompressionContext.js +117 -0
- package/dist/platform/logger/allCompressed.js +8 -7
- package/dist/platform/logger/compress.js +29 -129
- package/dist/platform/logger/output/BaseLoggerOutput.js +49 -31
- package/dist/platform/logger/output/InteractiveLoggerOutput.js +1 -1
- package/dist/platform/logger/output/LlmLoggerOutput.js +29 -0
- package/dist/platform/logger/output/factory.js +5 -1
- package/dist/platform/logger/output.js +24 -6
- package/dist/platform/logger/toInternalLogAttributes.js +10 -11
- package/dist/platform/logger/traceFileName.js +1 -0
- package/dist/platform/logger.js +52 -21
- package/dist/platform/mock.js +110 -19
- package/dist/platform/version.js +1 -2
- package/dist/platform/workerBootstrap.js +1 -1
- package/dist/reports/initReportBuilder.js +18 -0
- package/dist/reports/junit.js +64 -0
- package/dist/reports/saveReport.js +10 -0
- package/dist/reports/textReport.js +92 -0
- package/dist/reserveLogger.js +22 -0
- package/dist/sendToParentProcess.js +6 -0
- package/dist/start.js +79 -0
- package/dist/types/ISecretValue.js +1 -0
- package/dist/types/SecretValue.js +15 -0
- package/dist/ui/agent.js +4 -2
- package/dist/ui/html-report.js +2 -2
- package/dist/ui/lib.js +1 -1
- package/dist/ui/log-viewer.js +1 -1
- package/dist/utils/node/Folder.js +2 -4
- package/dist/utils/node/FramedStreamReader.js +4 -5
- package/dist/utils/node/FramedStreamWriter.js +6 -5
- package/dist/utils/node/anonymize.js +11 -0
- package/dist/utils/node/timeout.js +11 -0
- package/dist/utils/shared/ProgressBar.js +1 -2
- package/dist/utils/shared/TestReportBuilder.js +11 -7
- package/dist/utils/shared/host.js +11 -0
- package/dist/utils/shared/object.js +12 -3
- package/dist/utils/shared/schema.js +20 -0
- package/dist/utils/shared/string.js +1 -0
- package/dist/utils/shared/toIError.js +3 -7
- package/dist/utils/shared/version.js +52 -0
- package/package.json +2 -78
- package/dist/configuration/validators/browser.js +0 -11
- package/dist/modes/test/REserve.js +0 -31
- package/dist/modes/test/server.js +0 -109
|
@@ -4,6 +4,7 @@ export const options = [
|
|
|
4
4
|
short: 'c',
|
|
5
5
|
type: 'fs-entry',
|
|
6
6
|
description: 'set working directory',
|
|
7
|
+
defaultLabel: 'current working directory',
|
|
7
8
|
default: process.cwd()
|
|
8
9
|
},
|
|
9
10
|
{
|
|
@@ -19,26 +20,131 @@ export const options = [
|
|
|
19
20
|
description: 'path of the testsuite file',
|
|
20
21
|
default: 'test/testsuite.qunit.html'
|
|
21
22
|
},
|
|
23
|
+
{
|
|
24
|
+
name: 'agentDetectionInterval',
|
|
25
|
+
type: 'timeout',
|
|
26
|
+
browserExposed: true,
|
|
27
|
+
description: 'initial polling interval when detecting a test framework after page load',
|
|
28
|
+
default: 100
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'agentDetectionMaxInterval',
|
|
32
|
+
type: 'timeout',
|
|
33
|
+
browserExposed: true,
|
|
34
|
+
description: 'maximum polling interval when detecting a test framework after page load',
|
|
35
|
+
default: 1000
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'agentDetectionTimeout',
|
|
39
|
+
type: 'timeout',
|
|
40
|
+
browserExposed: true,
|
|
41
|
+
description: 'maximum time to wait for a test framework to be detected after page load',
|
|
42
|
+
default: 5000
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'agentNoTestsTimeout',
|
|
46
|
+
type: 'timeout',
|
|
47
|
+
browserExposed: true,
|
|
48
|
+
description: 'time to wait after QUnit.done fires with no tests before declaring the page done',
|
|
49
|
+
default: 5000
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'agentScreenshotTimeout',
|
|
53
|
+
type: 'timeout',
|
|
54
|
+
browserExposed: true,
|
|
55
|
+
description: 'maximum time OPA waits for a pending screenshot before continuing',
|
|
56
|
+
default: 10_000
|
|
57
|
+
},
|
|
22
58
|
{
|
|
23
59
|
name: 'alternateNpmPath',
|
|
24
60
|
type: 'fs-entry',
|
|
25
|
-
|
|
61
|
+
batchForwarded: true,
|
|
62
|
+
description: 'additional path the runner searches for npm packages after the local and global locations'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'batch',
|
|
66
|
+
type: 'string',
|
|
67
|
+
multiple: true,
|
|
68
|
+
description: 'batch item specification (folder, config file, or regex pattern)'
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'batchId',
|
|
72
|
+
type: 'string',
|
|
73
|
+
description: 'identifier for the batch item'
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'batchLabel',
|
|
77
|
+
type: 'string',
|
|
78
|
+
description: 'display label for the batch item'
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'batchOutput',
|
|
82
|
+
type: 'boolean',
|
|
83
|
+
description: 'print output.txt for every batch item after execution, in alphabetical batch-id order'
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'batchTimeout',
|
|
87
|
+
short: 'bt',
|
|
88
|
+
type: 'timeout',
|
|
89
|
+
description: 'fails a batch item if it takes longer than this timeout'
|
|
26
90
|
},
|
|
27
91
|
{
|
|
28
92
|
name: 'browser',
|
|
29
93
|
short: 'b',
|
|
30
|
-
type: '
|
|
31
|
-
|
|
32
|
-
|
|
94
|
+
type: 'enumeration',
|
|
95
|
+
typeModifiers: new Set(['chrome', 'chromium', 'firefox', 'webkit', 'edge', 'safari']),
|
|
96
|
+
batchForwarded: true,
|
|
97
|
+
description: 'browser selection (per driver)'
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'browserBasicAuthPassword',
|
|
101
|
+
type: 'secret',
|
|
102
|
+
description: 'password for HTTP basic authentication'
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'browserBasicAuthUsername',
|
|
106
|
+
type: 'string',
|
|
107
|
+
description: 'username for HTTP basic authentication'
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'browserDevice',
|
|
111
|
+
type: 'string',
|
|
112
|
+
batchForwarded: true,
|
|
113
|
+
description: 'emulate a Puppeteer-known device — sets the viewport, user agent, and touch support, overriding browser viewport width and height'
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'browserOptions',
|
|
117
|
+
type: 'json',
|
|
118
|
+
batchForwarded: true,
|
|
119
|
+
description: 'browser-specific options (JSON)',
|
|
120
|
+
default: {}
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'browserViewportHeight',
|
|
124
|
+
short: 'H',
|
|
125
|
+
type: 'integer',
|
|
126
|
+
typeModifiers: new Set(['positive', 'non-zero']),
|
|
127
|
+
description: 'height of the browser viewport in pixels',
|
|
128
|
+
default: 1080
|
|
33
129
|
},
|
|
34
130
|
{
|
|
35
|
-
name: '
|
|
131
|
+
name: 'browserViewportWidth',
|
|
132
|
+
short: 'W',
|
|
133
|
+
type: 'integer',
|
|
134
|
+
typeModifiers: new Set(['positive', 'non-zero']),
|
|
135
|
+
description: 'width of the browser viewport in pixels',
|
|
136
|
+
default: 1920
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'browserVisible',
|
|
140
|
+
short: 'V',
|
|
36
141
|
type: 'boolean',
|
|
37
|
-
description: '
|
|
142
|
+
description: 'control if the browser should be visible during the tests'
|
|
38
143
|
},
|
|
39
144
|
{
|
|
40
145
|
name: 'ci',
|
|
41
146
|
type: 'boolean',
|
|
147
|
+
batchForwarded: true,
|
|
42
148
|
description: 'forces CI mode (no interactive output)',
|
|
43
149
|
default: !process.stdout.isTTY
|
|
44
150
|
},
|
|
@@ -49,21 +155,137 @@ export const options = [
|
|
|
49
155
|
description: 'read options from a configuration file',
|
|
50
156
|
default: 'ui5-test-runner.json'
|
|
51
157
|
},
|
|
158
|
+
{
|
|
159
|
+
name: 'coverage',
|
|
160
|
+
type: 'boolean',
|
|
161
|
+
description: 'enable code coverage'
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: 'coverageCheckBranches',
|
|
165
|
+
short: 'ccb',
|
|
166
|
+
type: 'percent',
|
|
167
|
+
description: 'minimum branch coverage threshold (0 = no check)',
|
|
168
|
+
default: 0
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'coverageCheckFunctions',
|
|
172
|
+
short: 'ccf',
|
|
173
|
+
type: 'percent',
|
|
174
|
+
description: 'minimum function coverage threshold (0 = no check)',
|
|
175
|
+
default: 0
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'coverageCheckLines',
|
|
179
|
+
short: 'ccl',
|
|
180
|
+
type: 'percent',
|
|
181
|
+
description: 'minimum line coverage threshold (0 = no check)',
|
|
182
|
+
default: 0
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: 'coverageCheckStatements',
|
|
186
|
+
short: 'ccs',
|
|
187
|
+
type: 'percent',
|
|
188
|
+
description: 'minimum statement coverage threshold (0 = no check)',
|
|
189
|
+
default: 0
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: 'coverageRemoteInstrument',
|
|
193
|
+
type: 'regexp',
|
|
194
|
+
multiple: true,
|
|
195
|
+
browserExposed: true,
|
|
196
|
+
description: 'resources sub-paths to instrument for coverage in remote mode'
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: 'coverageReportDir',
|
|
200
|
+
short: 'crd',
|
|
201
|
+
type: 'fs-entry',
|
|
202
|
+
typeModifiers: new Set(['overwrite']),
|
|
203
|
+
description: 'directory for the final coverage report',
|
|
204
|
+
default: 'coverage'
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: 'coverageReporters',
|
|
208
|
+
short: 'cr',
|
|
209
|
+
type: 'string',
|
|
210
|
+
multiple: true,
|
|
211
|
+
description: 'istanbul-lib-report reporters to use',
|
|
212
|
+
default: ['lcov', 'cobertura']
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: 'coverageSettings',
|
|
216
|
+
short: 'cs',
|
|
217
|
+
type: 'fs-entry',
|
|
218
|
+
typeModifiers: new Set(['file', 'safe-default']),
|
|
219
|
+
description: 'path to the Istanbul configuration file (.nycrc.json)',
|
|
220
|
+
default: '.nycrc.json'
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: 'coverageSourceDir',
|
|
224
|
+
type: 'fs-entry',
|
|
225
|
+
typeModifiers: new Set(['safe-default']),
|
|
226
|
+
description: 'directory containing the source files used for coverage reporting'
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: 'coverageTempDir',
|
|
230
|
+
short: 'ctd',
|
|
231
|
+
type: 'fs-entry',
|
|
232
|
+
typeModifiers: new Set(['overwrite']),
|
|
233
|
+
description: 'temporary directory for coverage data',
|
|
234
|
+
default: '.nyc_output'
|
|
235
|
+
},
|
|
52
236
|
{
|
|
53
237
|
name: 'debugKeepBrowserOpen',
|
|
54
238
|
type: 'boolean',
|
|
55
239
|
description: 'keeps the browser open after the tests completed'
|
|
56
240
|
},
|
|
241
|
+
{
|
|
242
|
+
name: 'debugLog',
|
|
243
|
+
type: 'string',
|
|
244
|
+
multiple: true,
|
|
245
|
+
description: 'output debug logs for given sources'
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: 'debugMcpLocalDocs',
|
|
249
|
+
type: 'boolean',
|
|
250
|
+
description: 'use local docs/ directory instead of fetching from GitHub (development only)'
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: 'driver',
|
|
254
|
+
short: 'd',
|
|
255
|
+
type: 'enumeration',
|
|
256
|
+
typeModifiers: new Set(['puppeteer', 'playwright', 'webdriverio', 'selenium-webdriver']),
|
|
257
|
+
browserExposed: true,
|
|
258
|
+
batchForwarded: true,
|
|
259
|
+
description: 'driver selection',
|
|
260
|
+
default: 'puppeteer'
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: 'dumpConfig',
|
|
264
|
+
type: 'boolean',
|
|
265
|
+
description: 'dump the resolved configuration as JSON and exit'
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: 'end',
|
|
269
|
+
type: 'string',
|
|
270
|
+
description: 'command to be executed after the tests'
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
name: 'endTimeout',
|
|
274
|
+
type: 'timeout',
|
|
275
|
+
description: 'maximum waiting time for the end command to execute'
|
|
276
|
+
},
|
|
57
277
|
{
|
|
58
278
|
name: 'failFast',
|
|
59
279
|
short: 'f',
|
|
60
280
|
type: 'boolean',
|
|
281
|
+
batchForwarded: true,
|
|
61
282
|
description: 'stop the whole execution after the first failing page'
|
|
62
283
|
},
|
|
63
284
|
{
|
|
64
285
|
name: 'failOpaFast',
|
|
65
286
|
short: 'fo',
|
|
66
287
|
type: 'boolean',
|
|
288
|
+
batchForwarded: true,
|
|
67
289
|
description: 'stop the OPA page execution after the first failing test'
|
|
68
290
|
},
|
|
69
291
|
{
|
|
@@ -75,43 +297,84 @@ export const options = [
|
|
|
75
297
|
{
|
|
76
298
|
name: 'help',
|
|
77
299
|
type: 'boolean',
|
|
78
|
-
description: 'display
|
|
300
|
+
description: 'display the list of available options and exit'
|
|
79
301
|
},
|
|
80
302
|
{
|
|
81
|
-
name: '
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
description: 'keep the server alive'
|
|
303
|
+
name: 'if',
|
|
304
|
+
type: 'string',
|
|
305
|
+
description: 'skip execution if the expression evaluates to falsy'
|
|
85
306
|
},
|
|
86
307
|
{
|
|
87
|
-
name: '
|
|
308
|
+
name: 'junitXmlFilename',
|
|
88
309
|
type: 'string',
|
|
89
|
-
description: '
|
|
90
|
-
default: '
|
|
310
|
+
description: 'filename for the JUnit XML report saved in the report directory',
|
|
311
|
+
default: 'junit.xml'
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: 'lib',
|
|
315
|
+
type: 'library-mapping',
|
|
316
|
+
multiple: true,
|
|
317
|
+
description: 'map a UI5 resources sub-folder to a local source folder, used in legacy mode to serve custom libraries'
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
name: 'llm',
|
|
321
|
+
type: 'boolean',
|
|
322
|
+
batchForwarded: true,
|
|
323
|
+
description: 'forces LLM-friendly output (compact, no color, severity-tagged)'
|
|
91
324
|
},
|
|
92
325
|
{
|
|
93
326
|
name: 'log',
|
|
94
327
|
type: 'fs-entry',
|
|
95
328
|
typeModifiers: new Set(['file']),
|
|
96
|
-
description: '
|
|
329
|
+
description: 'path to a .logz trace file produced by a previous run; activates log viewer mode'
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: 'logDump',
|
|
333
|
+
type: 'boolean',
|
|
334
|
+
description: 'dump all traces to stdout instead of opening a browser (requires --log)'
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
name: 'logFilter',
|
|
338
|
+
short: 'lf',
|
|
339
|
+
type: 'string',
|
|
340
|
+
description: 'JavaScript expression (using punyexpr) to filter logs for dumping with --log-dump'
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: 'mcp',
|
|
344
|
+
type: 'boolean',
|
|
345
|
+
description: 'start a documentation-only MCP server that lets an MCP client answer questions about ui5-test-runner'
|
|
97
346
|
},
|
|
98
347
|
{
|
|
99
|
-
name: '
|
|
100
|
-
short: 'l',
|
|
348
|
+
name: 'noBanner',
|
|
101
349
|
type: 'boolean',
|
|
102
|
-
description: '
|
|
350
|
+
description: 'do not display the startup banner (logo) and environment information'
|
|
103
351
|
},
|
|
104
352
|
{
|
|
105
353
|
name: 'noNpmInstall',
|
|
106
354
|
type: 'boolean',
|
|
355
|
+
batchForwarded: true,
|
|
107
356
|
description: 'prevent any NPM install'
|
|
108
357
|
},
|
|
358
|
+
{
|
|
359
|
+
name: 'npmAllowInstallScripts',
|
|
360
|
+
type: 'boolean',
|
|
361
|
+
batchForwarded: true,
|
|
362
|
+
description: 'allow postinstall scripts when installing missing packages'
|
|
363
|
+
},
|
|
109
364
|
{
|
|
110
365
|
name: 'npmInstall',
|
|
111
366
|
type: 'string',
|
|
112
367
|
description: 'npm install strategy for missing packages',
|
|
113
368
|
default: 'global'
|
|
114
369
|
},
|
|
370
|
+
{
|
|
371
|
+
name: 'npmInstallMinReleaseAge',
|
|
372
|
+
type: 'integer',
|
|
373
|
+
typeModifiers: new Set(['positive']),
|
|
374
|
+
batchForwarded: true,
|
|
375
|
+
description: 'minimum release age (in days) required before installing a package',
|
|
376
|
+
default: 3
|
|
377
|
+
},
|
|
115
378
|
{
|
|
116
379
|
name: 'npmInstallPrefix',
|
|
117
380
|
type: 'fs-entry',
|
|
@@ -121,6 +384,7 @@ export const options = [
|
|
|
121
384
|
name: 'outputInterval',
|
|
122
385
|
short: 'oi',
|
|
123
386
|
type: 'timeout',
|
|
387
|
+
batchForwarded: true,
|
|
124
388
|
description: 'interval for reporting progress on non interactive output (CI/CD)',
|
|
125
389
|
default: 30_000
|
|
126
390
|
},
|
|
@@ -128,31 +392,38 @@ export const options = [
|
|
|
128
392
|
name: 'pageFilter',
|
|
129
393
|
short: 'pf',
|
|
130
394
|
type: 'regexp',
|
|
395
|
+
batchForwarded: true,
|
|
131
396
|
description: 'filter pages to execute'
|
|
132
397
|
},
|
|
133
398
|
{
|
|
134
399
|
name: 'pageParams',
|
|
135
400
|
short: 'pp',
|
|
136
401
|
type: 'string',
|
|
402
|
+
batchForwarded: true,
|
|
137
403
|
description: 'add parameters to page URL'
|
|
138
404
|
},
|
|
139
405
|
{
|
|
140
406
|
name: 'pageTimeout',
|
|
141
407
|
short: 'pt',
|
|
142
408
|
type: 'timeout',
|
|
409
|
+
batchForwarded: true,
|
|
143
410
|
description: 'fails a page if it takes longer than this timeout'
|
|
144
411
|
},
|
|
145
412
|
{
|
|
146
413
|
name: 'parallel',
|
|
147
414
|
short: 'p',
|
|
148
415
|
type: 'integer',
|
|
416
|
+
typeModifiers: new Set(['positive', 'non-zero']),
|
|
417
|
+
browserExposed: true,
|
|
418
|
+
batchForwarded: true,
|
|
149
419
|
description: 'number of parallel executions',
|
|
150
420
|
default: 2
|
|
151
421
|
},
|
|
152
422
|
{
|
|
153
423
|
name: 'port',
|
|
154
424
|
type: 'integer',
|
|
155
|
-
|
|
425
|
+
typeModifiers: new Set(['positive']),
|
|
426
|
+
description: 'Port the local web server listens on; 0 allocates a free port automatically'
|
|
156
427
|
},
|
|
157
428
|
{
|
|
158
429
|
name: 'reportDir',
|
|
@@ -162,16 +433,74 @@ export const options = [
|
|
|
162
433
|
description: 'directory to output test reports',
|
|
163
434
|
default: 'report'
|
|
164
435
|
},
|
|
436
|
+
{
|
|
437
|
+
name: 'screenshot',
|
|
438
|
+
type: 'boolean',
|
|
439
|
+
browserExposed: true,
|
|
440
|
+
batchForwarded: true,
|
|
441
|
+
description: 'take a screenshot after every OPA assertion'
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
name: 'screenshotOnFailure',
|
|
445
|
+
type: 'boolean',
|
|
446
|
+
batchForwarded: true,
|
|
447
|
+
description: 'take a screenshot when a test fails',
|
|
448
|
+
default: true
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
name: 'screenshotTimeout',
|
|
452
|
+
type: 'timeout',
|
|
453
|
+
batchForwarded: true,
|
|
454
|
+
description: 'maximum time allowed to take a screenshot',
|
|
455
|
+
default: 5000
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
name: 'seleniumApiTimeout',
|
|
459
|
+
type: 'timeout',
|
|
460
|
+
description: 'fails a page if a selenium webdriver api call does not respond within this timeout, indicating a dead session',
|
|
461
|
+
default: 10_000
|
|
462
|
+
},
|
|
165
463
|
{
|
|
166
464
|
name: 'serveOnly',
|
|
167
465
|
short: 's',
|
|
168
466
|
type: 'boolean',
|
|
169
|
-
description: 'serve
|
|
467
|
+
description: 'start the legacy web server and serve the application without running any tests'
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
name: 'splitOpa',
|
|
471
|
+
short: 'so',
|
|
472
|
+
type: 'boolean',
|
|
473
|
+
browserExposed: true,
|
|
474
|
+
batchForwarded: true,
|
|
475
|
+
description: 'split OPA tests by QUnit module, creating one test page per module'
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
name: 'start',
|
|
479
|
+
type: 'string',
|
|
480
|
+
description: 'command to be executed before the tests'
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
name: 'startTimeout',
|
|
484
|
+
type: 'timeout',
|
|
485
|
+
description: 'maximum waiting time for the start command to become ready',
|
|
486
|
+
default: 30_000
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: 'startWaitMethod',
|
|
490
|
+
type: 'string',
|
|
491
|
+
description: 'HTTP method used when polling the startWaitUrl',
|
|
492
|
+
default: 'GET'
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
name: 'startWaitUrl',
|
|
496
|
+
type: 'url',
|
|
497
|
+
description: 'URL to poll after the start command is executed'
|
|
170
498
|
},
|
|
171
499
|
{
|
|
172
500
|
name: 'ui5',
|
|
173
501
|
type: 'url',
|
|
174
|
-
|
|
502
|
+
batchForwarded: true,
|
|
503
|
+
description: 'URL of the UI5 CDN used in legacy mode to serve the UI5 framework resources',
|
|
175
504
|
default: 'https://ui5.sap.com'
|
|
176
505
|
},
|
|
177
506
|
{
|
|
@@ -185,19 +514,47 @@ export const options = [
|
|
|
185
514
|
name: 'version',
|
|
186
515
|
type: 'boolean',
|
|
187
516
|
description: 'display version'
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
name: 'watch',
|
|
520
|
+
type: 'boolean',
|
|
521
|
+
description: 'watch for file changes and automatically reload'
|
|
188
522
|
}
|
|
189
523
|
];
|
|
190
524
|
export const defaults = {
|
|
191
|
-
|
|
525
|
+
agentDetectionInterval: 100,
|
|
526
|
+
agentDetectionMaxInterval: 1000,
|
|
527
|
+
agentDetectionTimeout: 5000,
|
|
528
|
+
agentNoTestsTimeout: 5000,
|
|
529
|
+
agentScreenshotTimeout: 10_000,
|
|
530
|
+
browserOptions: {},
|
|
531
|
+
browserViewportHeight: 1080,
|
|
532
|
+
browserViewportWidth: 1920,
|
|
192
533
|
ci: !process.stdout.isTTY,
|
|
193
534
|
config: 'ui5-test-runner.json',
|
|
535
|
+
coverageCheckBranches: 0,
|
|
536
|
+
coverageCheckFunctions: 0,
|
|
537
|
+
coverageCheckLines: 0,
|
|
538
|
+
coverageCheckStatements: 0,
|
|
539
|
+
coverageReportDir: 'coverage',
|
|
540
|
+
coverageReporters: ['lcov', 'cobertura'],
|
|
541
|
+
coverageSettings: '.nycrc.json',
|
|
542
|
+
coverageTempDir: '.nyc_output',
|
|
194
543
|
cwd: process.cwd(),
|
|
195
|
-
|
|
544
|
+
driver: 'puppeteer',
|
|
545
|
+
junitXmlFilename: 'junit.xml',
|
|
196
546
|
npmInstall: 'global',
|
|
547
|
+
npmInstallMinReleaseAge: 3,
|
|
197
548
|
outputInterval: 30_000,
|
|
198
549
|
parallel: 2,
|
|
199
550
|
reportDir: 'report',
|
|
551
|
+
screenshotOnFailure: true,
|
|
552
|
+
screenshotTimeout: 5000,
|
|
553
|
+
seleniumApiTimeout: 10_000,
|
|
554
|
+
startTimeout: 30_000,
|
|
555
|
+
startWaitMethod: 'GET',
|
|
200
556
|
testsuite: 'test/testsuite.qunit.html',
|
|
201
557
|
ui5: 'https://ui5.sap.com',
|
|
202
558
|
webapp: 'webapp'
|
|
203
559
|
};
|
|
560
|
+
export const sensitiveKeys = new Set(['browserBasicAuthPassword']);
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { punyexpr } from 'punyexpr';
|
|
2
|
+
import { indexedOptions } from './indexedOptions.js';
|
|
3
|
+
import { OptionValidationError } from './OptionValidationError.js';
|
|
4
|
+
export const validations = [
|
|
5
|
+
(configuration) => {
|
|
6
|
+
if (Object.hasOwn(configuration, 'browser') &&
|
|
7
|
+
!punyexpr("(driver !== 'puppeteer' || browser === 'chrome' || browser === 'firefox')")(configuration)) {
|
|
8
|
+
throw OptionValidationError.createValidationError(indexedOptions.browser, 'browser is not supported by puppeteer (chrome, firefox)');
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
(configuration) => {
|
|
12
|
+
if (Object.hasOwn(configuration, 'browser') &&
|
|
13
|
+
!punyexpr("(driver !== 'playwright' || browser === 'chromium' || browser === 'firefox' || browser === 'webkit')")(configuration)) {
|
|
14
|
+
throw OptionValidationError.createValidationError(indexedOptions.browser, 'browser is not supported by playwright (chromium, firefox, webkit)');
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
(configuration) => {
|
|
18
|
+
if (Object.hasOwn(configuration, 'browser') &&
|
|
19
|
+
!punyexpr("(driver !== 'webdriverio' || browser === 'chrome' || browser === 'firefox' || browser === 'edge' || browser === 'safari')")(configuration)) {
|
|
20
|
+
throw OptionValidationError.createValidationError(indexedOptions.browser, 'browser is not supported by webdriverio (chrome, firefox, edge, safari)');
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
(configuration) => {
|
|
24
|
+
if (Object.hasOwn(configuration, 'browser') &&
|
|
25
|
+
!punyexpr("(driver !== 'selenium-webdriver' || browser === 'chrome' || browser === 'firefox' || browser === 'edge' || browser === 'safari')")(configuration)) {
|
|
26
|
+
throw OptionValidationError.createValidationError(indexedOptions.browser, 'browser is not supported by selenium-webdriver (chrome, firefox, edge, safari)');
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
(configuration) => {
|
|
30
|
+
if (Object.hasOwn(configuration, 'browserBasicAuthPassword') &&
|
|
31
|
+
!punyexpr("(driver === 'puppeteer' || driver === 'playwright')")(configuration)) {
|
|
32
|
+
throw OptionValidationError.createValidationError(indexedOptions.browserBasicAuthPassword, 'browserBasicAuthPassword is only supported with puppeteer and playwright drivers');
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
(configuration) => {
|
|
36
|
+
if (Object.hasOwn(configuration, 'browserBasicAuthPassword') &&
|
|
37
|
+
!punyexpr('(browserBasicAuthUsername !== undefined)')(configuration)) {
|
|
38
|
+
throw OptionValidationError.createValidationError(indexedOptions.browserBasicAuthPassword, 'browserBasicAuthPassword requires browserBasicAuthUsername');
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
(configuration) => {
|
|
42
|
+
if (Object.hasOwn(configuration, 'browserBasicAuthUsername') &&
|
|
43
|
+
!punyexpr("(driver === 'puppeteer' || driver === 'playwright')")(configuration)) {
|
|
44
|
+
throw OptionValidationError.createValidationError(indexedOptions.browserBasicAuthUsername, 'browserBasicAuthUsername is only supported with puppeteer and playwright drivers');
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
(configuration) => {
|
|
48
|
+
if (Object.hasOwn(configuration, 'browserBasicAuthUsername') &&
|
|
49
|
+
!punyexpr('(browserBasicAuthPassword !== undefined)')(configuration)) {
|
|
50
|
+
throw OptionValidationError.createValidationError(indexedOptions.browserBasicAuthUsername, 'browserBasicAuthUsername requires browserBasicAuthPassword');
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
(configuration) => {
|
|
54
|
+
if (Object.hasOwn(configuration, 'browserDevice') && !punyexpr("(driver === 'puppeteer')")(configuration)) {
|
|
55
|
+
throw OptionValidationError.createValidationError(indexedOptions.browserDevice, 'browserDevice is only supported with the puppeteer driver');
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
(configuration) => {
|
|
59
|
+
if (Object.hasOwn(configuration, 'browserDevice') &&
|
|
60
|
+
!punyexpr("(browser === undefined || browser === 'chrome')")(configuration)) {
|
|
61
|
+
throw OptionValidationError.createValidationError(indexedOptions.browserDevice, 'browserDevice requires the chrome browser');
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
(configuration) => {
|
|
65
|
+
if (Object.hasOwn(configuration, 'coverage') &&
|
|
66
|
+
!punyexpr("(!coverage || webapp !== '' || coverageSourceDir !== '')")(configuration)) {
|
|
67
|
+
throw OptionValidationError.createValidationError(indexedOptions.coverage, 'at least one of webapp or coverageSourceDir must be set');
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
(configuration) => {
|
|
71
|
+
if (Object.hasOwn(configuration, 'debugMcpLocalDocs') &&
|
|
72
|
+
!punyexpr("(!debugMcpLocalDocs || mode === 'mcp')")(configuration)) {
|
|
73
|
+
throw OptionValidationError.createValidationError(indexedOptions.debugMcpLocalDocs, 'this option requires --mcp');
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
(configuration) => {
|
|
77
|
+
if (Object.hasOwn(configuration, 'dumpConfig') && !punyexpr("(mode === 'dumpConfig')")(configuration)) {
|
|
78
|
+
throw OptionValidationError.createValidationError(indexedOptions.dumpConfig, 'this option cannot be combined with other mode options');
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
(configuration) => {
|
|
82
|
+
if (Object.hasOwn(configuration, 'help') && !punyexpr("(mode === 'help')")(configuration)) {
|
|
83
|
+
throw OptionValidationError.createValidationError(indexedOptions.help, 'this option cannot be combined with other mode options');
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
(configuration) => {
|
|
87
|
+
if (Object.hasOwn(configuration, 'log') && !punyexpr("(mode === 'log')")(configuration)) {
|
|
88
|
+
throw OptionValidationError.createValidationError(indexedOptions.log, 'this option cannot be combined with other mode options');
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
(configuration) => {
|
|
92
|
+
if (Object.hasOwn(configuration, 'logDump') && !punyexpr('(log !== undefined)')(configuration)) {
|
|
93
|
+
throw OptionValidationError.createValidationError(indexedOptions.logDump, 'requires log');
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
(configuration) => {
|
|
97
|
+
if (Object.hasOwn(configuration, 'logFilter') &&
|
|
98
|
+
!punyexpr('(log !== undefined) && (logDump !== undefined)')(configuration)) {
|
|
99
|
+
throw OptionValidationError.createValidationError(indexedOptions.logFilter, 'requires log and logDump');
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
(configuration) => {
|
|
103
|
+
if (Object.hasOwn(configuration, 'mcp') && !punyexpr("(mode === 'mcp')")(configuration)) {
|
|
104
|
+
throw OptionValidationError.createValidationError(indexedOptions.mcp, 'this option cannot be combined with other mode options');
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
(configuration) => {
|
|
108
|
+
if (Object.hasOwn(configuration, 'startTimeout') &&
|
|
109
|
+
!punyexpr('(start !== undefined) && (startWaitUrl !== undefined)')(configuration)) {
|
|
110
|
+
throw OptionValidationError.createValidationError(indexedOptions.startTimeout, 'requires start and startWaitUrl');
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
(configuration) => {
|
|
114
|
+
if (Object.hasOwn(configuration, 'startWaitMethod') &&
|
|
115
|
+
!punyexpr('(start !== undefined) && (startWaitUrl !== undefined)')(configuration)) {
|
|
116
|
+
throw OptionValidationError.createValidationError(indexedOptions.startWaitMethod, 'requires start and startWaitUrl');
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
(configuration) => {
|
|
120
|
+
if (Object.hasOwn(configuration, 'startWaitUrl') && !punyexpr('(start !== undefined)')(configuration)) {
|
|
121
|
+
throw OptionValidationError.createValidationError(indexedOptions.startWaitUrl, 'requires start');
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
(configuration) => {
|
|
125
|
+
if (Object.hasOwn(configuration, 'version') && !punyexpr("(mode === 'version')")(configuration)) {
|
|
126
|
+
throw OptionValidationError.createValidationError(indexedOptions.version, 'this option cannot be combined with other mode options');
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
(configuration) => {
|
|
130
|
+
if (Object.hasOwn(configuration, 'watch') &&
|
|
131
|
+
!punyexpr("(!watch || (mode === 'mcp' && debugMcpLocalDocs))")(configuration)) {
|
|
132
|
+
throw OptionValidationError.createValidationError(indexedOptions.watch, 'this option is valid only for --mcp with --debug-mcp-local-docs');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
];
|