fix: validate typed frontend startup in Chromium
This commit is contained in:
@@ -1590,7 +1590,7 @@ async function loadPlugins(group) {
|
||||
for (const path of pluginGroups[group]) await loadPlugin(path);
|
||||
}
|
||||
async function loadEagerPlugins() {
|
||||
await Promise.all(["digital-modes", "map-data", "bookmarks", "settings"].map(loadPlugins));
|
||||
await Promise.all(["digital-modes", "bookmarks", "settings"].map(loadPlugins));
|
||||
}
|
||||
async function loadPluginsForTab(tab) {
|
||||
await loadPlugins(tab);
|
||||
@@ -1892,7 +1892,7 @@ var centerFreqEl = requiredElement("center-freq");
|
||||
var wavelengthEl = requiredElement("wavelength");
|
||||
var sigStrengthEl = requiredElement("sig-strength");
|
||||
var modeEl = requiredElement("mode");
|
||||
var bandLabel = requiredElement("band-label");
|
||||
var bandLabel = document.getElementById("band-label");
|
||||
var powerBtn = requiredElement("power-btn");
|
||||
var powerHint = requiredElement("power-hint");
|
||||
var vfoPicker = requiredElement("vfo-picker");
|
||||
@@ -1912,7 +1912,7 @@ var loadingEl = requiredElement("loading");
|
||||
var contentEl = requiredElement("content");
|
||||
var serverSubtitle = requiredElement("server-subtitle");
|
||||
var rigSubtitle = requiredElement("rig-subtitle");
|
||||
var ownerSubtitle = requiredElement("owner-subtitle");
|
||||
var ownerSubtitle = document.getElementById("owner-subtitle");
|
||||
var locationSubtitle = requiredElement("location-subtitle");
|
||||
var loadingTitle = requiredElement("loading-title");
|
||||
var loadingSub = requiredElement("loading-sub");
|
||||
@@ -2241,7 +2241,7 @@ function setTheme(theme) {
|
||||
invalidateBookmarkColors();
|
||||
}
|
||||
function invalidateBookmarkColors() {
|
||||
const bookmarks = window.trx.modules.bookmarks;
|
||||
const bookmarks = window.trx?.modules.bookmarks;
|
||||
if (!bookmarks) return;
|
||||
bookmarks.invalidateColors();
|
||||
void getComputedStyle(document.documentElement).getPropertyValue("--bg");
|
||||
|
||||
@@ -26,8 +26,8 @@ npm run verify-generated
|
||||
|
||||
`npm run verify-generated` regenerates Rust wire contracts and browser bundles,
|
||||
then rejects drift from the committed files. The browser smoke test needs a
|
||||
local Chromium-family executable; set `CHROMIUM_PATH` when it is not installed
|
||||
at a conventional system path.
|
||||
local Chromium-family executable; set `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH`
|
||||
when it is not installed at `/usr/bin/chromium`.
|
||||
|
||||
Cargo consumes committed output under `../assets/web/generated`. It never
|
||||
invokes Node.js, installs packages, or accesses the network. After changing a
|
||||
|
||||
@@ -673,7 +673,7 @@ const centerFreqEl = requiredElement<HTMLInputElement>("center-freq");
|
||||
const wavelengthEl = requiredElement("wavelength");
|
||||
const sigStrengthEl = requiredElement("sig-strength");
|
||||
const modeEl = requiredElement<HTMLSelectElement>("mode");
|
||||
const bandLabel = requiredElement("band-label");
|
||||
const bandLabel = document.getElementById("band-label");
|
||||
const powerBtn = requiredElement<HTMLButtonElement>("power-btn");
|
||||
const powerHint = requiredElement("power-hint");
|
||||
const vfoPicker = requiredElement("vfo-picker");
|
||||
@@ -693,7 +693,7 @@ const loadingEl = requiredElement("loading");
|
||||
const contentEl = requiredElement("content");
|
||||
const serverSubtitle = requiredElement("server-subtitle");
|
||||
const rigSubtitle = requiredElement("rig-subtitle");
|
||||
const ownerSubtitle = requiredElement("owner-subtitle");
|
||||
const ownerSubtitle = document.getElementById("owner-subtitle");
|
||||
const locationSubtitle = requiredElement("location-subtitle");
|
||||
const loadingTitle = requiredElement("loading-title");
|
||||
const loadingSub = requiredElement("loading-sub");
|
||||
@@ -1063,7 +1063,7 @@ function setTheme(theme: string) {
|
||||
|
||||
// Recolour bookmark chips after any palette/theme change (setTheme or setStyle).
|
||||
function invalidateBookmarkColors() {
|
||||
const bookmarks = window.trx.modules.bookmarks;
|
||||
const bookmarks = window.trx?.modules.bookmarks;
|
||||
if (!bookmarks) return;
|
||||
bookmarks.invalidateColors();
|
||||
// Force the browser to recalculate styles so getComputedStyle reads new values.
|
||||
|
||||
@@ -37,7 +37,7 @@ async function loadPlugins(group: string): Promise<void> {
|
||||
}
|
||||
|
||||
export async function loadEagerPlugins(): Promise<void> {
|
||||
await Promise.all(["digital-modes", "map-data", "bookmarks", "settings"].map(loadPlugins));
|
||||
await Promise.all(["digital-modes", "bookmarks", "settings"].map(loadPlugins));
|
||||
}
|
||||
|
||||
export async function loadPluginsForTab(tab: string): Promise<void> {
|
||||
|
||||
@@ -17,6 +17,49 @@ const jsonRoutes = new Map([
|
||||
["/auth/session", { authenticated: true, role: "control", auth_disabled: true }],
|
||||
["/decoders", []],
|
||||
["/rigs", { rigs: [], active_remote: null }],
|
||||
["/status", {
|
||||
info: {
|
||||
manufacturer: "Smoke",
|
||||
model: "Fixture",
|
||||
revision: "1",
|
||||
access: { Tcp: { addr: "127.0.0.1:0" } },
|
||||
capabilities: {
|
||||
min_freq_step_hz: 1,
|
||||
supported_bands: [],
|
||||
supported_modes: ["FM"],
|
||||
num_vfos: 1,
|
||||
lock: false,
|
||||
lockable: false,
|
||||
attenuator: false,
|
||||
preamp: false,
|
||||
rit: false,
|
||||
rpt: false,
|
||||
split: false,
|
||||
tx: false,
|
||||
tx_limit: false,
|
||||
vfo_switch: false,
|
||||
filter_controls: false,
|
||||
signal_meter: false,
|
||||
},
|
||||
},
|
||||
status: { freq: { hz: 100_000_000 }, mode: "FM", tx_en: false, vfo: null, tx: null, rx: null, lock: null },
|
||||
band: null,
|
||||
enabled: true,
|
||||
initialized: true,
|
||||
cw_auto: false,
|
||||
cw_wpm: 20,
|
||||
cw_tone_hz: 700,
|
||||
aprs_decode_enabled: false,
|
||||
hf_aprs_decode_enabled: false,
|
||||
cw_decode_enabled: false,
|
||||
ft8_decode_enabled: false,
|
||||
ft4_decode_enabled: false,
|
||||
ft2_decode_enabled: false,
|
||||
wspr_decode_enabled: false,
|
||||
lrpt_decode_enabled: false,
|
||||
wefax_decode_enabled: false,
|
||||
recorder_enabled: false,
|
||||
}],
|
||||
["/bandplan.json", {}],
|
||||
["/api/recorder/status", []],
|
||||
["/api/recorder/files", []],
|
||||
@@ -80,10 +123,12 @@ const executablePath = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
|
||||
const browser = await chromium.launch({ executablePath, headless: true, args: ["--no-sandbox"] });
|
||||
const page = await browser.newPage();
|
||||
const runtimeErrors = [];
|
||||
page.on("pageerror", (error) => runtimeErrors.push(error.message));
|
||||
page.on("pageerror", (error) => runtimeErrors.push(error.stack ?? error.message));
|
||||
|
||||
try {
|
||||
await page.goto(`http://127.0.0.1:${address.port}/`, { waitUntil: "networkidle" });
|
||||
await page.goto(`http://127.0.0.1:${address.port}/`, { waitUntil: "domcontentloaded" });
|
||||
await page.waitForTimeout(500);
|
||||
assert.deepEqual(runtimeErrors, []);
|
||||
await page.locator("#content").waitFor({ state: "visible" });
|
||||
assert.equal(await page.locator("#auth-gate").isVisible(), false);
|
||||
assert.equal(await page.locator("#tab-main").isVisible(), true);
|
||||
|
||||
Reference in New Issue
Block a user