From 1e5722c9964784e1dc2dc4e0dd44afe89f87da26 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sun, 26 Apr 2026 23:51:02 +0700 Subject: [PATCH] test(app): align projects/vim e2e specs with current UI - Navigate Projects via the settings sidebar entry; the top-level Projects button never existed and the page lives under /settings/projects. - Match the row's accessibility label (Edit ) and the textbox label (Worktree setup commands) the screen actually uses. - Replace the .xterm-rows DOM selector with .xterm-screen for the vim layout assertion. With the WebGL renderer, .xterm-rows > div is empty, so the test has been red since it was added in 2b372765. --- packages/app/e2e/projects-settings.spec.ts | 15 +++++++++------ .../app/e2e/terminal-alternate-screen.spec.ts | 15 +++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/app/e2e/projects-settings.spec.ts b/packages/app/e2e/projects-settings.spec.ts index 9515ef842..ce13de15f 100644 --- a/packages/app/e2e/projects-settings.spec.ts +++ b/packages/app/e2e/projects-settings.spec.ts @@ -1,7 +1,7 @@ import { readFile } from "node:fs/promises"; import path from "node:path"; import { expect, test as base, type Page } from "./fixtures"; -import { gotoAppShell } from "./helpers/app"; +import { gotoAppShell, openSettings } from "./helpers/app"; import { connectNewWorkspaceDaemonClient, openProjectViaDaemon } from "./helpers/new-workspace"; import { createTempGitRepo } from "./helpers/workspace"; @@ -53,19 +53,22 @@ const test = base.extend({ async function openProjects(page: Page): Promise { await gotoAppShell(page); - await page.getByRole("button", { name: "Projects", exact: true }).click(); - await expect(page).toHaveURL(/\/projects$/); + await openSettings(page); + await page.getByTestId("settings-projects").click(); + await expect(page).toHaveURL(/\/settings\/projects$/); } async function openProjectSettings(page: Page, projectName: string): Promise { - await page.getByRole("button", { name: `${projectName} project details` }).click(); - await expect(page.getByRole("textbox", { name: "Worktree setup" })).toBeVisible({ + await page.getByRole("button", { name: `Edit ${projectName}`, exact: true }).click(); + await expect(page.getByRole("textbox", { name: "Worktree setup commands" })).toBeVisible({ timeout: 30_000, }); } async function editWorktreeSetup(page: Page, setupCommands: string[]): Promise { - await page.getByRole("textbox", { name: "Worktree setup" }).fill(setupCommands.join("\n")); + await page + .getByRole("textbox", { name: "Worktree setup commands" }) + .fill(setupCommands.join("\n")); } async function saveProjectConfig(page: Page): Promise { diff --git a/packages/app/e2e/terminal-alternate-screen.spec.ts b/packages/app/e2e/terminal-alternate-screen.spec.ts index 84364934b..53a657810 100644 --- a/packages/app/e2e/terminal-alternate-screen.spec.ts +++ b/packages/app/e2e/terminal-alternate-screen.spec.ts @@ -31,12 +31,12 @@ async function readTerminalLayoutMetrics(page: Page): Promise 0 && rect.height > 0; }); const surface = visibleSurfaces[0] ?? null; - const renderedRows = Array.from(document.querySelectorAll(".xterm-rows > div")); - const firstRow = renderedRows[0] ?? null; - const lastRow = renderedRows.at(-1) ?? null; const surfaceRect = surface?.getBoundingClientRect() ?? null; - const firstRowRect = firstRow?.getBoundingClientRect() ?? null; - const lastRowRect = lastRow?.getBoundingClientRect() ?? null; + // xterm.js exposes `.xterm-screen` regardless of renderer (DOM, canvas, WebGL), + // so use it as the canonical "rendered surface" rect rather than `.xterm-rows` + // which is only populated by the DOM renderer. + const xtermScreen = surface?.querySelector(".xterm-screen") ?? null; + const xtermScreenRect = xtermScreen?.getBoundingClientRect() ?? null; const term = ( window as Window & { __paseoTerminal?: { @@ -49,11 +49,10 @@ async function readTerminalLayoutMetrics(page: Page): Promise