ui5-test-runner 3.3.3 → 3.3.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui5-test-runner",
3
- "version": "3.3.3",
3
+ "version": "3.3.5",
4
4
  "description": "Standalone test runner for UI5",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -16,7 +16,11 @@
16
16
  },
17
17
  "scripts": {
18
18
  "lint": "standard --fix",
19
- "test": "npm run test:unit && npm run test:integration:jsdom && npm run test:integration:puppeteer && npm run test:integration:selenium-webdriver-chrome && npm run test:integration:playwright",
19
+ "test": "npm run test:unit && npm run test:browsers && npm run test:samples",
20
+ "test:browsers": "npm run test:integration:jsdom && npm run test:integration:puppeteer && npm run test:integration:selenium-webdriver-chrome && npm run test:integration:playwright",
21
+ "test:samples": "npm run test:samples:js && npm run test:samples:ts",
22
+ "test:samples:js": "npm run test:sample:js:legacy && npm run test:sample:js:coverage:legacy && npm run test:sample:js:legacy-remote && npm run test:sample:js:coverage:legacy-remote && npm run test:sample:js:remote && npm run test:sample:js:coverage:remote",
23
+ "test:samples:ts": "npm run test:sample:ts:remote && npm run test:sample:ts:coverage:remote",
20
24
  "test:coverall": "rimraf .nyc_output && jest --coverageDirectory .nyc_output --coverageReporters json && nyc --silent --no-clean npm run test:integration:jsdom && nyc --silent --no-clean npm run test:integration:puppeteer && nyc --silent --no-clean npm run test:integration:selenium-webdriver-chrome && nyc --silent --no-clean npm run test:integration:playwright && nyc merge .nyc_output .nyc_output/final/coverage.json && nyc report --temp-dir .nyc_output/final/ --report-dir coverage --branches 80 --functions 80 --lines 80 --statements 80",
21
25
  "test:unit": "jest",
22
26
  "test:unit:debug": "jest --runInBand",
@@ -26,6 +30,17 @@
26
30
  "test:integration:playwright": "node . --capabilities --browser $/playwright.js",
27
31
  "test:report": "node ./src/defaults/report.js ./test/report && reserve --config ./test/report/reserve.json",
28
32
  "test:text-report": "node ./src/defaults/text-report.js ./test/report",
33
+ "test:sample:js:legacy": "node . --cwd ./test/sample.js",
34
+ "test:sample:js:coverage:legacy": "node . --cwd ./test/sample.js --coverage --coverage-settings nyc.json --coverage-check-statements 67",
35
+ "test:sample:js:legacy-remote": "node . --port 8081 --cwd ./test/sample.js --url http://localhost:8081/test/testsuite.qunit.html",
36
+ "test:sample:js:coverage:legacy-remote": "node . --port 8081 --cwd ./test/sample.js --url http://localhost:8081/test/testsuite.qunit.html --coverage --coverage-settings nyc.json --coverage-check-statements 67",
37
+ "test:sample:js:remote": "start-server-and-test 'npm run serve:sample:js' http://localhost:8080 'node . --url http://localhost:8080/test/testsuite.qunit.html'",
38
+ "test:sample:js:coverage:remote": "start-server-and-test 'npm run serve:sample:js' http://localhost:8080 'node . --url http://localhost:8080/test/testsuite.qunit.html --coverage --coverage-check-statements 67'",
39
+ "serve:sample:js": "ui5 serve --config ./test/sample.js/ui5.yaml",
40
+ "test:sample:ts:remote": "start-server-and-test 'npm run serve:sample:ts' http://localhost:8080 'node . --url http://localhost:8080/test/testsuite.qunit.html'",
41
+ "serve:sample:ts": "cd ./test/sample.ts && node ui5.cjs serve",
42
+ "test:sample:ts:coverage:remote": "start-server-and-test 'npm run serve:sample:ts:coverage' http://localhost:8080 'node . --url http://localhost:8080/test/testsuite.qunit.html --coverage --coverage-check-statements 67'",
43
+ "serve:sample:ts:coverage": "cd ./test/sample.ts && node ui5.cjs serve --config ui5-coverage.yaml",
29
44
  "build:doc": "node build/doc"
30
45
  },
31
46
  "repository": {
@@ -52,13 +67,19 @@
52
67
  "mime": "^3.0.0",
53
68
  "punybind": "^1.2.1",
54
69
  "punyexpr": "^1.0.4",
55
- "reserve": "^1.15.3"
70
+ "reserve": "^1.15.4"
56
71
  },
57
72
  "devDependencies": {
73
+ "@openui5/types": "^1.119.0",
74
+ "@ui5/cli": "^3.6.1",
75
+ "@ui5/middleware-code-coverage": "^1.1.0",
58
76
  "jest": "^29.7.0",
59
77
  "nock": "^13.3.3",
60
78
  "nyc": "^15.1.0",
61
- "standard": "^17.1.0"
79
+ "standard": "^17.1.0",
80
+ "start-server-and-test": "^2.0.1",
81
+ "typescript": "^5.2.2",
82
+ "ui5-tooling-transpile": "^3.2.6"
62
83
  },
63
84
  "optionalDependencies": {
64
85
  "fsevents": "^2.3.3"
@@ -69,6 +90,10 @@
69
90
  "qunit",
70
91
  "node",
71
92
  "jest"
93
+ ],
94
+ "globals": [
95
+ "sap",
96
+ "opaTest"
72
97
  ]
73
98
  },
74
99
  "jest": {
@@ -98,4 +123,4 @@
98
123
  }
99
124
  }
100
125
  }
101
- }
126
+ }
package/src/coverage.js CHANGED
@@ -1,13 +1,15 @@
1
1
  'use strict'
2
2
 
3
- const { join, dirname } = require('path')
3
+ const { join, dirname, isAbsolute } = require('path')
4
4
  const { fork } = require('child_process')
5
- const { cleanDir, createDir, filename, download } = require('./tools')
5
+ const { cleanDir, createDir, filename, download, allocPromise } = require('./tools')
6
6
  const { readdir, readFile, stat, writeFile, access, constants } = require('fs').promises
7
7
  const { Readable } = require('stream')
8
8
  const { getOutput } = require('./output')
9
9
  const { resolvePackage } = require('./npm')
10
10
  const { promisify } = require('util')
11
+ const { UTRError } = require('./error')
12
+ const { $remoteOnLegacy } = require('./symbols')
11
13
 
12
14
  const $nycSettingsPath = Symbol('nycSettingsPath')
13
15
  const $coverageFileIndex = Symbol('coverageFileIndex')
@@ -28,9 +30,13 @@ async function nyc (job, ...args) {
28
30
  output.nyc(...args)
29
31
  const childProcess = fork(nycScript, args, { stdio: 'pipe' })
30
32
  output.monitor(childProcess)
31
- let done
32
- const promise = new Promise(resolve => { done = resolve })
33
- childProcess.on('close', done)
33
+ const { promise, resolve, reject } = allocPromise()
34
+ childProcess.on('close', async code => {
35
+ if (code !== 0) {
36
+ reject(UTRError.NYC_FAILED(`Return code ${code}`))
37
+ }
38
+ resolve()
39
+ })
34
40
  return promise
35
41
  }
36
42
 
@@ -70,15 +76,9 @@ async function instrument (job) {
70
76
  settings.exclude.push(join(job.coverageReportDir, '**'))
71
77
  await writeFile(job[$nycSettingsPath], JSON.stringify(settings))
72
78
  if (job.mode === 'url') {
73
- const port = job.port.toString()
74
- const useLocal = job.url.some(url => {
75
- // ignore host name since the machine might be exposed with any name
76
- const parsedUrl = new URL(url)
77
- return parsedUrl.port === port
78
- })
79
- if (!useLocal) {
80
- getOutput(job).instrumentationSkipped()
79
+ if (!job[$remoteOnLegacy]) {
81
80
  job[$coverageRemote] = true
81
+ getOutput(job).instrumentationSkipped()
82
82
  return
83
83
  }
84
84
  }
@@ -94,20 +94,30 @@ async function generateCoverageReport (job) {
94
94
  const coverageFilename = join(coverageMergedDir, 'coverage.json')
95
95
  await nyc(job, 'merge', job.coverageTempDir, coverageFilename)
96
96
  if (job[$coverageRemote] && !job.coverageProxy) {
97
- job.status = 'Collecting remote source files'
97
+ job.status = 'Checking remote source files'
98
98
  // Assuming all files are coming from the same server
99
99
  const { origin } = new URL(job.testPageUrls[0])
100
100
  const sourcesBasePath = join(job.coverageTempDir, 'sources')
101
101
  const coverageData = require(coverageFilename)
102
102
  const filenames = Object.keys(coverageData)
103
+ let changes = 0
103
104
  for (const filename of filenames) {
104
105
  const fileData = coverageData[filename]
105
106
  const { path } = fileData
107
+ if (isAbsolute(path)) {
108
+ try {
109
+ await access(path, constants.R_OK)
110
+ continue
111
+ } catch (e) {}
112
+ }
106
113
  const filePath = join(sourcesBasePath, path)
107
114
  fileData.path = filePath
108
115
  await download(origin + path, filePath)
116
+ ++changes
117
+ }
118
+ if (changes > 0) {
119
+ await writeFile(coverageFilename, JSON.stringify(coverageData))
109
120
  }
110
- await writeFile(coverageFilename, JSON.stringify(coverageData))
111
121
  }
112
122
  const reporters = job.coverageReporters.map(reporter => `--reporter=${reporter}`)
113
123
  if (!job.coverageReporters.includes('text')) {
@@ -115,6 +125,9 @@ async function generateCoverageReport (job) {
115
125
  }
116
126
  const checks = []
117
127
  if (job.coverageCheckBranches || job.coverageCheckFunctions || job.coverageCheckLines || job.coverageCheckStatements) {
128
+ if (!job.coverageReporters.includes('lcov')) {
129
+ reporters.push('--reporter=lcov')
130
+ }
118
131
  checks.push(
119
132
  `--branches=${job.coverageCheckBranches}`,
120
133
  `--functions=${job.coverageCheckFunctions}`,
@@ -124,6 +137,13 @@ async function generateCoverageReport (job) {
124
137
  )
125
138
  }
126
139
  await nyc(job, 'report', ...reporters, ...checks, '--temp-dir', coverageMergedDir, '--report-dir', job.coverageReportDir, '--nycrc-path', job[$nycSettingsPath])
140
+ if (checks.length) {
141
+ // The checks are not triggered if the coverage is empty
142
+ const lcov = await stat(join(job.coverageReportDir, 'lcov.info'))
143
+ if (lcov.size === 0) {
144
+ throw UTRError.NYC_FAILED('No coverage information extracted')
145
+ }
146
+ }
127
147
  }
128
148
 
129
149
  module.exports = {
@@ -136,18 +156,18 @@ module.exports = {
136
156
  }
137
157
  await writeFile(coverageFileName, JSON.stringify(coverageData))
138
158
  },
139
- generateCoverageReport: job => job.coverage && generateCoverageReport(job),
159
+ generateCoverageReport: job => job.coverage ? generateCoverageReport(job) : Promise.resolve(),
140
160
  mappings: async job => {
141
161
  if (!job.coverage) {
142
162
  return []
143
163
  }
144
164
  const instrumentedBasePath = join(job.coverageTempDir, 'instrumented')
145
165
  const instrumentedMapping = {
146
- match: /^\/(.*\.js)$/,
166
+ match: /(.*\.js)(\?.*)?$/,
147
167
  file: join(instrumentedBasePath, '$1'),
148
168
  'ignore-if-not-found': true
149
169
  }
150
- if (job.mode === 'legacy') {
170
+ if (job.mode === 'legacy' || job[$remoteOnLegacy]) {
151
171
  return [{
152
172
  ...instrumentedMapping,
153
173
  'custom-file-system': job.debugCoverageNoCustomFs ? undefined : customFileSystem
@@ -4,6 +4,7 @@ const { instrument, generateCoverageReport, mappings } = require('./coverage')
4
4
  const { stat } = require('fs/promises')
5
5
  const { cleanDir, createDir } = require('./tools')
6
6
  const { getOutput } = require('./output')
7
+ const { $remoteOnLegacy } = require('./symbols')
7
8
 
8
9
  describe('src/coverage', () => {
9
10
  const cwd = join(__dirname, '../test/project')
@@ -108,7 +109,8 @@ describe('src/coverage', () => {
108
109
  Object.assign(job, {
109
110
  mode: 'url',
110
111
  port: 8080,
111
- url: ['http://localhost:8080/whatever/test.html']
112
+ url: ['http://localhost:8080/whatever/test.html'],
113
+ [$remoteOnLegacy]: true // added on job finalization
112
114
  })
113
115
  await instrument(job)
114
116
  expect(instrumentationSkipped).not.toHaveBeenCalled()
@@ -88,7 +88,9 @@ require('./browser')({
88
88
  networkWriter
89
89
  }) {
90
90
  const browsers = require(modules.playwright)
91
- browser = await browsers[options.browser].launch()
91
+ browser = await browsers[options.browser].launch({
92
+ headless: !options.visible
93
+ })
92
94
 
93
95
  let recordVideo
94
96
  if (options.video) {
package/src/error.js CHANGED
@@ -37,6 +37,8 @@ const errors = [{
37
37
  name: 'BROWSER_MISS_SCRIPTS_CAPABILITY'
38
38
  }, {
39
39
  name: 'NPM_DEPENDENCY_NOT_FOUND'
40
+ }, {
41
+ name: 'NYC_FAILED'
40
42
  }]
41
43
 
42
44
  errors.forEach((error, index) => {
package/src/job.js CHANGED
@@ -5,7 +5,7 @@ const { statSync, accessSync, constants } = require('fs')
5
5
  const { dirname, join, isAbsolute } = require('path')
6
6
  const { name, description, version } = require(join(__dirname, '../package.json'))
7
7
  const { getOutput } = require('./output')
8
- const { $valueSources } = require('./symbols')
8
+ const { $valueSources, $remoteOnLegacy } = require('./symbols')
9
9
  const { buildAndCheckMode } = require('./job-mode')
10
10
  const { boolean, integer, timeout, url, arrayOf, regex, percent } = require('./options')
11
11
 
@@ -107,6 +107,7 @@ function getCommand (cwd) {
107
107
  .option('-br, --browser-retry <count>', '[💻🔗🧪] Browser instantiation retries : if the command fails unexpectedly, it is re-executed (0 means no retry)', 1)
108
108
 
109
109
  // Common to legacy and url
110
+ .option('-qs, --qunit-strict', '[💻🔗] Strict mode on qunit execution (fails if no modules declared)', boolean, false)
110
111
  .option('-pf, --page-filter <regexp>', '[💻🔗] Filter out pages not matching the regexp')
111
112
  .option('-pp, --page-params <params>', '[💻🔗] Add parameters to page URL')
112
113
  .option('-t, --global-timeout <timeout>', '[💻🔗] Limit the pages execution time, fail the page if it takes longer than the timeout (0 means no timeout)', timeout, 0)
@@ -287,6 +288,15 @@ function finalize (job) {
287
288
  overrideIfNotSet('coverageReporters', settings.reporter)
288
289
  }
289
290
 
291
+ if (job.mode === 'url') {
292
+ const port = job.port.toString()
293
+ job[$remoteOnLegacy] = job.url.every(url => {
294
+ // ignore host name since the machine might be exposed with any name
295
+ const parsedUrl = new URL(url)
296
+ return parsedUrl.port === port
297
+ })
298
+ }
299
+
290
300
  job[$status] = 'Starting'
291
301
  Object.defineProperty(job, 'status', {
292
302
  get () {
package/src/output.js CHANGED
@@ -412,6 +412,10 @@ function build (job) {
412
412
  log(job, p80()`Skipping nyc instrumentation (--url)`)
413
413
  }),
414
414
 
415
+ qunitEarlyStart: wrap(url => {
416
+ log(job, p80()`QUnit start without tests in ${pad.lt(url)}`)
417
+ }),
418
+
415
419
  endpointError: wrap(({ api, url, data, error }) => {
416
420
  const p = p80()
417
421
  log(job, p`┌──────────${pad.x('─')}┐`)
@@ -13,27 +13,40 @@ function error (job, url, details = '') {
13
13
  throw UTRError.QUNIT_ERROR(details)
14
14
  }
15
15
 
16
+ function invalidTestId (job, url, testId) {
17
+ error(job, url, `No QUnit unit test found with id ${testId}`)
18
+ }
19
+
16
20
  function get (job, urlWithHash, testId) {
17
21
  const url = stripUrlHash(urlWithHash)
18
22
  const page = job.qunitPages && job.qunitPages[url]
19
23
  if (!page) {
20
24
  error(job, url, `No QUnit page found for ${urlWithHash}`)
21
25
  }
26
+ let testModule
22
27
  let test
23
28
  if (testId !== undefined) {
24
29
  page.modules.every(module => {
25
30
  test = module.tests.find(test => test.testId === testId)
26
- return test === undefined
31
+ if (test === undefined) {
32
+ return true
33
+ } else {
34
+ testModule = module
35
+ return false
36
+ }
27
37
  })
28
- if (!test) {
29
- error(job, url, `No QUnit unit test found with id ${testId}`)
38
+ if (!test && job.qunitStrict) {
39
+ invalidTestId(job, url, testId)
30
40
  }
31
41
  }
32
- return { url, page, test }
42
+ return { url, page, testModule, test }
33
43
  }
34
44
 
35
45
  async function done (job, urlWithHash, report) {
36
46
  const { url, page } = get(job, urlWithHash)
47
+ if (page.earlyStart && page.count === 0) {
48
+ return // wait
49
+ }
37
50
  if (job.browserCapabilities.screenshot) {
38
51
  try {
39
52
  await screenshot(job, url, 'done')
@@ -41,11 +54,11 @@ async function done (job, urlWithHash, report) {
41
54
  getOutput(job).genericError(error, url)
42
55
  }
43
56
  }
57
+ page.end = new Date()
44
58
  if (report.__coverage__) {
45
- collect(job, url, report.__coverage__)
59
+ await collect(job, url, report.__coverage__)
46
60
  delete report.__coverage__
47
61
  }
48
- page.end = new Date()
49
62
  page.report = report
50
63
  stop(job, url)
51
64
  }
@@ -55,8 +68,12 @@ module.exports = {
55
68
 
56
69
  async begin (job, urlWithHash, { isOpa, totalTests, modules }) {
57
70
  const url = stripUrlHash(urlWithHash)
58
- if (!totalTests || !modules) {
59
- error(job, url, 'Invalid begin hook details')
71
+ const earlyStart = !totalTests || !modules
72
+ if (earlyStart) {
73
+ getOutput(job).qunitEarlyStart(url)
74
+ if (job.qunitStrict) {
75
+ error(job, url, 'Invalid begin hook details')
76
+ }
60
77
  }
61
78
  if (!job.qunitPages) {
62
79
  job.qunitPages = {}
@@ -70,16 +87,31 @@ module.exports = {
70
87
  count: totalTests,
71
88
  modules
72
89
  }
90
+ if (earlyStart) {
91
+ qunitPage.earlyStart = true
92
+ }
73
93
  job.qunitPages[url] = qunitPage
74
94
  },
75
95
 
76
96
  async testStart (job, urlWithHash, { module, name, testId }) {
77
- const { test } = get(job, urlWithHash, testId)
97
+ let { page, testModule, test } = get(job, urlWithHash, testId)
98
+ if (!testModule) {
99
+ testModule = { name: module, tests: [] }
100
+ page.modules.push(testModule)
101
+ }
102
+ if (!test) {
103
+ test = { name, testId }
104
+ testModule.tests.push(test)
105
+ ++page.count
106
+ }
78
107
  test.start = new Date()
79
108
  },
80
109
 
81
110
  async log (job, urlWithHash, { module, name, testId, ...log }) {
82
111
  const { url, page, test } = get(job, urlWithHash, testId)
112
+ if (!test) {
113
+ invalidTestId(job, url, testId)
114
+ }
83
115
  if (!test.logs) {
84
116
  test.logs = []
85
117
  }
@@ -97,6 +129,9 @@ module.exports = {
97
129
  async testDone (job, urlWithHash, { name, module, testId, assertions, ...report }) {
98
130
  const { failed } = report
99
131
  const { url, page, test } = get(job, urlWithHash, testId)
132
+ if (!test) {
133
+ invalidTestId(job, url, testId)
134
+ }
100
135
  if (failed) {
101
136
  if (job.browserCapabilities.screenshot) {
102
137
  try {
@@ -10,10 +10,12 @@ jest.mock('./coverage.js', () => ({
10
10
  const { collect } = require('./coverage')
11
11
 
12
12
  const mockGenericError = jest.fn()
13
+ const mockQunitEarlyStart = jest.fn()
13
14
 
14
15
  jest.mock('./output.js', () => ({
15
16
  getOutput: () => ({
16
- genericError: mockGenericError
17
+ genericError: mockGenericError,
18
+ qunitEarlyStart: mockQunitEarlyStart
17
19
  })
18
20
  }))
19
21
 
@@ -174,7 +176,11 @@ describe('src/qunit-hooks', () => {
174
176
  })
175
177
  })
176
178
 
177
- describe('validation', () => {
179
+ describe('validation (--qunit-strict)', () => {
180
+ beforeEach(() => {
181
+ job.qunitStrict = true
182
+ })
183
+
178
184
  afterEach(() => {
179
185
  expect(stop).toHaveBeenCalledWith(job, url)
180
186
  expect(job.failed).toStrictEqual(true)
@@ -185,6 +191,7 @@ describe('src/qunit-hooks', () => {
185
191
  isOpa: false,
186
192
  modules: getModules()
187
193
  })).rejects.toThrow(UTRError.QUNIT_ERROR('Invalid begin hook details'))
194
+ expect(mockQunitEarlyStart).toHaveBeenCalled()
188
195
  })
189
196
 
190
197
  it('requires modules', async () => {
@@ -192,6 +199,7 @@ describe('src/qunit-hooks', () => {
192
199
  isOpa: false,
193
200
  totalTests: 1
194
201
  })).rejects.toThrow(UTRError.QUNIT_ERROR('Invalid begin hook details'))
202
+ expect(mockQunitEarlyStart).toHaveBeenCalled()
195
203
  })
196
204
  })
197
205
  })
@@ -594,7 +602,18 @@ describe('src/qunit-hooks', () => {
594
602
  expect(job.failed).toStrictEqual(true)
595
603
  })
596
604
 
597
- it('fails on invalid test id', async () => {
605
+ it('fails on invalid test id (--qunit-strict)', async () => {
606
+ job.qunitStrict = true
607
+ await expect(testDone(job, url, {
608
+ ...getTestDoneFor1a(),
609
+ testId: '1c'
610
+ }))
611
+ .rejects.toThrow(UTRError.QUNIT_ERROR('No QUnit unit test found with id 1c'))
612
+ expect(stop).toHaveBeenCalledWith(job, url)
613
+ expect(job.failed).toStrictEqual(true)
614
+ })
615
+
616
+ it('fails on invalid test id (--no-qunit-strict)', async () => {
598
617
  await expect(testDone(job, url, {
599
618
  ...getTestDoneFor1a(),
600
619
  testId: '1c'
package/src/report.js CHANGED
@@ -51,7 +51,10 @@ module.exports = {
51
51
  })
52
52
  return promise
53
53
  })
54
- promises.push(generateCoverageReport(job))
54
+ promises.push(generateCoverageReport(job).catch(e => {
55
+ output.genericError(e)
56
+ job.failed = true
57
+ }))
55
58
  await Promise.all(promises)
56
59
  job.status = 'Done'
57
60
  }
@@ -213,6 +213,31 @@ describe('simulate', () => {
213
213
  })
214
214
  })
215
215
 
216
+ describe('simple test execution (--no-qunit-strict)', () => {
217
+ beforeAll(async () => {
218
+ await setup('simple-early')
219
+ pages = {
220
+ 'testsuite.qunit.html': async referer => {
221
+ await post('/_/addTestPages', referer, [
222
+ referer.replace('testsuite.qunit.html', 'page1.html')
223
+ ])
224
+ },
225
+ 'page1.html': async referer => {
226
+ await post('/_/QUnit/begin', referer, { totalTests: 0, modules: [] })
227
+ await post('/_/QUnit/done', referer, { failed: 0 })
228
+ await post('/_/QUnit/testStart', referer, { module: 'module', name: 'test', testId: '1' })
229
+ await post('/_/QUnit/testDone', referer, { testId: '1', failed: 0, passed: 1 })
230
+ await post('/_/QUnit/done', referer, { failed: 0 })
231
+ }
232
+ }
233
+ await safeExecute()
234
+ })
235
+
236
+ it('succeeded', () => {
237
+ expect(job.failed).toStrictEqual(false)
238
+ })
239
+ })
240
+
216
241
  describe('error', () => {
217
242
  describe('one test fail', () => {
218
243
  beforeAll(async () => {
package/src/symbols.js CHANGED
@@ -4,5 +4,6 @@ module.exports = {
4
4
  $probeUrlsCompleted: Symbol('probeUrlsCompleted'),
5
5
  $testPagesStarted: Symbol('testPagesStarted'),
6
6
  $testPagesCompleted: Symbol('testPagesCompleted'),
7
- $valueSources: Symbol('valueSources')
7
+ $valueSources: Symbol('valueSources'),
8
+ $remoteOnLegacy: Symbol('remoteOnLegacy')
8
9
  }