From a58dadf202fc56c149e5e75ab6946eea0b38cbf0 Mon Sep 17 00:00:00 2001 From: Stefan Stidl Date: Fri, 11 Sep 2026 20:54:25 +0200 Subject: [PATCH] fix: support SERVER_LIST_URL in classic frontend --- docker/entrypoint.sh | 2 +- tests/e2e/modes.spec.js | 55 ++++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index cdc8e80..8fe1987 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -105,7 +105,7 @@ if [[ "$MODE" == "frontend" || "$MODE" == "dual" || "$MODE" == "standalone" ]]; echo "using SERVER_LIST_URL for frontend server list" SERVER_LIST_URL_ESCAPED=$(printf '%s\n' "$SERVER_LIST_URL" | sed 's/[&/\\]/\\&/g; s/\$/\\$/g') sed -i "s/var SPEEDTEST_SERVERS = \"server-list.json\";/var SPEEDTEST_SERVERS = \"$SERVER_LIST_URL_ESCAPED\";/" /var/www/html/index-modern.html - sed -i "s/var SPEEDTEST_SERVERS = \\[/var SPEEDTEST_SERVERS = \"$SERVER_LIST_URL_ESCAPED\";\\n\\t\\t\\/\\*/" /var/www/html/index-classic.html + sed -i "/var SPEEDTEST_SERVERS = \\[/,/^[[:space:]]*];/c\\\t\tvar SPEEDTEST_SERVERS = \"$SERVER_LIST_URL_ESCAPED\";" /var/www/html/index-classic.html sed -i "s/var SPEEDTEST_SERVERS = \"server-list.json\";/var SPEEDTEST_SERVERS = \"$SERVER_LIST_URL_ESCAPED\";/" /var/www/html/stability.html fi diff --git a/tests/e2e/modes.spec.js b/tests/e2e/modes.spec.js index c714832..cb931d8 100644 --- a/tests/e2e/modes.spec.js +++ b/tests/e2e/modes.spec.js @@ -1,59 +1,59 @@ -const { test, expect } = require('@playwright/test'); -const { baseUrls } = require('./helpers/env'); -const { modernStartButton } = require('./helpers/ui'); +const { test, expect } = require("@playwright/test"); +const { baseUrls } = require("./helpers/env"); +const { modernStartButton, classicStartButton } = require("./helpers/ui"); -const defaultTagline = 'No Flash, No Java, No Websockets, No Bullsh*t'; -const frontendRemoteServerListUrl = 'http://127.0.0.1:18184/tests/e2e/fixtures/servers-frontend-remote.json'; +const defaultTagline = "No Flash, No Java, No Websockets, No Bullsh*t"; +const frontendRemoteServerListUrl = "http://127.0.0.1:18184/tests/e2e/fixtures/servers-frontend-remote.json"; -test.describe('Runtime mode smoke coverage', () => { - test('standalone exposes UI and local backend endpoints', async ({ page, request }) => { +test.describe("Runtime mode smoke coverage", () => { + test("standalone exposes UI and local backend endpoints", async ({ page, request }) => { const root = await request.get(`${baseUrls.standalone}/`); expect(root.ok()).toBeTruthy(); const index = await request.get(`${baseUrls.standalone}/index.html`); expect(index.ok()).toBeTruthy(); - await expect(await index.text()).toContain('design-switch.js'); + await expect(await index.text()).toContain("design-switch.js"); - for (const endpoint of ['/backend/empty.php', '/backend/garbage.php', '/backend/getIP.php']) { + for (const endpoint of ["/backend/empty.php", "/backend/garbage.php", "/backend/getIP.php"]) { const response = await request.get(`${baseUrls.standalone}${endpoint}`); expect(response.ok()).toBeTruthy(); } await page.goto(`${baseUrls.standalone}/index-modern.html`); await expect(modernStartButton(page)).toBeVisible(); - await expect(page.locator('main > p.tagline')).toHaveText(defaultTagline); + await expect(page.locator("main > p.tagline")).toHaveText(defaultTagline); }); - test('Alpine standalone serves modern frontend settings', async ({ page, request }) => { + test("Alpine standalone serves modern frontend settings", async ({ page, request }) => { const settings = await request.get(`${baseUrls.standaloneAlpine}/settings.json`); expect(settings.ok()).toBeTruthy(); - await expect(settings.json()).resolves.toMatchObject({ telemetry_level: 'off', time_dl_max: 12 }); + await expect(settings.json()).resolves.toMatchObject({ telemetry_level: "off", time_dl_max: 12 }); await page.goto(`${baseUrls.standaloneAlpine}/index-modern.html`); await expect(modernStartButton(page)).toBeVisible(); }); - test('backend exposes only local backend contract endpoints', async ({ request }) => { - for (const endpoint of ['/empty.php', '/garbage.php', '/getIP.php']) { + test("backend exposes only local backend contract endpoints", async ({ request }) => { + for (const endpoint of ["/empty.php", "/garbage.php", "/getIP.php"]) { const response = await request.get(`${baseUrls.backend}${endpoint}`); expect(response.ok()).toBeTruthy(); } }); - test('frontend serves UI and server list without local backend contract', async ({ page, request }) => { + test("frontend serves UI and server list without local backend contract", async ({ page, request }) => { const serverList = await request.get(`${baseUrls.frontend}/server-list.json`); expect(serverList.ok()).toBeTruthy(); - await expect(await serverList.text()).toContain('Backend testpoint'); + await expect(await serverList.text()).toContain("Backend testpoint"); const localBackendEndpoint = await request.get(`${baseUrls.frontend}/backend/empty.php`); expect(localBackendEndpoint.status()).toBe(404); await page.goto(`${baseUrls.frontend}/index-modern.html`); await expect(modernStartButton(page)).toBeVisible(); - await expect(page.locator('#selected-server')).not.toHaveText(/searching nearest server/i); + await expect(page.locator("#selected-server")).not.toHaveText(/searching nearest server/i); }); - test('frontend starts with SERVER_LIST_URL without requiring /servers.json', async ({ page, request }) => { + test("frontend starts with SERVER_LIST_URL without requiring /servers.json", async ({ page, request }) => { const index = await request.get(`${baseUrls.frontendRemote}/index-modern.html`); expect(index.ok()).toBeTruthy(); await expect(await index.text()).toContain(frontendRemoteServerListUrl); @@ -67,15 +67,26 @@ test.describe('Runtime mode smoke coverage', () => { await page.goto(`${baseUrls.frontendRemote}/index-modern.html`); await expect(modernStartButton(page)).toBeVisible(); - await expect(page.locator('#selected-server')).toContainText('Remote frontend backend', { timeout: 10_000 }); + await expect(page.locator("#selected-server")).toContainText("Remote frontend backend", { timeout: 10_000 }); }); - test('dual combines frontend and local backend availability', async ({ page, request }) => { + test("default entrypoint loads the classic frontend with SERVER_LIST_URL", async ({ page }) => { + const pageErrors = []; + page.on("pageerror", error => pageErrors.push(error.message)); + + await page.goto(`${baseUrls.frontendRemote}/index.html`); + await page.waitForURL(/index-classic\.html/); + await expect(classicStartButton(page)).toBeVisible(); + await expect(page.locator("#server")).toContainText("Remote frontend backend", { timeout: 10_000 }); + expect(pageErrors).toEqual([]); + }); + + test("dual combines frontend and local backend availability", async ({ page, request }) => { const serverList = await request.get(`${baseUrls.dual}/server-list.json`); expect(serverList.ok()).toBeTruthy(); - await expect(await serverList.text()).toContain('Local dual backend'); + await expect(await serverList.text()).toContain("Local dual backend"); - for (const endpoint of ['/backend/empty.php', '/backend/garbage.php', '/backend/getIP.php']) { + for (const endpoint of ["/backend/empty.php", "/backend/garbage.php", "/backend/getIP.php"]) { const response = await request.get(`${baseUrls.dual}${endpoint}`); expect(response.ok()).toBeTruthy(); }