ui5-test-runner 5.13.0 → 6.0.0-beta.1
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 +3 -2
- package/dist/Npm.js +80 -0
- package/dist/browsers/IBrowser.js +1 -0
- package/dist/browsers/factory.js +9 -0
- package/dist/browsers/puppeteer.js +158 -0
- package/dist/cli.js +17 -0
- package/dist/configuration/CommandLine.js +112 -0
- package/dist/configuration/Configuration.js +1 -0
- package/dist/configuration/ConfigurationValidator.js +79 -0
- package/dist/configuration/Option.js +1 -0
- package/dist/configuration/OptionValidationError.js +15 -0
- package/dist/configuration/indexedOptions.js +13 -0
- package/dist/configuration/options.js +191 -0
- package/dist/configuration/validators/OptionValidator.js +1 -0
- package/dist/configuration/validators/boolean.js +15 -0
- package/dist/configuration/validators/browser.js +11 -0
- package/dist/configuration/validators/fsEntry.js +70 -0
- package/dist/configuration/validators/index.js +20 -0
- package/dist/configuration/validators/integer.js +10 -0
- package/dist/configuration/validators/percent.js +17 -0
- package/dist/configuration/validators/regexp.js +20 -0
- package/dist/configuration/validators/string.js +7 -0
- package/dist/configuration/validators/timeout.js +24 -0
- package/dist/configuration/validators/url.js +8 -0
- package/dist/modes/ModeFunction.js +1 -0
- package/dist/modes/Modes.js +9 -0
- package/dist/modes/execute.js +27 -0
- package/dist/modes/help.js +3 -0
- package/dist/modes/log/ILogStorage.js +1 -0
- package/dist/modes/log/LogMetrics.js +9 -0
- package/dist/modes/log/LogReader.js +37 -0
- package/dist/modes/log/LogStorage.js +68 -0
- package/dist/modes/log/REserve.js +101 -0
- package/dist/modes/log/index.js +58 -0
- package/dist/modes/test/REserve.js +31 -0
- package/dist/modes/test/agent.js +8 -0
- package/dist/modes/test/browser.js +37 -0
- package/dist/modes/test/index.js +66 -0
- package/dist/modes/test/pageTask.js +145 -0
- package/dist/modes/test/report.js +3 -0
- package/dist/modes/test/server.js +109 -0
- package/dist/modes/version.js +11 -0
- package/dist/platform/Exit.js +139 -0
- package/dist/platform/FileSystem.js +13 -0
- package/dist/platform/Host.js +10 -0
- package/dist/platform/Http.js +38 -0
- package/dist/platform/Path.js +5 -0
- package/dist/platform/Process.js +133 -0
- package/dist/platform/Terminal.js +47 -0
- package/dist/platform/Thread.js +43 -0
- package/dist/platform/ZLib.js +7 -0
- package/dist/platform/assert.js +17 -0
- package/dist/platform/constants.js +5 -0
- package/dist/platform/environment.js +28 -0
- package/dist/platform/index.js +13 -0
- package/dist/platform/logger/ILogger.js +1 -0
- package/dist/platform/logger/allCompressed.js +54 -0
- package/dist/platform/logger/compress.js +277 -0
- package/dist/platform/logger/output/BaseLoggerOutput.js +158 -0
- package/dist/platform/logger/output/InteractiveLoggerOutput.js +102 -0
- package/dist/platform/logger/output/StaticLoggerOutput.js +32 -0
- package/dist/platform/logger/output/factory.js +10 -0
- package/dist/platform/logger/output.js +58 -0
- package/dist/platform/logger/proxy.js +6 -0
- package/dist/platform/logger/toInternalLogAttributes.js +22 -0
- package/dist/platform/logger/types.js +7 -0
- package/dist/platform/logger.js +138 -0
- package/dist/platform/mock.js +104 -0
- package/dist/platform/version.js +8 -0
- package/dist/platform/workerBootstrap.js +21 -0
- package/dist/reports/html.js +46 -0
- package/dist/types/AgentState.js +1 -0
- package/dist/types/CommonTestReportFormat.js +50 -0
- package/dist/types/IError.js +1 -0
- package/dist/types/IUserInterfaceController.js +1 -0
- package/dist/types/typeUtilities.js +1 -0
- package/dist/ui/agent.js +3 -0
- package/dist/ui/html-report.js +2 -0
- package/dist/ui/lib.js +1 -0
- package/dist/ui/log-viewer.js +2 -0
- package/dist/utils/node/Folder.js +28 -0
- package/dist/utils/node/FramedStreamReader.js +86 -0
- package/dist/utils/node/FramedStreamWriter.js +27 -0
- package/dist/utils/shared/ProgressBar.js +43 -0
- package/dist/utils/shared/TestReportBuilder.js +48 -0
- package/dist/utils/shared/memoize.js +19 -0
- package/dist/utils/shared/object.js +8 -0
- package/dist/utils/shared/parallelize.js +59 -0
- package/dist/utils/shared/string.js +23 -0
- package/dist/utils/shared/toIError.js +17 -0
- package/package.json +73 -50
- package/.releaserc +0 -5
- package/index.js +0 -175
- package/jest.config.json +0 -31
- package/src/add-test-pages.js +0 -67
- package/src/batch.js +0 -214
- package/src/browsers.js +0 -319
- package/src/capabilities/index.js +0 -204
- package/src/capabilities/tests/basic/iframe.html +0 -8
- package/src/capabilities/tests/basic/index.html +0 -12
- package/src/capabilities/tests/basic/index.js +0 -20
- package/src/capabilities/tests/basic/ui5.html +0 -24
- package/src/capabilities/tests/dynamic-include/index.js +0 -21
- package/src/capabilities/tests/dynamic-include/mix.html +0 -11
- package/src/capabilities/tests/dynamic-include/one.html +0 -11
- package/src/capabilities/tests/dynamic-include/post.js +0 -3
- package/src/capabilities/tests/dynamic-include/test.js +0 -1
- package/src/capabilities/tests/dynamic-include/two.html +0 -11
- package/src/capabilities/tests/index.js +0 -16
- package/src/capabilities/tests/local-storage/index.html +0 -16
- package/src/capabilities/tests/local-storage/index.js +0 -21
- package/src/capabilities/tests/screenshot/index.html +0 -23
- package/src/capabilities/tests/screenshot/index.js +0 -24
- package/src/capabilities/tests/scripts/coverage.html +0 -32
- package/src/capabilities/tests/scripts/iframe.html +0 -18
- package/src/capabilities/tests/scripts/index.js +0 -59
- package/src/capabilities/tests/scripts/qunit.html +0 -22
- package/src/capabilities/tests/scripts/testsuite.html +0 -10
- package/src/capabilities/tests/scripts/testsuite.js +0 -8
- package/src/capabilities/tests/timeout/index.html +0 -21
- package/src/capabilities/tests/timeout/index.js +0 -19
- package/src/capabilities/tests/traces/index.html +0 -18
- package/src/capabilities/tests/traces/index.js +0 -81
- package/src/capabilities/tests/ui5/focus.html +0 -89
- package/src/capabilities/tests/ui5/index.js +0 -39
- package/src/capabilities/tests/ui5/language.html +0 -50
- package/src/capabilities/tests/ui5/timezone.html +0 -27
- package/src/clean.js +0 -22
- package/src/cors.js +0 -21
- package/src/coverage.js +0 -384
- package/src/csv-reader.js +0 -36
- package/src/csv-writer.js +0 -55
- package/src/defaults/.nycrc.json +0 -4
- package/src/defaults/browser.js +0 -217
- package/src/defaults/happy-dom.js +0 -123
- package/src/defaults/jsdom/compatibility.js +0 -163
- package/src/defaults/jsdom/debug.js +0 -23
- package/src/defaults/jsdom/resource-loader.js +0 -44
- package/src/defaults/jsdom/sap.ui.test.matchers.visible.js +0 -39
- package/src/defaults/jsdom.js +0 -95
- package/src/defaults/json-report.js +0 -36
- package/src/defaults/junit-xml-report.js +0 -90
- package/src/defaults/playwright.js +0 -142
- package/src/defaults/puppeteer.js +0 -124
- package/src/defaults/report/common.js +0 -38
- package/src/defaults/report/decompress.js +0 -19
- package/src/defaults/report/default.html +0 -99
- package/src/defaults/report/main.js +0 -69
- package/src/defaults/report/progress.js +0 -60
- package/src/defaults/report/styles.css +0 -66
- package/src/defaults/report.js +0 -91
- package/src/defaults/scan-ui5.js +0 -26
- package/src/defaults/selenium-webdriver/chrome.js +0 -39
- package/src/defaults/selenium-webdriver/edge.js +0 -24
- package/src/defaults/selenium-webdriver/firefox.js +0 -30
- package/src/defaults/selenium-webdriver.js +0 -129
- package/src/defaults/text-report.js +0 -108
- package/src/defaults/webdriverio.js +0 -80
- package/src/end.js +0 -62
- package/src/endpoints.js +0 -219
- package/src/error.js +0 -54
- package/src/get-job-progress.js +0 -78
- package/src/handle.js +0 -43
- package/src/if.js +0 -10
- package/src/inject/jest2qunit.js +0 -289
- package/src/inject/opa-iframe-coverage.js +0 -22
- package/src/inject/post.js +0 -141
- package/src/inject/qunit-hooks.js +0 -107
- package/src/inject/qunit-redirect.js +0 -65
- package/src/inject/ui5-coverage.js +0 -33
- package/src/job-mode.js +0 -65
- package/src/job.js +0 -493
- package/src/npm.js +0 -136
- package/src/options.js +0 -95
- package/src/output.js +0 -739
- package/src/parallelize.js +0 -63
- package/src/qunit-hooks.js +0 -219
- package/src/report.js +0 -89
- package/src/reserve.js +0 -25
- package/src/start.js +0 -129
- package/src/symbols.js +0 -8
- package/src/tests.js +0 -183
- package/src/timeout.js +0 -53
- package/src/tools.js +0 -179
- package/src/ui5.js +0 -199
- package/src/unhandled.js +0 -32
package/src/browsers.js
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { fork } = require('child_process')
|
|
4
|
-
const { join } = require('path')
|
|
5
|
-
const { writeFile, readFile, open, stat, unlink } = require('fs/promises')
|
|
6
|
-
const { recreateDir, filename, allocPromise } = require('./tools')
|
|
7
|
-
const { getPageTimeout, pageTimedOut } = require('./timeout')
|
|
8
|
-
const { getOutput, newProgress } = require('./output')
|
|
9
|
-
const { resolvePackage } = require('./npm')
|
|
10
|
-
const { UTRError } = require('./error')
|
|
11
|
-
const { $browsers } = require('./symbols')
|
|
12
|
-
|
|
13
|
-
let lastScreenshotId = 0
|
|
14
|
-
const screenshots = {}
|
|
15
|
-
|
|
16
|
-
async function instantiate (job, config) {
|
|
17
|
-
const output = getOutput(job)
|
|
18
|
-
if (job.browserArgs.some((arg) => !arg.trim())) {
|
|
19
|
-
output.emptyBrowserArg()
|
|
20
|
-
job.browserArgs = job.browserArgs.filter((arg) => arg.trim())
|
|
21
|
-
}
|
|
22
|
-
const { dir, url } = config
|
|
23
|
-
await recreateDir(dir)
|
|
24
|
-
const browserConfig = {
|
|
25
|
-
capabilities: job.browserCapabilities,
|
|
26
|
-
modules: job.browserModules,
|
|
27
|
-
...config,
|
|
28
|
-
args: job.browserArgs
|
|
29
|
-
}
|
|
30
|
-
const browserConfigPath = join(dir, 'browser.json')
|
|
31
|
-
await writeFile(browserConfigPath, JSON.stringify(browserConfig, undefined, 2))
|
|
32
|
-
const stdoutFilename = join(dir, 'stdout.txt')
|
|
33
|
-
const stderrFilename = join(dir, 'stderr.txt')
|
|
34
|
-
const stdout = await open(stdoutFilename, 'w')
|
|
35
|
-
const stderr = await open(stderrFilename, 'w')
|
|
36
|
-
const childProcess = fork(job.browser, [browserConfigPath], {
|
|
37
|
-
stdio: [0, stdout, stderr, 'ipc'],
|
|
38
|
-
env: {
|
|
39
|
-
...process.env,
|
|
40
|
-
...job.env
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
const { promise, resolve } = allocPromise()
|
|
44
|
-
childProcess.on('close', async code => {
|
|
45
|
-
await stdout.close()
|
|
46
|
-
await stderr.close()
|
|
47
|
-
if (code !== 0) {
|
|
48
|
-
getOutput(job).browserFailed(url, code, dir)
|
|
49
|
-
}
|
|
50
|
-
resolve(code)
|
|
51
|
-
})
|
|
52
|
-
childProcess.on('error', err => {
|
|
53
|
-
output.browserChildProcessError(url, err)
|
|
54
|
-
})
|
|
55
|
-
childProcess.closed = promise
|
|
56
|
-
childProcess.stdoutFilename = stdoutFilename
|
|
57
|
-
childProcess.stderrFilename = stderrFilename
|
|
58
|
-
return childProcess
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async function probe (job) {
|
|
62
|
-
if (job.browserCapabilities) {
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
const output = getOutput(job)
|
|
66
|
-
job.status = 'Probing browser instantiation command'
|
|
67
|
-
|
|
68
|
-
async function execute (folder) {
|
|
69
|
-
const dir = join(job.reportDir, folder)
|
|
70
|
-
const capabilities = join(dir, 'capabilities.json')
|
|
71
|
-
const childProcess = await instantiate(job, {
|
|
72
|
-
url: 'about:blank',
|
|
73
|
-
capabilities,
|
|
74
|
-
dir
|
|
75
|
-
})
|
|
76
|
-
const code = await childProcess.closed
|
|
77
|
-
if (code !== 0) {
|
|
78
|
-
throw UTRError.BROWSER_PROBE_FAILED(code.toString())
|
|
79
|
-
}
|
|
80
|
-
let browserCapabilities
|
|
81
|
-
try {
|
|
82
|
-
browserCapabilities = Object.assign({
|
|
83
|
-
modules: [],
|
|
84
|
-
screenshot: null,
|
|
85
|
-
scripts: false,
|
|
86
|
-
parallel: true,
|
|
87
|
-
traces: []
|
|
88
|
-
}, JSON.parse((await readFile(capabilities)).toString()))
|
|
89
|
-
} catch (e) {
|
|
90
|
-
throw UTRError.MISSING_OR_INVALID_BROWSER_CAPABILITIES(e.message)
|
|
91
|
-
}
|
|
92
|
-
return browserCapabilities
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
output.debug('browsers/probe', 'initial probing')
|
|
96
|
-
const browserCapabilities = await execute('probe')
|
|
97
|
-
output.debug('browsers/probe', 'browser capabilities', browserCapabilities)
|
|
98
|
-
job.browserCapabilities = browserCapabilities
|
|
99
|
-
|
|
100
|
-
const { modules } = browserCapabilities
|
|
101
|
-
const resolvedModules = {}
|
|
102
|
-
if (modules.length) {
|
|
103
|
-
for await (const name of browserCapabilities.modules) {
|
|
104
|
-
output.debug('browsers/probe', `resolving package ${name}...`)
|
|
105
|
-
resolvedModules[name] = await resolvePackage(job, name)
|
|
106
|
-
output.debug('browsers/probe', `package ${name} resolved`)
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
job.browserModules = resolvedModules
|
|
110
|
-
if (browserCapabilities['probe-with-modules']) {
|
|
111
|
-
output.debug('browsers/probe', 'probing with modules')
|
|
112
|
-
job.browserCapabilities = await execute('probe/with-modules')
|
|
113
|
-
output.debug('browsers/probe', 'browser capabilities', browserCapabilities)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (job.debugCapabilitiesNoScript) {
|
|
117
|
-
job.browserCapabilities.scripts = false
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
output.browserCapabilities(job.browserCapabilities)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
async function start (job, url, scripts = []) {
|
|
124
|
-
const output = getOutput(job)
|
|
125
|
-
if (!job[$browsers]) {
|
|
126
|
-
job[$browsers] = {}
|
|
127
|
-
}
|
|
128
|
-
output.browserStart(url)
|
|
129
|
-
const reportDir = join(job.reportDir, filename(url))
|
|
130
|
-
const resolvedScripts = []
|
|
131
|
-
for await (const script of scripts) {
|
|
132
|
-
if (script.endsWith('.js')) {
|
|
133
|
-
const scriptFilename = join(__dirname, 'inject', script)
|
|
134
|
-
const scriptContent = (await readFile(scriptFilename)).toString()
|
|
135
|
-
resolvedScripts.push(scriptContent)
|
|
136
|
-
} else {
|
|
137
|
-
resolvedScripts.push(script)
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (resolvedScripts.length) {
|
|
141
|
-
resolvedScripts.unshift(`(function () {
|
|
142
|
-
window['ui5-test-runner/base-host'] = 'http://${job.localhost}:${job.port}'
|
|
143
|
-
}())`)
|
|
144
|
-
}
|
|
145
|
-
const progress = newProgress(job, url)
|
|
146
|
-
const pageBrowser = {
|
|
147
|
-
url,
|
|
148
|
-
reportDir,
|
|
149
|
-
scripts: resolvedScripts,
|
|
150
|
-
retry: 0,
|
|
151
|
-
progress
|
|
152
|
-
}
|
|
153
|
-
const { promise, resolve, reject } = allocPromise()
|
|
154
|
-
pageBrowser.done = value => {
|
|
155
|
-
delete job[$browsers][url]
|
|
156
|
-
resolve(value)
|
|
157
|
-
}
|
|
158
|
-
pageBrowser.failed = reason => {
|
|
159
|
-
delete job[$browsers][url]
|
|
160
|
-
reject(reason)
|
|
161
|
-
}
|
|
162
|
-
job[$browsers][url] = pageBrowser
|
|
163
|
-
await run(job, pageBrowser)
|
|
164
|
-
try {
|
|
165
|
-
await promise
|
|
166
|
-
} finally {
|
|
167
|
-
progress.done()
|
|
168
|
-
output.browserStopped(url)
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
async function run (job, pageBrowser) {
|
|
173
|
-
const output = getOutput(job)
|
|
174
|
-
const { url, retry, reportDir, scripts } = pageBrowser
|
|
175
|
-
let dir = reportDir
|
|
176
|
-
if (retry) {
|
|
177
|
-
output.browserRetry(url, retry)
|
|
178
|
-
dir = join(dir, retry.toString())
|
|
179
|
-
if (pageBrowser.console.count) {
|
|
180
|
-
try {
|
|
181
|
-
await pageBrowser.console.flush
|
|
182
|
-
.then(() => unlink(join(reportDir, 'console.jsonl')))
|
|
183
|
-
} catch (e) {
|
|
184
|
-
// ignore
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
pageBrowser.console = {
|
|
189
|
-
count: 0,
|
|
190
|
-
byApi: {},
|
|
191
|
-
flush: Promise.resolve()
|
|
192
|
-
}
|
|
193
|
-
await recreateDir(dir)
|
|
194
|
-
delete pageBrowser.stopped
|
|
195
|
-
const childProcess = await instantiate(job, {
|
|
196
|
-
url,
|
|
197
|
-
retry,
|
|
198
|
-
scripts,
|
|
199
|
-
dir
|
|
200
|
-
})
|
|
201
|
-
pageBrowser.childProcess = childProcess
|
|
202
|
-
const timeout = getPageTimeout(job)
|
|
203
|
-
if (timeout) {
|
|
204
|
-
pageBrowser.timeoutId = setTimeout(() => {
|
|
205
|
-
output.browserTimeout(url, dir)
|
|
206
|
-
pageTimedOut(job, url)
|
|
207
|
-
stop(job, url)
|
|
208
|
-
}, timeout)
|
|
209
|
-
}
|
|
210
|
-
childProcess.on('message', message => {
|
|
211
|
-
if (message.command === 'screenshot') {
|
|
212
|
-
const { id } = message
|
|
213
|
-
screenshots[id]()
|
|
214
|
-
delete screenshots[id]
|
|
215
|
-
} else if (message.command === 'console') {
|
|
216
|
-
++pageBrowser.console.count
|
|
217
|
-
if (!pageBrowser.console.byApi[message.api]) {
|
|
218
|
-
pageBrowser.console.byApi[message.api] = 1
|
|
219
|
-
} else {
|
|
220
|
-
++pageBrowser.console.byApi[message.api]
|
|
221
|
-
}
|
|
222
|
-
pageBrowser.console.flush = pageBrowser.console.flush
|
|
223
|
-
.then(() => writeFile(join(reportDir, 'console.jsonl'), JSON.stringify({
|
|
224
|
-
t: message.t,
|
|
225
|
-
api: message.api,
|
|
226
|
-
args: message.args
|
|
227
|
-
}) + '\n', {
|
|
228
|
-
flag: 'a+'
|
|
229
|
-
}))
|
|
230
|
-
}
|
|
231
|
-
})
|
|
232
|
-
childProcess.on('close', async code => {
|
|
233
|
-
if (!pageBrowser.stopped) {
|
|
234
|
-
if (code === 0) {
|
|
235
|
-
output.browserClosed(url, code, dir)
|
|
236
|
-
}
|
|
237
|
-
childProcess.closed.then(() => stop(job, url, true))
|
|
238
|
-
}
|
|
239
|
-
})
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async function screenshot (job, url, filename) {
|
|
243
|
-
if (!job.browserCapabilities.screenshot) {
|
|
244
|
-
throw UTRError.BROWSER_SCREENSHOT_NOT_SUPPORTED()
|
|
245
|
-
}
|
|
246
|
-
const output = getOutput(job)
|
|
247
|
-
const id = ++lastScreenshotId
|
|
248
|
-
try {
|
|
249
|
-
const { childProcess, reportDir } = job[$browsers][url]
|
|
250
|
-
const absoluteFilename = join(reportDir, filename + job.browserCapabilities.screenshot)
|
|
251
|
-
if (childProcess.connected) {
|
|
252
|
-
output.debug('screenshot', id, url, absoluteFilename)
|
|
253
|
-
const { promise, resolve, reject } = allocPromise()
|
|
254
|
-
screenshots[id] = resolve
|
|
255
|
-
output.debug('screenshot', id, 'sending command')
|
|
256
|
-
childProcess.send({
|
|
257
|
-
id,
|
|
258
|
-
command: 'screenshot',
|
|
259
|
-
filename: absoluteFilename
|
|
260
|
-
})
|
|
261
|
-
const timeoutId = setTimeout(() => {
|
|
262
|
-
reject(UTRError.BROWSER_SCREENSHOT_TIMEOUT())
|
|
263
|
-
}, job.screenshotTimeout)
|
|
264
|
-
output.debug('screenshot', id, 'command sent, waiting for answer')
|
|
265
|
-
await promise
|
|
266
|
-
output.debug('screenshot', id, 'answer received')
|
|
267
|
-
clearTimeout(timeoutId)
|
|
268
|
-
const result = await stat(absoluteFilename)
|
|
269
|
-
output.debug('screenshot', id, 'file size :', result.size)
|
|
270
|
-
if (!result.isFile() || result.size === 0) {
|
|
271
|
-
throw new Error('File expected')
|
|
272
|
-
}
|
|
273
|
-
output.debug('screenshot', id, 'done')
|
|
274
|
-
return absoluteFilename
|
|
275
|
-
}
|
|
276
|
-
} catch (e) {
|
|
277
|
-
output.debug('screenshot', id, e.message)
|
|
278
|
-
if (e.code === UTRError.BROWSER_SCREENSHOT_TIMEOUT_CODE) {
|
|
279
|
-
throw e
|
|
280
|
-
}
|
|
281
|
-
throw UTRError.BROWSER_SCREENSHOT_FAILED(e.toString())
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
async function stop (job, url, retry = false) {
|
|
286
|
-
const pageBrowser = job[$browsers][url]
|
|
287
|
-
if (pageBrowser) {
|
|
288
|
-
pageBrowser.stopped = true
|
|
289
|
-
const { childProcess, done, failed, timeoutId } = pageBrowser
|
|
290
|
-
if (timeoutId) {
|
|
291
|
-
clearTimeout(timeoutId)
|
|
292
|
-
}
|
|
293
|
-
if (childProcess.connected) {
|
|
294
|
-
/* istanbul ignore else */
|
|
295
|
-
if (!job.debugKeepBrowserOpen) {
|
|
296
|
-
childProcess.send({ command: 'stop' })
|
|
297
|
-
}
|
|
298
|
-
const { promise: closeTimeout, resolve } = allocPromise()
|
|
299
|
-
const timeoutId = setTimeout(resolve, job.browserCloseTimeout)
|
|
300
|
-
await Promise.race([
|
|
301
|
-
childProcess.closed,
|
|
302
|
-
closeTimeout
|
|
303
|
-
])
|
|
304
|
-
clearTimeout(timeoutId)
|
|
305
|
-
}
|
|
306
|
-
await pageBrowser.console.flush
|
|
307
|
-
if (retry) {
|
|
308
|
-
if (++pageBrowser.retry <= job.browserRetry) {
|
|
309
|
-
run(job, pageBrowser)
|
|
310
|
-
} else {
|
|
311
|
-
failed(UTRError.BROWSER_FAILED())
|
|
312
|
-
}
|
|
313
|
-
} else {
|
|
314
|
-
done()
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
module.exports = { probe, start, screenshot, stop }
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { check, serve, body } = require('reserve')
|
|
4
|
-
const { probe, start, stop } = require('../browsers')
|
|
5
|
-
const { join } = require('path')
|
|
6
|
-
const { getOutput } = require('../output')
|
|
7
|
-
const { performance } = require('perf_hooks')
|
|
8
|
-
const { cleanDir, allocPromise, filename } = require('../tools')
|
|
9
|
-
const { $statusProgressTotal, $statusProgressCount } = require('../symbols')
|
|
10
|
-
const tests = require('./tests')
|
|
11
|
-
const { parallelize } = require('../parallelize')
|
|
12
|
-
|
|
13
|
-
async function capabilities (job) {
|
|
14
|
-
const output = getOutput(job)
|
|
15
|
-
|
|
16
|
-
async function exit (code) {
|
|
17
|
-
if (job.keepAlive) {
|
|
18
|
-
job.status = 'Serving'
|
|
19
|
-
} else {
|
|
20
|
-
if (job.debugKeepReport) {
|
|
21
|
-
output.log('Report folder', job.reportDir, 'not cleaned because of --debug-keep-report.')
|
|
22
|
-
} else if (code !== 0) {
|
|
23
|
-
output.error('Report folder', job.reportDir, 'not cleaned because of errors.')
|
|
24
|
-
} else {
|
|
25
|
-
await cleanDir(job.reportDir)
|
|
26
|
-
}
|
|
27
|
-
output.stop()
|
|
28
|
-
process.exit(code)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
await probe(job)
|
|
34
|
-
} catch (e) {
|
|
35
|
-
output.error('Unable to probe')
|
|
36
|
-
exit(-1)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
const listeners = []
|
|
41
|
-
const configuration = await check({
|
|
42
|
-
port: job.port,
|
|
43
|
-
mappings: [
|
|
44
|
-
require('../cors'), {
|
|
45
|
-
custom: async (request, response) => {
|
|
46
|
-
response.setHeader('x-ui5-test-runner', 'capabilities')
|
|
47
|
-
}
|
|
48
|
-
}, {
|
|
49
|
-
match: /x-wait-time=(\d+)/,
|
|
50
|
-
custom: async (request, response, waitTime) => {
|
|
51
|
-
response.setHeader('x-wait-time', waitTime)
|
|
52
|
-
await new Promise(resolve => setTimeout(resolve, parseInt(waitTime)))
|
|
53
|
-
}
|
|
54
|
-
}, {
|
|
55
|
-
method: 'POST',
|
|
56
|
-
match: '^/_/(.*)',
|
|
57
|
-
custom: async (request, response, endpoint) => {
|
|
58
|
-
const { referer, 'x-page-url': xPageUrl } = request.headers
|
|
59
|
-
const listenerIndex = (xPageUrl || referer).match(/\blistener=(\d+)/)[1]
|
|
60
|
-
const listener = listeners[listenerIndex]
|
|
61
|
-
await listener({
|
|
62
|
-
endpoint,
|
|
63
|
-
body: await body(request).json()
|
|
64
|
-
})
|
|
65
|
-
response.writeHead(200)
|
|
66
|
-
response.end()
|
|
67
|
-
}
|
|
68
|
-
}, {
|
|
69
|
-
match: '^/inject/(.*)',
|
|
70
|
-
cwd: join(__dirname, '../inject'),
|
|
71
|
-
file: '$1',
|
|
72
|
-
static: !job.debugDevMode
|
|
73
|
-
}, {
|
|
74
|
-
match: '^/(.*)',
|
|
75
|
-
cwd: __dirname,
|
|
76
|
-
file: '$1',
|
|
77
|
-
static: !job.debugDevMode
|
|
78
|
-
}, {
|
|
79
|
-
status: 404
|
|
80
|
-
}]
|
|
81
|
-
})
|
|
82
|
-
const server = serve(configuration)
|
|
83
|
-
if (job.logServer) {
|
|
84
|
-
server
|
|
85
|
-
.on('incoming', output.logServerIncoming)
|
|
86
|
-
.on('redirected', output.logServerRedirected)
|
|
87
|
-
.on('closed', output.logServerClosed)
|
|
88
|
-
}
|
|
89
|
-
server.on('error', (error) => {
|
|
90
|
-
output.error('REserve error:', error)
|
|
91
|
-
})
|
|
92
|
-
await new Promise(resolve => server
|
|
93
|
-
.on('ready', ({ port }) => {
|
|
94
|
-
job.port = port
|
|
95
|
-
resolve()
|
|
96
|
-
})
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
job.status = 'Running tests'
|
|
100
|
-
|
|
101
|
-
const filteredTests = tests
|
|
102
|
-
.filter((test) => !test.for || test.for(job.browserCapabilities))
|
|
103
|
-
.filter(({ name }) => !job.debugCapabilitiesTest || name.startsWith(job.debugCapabilitiesTest))
|
|
104
|
-
output.log('Number of tests :', filteredTests.length)
|
|
105
|
-
|
|
106
|
-
let errors = 0
|
|
107
|
-
|
|
108
|
-
const task = async (test) => {
|
|
109
|
-
const { promise, resolve } = allocPromise()
|
|
110
|
-
const { label, url, args, scripts, endpoint = () => { } } = test
|
|
111
|
-
|
|
112
|
-
const listenerIndex = listeners.length
|
|
113
|
-
let pageUrl
|
|
114
|
-
if (url.startsWith('http')) {
|
|
115
|
-
pageUrl = url
|
|
116
|
-
} else {
|
|
117
|
-
pageUrl = `http://localhost:${job.port}/tests/${url}`
|
|
118
|
-
}
|
|
119
|
-
if (url.includes('?')) {
|
|
120
|
-
pageUrl += `&listener=${listenerIndex}`
|
|
121
|
-
} else {
|
|
122
|
-
pageUrl += `?listener=${listenerIndex}`
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const now = performance.now()
|
|
126
|
-
let timeoutId
|
|
127
|
-
if (!job.debugCapabilitiesNoTimeout) {
|
|
128
|
-
const timeout = job.pageTimeout || 120000
|
|
129
|
-
timeoutId = setTimeout(() => done(`Timeout (${timeout})`), timeout)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async function done (error) {
|
|
133
|
-
if (done.called) {
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
++job[$statusProgressCount]
|
|
137
|
-
done.called = true
|
|
138
|
-
if (timeoutId) {
|
|
139
|
-
clearTimeout(timeoutId)
|
|
140
|
-
}
|
|
141
|
-
await stop(job, pageUrl)
|
|
142
|
-
const timeSpent = Math.floor(performance.now() - now)
|
|
143
|
-
if (error) {
|
|
144
|
-
output.log('❌', label, `[${filename(pageUrl)}]`, error)
|
|
145
|
-
if (job.failFast) {
|
|
146
|
-
exit(1)
|
|
147
|
-
}
|
|
148
|
-
++errors
|
|
149
|
-
} else {
|
|
150
|
-
output.log('✔️ ', label, timeSpent, 'ms')
|
|
151
|
-
}
|
|
152
|
-
resolve()
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const context = {
|
|
156
|
-
job
|
|
157
|
-
}
|
|
158
|
-
listeners[listenerIndex] = async data => {
|
|
159
|
-
try {
|
|
160
|
-
if (await endpoint.call(context, data, pageUrl) !== false) {
|
|
161
|
-
done()
|
|
162
|
-
}
|
|
163
|
-
} catch (e) {
|
|
164
|
-
done(e)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (args) {
|
|
169
|
-
// TODO replace or concat ?
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
start(job, pageUrl, scripts)
|
|
173
|
-
.catch(reason => done(reason))
|
|
174
|
-
.then(() => {
|
|
175
|
-
if (!context.stopExpected) {
|
|
176
|
-
done('Failed')
|
|
177
|
-
}
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
return promise
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
let parallel
|
|
184
|
-
if (!job.browserCapabilities.parallel) {
|
|
185
|
-
parallel = 1
|
|
186
|
-
} else {
|
|
187
|
-
parallel = job.parallel
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
job[$statusProgressTotal] = filteredTests.length
|
|
191
|
-
job[$statusProgressCount] = 0
|
|
192
|
-
await parallelize(task, filteredTests, parallel)
|
|
193
|
-
|
|
194
|
-
output.log('Done.')
|
|
195
|
-
exit(errors)
|
|
196
|
-
} catch (error) {
|
|
197
|
-
output.error(error)
|
|
198
|
-
exit(-1)
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
module.exports = {
|
|
203
|
-
capabilities
|
|
204
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const assert = require('assert')
|
|
4
|
-
|
|
5
|
-
module.exports = [{
|
|
6
|
-
label: 'Loads a page',
|
|
7
|
-
url: 'basic/index.html'
|
|
8
|
-
}, {
|
|
9
|
-
label: 'Loads a UI5 example',
|
|
10
|
-
url: 'basic/ui5.html',
|
|
11
|
-
endpoint: ({ body }) => {
|
|
12
|
-
assert.strictEqual(body['sap.m.Button'], true)
|
|
13
|
-
}
|
|
14
|
-
}, {
|
|
15
|
-
label: 'Loads a UI5 inside an iframe',
|
|
16
|
-
url: 'basic/iframe.html',
|
|
17
|
-
endpoint: ({ body }) => {
|
|
18
|
-
assert.strictEqual(body['sap.m.Button'], true)
|
|
19
|
-
}
|
|
20
|
-
}]
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<body>
|
|
4
|
-
<H1>UI5 example</H1>
|
|
5
|
-
<p>Checks if the browser can load a page</p>
|
|
6
|
-
<script
|
|
7
|
-
src="https://ui5.sap.com/resources/sap-ui-core.js"
|
|
8
|
-
id="sap-ui-bootstrap"
|
|
9
|
-
data-sap-ui-libs="sap.m"
|
|
10
|
-
data-sap-ui-theme="sap_fiori_3"
|
|
11
|
-
data-sap-ui-compatVersion="edge">
|
|
12
|
-
</script>
|
|
13
|
-
<script>
|
|
14
|
-
sap.ui.getCore().attachInit(function() {
|
|
15
|
-
const xhr = new XMLHttpRequest()
|
|
16
|
-
xhr.open('POST', '/_/log')
|
|
17
|
-
if (parent !== window && parent.document.location.toString() !== 'about:blank') {
|
|
18
|
-
xhr.setRequestHeader('x-page-url', parent.document.location.toString())
|
|
19
|
-
}
|
|
20
|
-
xhr.send('{"sap.m.Button":' + !!sap.m.Button + '}')
|
|
21
|
-
});
|
|
22
|
-
</script>
|
|
23
|
-
</body>
|
|
24
|
-
</html>
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const assert = require('assert')
|
|
4
|
-
|
|
5
|
-
const endpoint = ({ body }) => {
|
|
6
|
-
assert.strictEqual(body.test, true)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
module.exports = [{
|
|
10
|
-
label: 'Dynamic include',
|
|
11
|
-
url: 'dynamic-include/one.html',
|
|
12
|
-
endpoint
|
|
13
|
-
}, {
|
|
14
|
-
label: 'Dynamic includes',
|
|
15
|
-
url: 'dynamic-include/two.html',
|
|
16
|
-
endpoint
|
|
17
|
-
}, {
|
|
18
|
-
label: 'Dynamic include mixed with a static one',
|
|
19
|
-
url: 'dynamic-include/mix.html',
|
|
20
|
-
endpoint
|
|
21
|
-
}]
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<body>
|
|
4
|
-
<H1>basic</H1>
|
|
5
|
-
<p>Checks if the browser can mix static script with a dynamic script inserted with document.write</p>
|
|
6
|
-
<script>
|
|
7
|
-
document.write('<script src="test.js?x-wait-time=1000"><' + '/script>'); // wait 1s before delivering
|
|
8
|
-
</script>
|
|
9
|
-
<script src="post.js"></script>
|
|
10
|
-
</body>
|
|
11
|
-
</html>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
window.test = true
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<body>
|
|
4
|
-
<H1>basic</H1>
|
|
5
|
-
<p>Checks if the browser can load sequentially scripts inserted with document.write</p>
|
|
6
|
-
<script>
|
|
7
|
-
document.write('<script src="test.js?x-wait-time=1000"><' + '/script>'); // wait 1s before delivering
|
|
8
|
-
document.write('<script src="post.js"><' + '/script>');
|
|
9
|
-
</script>
|
|
10
|
-
</body>
|
|
11
|
-
</html>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const { readdirSync } = require('fs')
|
|
2
|
-
|
|
3
|
-
module.exports = readdirSync(__dirname)
|
|
4
|
-
.filter(name => !name.endsWith('.js'))
|
|
5
|
-
.map(name => {
|
|
6
|
-
const tests = require(`./${name}`)
|
|
7
|
-
if (Array.isArray(tests)) {
|
|
8
|
-
tests.forEach((test, index) => {
|
|
9
|
-
test.name = `${name}:${index}`
|
|
10
|
-
})
|
|
11
|
-
} else {
|
|
12
|
-
tests.name = name
|
|
13
|
-
}
|
|
14
|
-
return tests
|
|
15
|
-
})
|
|
16
|
-
.flat()
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<body>
|
|
4
|
-
<H1>localStorage</H1>
|
|
5
|
-
<p>Check if the localStorage is isolated</p>
|
|
6
|
-
<script>
|
|
7
|
-
const initial = localStorage.value
|
|
8
|
-
const parameters = new URLSearchParams(location.search)
|
|
9
|
-
localStorage.value = parameters.get('value')
|
|
10
|
-
const modified = localStorage.value
|
|
11
|
-
const xhr = new XMLHttpRequest()
|
|
12
|
-
xhr.open('POST', '/_/log')
|
|
13
|
-
xhr.send(JSON.stringify({initial, modified}))
|
|
14
|
-
</script>
|
|
15
|
-
</body>
|
|
16
|
-
</html>
|