fix(settings): open the right Settings tab from the update link and Race Day

The sidebar update notice now lands on System & backup at Updates, and
Race Day's decoder/backend/audio fix buttons open the matching tab,
instead of whichever tab was used last.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
larssand
2026-10-07 20:44:28 +02:00
parent 9d79bcb4d3
commit 7f267e17fe
10 changed files with 57 additions and 11 deletions

View File

@@ -6,7 +6,7 @@ import assert from "node:assert/strict";
// load, and - the actual bug class this guards against - keep the selection when the page
// re-renders in place (e.g. after saving the form), not silently reset back to Connection.
// activeSettingsTab is a module-level variable specifically so it survives that re-render.
export async function runSettingsTabsSmoke({ evaluate, navigate }) {
export async function runSettingsTabsSmoke({ evaluate, navigate, waitFor }) {
await navigate("settings", "settingsForm");
const activeTab = () => evaluate(`document.querySelector(".settings-tab.active")?.dataset.settingsTab`);
@@ -56,4 +56,13 @@ export async function runSettingsTabsSmoke({ evaluate, navigate }) {
await evaluate(`(() => { document.querySelector('[name="raceAudioRaceCallouts"]').value = "passing"; document.getElementById("settingsForm").requestSubmit(); })()`);
assert.equal(await callouts(), "passing");
console.log("PASS the legacy audio panel is gone and race calls default to passing tone only");
// The sidebar "update available" link opens Settings on System & backup at Updates, even
// when another tab was the last one used.
await evaluate(`document.querySelector('[data-settings-tab="connection"]').click()`);
await navigate("dashboard", "view");
await evaluate(`(() => { const link = document.getElementById("appUpdateAvailable"); link.hidden = false; link.click(); })()`);
await waitFor(async () => (await activeTab()) === "system", "update link lands on System & backup");
assert.equal(await evaluate(`Boolean(document.getElementById("settingsUpdateSection")) && !document.getElementById("settingsUpdateSection").closest("[data-settings-panel]").hidden`), true, "the update section is visible");
console.log("PASS the sidebar update link opens Settings on System & backup -> Updates");
}

View File

@@ -148,7 +148,7 @@ try {
await runTeamMembershipSmoke({ evaluate, navigate, fill, savedState, waitFor, pause, base });
await runEventManagerTabsSmoke({ evaluate, navigate, savedState, waitFor, base });
await runEventScheduleSmoke({ evaluate, navigate, fill, savedState, waitFor, base });
await runSettingsTabsSmoke({ evaluate, navigate });
await runSettingsTabsSmoke({ evaluate, navigate, waitFor });
await runGuideTabsSmoke({ evaluate, navigate });
await runAuthSmoke({ evaluate, navigate, fill, savedState, waitFor });
await runTtsSettingsSmoke({ evaluate, navigate, savedState, waitFor });

View File

@@ -107,6 +107,8 @@ test("preflight shortcuts respect driver, shared-car and team setup", async () =
assert.equal(action(missing, { mode: "race", type: "team_race" }).view, "race_setup");
assert.equal(action({ id: "participants", level: "error" }, { mode: "track" }).view, "events");
assert.equal(action({ id: "decoder", level: "error" }).view, "settings");
assert.equal(action({ id: "decoder", level: "error" }).settingsTab, "connection", "the decoder fix opens the Connection tab");
assert.equal(action({ id: "audio", level: "warning" }).settingsTab, "audio", "the audio fix opens the Audio tab");
assert.equal(action({ id: "session", level: "error" }).view, "timing");
assert.equal(action({ id: "lap_window", level: "warning" }, { mode: "race" }).field, "minLapSec");
assert.equal(action({ id: "decoder", level: "ok" }), null);