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 <project>) 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.
This commit is contained in:
Mohamed Boudra
2026-04-26 23:51:02 +07:00
parent 175685a912
commit 1e5722c996
2 changed files with 16 additions and 14 deletions

View File

@@ -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<ProjectsSettingsFixtures>({
async function openProjects(page: Page): Promise<void> {
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<void> {
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<void> {
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<void> {

View File

@@ -31,12 +31,12 @@ async function readTerminalLayoutMetrics(page: Page): Promise<TerminalLayoutMetr
return rect.width > 0 && rect.height > 0;
});
const surface = visibleSurfaces[0] ?? null;
const renderedRows = Array.from(document.querySelectorAll<HTMLElement>(".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<HTMLElement>(".xterm-screen") ?? null;
const xtermScreenRect = xtermScreen?.getBoundingClientRect() ?? null;
const term = (
window as Window & {
__paseoTerminal?: {
@@ -49,11 +49,10 @@ async function readTerminalLayoutMetrics(page: Page): Promise<TerminalLayoutMetr
return {
visibleSurfaceCount: visibleSurfaces.length,
surfaceHeight: surfaceRect?.height ?? 0,
rowCount: renderedRows.length,
rowCount: typeof term?.rows === "number" ? term.rows : 0,
rows: typeof term?.rows === "number" ? term.rows : null,
cols: typeof term?.cols === "number" ? term.cols : null,
renderedRowsHeight:
firstRowRect && lastRowRect ? Math.max(0, lastRowRect.bottom - firstRowRect.top) : 0,
renderedRowsHeight: xtermScreenRect?.height ?? 0,
tabIds: currentTabIds,
};
}, tabIds);