90 lines
3.9 KiB
JavaScript
90 lines
3.9 KiB
JavaScript
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');
|
|
const icon = await read('public/images/icons/route-management.svg');
|
|
|
|
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(html, /id="route-control-button"[\s\S]*?<img[^>]+route-management\.svg/);
|
|
assert.match(html, /id="editor-button"[^>]*>Strecken verwalten<\/button>/);
|
|
assert.match(icon, /C[^\"]+/);
|
|
assert.match(icon, /stroke-dasharray/);
|
|
|
|
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</);
|
|
|
|
assert.match(client, /activatedOnly:\s*['"]true['"]/);
|
|
assert.match(api, /publishedOnly:\s*req\.query\.activatedOnly\s*===\s*['"]true['"]/);
|
|
assert.match(app, /renderRouteItems\(\s*['"]#local-route-list['"]/);
|
|
assert.match(app, /renderRouteControlList\(\s*['"]#route-control-local-list['"]/);
|
|
assert.match(app, /ns\.LocalRoutes\.getAppRoute\(id\)/);
|
|
assert.match(app, /\[data-route-select\]/);
|
|
});
|
|
|
|
test('persistent route control displays the next unvisited POI and preserves progress when switching', async () => {
|
|
const app = await read('public/js/app.js');
|
|
|
|
assert.match(app, /function nextPoiMetric\(/);
|
|
assert.match(app, /Nächster Streckenpunkt:/);
|
|
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\(/);
|
|
});
|