Skip to content

Commit 2f6ced0

Browse files
fix(ui): redirect to session hub when no sessions exist (#122)
When the terminal page (`/terminal`) has no sessions — on initial load, after the last session ends, or when polling detects all sessions are gone — it previously showed a dead-end "No sessions" label with no way forward. Now it redirects to the session hub (`/`) using `location.replace()` so users land on the proper empty state with a "+ New Session" button, without polluting browser history. **Changes:** - Replace three `window.location.href` dead-end states in `terminal.html` with `window.location.replace('/')` - Add `test/e2e-empty-sessions.test.js` — Playwright E2E test covering the redirect Closes #121 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent b0c6e47 commit 2f6ced0

2 files changed

Lines changed: 55 additions & 14 deletions

File tree

public/terminal.html

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,9 +2497,8 @@ <h3>
24972497

24982498
if (startId) activateSession(startId);
24992499
else {
2500-
sessionNameEl.textContent = 'No sessions';
2501-
statusText.textContent = '';
2502-
document.getElementById('stop-btn').style.display = 'none';
2500+
window.location.replace('/');
2501+
return;
25032502
}
25042503

25052504
renderTabs();
@@ -3139,11 +3138,8 @@ <h3>
31393138
const remaining = [...managed.keys()];
31403139
if (remaining.length > 0) activateSession(remaining[0]);
31413140
else {
3142-
activeId = null;
3143-
sessionNameEl.textContent = 'No sessions';
3144-
statusText.textContent = '';
3145-
statusDot.className = '';
3146-
document.getElementById('stop-btn').style.display = 'none';
3141+
window.location.replace('/');
3142+
return;
31473143
}
31483144
}
31493145
renderTabs();
@@ -4232,12 +4228,8 @@ <h3>
42324228
const remaining = [...managed.keys()];
42334229
if (remaining.length > 0) activateSession(remaining[0]);
42344230
else {
4235-
activeId = null;
4236-
sessionNameEl.textContent = 'No sessions';
4237-
statusText.textContent = '';
4238-
statusDot.className = '';
4239-
document.getElementById('stop-btn').style.display = 'none';
4240-
reconnectOverlay.classList.remove('visible');
4231+
window.location.replace('/');
4232+
return;
42414233
}
42424234
}
42434235
}

test/e2e-empty-sessions.test.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* E2E test — redirect to session hub when /terminal has no sessions.
3+
*
4+
* Run: npx playwright test test/e2e-empty-sessions.test.js
5+
*/
6+
const { test, expect } = require('@playwright/test');
7+
const { createTermBeamServer } = require('../src/server');
8+
9+
const baseConfig = {
10+
port: 0,
11+
host: '127.0.0.1',
12+
password: null,
13+
useTunnel: false,
14+
persistedTunnel: false,
15+
shell: process.platform === 'win32' ? 'cmd.exe' : '/bin/bash',
16+
shellArgs: [],
17+
cwd: process.cwd(),
18+
defaultShell: process.platform === 'win32' ? 'cmd.exe' : '/bin/bash',
19+
version: '0.1.0-test',
20+
logLevel: 'error',
21+
};
22+
23+
let inst;
24+
25+
test.beforeEach(async () => {
26+
inst = createTermBeamServer({ config: { ...baseConfig } });
27+
await inst.start();
28+
});
29+
30+
test.afterEach(async () => {
31+
if (inst) await inst.shutdown();
32+
});
33+
34+
test('redirects from /terminal to session hub when no sessions exist', async ({ page }) => {
35+
const port = inst.server.address().port;
36+
const base = `http://127.0.0.1:${port}`;
37+
38+
// Delete all sessions so the terminal page has nothing to show
39+
const res = await page.request.get(`${base}/api/sessions`);
40+
const sessions = await res.json();
41+
for (const s of sessions) {
42+
await page.request.delete(`${base}/api/sessions/${s.id}`);
43+
}
44+
45+
// Navigate to /terminal — should redirect to /
46+
await page.goto(`${base}/terminal`);
47+
await expect(page).toHaveURL(`${base}/`, { timeout: 5_000 });
48+
await expect(page.locator('.empty-state')).toBeVisible();
49+
});

0 commit comments

Comments
 (0)