chore(app): clean up e2e helpers — delete duplicates, dead code, and redundant seeding (#723)
- Delete clickNewTabButton (duplicate of clickNewChat) and clickNewTerminalButton (duplicate of clickNewTerminal); update all call sites - Rename clickTerminal → clickNewTerminal to match clickNewChat naming pattern - Delete waitForLauncherPanel (deprecated no-op) - Delete waitForAgentFinishUI and getToolCallCount (dead exports never imported) - Remove ensureE2EStorageSeeded, assertE2EUsesSeededTestDaemon, and related helpers from app.ts — the paseoE2ESetup auto-fixture seeds via addInitScript on every navigation, making these redundant - Simplify gotoAppShell to a one-liner; simplify gotoHome to use .or() instead of three-way if-else chain - Strip try/catch self-heal from ensureHostSelected — the fixture guarantees preferences alignment, so the workaround is never needed
This commit is contained in:
+19
-277
@@ -1,217 +1,36 @@
|
|||||||
import { expect, type Page } from "@playwright/test";
|
import { expect, type Page } from "@playwright/test";
|
||||||
import { buildCreateAgentPreferences, buildSeededHost } from "./daemon-registry";
|
|
||||||
|
|
||||||
function escapeRegex(value: string): string {
|
function escapeRegex(value: string): string {
|
||||||
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getE2EDaemonPort(): string {
|
|
||||||
const port = process.env.E2E_DAEMON_PORT;
|
|
||||||
if (!port) {
|
|
||||||
throw new Error("E2E_DAEMON_PORT is not set (expected from Playwright globalSetup).");
|
|
||||||
}
|
|
||||||
if (port === "6767") {
|
|
||||||
throw new Error(
|
|
||||||
"E2E_DAEMON_PORT is 6767. Refusing to run e2e against the default local daemon.",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function ensureE2EStorageSeeded(page: Page): Promise<void> {
|
|
||||||
const port = getE2EDaemonPort();
|
|
||||||
const expectedEndpoint = `127.0.0.1:${port}`;
|
|
||||||
const expectedServerId = process.env.E2E_SERVER_ID;
|
|
||||||
if (!expectedServerId) {
|
|
||||||
throw new Error("E2E_SERVER_ID is not set (expected from Playwright globalSetup).");
|
|
||||||
}
|
|
||||||
|
|
||||||
const needsReset = await page.evaluate(
|
|
||||||
({ expectedEndpoint: endpoint, expectedServerId: serverId }) => {
|
|
||||||
const raw = localStorage.getItem("@paseo:daemon-registry");
|
|
||||||
if (!raw) return true;
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(raw);
|
|
||||||
if (!Array.isArray(parsed) || parsed.length !== 1) return true;
|
|
||||||
const entry = parsed[0] as { serverId?: string; connections?: unknown };
|
|
||||||
if (entry?.serverId !== serverId) return true;
|
|
||||||
const connections = entry?.connections;
|
|
||||||
if (!Array.isArray(connections)) return true;
|
|
||||||
if (
|
|
||||||
connections.some(
|
|
||||||
(c: { type?: string; endpoint?: string }) =>
|
|
||||||
c?.type === "directTcp" &&
|
|
||||||
typeof c?.endpoint === "string" &&
|
|
||||||
/:6767\b/.test(c.endpoint),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return true;
|
|
||||||
return !connections.some(
|
|
||||||
(c: { type?: string; endpoint?: string }) =>
|
|
||||||
c?.type === "directTcp" && c?.endpoint === endpoint,
|
|
||||||
);
|
|
||||||
} catch {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ expectedEndpoint, expectedServerId },
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!needsReset) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nowIso = new Date().toISOString();
|
|
||||||
const daemon = buildSeededHost({
|
|
||||||
serverId: expectedServerId,
|
|
||||||
endpoint: expectedEndpoint,
|
|
||||||
nowIso,
|
|
||||||
});
|
|
||||||
const preferences = buildCreateAgentPreferences(expectedServerId);
|
|
||||||
await page.evaluate(
|
|
||||||
({ daemon: seededDaemon, preferences: seededPreferences }) => {
|
|
||||||
localStorage.setItem("@paseo:e2e", "1");
|
|
||||||
localStorage.setItem("@paseo:daemon-registry", JSON.stringify([seededDaemon]));
|
|
||||||
localStorage.setItem("@paseo:create-agent-preferences", JSON.stringify(seededPreferences));
|
|
||||||
localStorage.removeItem("@paseo:settings");
|
|
||||||
},
|
|
||||||
{ daemon, preferences },
|
|
||||||
);
|
|
||||||
|
|
||||||
await page.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseRegistryEntry(registryRaw: string): { serverId: string; connections: unknown } {
|
|
||||||
let registry: unknown;
|
|
||||||
try {
|
|
||||||
registry = JSON.parse(registryRaw);
|
|
||||||
} catch {
|
|
||||||
throw new Error("E2E expected @paseo:daemon-registry to be valid JSON.");
|
|
||||||
}
|
|
||||||
if (!Array.isArray(registry) || registry.length !== 1) {
|
|
||||||
throw new Error(
|
|
||||||
`E2E expected @paseo:daemon-registry to contain exactly 1 daemon (got ${Array.isArray(registry) ? registry.length : "non-array"}).`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const daemon = registry[0] as { serverId?: string; connections?: unknown };
|
|
||||||
if (typeof daemon?.serverId !== "string" || daemon.serverId.length === 0) {
|
|
||||||
throw new Error(
|
|
||||||
`E2E expected seeded daemon to have a string serverId (got ${String(daemon?.serverId)}).`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return { serverId: daemon.serverId, connections: daemon.connections };
|
|
||||||
}
|
|
||||||
|
|
||||||
function assertDaemonConnections(connections: unknown, expectedEndpoint: string): void {
|
|
||||||
if (
|
|
||||||
!Array.isArray(connections) ||
|
|
||||||
!connections.some(
|
|
||||||
(c: { type?: string; endpoint?: string }) =>
|
|
||||||
c?.type === "directTcp" && c?.endpoint === expectedEndpoint,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
throw new Error(
|
|
||||||
`E2E expected seeded daemon connections to include directTcp ${expectedEndpoint} (got ${JSON.stringify(connections)}).`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
Array.isArray(connections) &&
|
|
||||||
connections.some(
|
|
||||||
(c: { type?: string; endpoint?: string }) =>
|
|
||||||
c?.type === "directTcp" && typeof c?.endpoint === "string" && /:6767\b/.test(c.endpoint),
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
throw new Error(
|
|
||||||
`E2E detected a daemon endpoint pointing at :6767 (${JSON.stringify(connections)}).`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function assertPreferencesMatch(prefsRaw: string, serverId: string): void {
|
|
||||||
try {
|
|
||||||
const prefs = JSON.parse(prefsRaw) as { serverId?: string };
|
|
||||||
if (prefs?.serverId !== serverId) {
|
|
||||||
throw new Error(
|
|
||||||
`E2E expected create-agent-preferences.serverId to match seeded daemon serverId (${serverId}) (got ${String(prefs?.serverId)}).`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof Error) throw error;
|
|
||||||
throw new Error("E2E expected @paseo:create-agent-preferences to be valid JSON.", {
|
|
||||||
cause: error,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function assertE2EUsesSeededTestDaemon(page: Page): Promise<void> {
|
|
||||||
const port = getE2EDaemonPort();
|
|
||||||
const expectedEndpoint = `127.0.0.1:${port}`;
|
|
||||||
const expectedServerId = process.env.E2E_SERVER_ID;
|
|
||||||
if (!expectedServerId) {
|
|
||||||
throw new Error("E2E_SERVER_ID is not set (expected from Playwright globalSetup).");
|
|
||||||
}
|
|
||||||
|
|
||||||
const snapshot = await page.evaluate(() => {
|
|
||||||
const registryRaw = localStorage.getItem("@paseo:daemon-registry");
|
|
||||||
const prefsRaw = localStorage.getItem("@paseo:create-agent-preferences");
|
|
||||||
return { registryRaw, prefsRaw };
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!snapshot.registryRaw) {
|
|
||||||
throw new Error("E2E expected @paseo:daemon-registry to be set before app load.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const { serverId, connections } = parseRegistryEntry(snapshot.registryRaw);
|
|
||||||
if (serverId !== expectedServerId) {
|
|
||||||
throw new Error(
|
|
||||||
`E2E expected seeded daemon serverId to be ${expectedServerId} (got ${serverId}).`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
assertDaemonConnections(connections, expectedEndpoint);
|
|
||||||
|
|
||||||
if (!snapshot.prefsRaw) {
|
|
||||||
throw new Error("E2E expected @paseo:create-agent-preferences to be set before app load.");
|
|
||||||
}
|
|
||||||
assertPreferencesMatch(snapshot.prefsRaw, serverId);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const gotoAppShell = async (page: Page) => {
|
export const gotoAppShell = async (page: Page) => {
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
await ensureE2EStorageSeeded(page);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const gotoHome = async (page: Page) => {
|
export const gotoHome = async (page: Page) => {
|
||||||
await gotoAppShell(page);
|
await gotoAppShell(page);
|
||||||
const composer = page.getByRole("textbox", { name: "Message agent..." });
|
const composer = page.getByRole("textbox", { name: "Message agent..." }).first();
|
||||||
if (
|
const entryButton = page
|
||||||
!(await composer
|
.getByText("Add a project", { exact: true })
|
||||||
.first()
|
.or(page.getByText("Add project", { exact: true }))
|
||||||
.isVisible()
|
.or(page.getByText("New agent", { exact: true }))
|
||||||
.catch(() => false))
|
.first();
|
||||||
) {
|
|
||||||
const addProjectCta = page.getByText("Add a project", { exact: true }).first();
|
|
||||||
const addProjectSidebar = page.getByText("Add project", { exact: true }).first();
|
|
||||||
const newAgentButton = page.getByText("New agent", { exact: true }).first();
|
|
||||||
|
|
||||||
await expect
|
await expect
|
||||||
.poll(
|
.poll(
|
||||||
async () =>
|
async () =>
|
||||||
(await addProjectCta.isVisible().catch(() => false)) ||
|
(await composer.isVisible().catch(() => false)) ||
|
||||||
(await addProjectSidebar.isVisible().catch(() => false)) ||
|
(await entryButton.isVisible().catch(() => false)),
|
||||||
(await newAgentButton.isVisible().catch(() => false)),
|
{ timeout: 10_000 },
|
||||||
{ timeout: 10000 },
|
)
|
||||||
)
|
.toBe(true);
|
||||||
.toBe(true);
|
|
||||||
|
|
||||||
if (await addProjectCta.isVisible().catch(() => false)) {
|
if (!(await composer.isVisible().catch(() => false))) {
|
||||||
await addProjectCta.click();
|
await entryButton.click();
|
||||||
} else if (await addProjectSidebar.isVisible().catch(() => false)) {
|
|
||||||
await addProjectSidebar.click();
|
|
||||||
} else {
|
|
||||||
await newAgentButton.click();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
await expect(composer.first()).toBeVisible({ timeout: 30000 });
|
|
||||||
|
await expect(composer).toBeVisible({ timeout: 30_000 });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const openSettings = async (page: Page) => {
|
export const openSettings = async (page: Page) => {
|
||||||
@@ -341,46 +160,6 @@ export const setWorkingDirectory = async (page: Page, directory: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const ensureHostSelected = async (page: Page) => {
|
export const ensureHostSelected = async (page: Page) => {
|
||||||
await ensureE2EStorageSeeded(page);
|
|
||||||
|
|
||||||
// Absolute verification that we're using the per-run e2e daemon (never :6767).
|
|
||||||
// Also self-heal a rare case where app code rewrites daemon IDs after boot, by
|
|
||||||
// realigning create-agent-preferences.serverId to the sole seeded daemon.
|
|
||||||
try {
|
|
||||||
await assertE2EUsesSeededTestDaemon(page);
|
|
||||||
} catch (error) {
|
|
||||||
const message = error instanceof Error ? error.message : String(error);
|
|
||||||
if (!/create-agent-preferences\.serverId/i.test(message)) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fix = await page.evaluate(() => {
|
|
||||||
const registryRaw = localStorage.getItem("@paseo:daemon-registry");
|
|
||||||
const prefsRaw = localStorage.getItem("@paseo:create-agent-preferences");
|
|
||||||
if (!registryRaw || !prefsRaw) return { ok: false, reason: "missing storage" } as const;
|
|
||||||
const registry = JSON.parse(registryRaw) as Array<{ serverId?: string }>;
|
|
||||||
const prefs = JSON.parse(prefsRaw) as { serverId?: string };
|
|
||||||
if (!Array.isArray(registry) || registry.length !== 1)
|
|
||||||
return { ok: false, reason: "registry shape" } as const;
|
|
||||||
const serverId = registry[0]?.serverId;
|
|
||||||
if (typeof serverId !== "string" || serverId.length === 0)
|
|
||||||
return { ok: false, reason: "missing serverId" } as const;
|
|
||||||
prefs.serverId = serverId;
|
|
||||||
localStorage.setItem("@paseo:create-agent-preferences", JSON.stringify(prefs));
|
|
||||||
// Prevent the fixture's init-script from overwriting the corrected prefs on reload.
|
|
||||||
const nonce = localStorage.getItem("@paseo:e2e-seed-nonce") ?? "1";
|
|
||||||
localStorage.setItem("@paseo:e2e-disable-default-seed-once", nonce);
|
|
||||||
return { ok: true } as const;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!fix.ok) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
await page.reload();
|
|
||||||
await assertE2EUsesSeededTestDaemon(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
const input = page.getByRole("textbox", { name: "Message agent..." });
|
const input = page.getByRole("textbox", { name: "Message agent..." });
|
||||||
await expect(input).toBeVisible();
|
await expect(input).toBeVisible();
|
||||||
|
|
||||||
@@ -392,7 +171,7 @@ export const ensureHostSelected = async (page: Page) => {
|
|||||||
if (await selectHostLabel.isVisible()) {
|
if (await selectHostLabel.isVisible()) {
|
||||||
await selectHostLabel.click();
|
await selectHostLabel.click();
|
||||||
|
|
||||||
// E2E safety: we enforce a single seeded daemon, so the option should be unambiguous.
|
// We enforce a single seeded daemon, so the option should be unambiguous.
|
||||||
const localhostOption = page.getByText("localhost", { exact: true }).first();
|
const localhostOption = page.getByText("localhost", { exact: true }).first();
|
||||||
const daemonIdOption = page
|
const daemonIdOption = page
|
||||||
.getByText(process.env.E2E_SERVER_ID ?? "srv_e2e_test_daemon", { exact: true })
|
.getByText(process.env.E2E_SERVER_ID ?? "srv_e2e_test_daemon", { exact: true })
|
||||||
@@ -657,40 +436,3 @@ export const createAgentInRepo = async (
|
|||||||
await setWorkingDirectory(page, config.directory);
|
await setWorkingDirectory(page, config.directory);
|
||||||
await createAgent(page, config.prompt);
|
await createAgent(page, config.prompt);
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function waitForAgentFinishUI(page: Page, timeout = 30000) {
|
|
||||||
// Wait for the stop button to disappear
|
|
||||||
const stopButton = page.getByRole("button", { name: /stop|cancel/i });
|
|
||||||
|
|
||||||
// First, let's debug what's happening - wait a bit to see the state
|
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
|
||||||
// Check if stop button is visible
|
|
||||||
const isVisible = await stopButton.isVisible().catch(() => false);
|
|
||||||
|
|
||||||
if (isVisible) {
|
|
||||||
// If stop button is still visible after permission denial,
|
|
||||||
// it might be that the agent is waiting for something.
|
|
||||||
// Let's check if there's a tool call result or other UI indication
|
|
||||||
|
|
||||||
// Look for any indication that the agent has processed the permission denial
|
|
||||||
const toolCallResult = page.getByText(/permission.*denied|denied|blocked/i);
|
|
||||||
|
|
||||||
// Wait for the tool call result to appear
|
|
||||||
await expect(toolCallResult)
|
|
||||||
.toBeVisible({ timeout: 10000 })
|
|
||||||
.catch(() => {
|
|
||||||
// If no specific message, just wait for the button to disappear
|
|
||||||
});
|
|
||||||
|
|
||||||
// Now wait for the stop button to disappear
|
|
||||||
await expect(stopButton).not.toBeVisible({ timeout });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getToolCallCount(page: Page): Promise<number> {
|
|
||||||
// Tool calls are rendered as ExpandableBadge components with tool names like Bash, Write, Read, etc.
|
|
||||||
// They appear as pressable badges in the agent stream
|
|
||||||
const toolCallBadges = page.locator('[data-testid="tool-call-badge"]');
|
|
||||||
return toolCallBadges.count();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -68,20 +68,6 @@ export async function getActiveTabTestId(page: Page): Promise<string | null> {
|
|||||||
|
|
||||||
// ─── Tab actions ───────────────────────────────────────────────────────────
|
// ─── Tab actions ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/** Click the new agent tab button in the tab bar. Creates a draft/chat tab directly. */
|
|
||||||
export async function clickNewTabButton(page: Page): Promise<void> {
|
|
||||||
const button = page.getByTestId("workspace-new-agent-tab").filter({ visible: true }).first();
|
|
||||||
await expect(button).toBeVisible({ timeout: 10_000 });
|
|
||||||
await button.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Click the new terminal button in the workspace tab bar. Creates a terminal tab directly. */
|
|
||||||
export async function clickNewTerminalButton(page: Page): Promise<void> {
|
|
||||||
const button = page.getByTestId("workspace-new-terminal").filter({ visible: true }).first();
|
|
||||||
await expect(button).toBeVisible({ timeout: 10_000 });
|
|
||||||
await button.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Press Cmd+T (macOS) or Ctrl+T (Linux/Windows) 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> {
|
export async function pressNewTabShortcut(page: Page): Promise<void> {
|
||||||
const modifier = process.platform === "darwin" ? "Meta" : "Control";
|
const modifier = process.platform === "darwin" ? "Meta" : "Control";
|
||||||
@@ -90,11 +76,6 @@ export async function pressNewTabShortcut(page: Page): Promise<void> {
|
|||||||
|
|
||||||
// ─── Tab bar assertions ───────────────────────────────────────────────────
|
// ─── Tab bar assertions ───────────────────────────────────────────────────
|
||||||
|
|
||||||
/** @deprecated The launcher panel was removed. Actions go directly to their target. */
|
|
||||||
export async function waitForLauncherPanel(_page: Page): Promise<void> {
|
|
||||||
// No-op: the launcher panel no longer exists.
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Assert the new agent tab button is visible in the tab bar. */
|
/** Assert the new agent tab button is visible in the tab bar. */
|
||||||
export async function assertNewChatTileVisible(page: Page): Promise<void> {
|
export async function assertNewChatTileVisible(page: Page): Promise<void> {
|
||||||
await expect(
|
await expect(
|
||||||
@@ -119,7 +100,7 @@ export async function clickNewChat(page: Page): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Click the new terminal button to create a terminal tab. */
|
/** Click the new terminal button to create a terminal tab. */
|
||||||
export async function clickTerminal(page: Page): Promise<void> {
|
export async function clickNewTerminal(page: Page): Promise<void> {
|
||||||
const button = page.getByTestId("workspace-new-terminal").filter({ visible: true }).first();
|
const button = page.getByTestId("workspace-new-terminal").filter({ visible: true }).first();
|
||||||
await expect(button).toBeVisible({ timeout: 10_000 });
|
await expect(button).toBeVisible({ timeout: 10_000 });
|
||||||
await button.click();
|
await button.click();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { expect, type Page } from "@playwright/test";
|
import { expect, type Page } from "@playwright/test";
|
||||||
import { clickNewChat, clickTerminal } from "./launcher";
|
import { clickNewChat, clickNewTerminal } from "./launcher";
|
||||||
import { setupDeterministicPrompt, waitForTerminalContent } from "./terminal-perf";
|
import { setupDeterministicPrompt, waitForTerminalContent } from "./terminal-perf";
|
||||||
|
|
||||||
function terminalSurface(page: Page) {
|
function terminalSurface(page: Page) {
|
||||||
@@ -20,7 +20,7 @@ export async function expectTerminalCwd(page: Page, expectedPath: string): Promi
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createStandaloneTerminalFromLauncher(page: Page): Promise<void> {
|
export async function createStandaloneTerminalFromLauncher(page: Page): Promise<void> {
|
||||||
await clickTerminal(page);
|
await clickNewTerminal(page);
|
||||||
await expect(terminalSurface(page)).toBeVisible({ timeout: 20_000 });
|
await expect(terminalSurface(page)).toBeVisible({ timeout: 20_000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import {
|
|||||||
assertNewChatTileVisible,
|
assertNewChatTileVisible,
|
||||||
assertTerminalTileVisible,
|
assertTerminalTileVisible,
|
||||||
assertSingleNewTabButton,
|
assertSingleNewTabButton,
|
||||||
clickNewTabButton,
|
|
||||||
pressNewTabShortcut,
|
pressNewTabShortcut,
|
||||||
clickNewChat,
|
clickNewChat,
|
||||||
clickTerminal,
|
clickNewTerminal,
|
||||||
countTabsOfKind,
|
countTabsOfKind,
|
||||||
getTabTestIds,
|
getTabTestIds,
|
||||||
waitForTabWithTitle,
|
waitForTabWithTitle,
|
||||||
@@ -77,7 +76,7 @@ test.describe("Tab creation", () => {
|
|||||||
test("clicking new agent tab creates a draft tab", async ({ page }) => {
|
test("clicking new agent tab creates a draft tab", async ({ page }) => {
|
||||||
await gotoWorkspace(page, workspaceId);
|
await gotoWorkspace(page, workspaceId);
|
||||||
|
|
||||||
await clickNewTabButton(page);
|
await clickNewChat(page);
|
||||||
|
|
||||||
// Draft composer should appear (the agent message input)
|
// Draft composer should appear (the agent message input)
|
||||||
const composer = page.getByRole("textbox", { name: "Message agent..." });
|
const composer = page.getByRole("textbox", { name: "Message agent..." });
|
||||||
@@ -92,7 +91,7 @@ test.describe("Tab creation", () => {
|
|||||||
test.setTimeout(45_000);
|
test.setTimeout(45_000);
|
||||||
await gotoWorkspace(page, workspaceId);
|
await gotoWorkspace(page, workspaceId);
|
||||||
|
|
||||||
await clickTerminal(page);
|
await clickNewTerminal(page);
|
||||||
|
|
||||||
// Terminal surface should appear
|
// Terminal surface should appear
|
||||||
const terminal = page.locator('[data-testid="terminal-surface"]');
|
const terminal = page.locator('[data-testid="terminal-surface"]');
|
||||||
@@ -141,7 +140,7 @@ test.describe("Terminal title propagation", () => {
|
|||||||
try {
|
try {
|
||||||
// Navigate to workspace and open a terminal
|
// Navigate to workspace and open a terminal
|
||||||
await gotoWorkspace(page, workspaceId);
|
await gotoWorkspace(page, workspaceId);
|
||||||
await clickTerminal(page);
|
await clickNewTerminal(page);
|
||||||
|
|
||||||
const terminal = page.locator('[data-testid="terminal-surface"]');
|
const terminal = page.locator('[data-testid="terminal-surface"]');
|
||||||
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
||||||
@@ -171,7 +170,7 @@ test.describe("Terminal title propagation", () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await gotoWorkspace(page, workspaceId);
|
await gotoWorkspace(page, workspaceId);
|
||||||
await clickTerminal(page);
|
await clickNewTerminal(page);
|
||||||
|
|
||||||
const terminal = page.locator('[data-testid="terminal-surface"]');
|
const terminal = page.locator('[data-testid="terminal-surface"]');
|
||||||
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
||||||
@@ -231,7 +230,7 @@ test.describe("Tab transitions (no flash)", () => {
|
|||||||
const terminal = page.locator('[data-testid="terminal-surface"]');
|
const terminal = page.locator('[data-testid="terminal-surface"]');
|
||||||
const elapsed = await measureTileTransition(
|
const elapsed = await measureTileTransition(
|
||||||
page,
|
page,
|
||||||
() => clickTerminal(page),
|
() => clickNewTerminal(page),
|
||||||
terminal.first(),
|
terminal.first(),
|
||||||
20_000,
|
20_000,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { expect, test } from "./fixtures";
|
import { expect, test } from "./fixtures";
|
||||||
import { clickTerminal } from "./helpers/launcher";
|
import { clickNewTerminal } from "./helpers/launcher";
|
||||||
import { setupDeterministicPrompt, waitForTerminalContent } from "./helpers/terminal-perf";
|
import { setupDeterministicPrompt, waitForTerminalContent } from "./helpers/terminal-perf";
|
||||||
|
|
||||||
test.describe("Workspace cwd correctness", () => {
|
test.describe("Workspace cwd correctness", () => {
|
||||||
@@ -11,7 +11,7 @@ test.describe("Workspace cwd correctness", () => {
|
|||||||
|
|
||||||
const workspace = await withWorkspace({ prefix: "workspace-cwd-main-" });
|
const workspace = await withWorkspace({ prefix: "workspace-cwd-main-" });
|
||||||
await workspace.navigateTo();
|
await workspace.navigateTo();
|
||||||
await clickTerminal(page);
|
await clickNewTerminal(page);
|
||||||
|
|
||||||
const terminal = page.locator('[data-testid="terminal-surface"]');
|
const terminal = page.locator('[data-testid="terminal-surface"]');
|
||||||
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
||||||
@@ -31,7 +31,7 @@ test.describe("Workspace cwd correctness", () => {
|
|||||||
|
|
||||||
const workspace = await withWorkspace({ worktree: true, prefix: "workspace-cwd-worktree-" });
|
const workspace = await withWorkspace({ worktree: true, prefix: "workspace-cwd-worktree-" });
|
||||||
await workspace.navigateTo();
|
await workspace.navigateTo();
|
||||||
await clickTerminal(page);
|
await clickNewTerminal(page);
|
||||||
|
|
||||||
const terminal = page.locator('[data-testid="terminal-surface"]');
|
const terminal = page.locator('[data-testid="terminal-surface"]');
|
||||||
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { existsSync } from "node:fs";
|
import { existsSync } from "node:fs";
|
||||||
import { expect, test } from "./fixtures";
|
import { expect, test } from "./fixtures";
|
||||||
import { createTempGitRepo } from "./helpers/workspace";
|
import { createTempGitRepo } from "./helpers/workspace";
|
||||||
import { clickTerminal, waitForTabBar } from "./helpers/launcher";
|
import { clickNewTerminal, waitForTabBar } from "./helpers/launcher";
|
||||||
import {
|
import {
|
||||||
connectWorkspaceSetupClient,
|
connectWorkspaceSetupClient,
|
||||||
createWorkspaceThroughDaemon,
|
createWorkspaceThroughDaemon,
|
||||||
@@ -86,7 +86,7 @@ test.describe("Workspace setup runtime authority", () => {
|
|||||||
await openHomeWithProject(page, repo.path);
|
await openHomeWithProject(page, repo.path);
|
||||||
await navigateToWorkspaceViaSidebar(page, workspaceId);
|
await navigateToWorkspaceViaSidebar(page, workspaceId);
|
||||||
|
|
||||||
await clickTerminal(page);
|
await clickNewTerminal(page);
|
||||||
|
|
||||||
const terminal = page.locator('[data-testid="terminal-surface"]');
|
const terminal = page.locator('[data-testid="terminal-surface"]');
|
||||||
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
await expect(terminal.first()).toBeVisible({ timeout: 20_000 });
|
||||||
|
|||||||
Reference in New Issue
Block a user