fix(tests): iteration 16

This commit is contained in:
Mohamed Boudra
2026-03-13 13:43:34 +07:00
parent 40ebd1b730
commit e8b55eccab
8 changed files with 70 additions and 55 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
import { test, expect } from './fixtures';
import { gotoHome, openSettings } from './helpers/app';
import { gotoAppShell, openSettings } from './helpers/app';
test('daemon is connected in settings', async ({ page }) => {
const daemonPort = process.env.E2E_DAEMON_PORT;
@@ -11,7 +11,7 @@ test('daemon is connected in settings', async ({ page }) => {
throw new Error('E2E_SERVER_ID is not set (expected from globalSetup).');
}
await gotoHome(page);
await gotoAppShell(page);
await openSettings(page);
await expect(page.getByText(`127.0.0.1:${daemonPort}`)).toBeVisible();
+14
View File
@@ -199,6 +199,19 @@ function stripAnsi(input: string): string {
return input.replace(/\u001b\[[0-9;]*m/g, '');
}
function ensureRelayBuildArtifact(repoRoot: string): void {
const relayDistEntry = path.join(repoRoot, 'packages/relay/dist/e2ee.js');
if (existsSync(relayDistEntry)) {
return;
}
console.log('[e2e] Building @getpaseo/relay for daemon startup');
execSync('npm run build --workspace=@getpaseo/relay', {
cwd: repoRoot,
stdio: 'inherit',
});
}
function decodeOfferFromFragmentUrl(url: string): OfferPayload {
const marker = '#offer=';
const idx = url.indexOf(marker);
@@ -217,6 +230,7 @@ function decodeOfferFromFragmentUrl(url: string): OfferPayload {
export default async function globalSetup() {
const repoRoot = path.resolve(__dirname, '../../..');
ensureRelayBuildArtifact(repoRoot);
const envTestPath = path.join(repoRoot, '.env.test');
if (existsSync(envTestPath)) {
dotenv.config({ path: envTestPath });
@@ -165,8 +165,12 @@ export async function seedBottomAnchorAgent(input: {
};
}
function getVisibleChatScroll(page: Page) {
return page.locator('[data-testid="agent-chat-scroll"]:visible').first();
}
export async function readScrollMetrics(page: Page): Promise<ScrollMetrics> {
return page.getByTestId("agent-chat-scroll").evaluate((root: Element) => {
return getVisibleChatScroll(page).evaluate((root: Element) => {
const rootElement = root as HTMLElement;
const candidates = [rootElement, ...Array.from(rootElement.querySelectorAll("*"))];
const scrollElement =
@@ -194,7 +198,7 @@ export async function readScrollMetrics(page: Page): Promise<ScrollMetrics> {
}
export async function scrollUpFromBottom(page: Page, pixels: number): Promise<void> {
const scrollViewport = page.getByTestId("agent-chat-scroll");
const scrollViewport = getVisibleChatScroll(page);
await expect(scrollViewport).toHaveCount(1, { timeout: 30000 });
await scrollViewport.evaluate(
(root: Element, amount: number) => {
@@ -240,7 +244,7 @@ export async function scrollUpFromBottom(page: Page, pixels: number): Promise<vo
}
export async function waitForAgentReady(page: Page, expectedTailText?: string): Promise<void> {
await expect(page.getByTestId("agent-chat-scroll")).toBeVisible({ timeout: 60000 });
await expect(getVisibleChatScroll(page)).toBeVisible({ timeout: 60000 });
await expect(page.getByRole("textbox", { name: "Message agent..." }).first()).toBeVisible({
timeout: 60000,
});
@@ -287,9 +291,7 @@ export async function waitForContentGrowth(
}
export async function getChatContainerKey(page: Page): Promise<string | null> {
return page
.getByTestId("agent-chat-scroll")
.evaluate((element) => {
return getVisibleChatScroll(page).evaluate((element) => {
const nativeId = (element as HTMLElement).id;
const prefix = "agent-chat-scroll-";
return nativeId.startsWith(prefix) ? nativeId.slice(prefix.length) : null;
+25 -3
View File
@@ -136,14 +136,36 @@ async function assertE2EUsesSeededTestDaemon(page: Page): Promise<void> {
}
}
export const gotoHome = async (page: Page) => {
export const gotoAppShell = async (page: Page) => {
await page.goto('/');
await ensureE2EStorageSeeded(page);
await expect(page.getByText('New agent', { exact: true }).first()).toBeVisible();
};
export const gotoHome = async (page: Page) => {
await gotoAppShell(page);
const composer = page.getByRole('textbox', { name: 'Message agent...' });
if (!(await composer.first().isVisible().catch(() => false))) {
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 newAgentButton.click();
await expect
.poll(
async () =>
(await addProjectCta.isVisible().catch(() => false)) ||
(await addProjectSidebar.isVisible().catch(() => false)) ||
(await newAgentButton.isVisible().catch(() => false)),
{ timeout: 10000 }
)
.toBe(true);
if (await addProjectCta.isVisible().catch(() => false)) {
await addProjectCta.click();
} else if (await addProjectSidebar.isVisible().catch(() => false)) {
await addProjectSidebar.click();
} else {
await newAgentButton.click();
}
}
await expect(composer.first()).toBeVisible({ timeout: 30000 });
};
+9 -12
View File
@@ -13,24 +13,21 @@
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": [
"./dist/index.js",
"./src/index.ts"
]
"node": "./dist/index.js",
"import": "./src/index.ts",
"default": "./src/index.ts"
},
"./e2ee": {
"types": "./dist/e2ee.d.ts",
"default": [
"./dist/e2ee.js",
"./src/e2ee.ts"
]
"node": "./dist/e2ee.js",
"import": "./src/e2ee.ts",
"default": "./src/e2ee.ts"
},
"./cloudflare": {
"types": "./dist/cloudflare-adapter.d.ts",
"default": [
"./dist/cloudflare-adapter.js",
"./src/cloudflare-adapter.ts"
]
"node": "./dist/cloudflare-adapter.js",
"import": "./src/cloudflare-adapter.ts",
"default": "./src/cloudflare-adapter.ts"
}
},
"scripts": {
@@ -284,23 +284,9 @@ describe("TerminalManager - Command Execution", () => {
5000
);
// First command
await manager.sendTextToCommand(
execResult.commandId,
"x = 5",
true,
{ lines: 50, maxWait: 2000 }
);
await manager.sendTextToCommand(execResult.commandId, "x = 5", true);
await manager.sendTextToCommand(execResult.commandId, "y = 3", true);
// Second command
await manager.sendTextToCommand(
execResult.commandId,
"y = 3",
true,
{ lines: 50, maxWait: 2000 }
);
// Third command - use variables
const output = await manager.sendTextToCommand(
execResult.commandId,
"print(x + y)",
@@ -449,24 +435,16 @@ describe("TerminalManager - Command Execution", () => {
expect(execResult.output).toContain(">"); // Node prompt
expect(execResult.isDead).toBe(false);
// Execute JavaScript
await manager.sendTextToCommand(
execResult.commandId,
"const x = [1, 2, 3]",
true,
{ lines: 50, maxWait: 2000 }
);
await manager.sendTextToCommand(execResult.commandId, "const x = [1, 2, 3]", true);
const output2 = await manager.sendTextToCommand(
execResult.commandId,
"x.map(n => n * 2)",
"console.log(x.map(n => n * 2).join(','))",
true,
{ lines: 50, maxWait: 2000 }
);
expect(output2).toContain("2");
expect(output2).toContain("4");
expect(output2).toContain("6");
expect(output2).toContain("2,4,6");
// Exit
await manager.sendTextToCommand(execResult.commandId, ".exit", true);
@@ -1,4 +1,3 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, test } from "vitest";
@@ -26,7 +25,9 @@ describe("resolveVoiceMcpBridgeFromRuntime", () => {
});
test("uses explicit script override when provided", () => {
const explicitScriptPath = path.resolve(process.cwd(), "scripts/mcp-stdio-socket-bridge-cli.mjs");
const explicitScriptPath = fileURLToPath(
new URL("../../scripts/mcp-stdio-socket-bridge-cli.mjs", bootstrapModuleUrl)
);
const result = resolveVoiceMcpBridgeFromRuntime({
bootstrapModuleUrl,
@@ -9,6 +9,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import pino from "pino";
import { createVoiceMcpSocketBridgeManager } from "./voice-mcp-bridge.js";
import { resolveVoiceMcpBridgeScriptPath } from "./voice-mcp-bridge-command.js";
describe("voice MCP bridge", () => {
test("proxies stdio MCP bytes through per-agent unix socket bridge", async () => {
@@ -54,12 +55,12 @@ describe("voice MCP bridge", () => {
const socketPath = await bridgeManager.ensureBridgeForCaller(callerAgentId);
const bridgeScript = path.resolve(process.cwd(), "scripts/mcp-stdio-socket-bridge-cli.mjs");
const transport = new StdioClientTransport({
command: process.execPath,
args: [
bridgeScript,
resolveVoiceMcpBridgeScriptPath({
bootstrapModuleUrl: import.meta.url,
}),
"--socket",
socketPath,
],