From bdfed2db4bc6916f187bcbb9a6377c40c9a09aa1 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Thu, 5 Mar 2026 09:58:02 +0700 Subject: [PATCH] app: add testIDs to workspace header and use them in e2e assertions --- .../workspace-sidebar-content-sync.spec.ts | 36 +++++++++++++++++-- .../workspace/[workspaceId]/_layout.tsx | 26 ++++++-------- .../screens/workspace/workspace-screen.tsx | 12 +++++-- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/packages/app/e2e/workspace-sidebar-content-sync.spec.ts b/packages/app/e2e/workspace-sidebar-content-sync.spec.ts index a7bb1e6dd..ce554cfab 100644 --- a/packages/app/e2e/workspace-sidebar-content-sync.spec.ts +++ b/packages/app/e2e/workspace-sidebar-content-sync.spec.ts @@ -8,6 +8,12 @@ function escapeRegex(value: string): string { return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } +function workspaceLabelFromPath(value: string): string { + const normalized = value.replace(/\\/g, '/').replace(/\/+$/, ''); + const parts = normalized.split('/').filter(Boolean); + return parts[parts.length - 1] ?? normalized; +} + function candidateWorkspaceIds(inputPath: string): string[] { const trimmed = inputPath.replace(/\/+$/, ''); const candidates = new Set([trimmed]); @@ -63,6 +69,21 @@ async function switchViaSidebar(input: { }); } +async function expectWorkspaceHeader( + page: Page, + input: { title: string; subtitle: string } +): Promise { + const titleLocator = page.getByTestId('workspace-header-title'); + const subtitleLocator = page.getByTestId('workspace-header-subtitle'); + + await expect(titleLocator.first()).toHaveText(input.title, { + timeout: 30000, + }); + await expect(subtitleLocator.first()).toHaveText(input.subtitle, { + timeout: 30000, + }); +} + test('sidebar workspace switch keeps visible content in sync with selected workspace', async ({ page }) => { const serverId = process.env.E2E_SERVER_ID; if (!serverId) { @@ -89,13 +110,22 @@ test('sidebar workspace switch keeps visible content in sync with selected works await page.goto(buildHostWorkspaceRoute(serverId, repoA.path)); await expect(page).toHaveURL(new RegExp('/workspace/'), { timeout: 30000 }); - await expect(page.getByText('sync-a-branch', { exact: true }).first()).toBeVisible({ timeout: 30000 }); + await expectWorkspaceHeader(page, { + title: 'sync-a-branch', + subtitle: workspaceLabelFromPath(repoA.path), + }); await switchViaSidebar({ page, serverId, targetWorkspacePath: repoB.path }); - await expect(page.getByText('sync-b-branch', { exact: true }).first()).toBeVisible({ timeout: 30000 }); + await expectWorkspaceHeader(page, { + title: 'sync-b-branch', + subtitle: workspaceLabelFromPath(repoB.path), + }); await switchViaSidebar({ page, serverId, targetWorkspacePath: repoA.path }); - await expect(page.getByText('sync-a-branch', { exact: true }).first()).toBeVisible({ timeout: 30000 }); + await expectWorkspaceHeader(page, { + title: 'sync-a-branch', + subtitle: workspaceLabelFromPath(repoA.path), + }); } finally { await repoA.cleanup(); await repoB.cleanup(); diff --git a/packages/app/src/app/h/[serverId]/workspace/[workspaceId]/_layout.tsx b/packages/app/src/app/h/[serverId]/workspace/[workspaceId]/_layout.tsx index c8adcbf3b..d7f66acca 100644 --- a/packages/app/src/app/h/[serverId]/workspace/[workspaceId]/_layout.tsx +++ b/packages/app/src/app/h/[serverId]/workspace/[workspaceId]/_layout.tsx @@ -1,21 +1,17 @@ -import { usePathname } from "expo-router"; -import { Platform } from "react-native"; -import { WorkspaceScreen } from "@/screens/workspace/workspace-screen"; +import { usePathname } from 'expo-router' +import { WorkspaceScreen } from '@/screens/workspace/workspace-screen' import { - parseHostWorkspaceOpenIntentFromPathname, parseHostWorkspaceRouteFromPathname, -} from "@/utils/host-routes"; + parseHostWorkspaceOpenIntentFromPathname, +} from '@/utils/host-routes' export default function HostWorkspaceLayout() { - const pathname = usePathname(); - const resolvedPathname = - Platform.OS === "web" && typeof window !== "undefined" - ? `${window.location.pathname}${window.location.search}${window.location.hash}` - : pathname; - const activeRoute = parseHostWorkspaceRouteFromPathname(resolvedPathname); - const serverId = activeRoute?.serverId ?? ""; - const workspaceId = activeRoute?.workspaceId ?? ""; - const openIntent = parseHostWorkspaceOpenIntentFromPathname(resolvedPathname); + const expoPathname = usePathname() + const resolvedPathname = expoPathname + const activeRoute = parseHostWorkspaceRouteFromPathname(resolvedPathname) + const serverId = activeRoute?.serverId ?? '' + const workspaceId = activeRoute?.workspaceId ?? '' + const openIntent = parseHostWorkspaceOpenIntentFromPathname(resolvedPathname) return ( - ); + ) } diff --git a/packages/app/src/screens/workspace/workspace-screen.tsx b/packages/app/src/screens/workspace/workspace-screen.tsx index b1aa8c5e9..fa2cee6ab 100644 --- a/packages/app/src/screens/workspace/workspace-screen.tsx +++ b/packages/app/src/screens/workspace/workspace-screen.tsx @@ -1059,10 +1059,18 @@ function WorkspaceScreenContent({ ) : ( <> - + {workspaceHeader.title} - + {workspaceHeader.subtitle}