velocious 1.0.594 → 1.0.595
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/build/configuration.js +41 -1
- package/build/src/configuration.d.ts +18 -0
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +33 -2
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +9 -8
- package/build/testing/test-runner.js +8 -7
- package/package.json +2 -1
- package/scripts/browser-test-session.js +60 -0
- package/scripts/test-browser.js +2 -6
- package/src/configuration.js +41 -1
- package/src/testing/test-runner.js +8 -7
|
@@ -1456,14 +1456,15 @@ export default class TestRunner {
|
|
|
1456
1456
|
* @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */
|
|
1457
1457
|
const consoleObject = /** @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */ (console)
|
|
1458
1458
|
/**
|
|
1459
|
-
* Original console methods
|
|
1459
|
+
* Original console methods captured as direct references so stopping restores
|
|
1460
|
+
* the exact method that was installed at capture start.
|
|
1460
1461
|
* @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */
|
|
1461
1462
|
const originalConsoleMethods = {
|
|
1462
|
-
debug: consoleObject.debug
|
|
1463
|
-
error: consoleObject.error
|
|
1464
|
-
info: consoleObject.info
|
|
1465
|
-
log: consoleObject.log
|
|
1466
|
-
warn: consoleObject.warn
|
|
1463
|
+
debug: consoleObject.debug,
|
|
1464
|
+
error: consoleObject.error,
|
|
1465
|
+
info: consoleObject.info,
|
|
1466
|
+
log: consoleObject.log,
|
|
1467
|
+
warn: consoleObject.warn
|
|
1467
1468
|
}
|
|
1468
1469
|
let stopped = false
|
|
1469
1470
|
let outputText = ""
|
|
@@ -1473,7 +1474,7 @@ export default class TestRunner {
|
|
|
1473
1474
|
lines.push(`[${new Date().toISOString()}] [${methodName}] ${format(...args)}`)
|
|
1474
1475
|
|
|
1475
1476
|
if (passthrough) {
|
|
1476
|
-
originalConsoleMethods[methodName](
|
|
1477
|
+
originalConsoleMethods[methodName].apply(consoleObject, args)
|
|
1477
1478
|
}
|
|
1478
1479
|
}
|
|
1479
1480
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"velocious": "build/bin/velocious.js"
|
|
4
4
|
},
|
|
5
5
|
"name": "velocious",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.595",
|
|
7
7
|
"main": "build/index.js",
|
|
8
8
|
"types": "build/index.d.ts",
|
|
9
9
|
"files": [
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"benchmark:http-client-content-length-byte-length": "node benchmark/http-client-content-length-byte-length.js",
|
|
28
28
|
"benchmark:frontend-model-serialization-resource-metadata": "node benchmark/frontend-model-serialization-resource-metadata.js",
|
|
29
29
|
"benchmark:sql-diagnostic-scans": "node --expose-gc benchmark/sql-diagnostic-scans.js",
|
|
30
|
+
"benchmark:test-mode-diagnostics": "node --expose-gc benchmark/test-mode-diagnostics.js",
|
|
30
31
|
"build": "node scripts/clean-build.js && npm run compile",
|
|
31
32
|
"compile": "tsc -b && npm run copy:js && npm run copy:ejs && npm run copy:templates && node scripts/ensure-bin-executable.js",
|
|
32
33
|
"copy:js": "cpy \"index.js\" build && cpy \"bin/**/*.js\" build/bin && cpy \"src/**/*.js\" build --parents",
|
|
@@ -7,6 +7,7 @@ import { createRequire } from "node:module"
|
|
|
7
7
|
import path from "node:path"
|
|
8
8
|
import { promisify } from "node:util"
|
|
9
9
|
import timeout from "awaitery/build/timeout.js"
|
|
10
|
+
import SystemTest from "system-testing/build/system-test.js"
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* @typedef {object} BrowserTestChromeRuntime
|
|
@@ -29,6 +30,14 @@ import timeout from "awaitery/build/timeout.js"
|
|
|
29
30
|
* @property {() => Promise<string>} diagnostics - Reads retained ChromeDriver diagnostics.
|
|
30
31
|
*/
|
|
31
32
|
|
|
33
|
+
/**
|
|
34
|
+
* @typedef {object} BrowserTestSystemTestConfig
|
|
35
|
+
* @property {boolean} debug - Whether SystemTest should emit debug output.
|
|
36
|
+
* @property {{type: "selenium", options: {chromeArguments: string[], chromeBinaryPath: string}}} driver - Selenium driver config.
|
|
37
|
+
* @property {string} httpHost - HTTP host for the browser-test app.
|
|
38
|
+
* @property {number} httpPort - HTTP port for the browser-test app.
|
|
39
|
+
*/
|
|
40
|
+
|
|
32
41
|
const require = createRequire(import.meta.url)
|
|
33
42
|
const { binaryPaths } = require("selenium-webdriver/common/seleniumManager.js")
|
|
34
43
|
const { CancellationError, waitForServer } = require("selenium-webdriver/http/util.js")
|
|
@@ -185,6 +194,57 @@ export async function loadOrPrewarmBrowserTestChromeRuntime() {
|
|
|
185
194
|
}
|
|
186
195
|
}
|
|
187
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Formatted default Chrome launch arguments for every browser-test session. Mirrors the
|
|
199
|
+
* Selenium driver defaults used by system-testing so supplying the list does not drop the
|
|
200
|
+
* headless container requirements, and adds pipe-mode devtools transport, which ChromeDriver
|
|
201
|
+
* recommends over the injected `--remote-debugging-port` and which keeps the Chrome instance
|
|
202
|
+
* alive until a session is created on headless container CI.
|
|
203
|
+
* @returns {string[]} - Chrome launch arguments.
|
|
204
|
+
*/
|
|
205
|
+
function browserTestChromeArguments() {
|
|
206
|
+
return [
|
|
207
|
+
"--disable-backgrounding-occluded-windows",
|
|
208
|
+
"--disable-background-timer-throttling",
|
|
209
|
+
"--disable-dev-shm-usage",
|
|
210
|
+
"--disable-gpu",
|
|
211
|
+
"--disable-renderer-backgrounding",
|
|
212
|
+
"--headless=new",
|
|
213
|
+
"--no-sandbox",
|
|
214
|
+
"--remote-debugging-pipe",
|
|
215
|
+
"--window-size=1920,1080"
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Builds the SystemTest factory used by BrowserTestSession so the Selenium builder path
|
|
221
|
+
* receives the pinned Chrome binary and the required headless container Chrome arguments.
|
|
222
|
+
* @param {object} [args] - Factory options.
|
|
223
|
+
* @param {string[]} [args.chromeArguments] - Chrome launch arguments.
|
|
224
|
+
* @param {boolean} [args.debug] - Whether SystemTest should emit debug output.
|
|
225
|
+
* @param {string} [args.httpHost] - HTTP host for the browser-test app.
|
|
226
|
+
* @param {number} [args.httpPort] - HTTP port for the browser-test app.
|
|
227
|
+
* @param {(config: BrowserTestSystemTestConfig) => BrowserTestSystemTest} [args.systemTestCurrent] - SystemTest factory.
|
|
228
|
+
* @returns {(args: {browserPath: string, remoteUrl: string}) => BrowserTestSystemTest} - SystemTest factory.
|
|
229
|
+
*/
|
|
230
|
+
export function buildBrowserTestSystemTestFactory({
|
|
231
|
+
chromeArguments = browserTestChromeArguments(),
|
|
232
|
+
debug = false,
|
|
233
|
+
httpHost = "127.0.0.1",
|
|
234
|
+
httpPort = 1984,
|
|
235
|
+
systemTestCurrent = SystemTest.current
|
|
236
|
+
} = {}) {
|
|
237
|
+
return ({browserPath}) => systemTestCurrent({
|
|
238
|
+
debug,
|
|
239
|
+
driver: {
|
|
240
|
+
type: "selenium",
|
|
241
|
+
options: {chromeArguments, chromeBinaryPath: browserPath}
|
|
242
|
+
},
|
|
243
|
+
httpHost,
|
|
244
|
+
httpPort
|
|
245
|
+
})
|
|
246
|
+
}
|
|
247
|
+
|
|
188
248
|
/**
|
|
189
249
|
* Formats a child process exit.
|
|
190
250
|
* @param {{code: number | null, error?: Error, signal: NodeJS.Signals | null}} result - Exit result.
|
package/scripts/test-browser.js
CHANGED
|
@@ -5,7 +5,6 @@ import path from "node:path"
|
|
|
5
5
|
import {pathToFileURL} from "node:url"
|
|
6
6
|
import {build} from "esbuild"
|
|
7
7
|
import initSqlJs from "sql.js"
|
|
8
|
-
import SystemTest from "system-testing/build/system-test.js"
|
|
9
8
|
import Application from "../src/application.js"
|
|
10
9
|
import Configuration from "../src/configuration.js"
|
|
11
10
|
import BrowserEnvironmentHandler from "../src/environment-handlers/browser.js"
|
|
@@ -22,6 +21,7 @@ import dummyDirectory from "../spec/dummy/dummy-directory.js"
|
|
|
22
21
|
import {withSourcePeerPackage} from "../src/environment-handlers/node/source-peer-package.js"
|
|
23
22
|
import {
|
|
24
23
|
BrowserTestSession,
|
|
24
|
+
buildBrowserTestSystemTestFactory,
|
|
25
25
|
loadOrPrewarmBrowserTestChromeRuntime,
|
|
26
26
|
stopBrowserTestSession
|
|
27
27
|
} from "./browser-test-session.js"
|
|
@@ -405,12 +405,8 @@ async function runBrowserTests() {
|
|
|
405
405
|
backendApplication = await startBrowserBackendServer(backendConfiguration, browserBackendPort)
|
|
406
406
|
browserTestSession = new BrowserTestSession({
|
|
407
407
|
runtime: chromeRuntime,
|
|
408
|
-
systemTestFactory: ({
|
|
408
|
+
systemTestFactory: buildBrowserTestSystemTestFactory({
|
|
409
409
|
debug: process.env.SYSTEM_TEST_DEBUG === "true",
|
|
410
|
-
driver: {
|
|
411
|
-
type: "selenium",
|
|
412
|
-
options: {chromeBinaryPath: browserPath}
|
|
413
|
-
},
|
|
414
410
|
httpHost: systemTestHttpHost,
|
|
415
411
|
httpPort: systemTestHttpPort
|
|
416
412
|
})
|
package/src/configuration.js
CHANGED
|
@@ -364,6 +364,15 @@ export default class VelociousConfiguration {
|
|
|
364
364
|
*/
|
|
365
365
|
this._websocketChannelSubscriptions = new Map()
|
|
366
366
|
|
|
367
|
+
/**
|
|
368
|
+
* In-flight local (per-process) websocket channel broadcast deliveries,
|
|
369
|
+
* launched fire-and-forget from `_broadcastToChannelLocal` so one slow
|
|
370
|
+
* subscriber never blocks another. Tracked here so
|
|
371
|
+
* `awaitPendingBroadcasts` can snapshot and drain them before settling.
|
|
372
|
+
* Settled deliveries are removed by the tracking-level cleanup.
|
|
373
|
+
* @type {Set<Promise<void>>} */
|
|
374
|
+
this._localBroadcastDeliveries = new Set()
|
|
375
|
+
|
|
367
376
|
/**
|
|
368
377
|
* Stores the websocket sessions value.
|
|
369
378
|
* @type {Set<import("./http-server/client/websocket-session.js").default>} - Live websocket sessions, including paused sessions within the grace window.
|
|
@@ -2810,8 +2819,13 @@ export default class VelociousConfiguration {
|
|
|
2810
2819
|
const websocketEvents = this._websocketEvents
|
|
2811
2820
|
|
|
2812
2821
|
if (websocketEvents && typeof websocketEvents.awaitPendingBroadcasts === "function") {
|
|
2822
|
+
// Drain the host/worker publish queues (including event-log persistence)
|
|
2823
|
+
// before draining local deliveries, because host dispatch launches the
|
|
2824
|
+
// local deliveries synchronously and they must be part of the snapshot.
|
|
2813
2825
|
await websocketEvents.awaitPendingBroadcasts()
|
|
2814
2826
|
}
|
|
2827
|
+
|
|
2828
|
+
await this._awaitLocalBroadcastDeliveries()
|
|
2815
2829
|
}
|
|
2816
2830
|
|
|
2817
2831
|
/**
|
|
@@ -2845,7 +2859,7 @@ export default class VelociousConfiguration {
|
|
|
2845
2859
|
|
|
2846
2860
|
if (!matches) continue
|
|
2847
2861
|
|
|
2848
|
-
|
|
2862
|
+
const delivery = this.withoutCurrentConnectionContexts(() => {
|
|
2849
2863
|
return Promise
|
|
2850
2864
|
.resolve()
|
|
2851
2865
|
.then(() => this._deliverWebsocketChannelBroadcast(subscription, body, {eventId: meta?.eventId}))
|
|
@@ -2853,9 +2867,35 @@ export default class VelociousConfiguration {
|
|
|
2853
2867
|
console.error(`broadcastToChannel: ${name} subscription ${subscription.subscriptionId} deliverBroadcast threw`, error)
|
|
2854
2868
|
})
|
|
2855
2869
|
})
|
|
2870
|
+
|
|
2871
|
+
// Keep the fire-and-forget delivery (never awaited at broadcast time) but
|
|
2872
|
+
// track it so `awaitPendingBroadcasts` can drain it before settling. Remove
|
|
2873
|
+
// on settle; the failure handler also satisfies the promise so a rejected
|
|
2874
|
+
// delivery never becomes an unhandled rejection.
|
|
2875
|
+
this._localBroadcastDeliveries.add(delivery)
|
|
2876
|
+
|
|
2877
|
+
delivery.then(
|
|
2878
|
+
() => { this._localBroadcastDeliveries.delete(delivery) },
|
|
2879
|
+
() => { this._localBroadcastDeliveries.delete(delivery) }
|
|
2880
|
+
)
|
|
2856
2881
|
}
|
|
2857
2882
|
}
|
|
2858
2883
|
|
|
2884
|
+
/**
|
|
2885
|
+
* Awaits a snapshot of the in-flight local (per-process) websocket channel
|
|
2886
|
+
* broadcast deliveries. Called from `awaitPendingBroadcasts` after the host
|
|
2887
|
+
* publish queues drain, so every delivery those queues launched is captured.
|
|
2888
|
+
* New deliveries enqueued after the snapshot are not awaited. Individual
|
|
2889
|
+
* delivery errors are isolated per subscriber — the delivery chain already
|
|
2890
|
+
* logs them and resolves — so a snapshotted rejection never fails this barrier.
|
|
2891
|
+
* @returns {Promise<void>}
|
|
2892
|
+
*/
|
|
2893
|
+
async _awaitLocalBroadcastDeliveries() {
|
|
2894
|
+
const snapshot = [...this._localBroadcastDeliveries]
|
|
2895
|
+
|
|
2896
|
+
await Promise.allSettled(snapshot)
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2859
2899
|
/**
|
|
2860
2900
|
* Runs deliver websocket channel broadcast.
|
|
2861
2901
|
* @param {import("./http-server/websocket-channel.js").default} subscription - Channel subscription.
|
|
@@ -1456,14 +1456,15 @@ export default class TestRunner {
|
|
|
1456
1456
|
* @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */
|
|
1457
1457
|
const consoleObject = /** @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */ (console)
|
|
1458
1458
|
/**
|
|
1459
|
-
* Original console methods
|
|
1459
|
+
* Original console methods captured as direct references so stopping restores
|
|
1460
|
+
* the exact method that was installed at capture start.
|
|
1460
1461
|
* @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */
|
|
1461
1462
|
const originalConsoleMethods = {
|
|
1462
|
-
debug: consoleObject.debug
|
|
1463
|
-
error: consoleObject.error
|
|
1464
|
-
info: consoleObject.info
|
|
1465
|
-
log: consoleObject.log
|
|
1466
|
-
warn: consoleObject.warn
|
|
1463
|
+
debug: consoleObject.debug,
|
|
1464
|
+
error: consoleObject.error,
|
|
1465
|
+
info: consoleObject.info,
|
|
1466
|
+
log: consoleObject.log,
|
|
1467
|
+
warn: consoleObject.warn
|
|
1467
1468
|
}
|
|
1468
1469
|
let stopped = false
|
|
1469
1470
|
let outputText = ""
|
|
@@ -1473,7 +1474,7 @@ export default class TestRunner {
|
|
|
1473
1474
|
lines.push(`[${new Date().toISOString()}] [${methodName}] ${format(...args)}`)
|
|
1474
1475
|
|
|
1475
1476
|
if (passthrough) {
|
|
1476
|
-
originalConsoleMethods[methodName](
|
|
1477
|
+
originalConsoleMethods[methodName].apply(consoleObject, args)
|
|
1477
1478
|
}
|
|
1478
1479
|
}
|
|
1479
1480
|
}
|