fix: resolve 6 remaining Playwright e2e test failures on CI

- archive-tab: replace waitForFunction with waitForURL for ?open= intent
  consumption, increase test timeout to 300s for slow rootNavigationState
  init on CI
- launcher-tab: use Control+t on Linux instead of Meta+t to match app's
  keyboard shortcut definitions for non-Mac platforms
- new-workspace: add waitForSidebarHydration to wait for daemon
  connection before checking sidebar rows, add re-navigation fallback
  if app redirects during hydration, increase timeouts
- setup-streaming: use waitForTerminalContent (xterm buffer API) instead
  of fragile .xterm-rows CSS text matching, wait for terminal attachment
  before checking content
This commit is contained in:
Mohamed Boudra
2026-04-14 10:54:38 +07:00
parent e647c61fb5
commit 95ea02a87f
6 changed files with 63 additions and 19 deletions
+10 -5
View File
@@ -188,11 +188,16 @@ export async function openWorkspaceWithAgents(
const serverId = getServerId();
for (const agent of agents) {
await page.goto(buildHostAgentDetailRoute(serverId, agent.id, agent.cwd));
// Wait for the ?open=agent:xxx intent to be consumed by the layout effect.
// The layout removes the query param via history.replaceState once processed.
await page.waitForFunction(() => !window.location.search.includes("open="), {
timeout: 15_000,
});
// The workspace layout consumes `?open=agent:xxx`, returns null during the effect,
// then replaces the URL with the clean workspace route after preparing the tab.
// On CI, Expo Router's rootNavigationState may take time to initialize,
// so we allow a generous timeout here (matching terminal-perf pattern).
await page.waitForURL(
(url) => url.pathname.includes("/workspace/") && !url.searchParams.has("open"),
{ timeout: 60_000 },
);
await waitForWorkspaceTabsVisible(page);
await expectWorkspaceTabVisible(page, agent.id);
}
+3 -2
View File
@@ -79,9 +79,10 @@ export async function clickNewTerminalButton(page: Page): Promise<void> {
await button.click();
}
/** Press Cmd+T (macOS) to open a new tab. */
/** Press Cmd+T (macOS) or Ctrl+T (Linux/Windows) to open a new tab. */
export async function pressNewTabShortcut(page: Page): Promise<void> {
await page.keyboard.press("Meta+t");
const modifier = process.platform === "darwin" ? "Meta" : "Control";
await page.keyboard.press(`${modifier}+t`);
}
// ─── Tab bar assertions ───────────────────────────────────────────────────
+12 -1
View File
@@ -6,6 +6,17 @@ export async function openNewAgentComposer(page: Page): Promise<void> {
await gotoHome(page);
}
/**
* Wait for the sidebar to show at least one project row, indicating that the
* WebSocket connection is up and workspace hydration has completed.
*/
export async function waitForSidebarHydration(page: Page, timeout = 60_000): Promise<void> {
await page
.locator('[data-testid^="sidebar-project-row-"]')
.first()
.waitFor({ state: "visible", timeout });
}
export function workspaceLabelFromPath(value: string): string {
const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
const parts = normalized.split("/").filter(Boolean);
@@ -62,7 +73,7 @@ export async function waitForWorkspaceInSidebar(
const selector = candidates
.map((id) => `[data-testid="sidebar-workspace-row-${input.serverId}:${id}"]`)
.join(",");
await page.locator(selector).first().waitFor({ state: "visible", timeout: 30_000 });
await page.locator(selector).first().waitFor({ state: "visible", timeout: 60_000 });
}
export async function expectWorkspaceHeader(