import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import path from 'node:path'; import test from 'node:test'; const root = path.resolve(import.meta.dirname, '..'); async function read(relativePath) { return fs.readFile(path.join(root, relativePath), 'utf8'); } test('main screen contains a persistent route control next to the information control', async () => { const html = await read('public/index.html'); const css = await read('public/css/editor.css'); assert.match(html, /class="route-control"/); assert.match(html, /id="route-control-button"/); assert.match(html, /id="route-control-dropdown"/); assert.match(html, /id="route-control-title"/); assert.match(html, /id="route-control-next"/); assert.match(html, /id="route-control-server-list"/); assert.match(html, /id="route-control-local-list"/); assert.match(html, /id="route-control-new"/); assert.match(html, /id="info-button"/); assert.match(css, /\.route-control\s*\{[\s\S]*position:\s*fixed/i); assert.match(css, /\.route-control\s*\{[\s\S]*right:\s*calc\([\s\S]*--icon-button-size/i); assert.match(css, /\.route-control-dropdown/); }); test('route selection separates activated server routes from local browser routes', async () => { const html = await read('public/index.html'); const app = await read('public/js/app.js'); const client = await read('public/js/api-client.js'); const api = await read('src/routes/api.js'); assert.match(html, /id="all-route-list"/); assert.match(html, /id="local-route-list"/); assert.match(html, />Lokale Strecken { const app = await read('public/js/app.js'); assert.match(app, /function nextPoiMetric\(/); assert.match(app, /Nächster POI:/); assert.match(app, /state\.triggered\.has\(poi\.id\)/); assert.match(app, /function suspendCurrentRoute\(/); assert.match(app, /persistRouteProgress\(\)/); assert.match(app, /await selectRoute/); }); test('local route storage is loaded independently from optional route progress storage', async () => { const html = await read('public/index.html'); const app = await read('public/js/app.js'); const localRoutes = await read('public/js/local-routes.js'); const localScript = html.indexOf('js/local-routes.js'); const editorScript = html.indexOf('js/editor-ui.js'); assert.ok(localScript >= 0 && editorScript > localScript, 'local route storage must load before the editor'); assert.match(localRoutes, /wegwichtel\.local-routes\.v1/); assert.match(localRoutes, /routeKey\(id, ['"]gpx['"]\)/); assert.match(localRoutes, /routeKey\(id, ['"]json['"]\)/); assert.match(localRoutes, /wegwichtel:local-routes-changed/); assert.match(app, /wegwichtel:local-routes-changed/); }); test('route selection remains pointer-oriented and avoids unsupported relational selectors', async () => { const app = await read('public/js/app.js'); const editor = await read('public/js/editor-ui.js'); assert.match(app, /pointerup/); assert.match(editor, /pointerup/); assert.doesNotMatch(editor, /addEventListener\(['"]click['"]/); assert.doesNotMatch(app, /:has\(/); });