- updater-fallback.mjs (82 assertions): GitHub probe fallback to Gitea, timeout budgets, in-flight check never stuck in 'checking'; updater.ts gains a setUpdateTimeouts test seam, electron-updater aliased to a stub - ipc-guard.mjs (43): trusted-frame guard exercised through real registerIpc handlers with forged senderFrames; electron-stub now records registrations via globalThis so bundle and test share one instance - log-sanitizer.mjs (71): CSI/OSC/charset state machine, alt-screen fold, byte-split fuzz equal to whole-chunk output; fixes a wrong comment - sftp-timeout.mjs (39): per-op timeouts (metadata 30s, transfer chunk 60s, open 10s) evict half-dead channels with one retry, slow-but-progressing transfers untouched, late rejections never unhandled - reservedAccelerators.ts: single pure isReservedAccelerator shared by the settings recorder and applyGlobalShortcut (the two tables had drifted — main now also refuses Ctrl+=/-/0/PgUp/PgDn legacy values); 56 assertions - ssh-loopback.mjs loads the real ssh.ts via a bundle (50 assertions): TOFU pinning, fail-closed stores, auth gate, connect budget Offline suite grows 13 -> 17. Renderer test framework evaluated: not introducing vitest/jsdom; pure logic keeps being extracted and tested through the existing bundle harness.
89 lines
4.7 KiB
JavaScript
89 lines
4.7 KiB
JavaScript
/* Rebuild every esbuild bundle the tests load, so a test run can never exercise
|
|
a stale bundle. `npm test` calls this first; run it standalone when you only
|
|
want fresh bundles.
|
|
|
|
The aliases live here (and nowhere else) so every bundle resolves `electron`
|
|
and `@shared` the same way. A bundle built without
|
|
`--alias:@shared=./src/shared` does not even compile: pty.ts reaches
|
|
@shared/theme through settingsStore.ts -> windowChrome.ts.
|
|
|
|
Usage: node tests/build-bundles.cjs */
|
|
const path = require('node:path')
|
|
const esbuild = require('esbuild')
|
|
|
|
const ROOT = path.join(__dirname, '..')
|
|
|
|
/** Loader tweaks every bundle shares: `?asset` imports land on text loaders. */
|
|
const LOADERS = { '.png': 'text' }
|
|
|
|
const BUNDLES = [
|
|
// Real session layer: pty.ts also re-exports the ssh + sysinfo engines.
|
|
{ entry: 'src/main/pty.ts', out: 'tests/.session-e2e.cjs', external: ['@lydell/node-pty', 'ssh2'] },
|
|
// The real SSH service on its own (no electron surface at all), so the
|
|
// loopback harness can exercise the shipped connect/verify/shell code
|
|
// instead of a hand-copied ConnectConfig.
|
|
{ entry: 'src/main/ssh.ts', out: 'tests/.ssh.cjs', external: ['ssh2'] },
|
|
// ESM (`.mjs`): tests/sftp-*.mjs load it with `await import()`.
|
|
{ entry: 'src/main/sftp.ts', out: 'tests/.sftp-svc.mjs', format: 'esm', external: ['ssh2'] },
|
|
{ entry: 'src/main/commands.ts', out: 'tests/.commands-store.cjs' },
|
|
// SSH bookmarks store: CRUD, the public/secret split, corrupt-file backup.
|
|
// Its electron surface is `safeStorage` (already in the stub, unavailable ->
|
|
// the store's `plain:` dev fallback).
|
|
{ entry: 'src/main/connectionsStore.ts', out: 'tests/.connections-store.cjs' },
|
|
// Known-hosts store: TOFU / changed / unreadable fail-closed behavior.
|
|
{ entry: 'src/main/knownHosts.ts', out: 'tests/.known-hosts.cjs' },
|
|
{ entry: 'src/main/settingsStore.ts', out: 'tests/.settings-store.cjs' },
|
|
// Local-path admission (grants): pure fs/path, no electron surface at all.
|
|
{ entry: 'src/main/localPathGrants.ts', out: 'tests/.local-path-grants.cjs' },
|
|
// Lock-password store: scrypt verifier, round trip, damaged-file handling.
|
|
{ entry: 'src/main/lockStore.ts', out: 'tests/.lock-store.cjs' },
|
|
// Lock controller: cooldown ladder, serialized attempts, persisted flags.
|
|
// Pulls in settingsStore + broadcast, which is why the electron stub needs
|
|
// powerMonitor as well.
|
|
{ entry: 'src/main/lockController.ts', out: 'tests/.lock-controller.cjs' },
|
|
// Lock keyboard classifier: pure, so the bundle needs no electron surface.
|
|
{ entry: 'src/main/lockShortcuts.ts', out: 'tests/.lock-shortcuts.cjs' },
|
|
// Reserved-accelerator table shared by the settings recorder and main's
|
|
// registration guard: pure, table-tested.
|
|
{ entry: 'src/shared/reservedAccelerators.ts', out: 'tests/.reserved-accelerators.cjs' },
|
|
// Update service: feed probe/fallback. `electron-updater` is aliased to a
|
|
// stub (the real package boots Electron), and the shell half (tray.ts) pulls
|
|
// a `?asset` import, hence LOADERS.
|
|
{ entry: 'src/main/updater.ts', out: 'tests/.updater.cjs', alias: { 'electron-updater': './tests/electron-updater-stub.cjs' } },
|
|
// IPC sender-frame guard: driven through the real registerIpc registration
|
|
// path (the stub records handlers instead of dropping them).
|
|
{
|
|
entry: 'src/main/ipc.ts',
|
|
out: 'tests/.ipc.cjs',
|
|
external: ['ssh2', '@lydell/node-pty', 'font-list', 'cpu-features']
|
|
},
|
|
// Session-log plain-text transformer: ANSI state machine + alt-screen folding.
|
|
{ entry: 'src/main/logSanitizer.ts', out: 'tests/.log-sanitizer.cjs' },
|
|
// Channel-name constants, so a test can name channels instead of inlining
|
|
// string literals that would silently drift from src/shared/ipc.ts.
|
|
{ entry: 'src/shared/ipc.ts', out: 'tests/.ipc-channels.cjs' },
|
|
// zmodem.js stays bundled (NOT external) — the test drives a second in-process
|
|
// Sentry from the same library.
|
|
{ entry: 'src/main/zmodem.ts', out: 'tests/.zmodem-e2e.cjs', external: ['ssh2'] },
|
|
// The smoke test imports the renderer engine (.ts), so it needs bundling too.
|
|
{ entry: 'tests/hl-split-smoke.mjs', out: 'tests/.hl-split-smoke.cjs' },
|
|
// Preset-rule assertions (word boundaries, case flag) over the same engine.
|
|
{ entry: 'tests/hl-rules.mjs', out: 'tests/.hl-rules.cjs' }
|
|
]
|
|
|
|
for (const { entry, out, format = 'cjs', external = [], alias = {} } of BUNDLES) {
|
|
esbuild.buildSync({
|
|
absWorkingDir: ROOT,
|
|
entryPoints: [path.join(ROOT, entry)],
|
|
outfile: path.join(ROOT, out),
|
|
bundle: true,
|
|
platform: 'node',
|
|
format,
|
|
external,
|
|
loader: LOADERS,
|
|
alias: { electron: './tests/electron-stub.cjs', '@shared': './src/shared', ...alias },
|
|
logLevel: 'warning'
|
|
})
|
|
console.log(`built ${out}`)
|
|
}
|