feat: accept sourceUrl parameter in connectWebSocket for remote sessions (task-6)
🤖 Generated with Amplifier
This commit is contained in:
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
Reference in New Issue
Block a user