Add endpoint mode options, release channel rollback handling, and runtime refresh improvements

- Implement `endpoint_mode` (manual/auto) and related configuration in i18n across multiple locales.
- Add new utility methods for channel rollback and runtime confirmation workflows.
- Update unit and E2E tests to cover runtime refresh behavior, channel switching mechanics, and release references.
- Enhance `SessionUser` and related services to improve error handling during release runtime refresh.
- Add data-test attributes for frontend components to support improved test coverage.
This commit is contained in:
Jeppe Bundgaard
2026-05-21 14:47:46 +02:00
parent b2ddf0db5c
commit ebcd52a019
30 changed files with 1234 additions and 157 deletions
@@ -122,6 +122,61 @@ const runtimeWithSelectableReleaseDetails = () => ({
],
});
const runtimeWithFailingBetaSwitch = () => ({
generated_at: "2026-05-19T09:10:00.000Z",
trace_id: "trace-stable-channel",
channel: {
id: 1,
slug: "stable",
name: "Stable",
description: "Standard production channel.",
enabled: true,
default_channel: true,
},
versions: {
frontend: { version_label: "frontend-stable", commit_sha: "abc123" },
api: { version_label: "api-stable", commit_sha: "def456" },
bundle_id: 31,
},
availability: {
configured: true,
missing: [],
status: "ready",
},
available_channels: [
{
channel: {
id: 1,
slug: "stable",
name: "Stable",
description: "Standard production channel.",
enabled: true,
default_channel: true,
},
availability: {
configured: true,
missing: [],
status: "ready",
},
},
{
channel: {
id: 3,
slug: "beta",
name: "Beta",
description: "Beta validation channel.",
enabled: true,
default_channel: false,
},
availability: {
configured: true,
missing: [],
status: "ready",
},
},
],
});
async function boot(page, runtime = unavailableRuntime, locale = "en") {
await page.addInitScript((selectedLocale) => {
window.localStorage.setItem("locale", selectedLocale);
@@ -283,6 +338,40 @@ test("release channel choices show git commit and release time when available",
);
});
test("failed sidebar release channel switches keep the previous channel active", async ({ page }, testInfo) => {
test.skip(testInfo.project.name.includes("mobile"), "The sidebar release selector is hidden in the mobile layout.");
const runtime = runtimeWithFailingBetaSwitch();
await boot(page, runtime);
const runtimeRequests = [];
await page.route("**/release/runtime**", async (route) => {
const url = new URL(route.request().url());
const selectedChannel = url.searchParams.get("release_channel") || "";
runtimeRequests.push(selectedChannel || "default");
if (selectedChannel === "beta") {
await route.fulfill(json({ data: { message: "Beta runtime unavailable" } }, 502));
return;
}
await route.fulfill(json({ data: runtime }));
});
await page.goto("/user", { waitUntil: "domcontentloaded" });
const stable = page.getByTestId("release-channel-option-stable");
const beta = page.getByTestId("release-channel-option-beta");
await expect(stable).toBeVisible({ timeout: GUARD_TIMEOUT_MS });
await expect(stable).toHaveAttribute("aria-pressed", "true");
await expect(beta).toHaveAttribute("aria-pressed", "false");
await beta.click();
await expect(stable).toHaveAttribute("aria-pressed", "true");
await expect(beta).toHaveAttribute("aria-pressed", "false");
await expect(page.getByRole("alert")).toContainText("previous channel is still active");
await expect.poll(() => page.evaluate(() => window.localStorage.getItem("release_channel_selected_slug"))).toBeNull();
expect(runtimeRequests).toContain("beta");
});
test("predefined release channel text is localized on the guard page", async ({ page }) => {
const internalRuntime = {
...unavailableRuntime,