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>
69 lines
4.8 KiB
JavaScript
69 lines
4.8 KiB
JavaScript
import assert from "node:assert/strict";
|
|
|
|
// Regression coverage for the Settings page's tab restructuring (previously one long
|
|
// scrolling page: Connection, Audio, Appearance & overlay, System & backup all at once).
|
|
// Tabs must show exactly one group of panels at a time, default to Connection on first
|
|
// 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, waitFor }) {
|
|
await navigate("settings", "settingsForm");
|
|
|
|
const activeTab = () => evaluate(`document.querySelector(".settings-tab.active")?.dataset.settingsTab`);
|
|
const panelVisibility = () => evaluate(`
|
|
Object.fromEntries(Array.from(document.querySelectorAll("[data-settings-panel]"))
|
|
.map((panel) => [panel.dataset.settingsPanel, !panel.hidden]))
|
|
`);
|
|
|
|
assert.equal(await activeTab(), "connection", "Connection is the default tab on first load");
|
|
let visible = await panelVisibility();
|
|
assert.equal(visible.connection, true, "connection panel visible by default");
|
|
assert.equal(visible.audio, false, "audio panel hidden by default");
|
|
assert.equal(visible.appearance, false, "appearance panel hidden by default");
|
|
assert.equal(visible.system, false, "system panel hidden by default");
|
|
console.log("PASS settings defaults to the Connection tab with only that panel visible");
|
|
|
|
for (const tab of ["audio", "appearance", "system", "connection"]) {
|
|
await evaluate(`document.querySelector('[data-settings-tab="${tab}"]').click()`);
|
|
assert.equal(await activeTab(), tab, `clicking the ${tab} tab activates it`);
|
|
visible = await panelVisibility();
|
|
for (const [panelId, isVisible] of Object.entries(visible)) {
|
|
assert.equal(isVisible, panelId === tab, `after switching to ${tab}, panel ${panelId} should be ${panelId === tab ? "visible" : "hidden"}`);
|
|
}
|
|
}
|
|
console.log("PASS clicking each settings tab shows only its own panel and hides the rest");
|
|
|
|
await evaluate(`document.querySelector('[data-settings-tab="system"]').click()`);
|
|
assert.equal(await activeTab(), "system");
|
|
// Submitting the settings form re-renders the whole page in place (no navigation), which
|
|
// is exactly the path that used to drop the user back onto the Connection tab.
|
|
await evaluate(`document.getElementById("settingsForm").requestSubmit()`);
|
|
assert.equal(await activeTab(), "system", "the selected tab survives an in-place re-render after saving, instead of resetting to Connection");
|
|
visible = await panelVisibility();
|
|
assert.equal(visible.system, true);
|
|
assert.equal(visible.connection, false);
|
|
console.log("PASS the active settings tab is preserved across a save-triggered re-render");
|
|
|
|
// The old "Audio · Legacy" panel is gone; "Calls during a race" defaults to passing tone
|
|
// only and survives a save.
|
|
await evaluate(`document.querySelector('[data-settings-tab="audio"]').click()`);
|
|
assert.equal(await evaluate(`/Legacy/.test(document.querySelector('[data-settings-panel="audio"]').innerText)`), false, "no legacy audio panel");
|
|
assert.equal(await evaluate(`Boolean(document.querySelector('[name="audioEnabled"], [name="passingSoundMode"]'))`), false, "no legacy sound switches");
|
|
const callouts = () => evaluate(`document.querySelector('[name="raceAudioRaceCallouts"]').value`);
|
|
assert.equal(await callouts(), "passing");
|
|
await evaluate(`(() => { document.querySelector('[name="raceAudioRaceCallouts"]').value = "full"; document.getElementById("settingsForm").requestSubmit(); })()`);
|
|
assert.equal(await callouts(), "full", "speaker mode is saved");
|
|
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");
|
|
}
|