mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
refactor(app/e2e): rewrite settings-navigation spec to zero raw locators (#726)
Replace 21 raw page.locator/getByTestId/getByText calls in the spec body with named DSL operations in helpers/settings.ts. Each test body now reads as prose: open settings, navigate to section, expect content. New helpers: openCompactSettings, expectCompactSettingsList, expectSettingsSidebarVisible/Hidden/Sections, goBackInSettings, expectSettingsBackButton, clickSettingsBackToWorkspace, verifyLegacyHostSettingsRedirect, openCompactSettingsHost, expectHostSettingsUrl, expectAddHostMethodOptions, fillDirectHostUri, expectDirectHostFormValues, expectDirectHostSslEnabled, expectDirectHostUriValue/Hidden, expectDiagnosticsContent, expectAboutContent, expectGeneralContent. Export requireServerId from sidebar.ts so helpers encapsulate serverId logic — spec has no direct env reads. Also fix pre-existing typecheck error in use-keyboard-shortcuts.ts: cast action.route to the expo-router Href type at call sites.
This commit is contained in:
@@ -1,4 +1,9 @@
|
|||||||
import { expect, type Page } from "@playwright/test";
|
import { expect, type Page } from "@playwright/test";
|
||||||
|
import { requireServerId } from "./sidebar";
|
||||||
|
|
||||||
|
function escapeRegex(value: string): string {
|
||||||
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
|
}
|
||||||
|
|
||||||
const SECTION_LABELS = {
|
const SECTION_LABELS = {
|
||||||
general: "General",
|
general: "General",
|
||||||
@@ -50,3 +55,113 @@ export async function selectHostConnectionType(
|
|||||||
export async function toggleHostAdvanced(page: Page): Promise<void> {
|
export async function toggleHostAdvanced(page: Page): Promise<void> {
|
||||||
await page.getByTestId("direct-host-advanced-toggle").click();
|
await page.getByTestId("direct-host-advanced-toggle").click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function openCompactSettings(page: Page): Promise<void> {
|
||||||
|
await expect(page).toHaveURL(/\/h\/|\/welcome/, { timeout: 15000 });
|
||||||
|
await page.getByRole("button", { name: "Open menu", exact: true }).first().click();
|
||||||
|
const settingsButton = page.locator('[data-testid="sidebar-settings"]:visible').first();
|
||||||
|
await expect(settingsButton).toBeVisible();
|
||||||
|
await settingsButton.click();
|
||||||
|
await expect(page).toHaveURL(/\/settings$/);
|
||||||
|
await expect(page.getByTestId("settings-sidebar")).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectCompactSettingsList(page: Page): Promise<void> {
|
||||||
|
await expect(page).toHaveURL(/\/settings$/);
|
||||||
|
await expect(page.getByTestId("settings-sidebar")).toBeVisible();
|
||||||
|
await expect(page.getByText("Theme", { exact: true })).toHaveCount(0);
|
||||||
|
await expect(page.getByRole("button", { name: "Play test" })).toHaveCount(0);
|
||||||
|
await expect(page.locator('[data-testid^="settings-host-page-"]')).toHaveCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectSettingsSidebarVisible(page: Page): Promise<void> {
|
||||||
|
await expect(page.getByTestId("settings-sidebar")).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectSettingsSidebarHidden(page: Page): Promise<void> {
|
||||||
|
await expect(page.locator('[data-testid="settings-sidebar"]:visible')).toHaveCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectSettingsSidebarSections(
|
||||||
|
page: Page,
|
||||||
|
sections: Array<Exclude<SettingsSection, "projects">>,
|
||||||
|
): Promise<void> {
|
||||||
|
const sidebar = page.getByTestId("settings-sidebar");
|
||||||
|
for (const section of sections) {
|
||||||
|
await expect(
|
||||||
|
sidebar.getByRole("button", { name: SECTION_LABELS[section], exact: true }),
|
||||||
|
).toBeVisible();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function goBackInSettings(page: Page): Promise<void> {
|
||||||
|
await page.getByRole("button", { name: "Back", exact: true }).click();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectSettingsBackButton(page: Page): Promise<void> {
|
||||||
|
await expect(page.getByRole("button", { name: "Back", exact: true })).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function clickSettingsBackToWorkspace(page: Page): Promise<void> {
|
||||||
|
await page.getByTestId("settings-back-to-workspace").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectHostSettingsUrl(page: Page, serverId: string): Promise<void> {
|
||||||
|
await expect(page).toHaveURL(
|
||||||
|
new RegExp(`/settings/hosts/${escapeRegex(encodeURIComponent(serverId))}$`),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function verifyLegacyHostSettingsRedirect(page: Page): Promise<void> {
|
||||||
|
const serverId = requireServerId();
|
||||||
|
await page.goto(`/h/${encodeURIComponent(serverId)}/settings`);
|
||||||
|
await expectHostSettingsUrl(page, serverId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function openCompactSettingsHost(page: Page): Promise<void> {
|
||||||
|
const serverId = requireServerId();
|
||||||
|
await openSettingsHost(page, serverId);
|
||||||
|
await expectHostSettingsUrl(page, serverId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectAddHostMethodOptions(page: Page): Promise<void> {
|
||||||
|
await expect(page.getByRole("button", { name: "Direct connection" })).toBeVisible();
|
||||||
|
await expect(page.getByRole("button", { name: "Paste pairing link" })).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fillDirectHostUri(page: Page, uri: string): Promise<void> {
|
||||||
|
await page.getByTestId("direct-host-uri-input").fill(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectDirectHostFormValues(
|
||||||
|
page: Page,
|
||||||
|
fields: { host: string; port: string; password: string },
|
||||||
|
): Promise<void> {
|
||||||
|
await expect(page.getByTestId("direct-host-input")).toHaveValue(fields.host);
|
||||||
|
await expect(page.getByTestId("direct-port-input")).toHaveValue(fields.port);
|
||||||
|
await expect(page.getByTestId("direct-password-input")).toHaveValue(fields.password);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectDirectHostSslEnabled(page: Page): Promise<void> {
|
||||||
|
await expect(page.getByTestId("direct-ssl-toggle-checked")).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectDirectHostUriValue(page: Page, uri: string): Promise<void> {
|
||||||
|
await expect(page.getByTestId("direct-host-uri-input")).toHaveValue(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectDirectHostUriHidden(page: Page): Promise<void> {
|
||||||
|
await expect(page.getByTestId("direct-host-uri-input")).toHaveCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectDiagnosticsContent(page: Page): Promise<void> {
|
||||||
|
await expect(page.getByRole("button", { name: "Play test" })).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectAboutContent(page: Page): Promise<void> {
|
||||||
|
await expect(page.getByText("Version", { exact: true }).first()).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function expectGeneralContent(page: Page): Promise<void> {
|
||||||
|
await expect(page.getByText("Theme", { exact: true }).first()).toBeVisible();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { expect, type Page } from "@playwright/test";
|
import { expect, type Page } from "@playwright/test";
|
||||||
|
|
||||||
function requireServerId(): string {
|
export function requireServerId(): string {
|
||||||
const serverId = process.env.E2E_SERVER_ID;
|
const serverId = process.env.E2E_SERVER_ID;
|
||||||
if (!serverId) {
|
if (!serverId) {
|
||||||
throw new Error("E2E_SERVER_ID is not set (expected from Playwright globalSetup).");
|
throw new Error("E2E_SERVER_ID is not set (expected from Playwright globalSetup).");
|
||||||
|
|||||||
@@ -1,62 +1,60 @@
|
|||||||
import { test, expect, type Page } from "./fixtures";
|
import { test, expect } from "./fixtures";
|
||||||
import { gotoAppShell, openSettings } from "./helpers/app";
|
import { gotoAppShell, openSettings } from "./helpers/app";
|
||||||
|
import {
|
||||||
function escapeRegex(value: string): string {
|
openSettingsSection,
|
||||||
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
expectSettingsHeader,
|
||||||
}
|
openAddHostFlow,
|
||||||
|
selectHostConnectionType,
|
||||||
function getServerId(): string {
|
toggleHostAdvanced,
|
||||||
const serverId = process.env.E2E_SERVER_ID;
|
openCompactSettings,
|
||||||
if (!serverId) {
|
expectCompactSettingsList,
|
||||||
throw new Error("E2E_SERVER_ID is not set (expected from Playwright globalSetup).");
|
expectSettingsSidebarVisible,
|
||||||
}
|
expectSettingsSidebarHidden,
|
||||||
return serverId;
|
expectSettingsSidebarSections,
|
||||||
}
|
goBackInSettings,
|
||||||
|
expectSettingsBackButton,
|
||||||
async function clickSidebarSection(page: Page, label: string) {
|
clickSettingsBackToWorkspace,
|
||||||
const sidebar = page.getByTestId("settings-sidebar");
|
verifyLegacyHostSettingsRedirect,
|
||||||
await expect(sidebar).toBeVisible();
|
openCompactSettingsHost,
|
||||||
await sidebar.getByRole("button", { name: label, exact: true }).click();
|
expectAddHostMethodOptions,
|
||||||
}
|
fillDirectHostUri,
|
||||||
|
expectDirectHostFormValues,
|
||||||
|
expectDirectHostSslEnabled,
|
||||||
|
expectDirectHostUriValue,
|
||||||
|
expectDirectHostUriHidden,
|
||||||
|
expectDiagnosticsContent,
|
||||||
|
expectAboutContent,
|
||||||
|
expectGeneralContent,
|
||||||
|
} from "./helpers/settings";
|
||||||
|
|
||||||
test.describe("Settings sidebar navigation", () => {
|
test.describe("Settings sidebar navigation", () => {
|
||||||
test("clicking a sidebar section updates the URL and renders the section", async ({ page }) => {
|
test("clicking a sidebar section updates the URL and renders the section", async ({ page }) => {
|
||||||
await gotoAppShell(page);
|
await gotoAppShell(page);
|
||||||
await openSettings(page);
|
await openSettings(page);
|
||||||
|
|
||||||
await clickSidebarSection(page, "Diagnostics");
|
await openSettingsSection(page, "diagnostics");
|
||||||
await expect(page).toHaveURL(/\/settings\/diagnostics$/);
|
await expectSettingsHeader(page, "Diagnostics");
|
||||||
await expect(page.getByRole("button", { name: "Play test" })).toBeVisible();
|
await expectDiagnosticsContent(page);
|
||||||
await expect(page.getByTestId("settings-detail-header-title")).toHaveText("Diagnostics");
|
|
||||||
|
|
||||||
await clickSidebarSection(page, "About");
|
await openSettingsSection(page, "about");
|
||||||
await expect(page).toHaveURL(/\/settings\/about$/);
|
await expectSettingsHeader(page, "About");
|
||||||
await expect(page.getByText("Version", { exact: true }).first()).toBeVisible();
|
await expectAboutContent(page);
|
||||||
await expect(page.getByTestId("settings-detail-header-title")).toHaveText("About");
|
|
||||||
|
|
||||||
await clickSidebarSection(page, "General");
|
await openSettingsSection(page, "general");
|
||||||
await expect(page).toHaveURL(/\/settings\/general$/);
|
await expectSettingsHeader(page, "General");
|
||||||
await expect(page.getByText("Theme", { exact: true }).first()).toBeVisible();
|
await expectGeneralContent(page);
|
||||||
await expect(page.getByTestId("settings-detail-header-title")).toHaveText("General");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("/h/[serverId]/settings redirects to /settings/hosts/[serverId]", async ({ page }) => {
|
test("/h/[serverId]/settings redirects to /settings/hosts/[serverId]", async ({ page }) => {
|
||||||
const serverId = getServerId();
|
|
||||||
await gotoAppShell(page);
|
await gotoAppShell(page);
|
||||||
await page.goto(`/h/${encodeURIComponent(serverId)}/settings`);
|
await verifyLegacyHostSettingsRedirect(page);
|
||||||
await expect(page).toHaveURL(
|
|
||||||
new RegExp(`/settings/hosts/${escapeRegex(encodeURIComponent(serverId))}$`),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("the + Add host button opens the add-host method modal", async ({ page }) => {
|
test("the + Add host button opens the add-host method modal", async ({ page }) => {
|
||||||
await gotoAppShell(page);
|
await gotoAppShell(page);
|
||||||
await openSettings(page);
|
await openSettings(page);
|
||||||
|
await openAddHostFlow(page);
|
||||||
await page.getByTestId("settings-add-host").click();
|
await expectAddHostMethodOptions(page);
|
||||||
await expect(page.getByText("Add connection", { exact: true })).toBeVisible();
|
|
||||||
await expect(page.getByRole("button", { name: "Direct connection" })).toBeVisible();
|
|
||||||
await expect(page.getByRole("button", { name: "Paste pairing link" })).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("direct connection advanced URI round-trips SSL and password into the form", async ({
|
test("direct connection advanced URI round-trips SSL and password into the form", async ({
|
||||||
@@ -64,38 +62,34 @@ test.describe("Settings sidebar navigation", () => {
|
|||||||
}) => {
|
}) => {
|
||||||
await gotoAppShell(page);
|
await gotoAppShell(page);
|
||||||
await openSettings(page);
|
await openSettings(page);
|
||||||
|
await openAddHostFlow(page);
|
||||||
|
await selectHostConnectionType(page, "direct");
|
||||||
|
|
||||||
await page.getByTestId("settings-add-host").click();
|
await toggleHostAdvanced(page);
|
||||||
await page.getByRole("button", { name: "Direct connection" }).click();
|
await fillDirectHostUri(page, "tcp://example.paseo.test:7443?ssl=true&password=shared-secret");
|
||||||
|
await toggleHostAdvanced(page);
|
||||||
|
|
||||||
await page.getByTestId("direct-host-advanced-toggle").click();
|
await expectDirectHostFormValues(page, {
|
||||||
await page
|
host: "example.paseo.test",
|
||||||
.getByTestId("direct-host-uri-input")
|
port: "7443",
|
||||||
.fill("tcp://example.paseo.test:7443?ssl=true&password=shared-secret");
|
password: "shared-secret",
|
||||||
await page.getByTestId("direct-host-advanced-toggle").click();
|
});
|
||||||
|
await expectDirectHostSslEnabled(page);
|
||||||
|
await expectDirectHostUriHidden(page);
|
||||||
|
|
||||||
await expect(page.getByTestId("direct-host-input")).toHaveValue("example.paseo.test");
|
await toggleHostAdvanced(page);
|
||||||
await expect(page.getByTestId("direct-port-input")).toHaveValue("7443");
|
await expectDirectHostUriValue(
|
||||||
await expect(page.getByTestId("direct-ssl-toggle-checked")).toBeVisible();
|
page,
|
||||||
await expect(page.getByTestId("direct-password-input")).toHaveValue("shared-secret");
|
|
||||||
await expect(page.getByTestId("direct-host-uri-input")).toHaveCount(0);
|
|
||||||
|
|
||||||
await page.getByTestId("direct-host-advanced-toggle").click();
|
|
||||||
await expect(page.getByTestId("direct-host-uri-input")).toHaveValue(
|
|
||||||
"tcp://example.paseo.test:7443?ssl=true&password=shared-secret",
|
"tcp://example.paseo.test:7443?ssl=true&password=shared-secret",
|
||||||
);
|
);
|
||||||
await page.getByTestId("direct-host-advanced-toggle").click();
|
await toggleHostAdvanced(page);
|
||||||
await expect(page.getByTestId("direct-host-uri-input")).toHaveCount(0);
|
await expectDirectHostUriHidden(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sidebar shows a Back to workspace row that leaves /settings", async ({ page }) => {
|
test("sidebar shows a Back to workspace row that leaves /settings", async ({ page }) => {
|
||||||
await gotoAppShell(page);
|
await gotoAppShell(page);
|
||||||
await openSettings(page);
|
await openSettings(page);
|
||||||
|
await clickSettingsBackToWorkspace(page);
|
||||||
const backRow = page.getByTestId("settings-back-to-workspace");
|
|
||||||
await expect(backRow).toBeVisible();
|
|
||||||
|
|
||||||
await backRow.click();
|
|
||||||
await expect(page).not.toHaveURL(/\/settings(\/|$)/);
|
await expect(page).not.toHaveURL(/\/settings(\/|$)/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -103,113 +97,57 @@ test.describe("Settings sidebar navigation", () => {
|
|||||||
test.describe("Settings — compact master-detail", () => {
|
test.describe("Settings — compact master-detail", () => {
|
||||||
test.use({ viewport: { width: 390, height: 844 } });
|
test.use({ viewport: { width: 390, height: 844 } });
|
||||||
|
|
||||||
async function openCompactSettingsRoot(page: Page) {
|
|
||||||
await gotoAppShell(page);
|
|
||||||
// Wait for bootstrap to settle on a host route so storeReady is true before
|
|
||||||
// we navigate into the protected settings stack. A direct page.goto("/settings")
|
|
||||||
// on a cold load is eaten by Stack.Protected while bootstrap is still running.
|
|
||||||
await expect(page).toHaveURL(/\/h\/|\/welcome/, { timeout: 15000 });
|
|
||||||
|
|
||||||
// Drive navigation the same way a user would: open the mobile drawer and tap
|
|
||||||
// the Settings footer icon. This preserves the in-app router state instead of
|
|
||||||
// triggering a full reload through Stack.Protected.
|
|
||||||
await page.getByRole("button", { name: "Open menu", exact: true }).first().click();
|
|
||||||
const sidebarSettingsButton = page.locator('[data-testid="sidebar-settings"]:visible').first();
|
|
||||||
await expect(sidebarSettingsButton).toBeVisible();
|
|
||||||
await sidebarSettingsButton.click();
|
|
||||||
|
|
||||||
await expect(page).toHaveURL(/\/settings$/);
|
|
||||||
await expect(page.getByTestId("settings-sidebar")).toBeVisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function expectCompactSettingsRootList(page: Page) {
|
|
||||||
await expect(page).toHaveURL(/\/settings$/);
|
|
||||||
await expect(page.getByTestId("settings-sidebar")).toBeVisible();
|
|
||||||
|
|
||||||
await expect(page.getByText("Theme", { exact: true })).toHaveCount(0);
|
|
||||||
await expect(page.getByRole("button", { name: "Play test" })).toHaveCount(0);
|
|
||||||
await expect(page.locator('[data-testid^="settings-host-page-"]')).toHaveCount(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
test("/settings renders only the sidebar list (no section content)", async ({ page }) => {
|
test("/settings renders only the sidebar list (no section content)", async ({ page }) => {
|
||||||
await openCompactSettingsRoot(page);
|
await gotoAppShell(page);
|
||||||
|
await openCompactSettings(page);
|
||||||
|
|
||||||
// Sidebar rows are present.
|
await expectSettingsSidebarSections(page, ["general", "diagnostics", "about"]);
|
||||||
await expect(
|
await expectCompactSettingsList(page);
|
||||||
page.getByTestId("settings-sidebar").getByRole("button", { name: "General", exact: true }),
|
|
||||||
).toBeVisible();
|
|
||||||
await expect(
|
|
||||||
page
|
|
||||||
.getByTestId("settings-sidebar")
|
|
||||||
.getByRole("button", { name: "Diagnostics", exact: true }),
|
|
||||||
).toBeVisible();
|
|
||||||
await expect(
|
|
||||||
page.getByTestId("settings-sidebar").getByRole("button", { name: "About", exact: true }),
|
|
||||||
).toBeVisible();
|
|
||||||
|
|
||||||
// Section detail content is NOT rendered at the root.
|
await expectSettingsBackButton(page);
|
||||||
await expectCompactSettingsRootList(page);
|
await goBackInSettings(page);
|
||||||
|
|
||||||
const rootBackButton = page.getByRole("button", { name: "Back", exact: true });
|
|
||||||
await expect(rootBackButton).toBeVisible();
|
|
||||||
await rootBackButton.click();
|
|
||||||
await expect(page).not.toHaveURL(/\/settings(\/|$)/);
|
await expect(page).not.toHaveURL(/\/settings(\/|$)/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("tapping a section pushes /settings/[section] and shows a back button", async ({ page }) => {
|
test("tapping a section pushes /settings/[section] and shows a back button", async ({ page }) => {
|
||||||
await openCompactSettingsRoot(page);
|
await gotoAppShell(page);
|
||||||
|
await openCompactSettings(page);
|
||||||
|
|
||||||
await page
|
await openSettingsSection(page, "diagnostics");
|
||||||
.getByTestId("settings-sidebar")
|
|
||||||
.getByRole("button", { name: "Diagnostics", exact: true })
|
|
||||||
.click();
|
|
||||||
await expect(page).toHaveURL(/\/settings\/diagnostics$/);
|
await expect(page).toHaveURL(/\/settings\/diagnostics$/);
|
||||||
await expect(page.getByRole("button", { name: "Play test" })).toBeVisible();
|
await expectDiagnosticsContent(page);
|
||||||
// Sidebar is no longer visible — we are on a detail screen.
|
await expectSettingsSidebarHidden(page);
|
||||||
// (Expo Router stack keeps the previous screen in the DOM but hidden; check
|
await expectSettingsBackButton(page);
|
||||||
// only visible instances.)
|
|
||||||
await expect(page.locator('[data-testid="settings-sidebar"]:visible')).toHaveCount(0);
|
|
||||||
await expect(page.getByRole("button", { name: "Back", exact: true })).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("back from a section detail returns to the /settings list", async ({ page }) => {
|
test("back from a section detail returns to the /settings list", async ({ page }) => {
|
||||||
await openCompactSettingsRoot(page);
|
await gotoAppShell(page);
|
||||||
|
await openCompactSettings(page);
|
||||||
|
|
||||||
await page
|
await openSettingsSection(page, "about");
|
||||||
.getByTestId("settings-sidebar")
|
|
||||||
.getByRole("button", { name: "About", exact: true })
|
|
||||||
.click();
|
|
||||||
await expect(page).toHaveURL(/\/settings\/about$/);
|
await expect(page).toHaveURL(/\/settings\/about$/);
|
||||||
|
|
||||||
await page.getByRole("button", { name: "Back", exact: true }).click();
|
await goBackInSettings(page);
|
||||||
await expectCompactSettingsRootList(page);
|
await expectCompactSettingsList(page);
|
||||||
await expect(page.getByRole("button", { name: "Back", exact: true })).toBeVisible();
|
await expectSettingsBackButton(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("tapping a host entry pushes /settings/hosts/[serverId]", async ({ page }) => {
|
test("tapping a host entry pushes /settings/hosts/[serverId]", async ({ page }) => {
|
||||||
const serverId = getServerId();
|
await gotoAppShell(page);
|
||||||
await openCompactSettingsRoot(page);
|
await openCompactSettings(page);
|
||||||
|
|
||||||
await page.getByTestId(`settings-host-entry-${serverId}`).click();
|
await openCompactSettingsHost(page);
|
||||||
await expect(page).toHaveURL(
|
await expectSettingsBackButton(page);
|
||||||
new RegExp(`/settings/hosts/${escapeRegex(encodeURIComponent(serverId))}$`),
|
await expectSettingsSidebarHidden(page);
|
||||||
);
|
|
||||||
await expect(page.getByTestId(`settings-host-page-${serverId}`)).toBeVisible();
|
|
||||||
await expect(page.getByRole("button", { name: "Back", exact: true })).toBeVisible();
|
|
||||||
await expect(page.locator('[data-testid="settings-sidebar"]:visible')).toHaveCount(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("back from a host detail returns to the /settings list", async ({ page }) => {
|
test("back from a host detail returns to the /settings list", async ({ page }) => {
|
||||||
const serverId = getServerId();
|
await gotoAppShell(page);
|
||||||
await openCompactSettingsRoot(page);
|
await openCompactSettings(page);
|
||||||
|
|
||||||
await page.getByTestId(`settings-host-entry-${serverId}`).click();
|
await openCompactSettingsHost(page);
|
||||||
await expect(page).toHaveURL(
|
await goBackInSettings(page);
|
||||||
new RegExp(`/settings/hosts/${escapeRegex(encodeURIComponent(serverId))}$`),
|
|
||||||
);
|
|
||||||
|
|
||||||
await page.getByRole("button", { name: "Back", exact: true }).click();
|
|
||||||
await expect(page).toHaveURL(/\/settings$/);
|
await expect(page).toHaveURL(/\/settings$/);
|
||||||
await expect(page.getByTestId("settings-sidebar")).toBeVisible();
|
await expectSettingsSidebarVisible(page);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ export function useKeyboardShortcuts({
|
|||||||
navigateToWorkspace(action.serverId, action.workspaceId, { currentPathname: pathname });
|
navigateToWorkspace(action.serverId, action.workspaceId, { currentPathname: pathname });
|
||||||
return true;
|
return true;
|
||||||
case "router-replace":
|
case "router-replace":
|
||||||
router.replace(action.route);
|
router.replace(action.route as Parameters<typeof router.replace>[0]);
|
||||||
return true;
|
return true;
|
||||||
case "router-back":
|
case "router-back":
|
||||||
router.back();
|
router.back();
|
||||||
return true;
|
return true;
|
||||||
case "router-push":
|
case "router-push":
|
||||||
router.push(action.route);
|
router.push(action.route as Parameters<typeof router.push>[0]);
|
||||||
return true;
|
return true;
|
||||||
case "open-project-picker":
|
case "open-project-picker":
|
||||||
void openProjectPickerAction();
|
void openProjectPickerAction();
|
||||||
|
|||||||
Reference in New Issue
Block a user