app: add testIDs to workspace header and use them in e2e assertions
This commit is contained in:
@@ -8,6 +8,12 @@ function escapeRegex(value: string): string {
|
|||||||
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
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[] {
|
function candidateWorkspaceIds(inputPath: string): string[] {
|
||||||
const trimmed = inputPath.replace(/\/+$/, '');
|
const trimmed = inputPath.replace(/\/+$/, '');
|
||||||
const candidates = new Set<string>([trimmed]);
|
const candidates = new Set<string>([trimmed]);
|
||||||
@@ -63,6 +69,21 @@ async function switchViaSidebar(input: {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function expectWorkspaceHeader(
|
||||||
|
page: Page,
|
||||||
|
input: { title: string; subtitle: string }
|
||||||
|
): Promise<void> {
|
||||||
|
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 }) => {
|
test('sidebar workspace switch keeps visible content in sync with selected workspace', async ({ page }) => {
|
||||||
const serverId = process.env.E2E_SERVER_ID;
|
const serverId = process.env.E2E_SERVER_ID;
|
||||||
if (!serverId) {
|
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 page.goto(buildHostWorkspaceRoute(serverId, repoA.path));
|
||||||
await expect(page).toHaveURL(new RegExp('/workspace/'), { timeout: 30000 });
|
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 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 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 {
|
} finally {
|
||||||
await repoA.cleanup();
|
await repoA.cleanup();
|
||||||
await repoB.cleanup();
|
await repoB.cleanup();
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
import { usePathname } from "expo-router";
|
import { usePathname } from 'expo-router'
|
||||||
import { Platform } from "react-native";
|
import { WorkspaceScreen } from '@/screens/workspace/workspace-screen'
|
||||||
import { WorkspaceScreen } from "@/screens/workspace/workspace-screen";
|
|
||||||
import {
|
import {
|
||||||
parseHostWorkspaceOpenIntentFromPathname,
|
|
||||||
parseHostWorkspaceRouteFromPathname,
|
parseHostWorkspaceRouteFromPathname,
|
||||||
} from "@/utils/host-routes";
|
parseHostWorkspaceOpenIntentFromPathname,
|
||||||
|
} from '@/utils/host-routes'
|
||||||
|
|
||||||
export default function HostWorkspaceLayout() {
|
export default function HostWorkspaceLayout() {
|
||||||
const pathname = usePathname();
|
const expoPathname = usePathname()
|
||||||
const resolvedPathname =
|
const resolvedPathname = expoPathname
|
||||||
Platform.OS === "web" && typeof window !== "undefined"
|
const activeRoute = parseHostWorkspaceRouteFromPathname(resolvedPathname)
|
||||||
? `${window.location.pathname}${window.location.search}${window.location.hash}`
|
const serverId = activeRoute?.serverId ?? ''
|
||||||
: pathname;
|
const workspaceId = activeRoute?.workspaceId ?? ''
|
||||||
const activeRoute = parseHostWorkspaceRouteFromPathname(resolvedPathname);
|
const openIntent = parseHostWorkspaceOpenIntentFromPathname(resolvedPathname)
|
||||||
const serverId = activeRoute?.serverId ?? "";
|
|
||||||
const workspaceId = activeRoute?.workspaceId ?? "";
|
|
||||||
const openIntent = parseHostWorkspaceOpenIntentFromPathname(resolvedPathname);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WorkspaceScreen
|
<WorkspaceScreen
|
||||||
@@ -24,5 +20,5 @@ export default function HostWorkspaceLayout() {
|
|||||||
workspaceId={workspaceId}
|
workspaceId={workspaceId}
|
||||||
openIntent={openIntent}
|
openIntent={openIntent}
|
||||||
/>
|
/>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1059,10 +1059,18 @@ function WorkspaceScreenContent({
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Text style={styles.headerTitle} numberOfLines={1}>
|
<Text
|
||||||
|
testID="workspace-header-title"
|
||||||
|
style={styles.headerTitle}
|
||||||
|
numberOfLines={1}
|
||||||
|
>
|
||||||
{workspaceHeader.title}
|
{workspaceHeader.title}
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={styles.headerProjectTitle} numberOfLines={1}>
|
<Text
|
||||||
|
testID="workspace-header-subtitle"
|
||||||
|
style={styles.headerProjectTitle}
|
||||||
|
numberOfLines={1}
|
||||||
|
>
|
||||||
{workspaceHeader.subtitle}
|
{workspaceHeader.subtitle}
|
||||||
</Text>
|
</Text>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user