feat: accept sourceUrl parameter in connectWebSocket for remote sessions (task-6)

🤖 Generated with Amplifier
This commit is contained in:
Amplifier
2026-03-31 03:27:30 -07:00
committed by Brian Krabach
parent d955c90c0b
commit 3444310bb2
2 changed files with 89 additions and 5 deletions
+15 -5
View File
@@ -11,9 +11,16 @@ let _vpHandler = null;
// ─── Forward declarations ─────────────────────────────────────────────────────
function connectWebSocket(name) {
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
const url = `${proto}//${location.host}/terminal/ws`;
function connectWebSocket(name, sourceUrl) {
var url;
if (sourceUrl) {
// Remote session: derive WS URL from the source's HTTP URL
url = sourceUrl.replace(/^http/, 'ws').replace(/\/+$/, '') + '/terminal/ws';
} else {
// Local session: same origin
var proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
url = proto + '//' + location.host + '/terminal/ws';
}
const reconnectOverlay = document.getElementById('reconnect-overlay');
const encoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;
@@ -175,8 +182,11 @@ function createTerminal() {
/**
* Open a terminal session inside #terminal-container.
* @param {string} sessionName
* @param {string} [sourceUrl] Optional HTTP URL of the remote muxplex instance.
* When provided, the WebSocket connects to that remote host instead of the
* current page origin.
*/
function openTerminal(sessionName) {
function openTerminal(sessionName, sourceUrl) {
// Null _currentSession first so any in-flight close handler on the old WS won't
// schedule a reconnect (it checks `if (!_currentSession) return;`).
_currentSession = null;
@@ -222,7 +232,7 @@ function openTerminal(sessionName) {
});
}
connectWebSocket(sessionName);
connectWebSocket(sessionName, sourceUrl);
initVisualViewport(); /* defined in Task 14 */
}
+74
View File
@@ -719,6 +719,80 @@ test('terminal is auto-focused when WebSocket opens', () => {
'_term.focus() should be called exactly once when the WebSocket open event fires');
});
// --- sourceUrl / remote WebSocket tests ------------------------------------
test('connectWebSocket uses remote origin when sourceUrl is provided', () => {
const t = loadTerminal();
const orig = globalThis.setTimeout;
globalThis.setTimeout = (_fn, _ms) => 0;
t.openTerminal('remote-session', 'http://work:8088');
globalThis.setTimeout = orig;
assert.ok(t.capturedWsUrl, 'WebSocket URL should have been captured');
assert.ok(
t.capturedWsUrl.startsWith('ws://work:8088/'),
`WebSocket URL should start with ws://work:8088/, got: ${t.capturedWsUrl}`,
);
assert.ok(
t.capturedWsUrl.endsWith('/terminal/ws'),
`WebSocket URL should end with /terminal/ws, got: ${t.capturedWsUrl}`,
);
});
test('connectWebSocket uses local origin when sourceUrl is empty string', () => {
const t = loadTerminal();
const orig = globalThis.setTimeout;
globalThis.setTimeout = (_fn, _ms) => 0;
t.openTerminal('local-session', '');
globalThis.setTimeout = orig;
assert.ok(t.capturedWsUrl, 'WebSocket URL should have been captured');
assert.ok(
t.capturedWsUrl.includes('localhost'),
`WebSocket URL should include localhost for empty sourceUrl, got: ${t.capturedWsUrl}`,
);
});
test('connectWebSocket uses local origin when sourceUrl is undefined', () => {
const t = loadTerminal();
const orig = globalThis.setTimeout;
globalThis.setTimeout = (_fn, _ms) => 0;
t.openTerminal('local-session');
globalThis.setTimeout = orig;
assert.ok(t.capturedWsUrl, 'WebSocket URL should have been captured');
assert.ok(
t.capturedWsUrl.includes('localhost'),
`WebSocket URL should include localhost when sourceUrl is undefined, got: ${t.capturedWsUrl}`,
);
});
test('connectWebSocket converts https sourceUrl to wss protocol', () => {
const t = loadTerminal();
const orig = globalThis.setTimeout;
globalThis.setTimeout = (_fn, _ms) => 0;
t.openTerminal('secure-session', 'https://devserver:8088');
globalThis.setTimeout = orig;
assert.ok(t.capturedWsUrl, 'WebSocket URL should have been captured');
assert.ok(
t.capturedWsUrl.startsWith('wss://devserver:8088/'),
`WebSocket URL should start with wss://devserver:8088/, got: ${t.capturedWsUrl}`,
);
});
// --- Android touch scroll ---------------------------------------------------
test('terminal.js Android touch scroll is UA-gated', () => {