Skip to content

Commit 9cbf183

Browse files
committed
Add remote HTTP auth e2e
1 parent 50e7631 commit 9cbf183

1 file changed

Lines changed: 66 additions & 1 deletion

File tree

tests/e2e/e2e.spec.ts

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os from 'node:os';
22
import path from 'node:path';
33
import fs from 'node:fs/promises';
4-
import type { Page } from '@playwright/test';
4+
import type { APIRequestContext, Page } from '@playwright/test';
55
import { expect, test } from '@playwright/test';
66

77
const HOME_DIR = os.homedir();
@@ -11,6 +11,8 @@ const TAB_STABILITY_DIRS = [
1111
path.join(HOME_DIR, 'coder-studio-e2e-tab-b'),
1212
];
1313
const TAB_STABILITY_LABELS = TAB_STABILITY_DIRS.map((dir) => path.basename(dir));
14+
const REMOTE_HTTP_HOST = 'coder-studio.test';
15+
const REMOTE_HTTP_PASSWORD = 'demo-passphrase';
1416

1517
const gotoWorkspaceRoot = async (page: Page) => {
1618
await Promise.all([
@@ -65,6 +67,30 @@ const invokeRpc = async <T>(page: Page, command: string, payload: Record<string,
6567
return body.data as T;
6668
};
6769

70+
const patchSystemConfig = async (request: APIRequestContext, updates: Record<string, unknown>) => {
71+
const response = await request.patch('http://127.0.0.1:4173/api/system/config', {
72+
data: { updates },
73+
});
74+
expect(response.ok()).toBeTruthy();
75+
const body = await response.json();
76+
expect(body.ok).not.toBe(false);
77+
return body.data as {
78+
config: {
79+
root: { path?: string | null };
80+
};
81+
};
82+
};
83+
84+
const readSystemConfig = async (request: APIRequestContext) => {
85+
const response = await request.get('http://127.0.0.1:4173/api/system/config');
86+
expect(response.ok()).toBeTruthy();
87+
const body = await response.json();
88+
expect(body.ok).not.toBe(false);
89+
return body.data as {
90+
root: { path?: string | null };
91+
};
92+
};
93+
6894
const launchWorkspaceByPath = async (page: Page, workspacePath: string) => {
6995
await invokeRpc(page, 'launch_workspace', {
7096
source: {
@@ -170,3 +196,42 @@ test('workspace tabs keep a stable order when switching between workspaces', asy
170196
await expect(page.locator('.workspace-top-tab.active .session-top-label')).toHaveText(TAB_STABILITY_LABELS[1]);
171197
await expect.poll(() => readWorkspaceTabLabels(page)).toEqual(initialOrder);
172198
});
199+
200+
test('release runtime allows sign-in from a remote HTTP host', async ({ page, request, baseURL }) => {
201+
test.skip(!baseURL?.includes(':4173'), 'Release runtime only');
202+
203+
const currentConfig = await readSystemConfig(request);
204+
const originalRootPath = currentConfig.root.path ?? null;
205+
206+
try {
207+
await patchSystemConfig(request, {
208+
'auth.password': REMOTE_HTTP_PASSWORD,
209+
'root.path': process.cwd(),
210+
});
211+
212+
await page.route('**/*', async (route) => {
213+
await route.continue({
214+
headers: {
215+
...route.request().headers(),
216+
'x-forwarded-host': REMOTE_HTTP_HOST,
217+
'x-forwarded-proto': 'http',
218+
},
219+
});
220+
});
221+
222+
await page.goto('/?auth=force');
223+
await expect(page.getByRole('heading', { name: 'Unlock Coder Studio' })).toBeVisible();
224+
await expect(page.getByText('HTTPS is required on this host')).toHaveCount(0);
225+
226+
await page.getByPlaceholder('Enter passphrase').fill(REMOTE_HTTP_PASSWORD);
227+
await page.getByRole('button', { name: 'Enter workspace' }).click();
228+
229+
await expect(page.getByTestId('overlay')).toBeVisible();
230+
await expect(page.getByTestId('folder-select')).toBeVisible();
231+
} finally {
232+
await patchSystemConfig(request, {
233+
'auth.password': null,
234+
'root.path': originalRootPath,
235+
});
236+
}
237+
});

0 commit comments

Comments
 (0)