Skip to content

Commit cdcca39

Browse files
author
Shaw
committed
Merge remote-tracking branch 'origin/develop' into fix/pr-7714-7715-review-issues
# Conflicts: # packages/elizaos/templates-manifest.json # packages/homepage/package.json # scripts/ai-qa/route-catalog.ts
2 parents f146dc8 + 729b3e2 commit cdcca39

23 files changed

Lines changed: 586 additions & 63 deletions

File tree

.github/workflows/live-scenarios.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ jobs:
126126
bun run --cwd packages/core build
127127
echo "::endgroup::"
128128
129+
echo "::group::Build packages/shared"
130+
# plugin-agent-skills (and others) consume @elizaos/shared via dist
131+
# exports (RouteRequestContext, ReadJsonBodyOptions, route schemas).
132+
# Must build before any plugin that imports from it.
133+
bun run --cwd packages/shared build
134+
echo "::endgroup::"
135+
129136
provider_package=""
130137
if [ -n "${GROQ_API_KEY:-}" ]; then
131138
provider_package="plugins/plugin-groq"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
"dev:cloud": "concurrently -n api,web -c blue,magenta \"bun run dev:cloud:api\" \"bun run dev:cloud:web\"",
125125
"dev:cloud:api": "bun run --cwd packages/cloud-api dev",
126126
"dev:cloud:web": "bun run --cwd packages/cloud-frontend dev",
127-
"dev:cloud:full": "concurrently -n db,api,web -c yellow,blue,magenta \"bun run db:cloud:pglite\" \"bun run dev:cloud:api\" \"bun run dev:cloud:web\"",
127+
"dev:cloud:full": "bun run dev:cloud",
128128
"build:cloud": "bun run --cwd packages/cloud-api build && bun run --cwd packages/cloud-frontend build",
129129
"build:android:cloud": "node packages/app-core/scripts/run-mobile-build.mjs android-cloud",
130130
"build:android:system": "node packages/app-core/scripts/run-mobile-build.mjs android-system",

packages/app/test/ui-smoke/android-system-apps.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,15 @@ test("Phone, Contacts, WiFi, Messages, and Device Settings handle core interacti
176176
await page.getByTestId("phone-dial-key-3").click();
177177
await page.getByTestId("phone-dial-backspace").click();
178178
await expect(
179-
page.getByRole("status", { name: "phone.dialer.display" }),
179+
page.getByRole("status", { name: "Number being dialed" }),
180180
).toContainText("12");
181181
await page.getByRole("tab", { name: "Recent" }).click();
182-
await expect(page.getByText("phone.recent.empty", { exact: true })).toBeVisible();
182+
await expect(page.getByText("No recent calls.", { exact: true })).toBeVisible();
183183
const phoneContactsTab = page.getByRole("tab", { name: "Contacts" });
184184
if (await phoneContactsTab.isEnabled()) {
185185
await phoneContactsTab.click();
186186
await expect(
187-
page.getByText("phone.contacts.empty", { exact: true }),
187+
page.getByText("No contacts with phone numbers.", { exact: true }),
188188
).toBeVisible();
189189
} else {
190190
await expect(phoneContactsTab).toBeDisabled();
@@ -194,9 +194,9 @@ test("Phone, Contacts, WiFi, Messages, and Device Settings handle core interacti
194194
await openAppWindow(page, byName.get("contacts")!);
195195
await page.getByTestId("contacts-search").fill("ada");
196196
await page.getByTestId("contacts-new").click();
197-
await page.getByPlaceholder("contacts.form.namePlaceholder").fill("Ada Lovelace");
197+
await page.getByPlaceholder("Full name").fill("Ada Lovelace");
198198
await page.getByPlaceholder("+1 555 123 4567").fill("+1 555 0100");
199-
await page.getByRole("button", { name: "actions.cancel" }).click();
199+
await page.getByRole("button", { name: "Cancel" }).click();
200200
await expect(page.getByTestId("contacts-shell")).toBeVisible();
201201
await expectNoIssues(page, issues.splice(0), "contacts interactions");
202202

packages/app/test/ui-smoke/cloud-provisioning-startup.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ async function clickIfVisible(locator: ReturnType<Page["getByRole"]>) {
4242
}
4343

4444
for (const viewport of VIEWPORTS) {
45-
test(`cloud provisioning reaches chat from startup on ${viewport.name}`, async ({
46-
page,
47-
baseURL,
48-
}) => {
45+
test.skip(`cloud provisioning reaches chat from startup on ${viewport.name}`, async ({
46+
page,
47+
baseURL,
48+
}) => {
4949
const apiBase = apiBaseFromTest(baseURL);
5050
let provisionRequests = 0;
5151
let jobPollRequests = 0;

packages/app/test/ui-smoke/onboarding-full-flow.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,7 @@ async function expectRuntimeGateMounted(page: Page): Promise<void> {
131131
).toBeVisible();
132132
}
133133

134-
test.describe
135-
.serial("web onboarding — full flow (W1–W11)", () => {
134+
test.describe.skip("web onboarding — full flow (W1–W11)", () => {
136135
test("W1 cold launch renders the runtime gate landing", async ({
137136
page,
138137
}) => {

packages/cloud-api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"scripts": {
77
"lint": "biome check .",
88
"lint:fix": "biome check --write .",
9-
"dev": "bun run ../scripts/cloud/admin/sync-api-dev-vars.ts && wrangler dev --port ${API_DEV_PORT:-8787} --local",
9+
"dev": "node ../scripts/cloud/admin/dev/cloud-api-dev.mjs",
1010
"build": "tsc --noEmit",
1111
"deploy": "wrangler deploy",
1212
"codegen": "node src/_generate-router.mjs",

packages/cloud-api/test/e2e/group-e-agent-admin.test.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ describe("Group E: admin / docker-containers (live + 501 stubs)", () => {
245245
expect([400, 403]).toContain(res.status);
246246
});
247247

248-
test("GET /api/v1/admin/docker-containers/:id/logs is a 501 stub (auth required first)", async () => {
248+
test("GET /api/v1/admin/docker-containers/:id/logs is gated before route handling", async () => {
249249
if (!shouldRun()) return;
250250
const unauthed = await api.get(
251251
`/api/v1/admin/docker-containers/${FAKE_UUID}/logs`,
@@ -258,9 +258,11 @@ describe("Group E: admin / docker-containers (live + 501 stubs)", () => {
258258
headers: bearerHeaders(),
259259
},
260260
);
261-
expect(authed.status).toBe(501);
262-
const body = (await authed.json()) as { error?: string };
263-
expect(body.error).toBe("not_yet_migrated");
261+
expect([404, 501]).toContain(authed.status);
262+
if (authed.status === 501) {
263+
const body = (await authed.json()) as { error?: string };
264+
expect(body.error).toBe("not_yet_migrated");
265+
}
264266
});
265267

266268
test("GET /api/v1/admin/docker-containers/audit is a 501 stub", async () => {

packages/cloud-api/test/e2e/run-e2e-batches.mjs

Lines changed: 104 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { spawn, spawnSync } from "node:child_process";
2-
import { readdirSync } from "node:fs";
3-
import { dirname, join, relative } from "node:path";
2+
import { readdirSync, rmSync } from "node:fs";
3+
import { createConnection } from "node:net";
4+
import { dirname, join, relative, resolve } from "node:path";
45
import { fileURLToPath } from "node:url";
56

67
const testDir = dirname(fileURLToPath(import.meta.url));
@@ -14,10 +15,19 @@ const baseUrl =
1415
process.env.TEST_API_BASE_URL ||
1516
process.env.TEST_BASE_URL ||
1617
`http://localhost:${apiPort}`;
18+
const configuredDatabaseUrl =
19+
process.env.TEST_DATABASE_URL || process.env.DATABASE_URL || "";
20+
const pglitePort = process.env.TEST_PGLITE_PORT || "55433";
21+
const pgliteHost = process.env.PGLITE_HOST || "127.0.0.1";
22+
const pgliteDataDir =
23+
process.env.TEST_PGLITE_DATA_DIR || ".eliza/.pgdata-cloud-api-e2e";
24+
const pgliteMaxConnections =
25+
process.env.TEST_PGLITE_MAX_CONNECTIONS ||
26+
process.env.PGLITE_MAX_CONNECTIONS ||
27+
"16";
1728
const databaseUrl =
18-
process.env.TEST_DATABASE_URL ||
19-
process.env.DATABASE_URL ||
20-
"postgresql://eliza_test:test123@localhost:5432/eliza_test";
29+
configuredDatabaseUrl ||
30+
`postgresql://postgres@${pgliteHost}:${pglitePort}/postgres`;
2131
const e2eEnv = {
2232
...process.env,
2333
API_DEV_PORT: apiPort,
@@ -61,6 +71,93 @@ async function waitForHealth(processRef) {
6171
throw new Error(`[api-e2e] timed out waiting for ${baseUrl}/api/health`);
6272
}
6373

74+
function parsePGliteDataDir(url) {
75+
if (!url?.startsWith("pglite://")) return null;
76+
const dataDir = url.slice("pglite://".length);
77+
if (!dataDir || dataDir === "memory") return null;
78+
return dataDir;
79+
}
80+
81+
async function tcpOk(host, port) {
82+
return new Promise((resolveOk) => {
83+
const socket = createConnection({ host, port: Number(port) });
84+
socket.setTimeout(1_000);
85+
socket.once("connect", () => {
86+
socket.end();
87+
resolveOk(true);
88+
});
89+
socket.once("timeout", () => {
90+
socket.destroy();
91+
resolveOk(false);
92+
});
93+
socket.once("error", () => {
94+
socket.destroy();
95+
resolveOk(false);
96+
});
97+
});
98+
}
99+
100+
async function waitForTcp(processRef, host, port) {
101+
const deadline = Date.now() + 90_000;
102+
while (Date.now() < deadline) {
103+
if (await tcpOk(host, port)) return;
104+
if (processRef.exitCode !== null) {
105+
throw new Error(
106+
`[api-e2e] PGlite TCP server exited before becoming reachable (code ${processRef.exitCode})`,
107+
);
108+
}
109+
await new Promise((resolveWait) => setTimeout(resolveWait, 500));
110+
}
111+
throw new Error(
112+
`[api-e2e] timed out waiting for PGlite TCP server at ${host}:${port}`,
113+
);
114+
}
115+
116+
async function ensurePGliteBridge() {
117+
const usingPGliteBridge =
118+
!configuredDatabaseUrl || configuredDatabaseUrl.startsWith("pglite://");
119+
if (!usingPGliteBridge) return null;
120+
121+
const dataDir = parsePGliteDataDir(configuredDatabaseUrl) || pgliteDataDir;
122+
const shouldResetDefaultPGlite =
123+
!configuredDatabaseUrl &&
124+
process.env.TEST_PGLITE_PERSIST !== "1" &&
125+
Boolean(dataDir);
126+
const alreadyRunning = await tcpOk(pgliteHost, pglitePort);
127+
128+
if (shouldResetDefaultPGlite) {
129+
if (alreadyRunning) {
130+
throw new Error(
131+
`[api-e2e] default PGlite server is already running at ${pgliteHost}:${pglitePort}; stop it before running isolated tests, or set TEST_PGLITE_PERSIST=1 to reuse it.`,
132+
);
133+
}
134+
rmSync(resolve(repoRoot, dataDir), { recursive: true, force: true });
135+
}
136+
137+
if (alreadyRunning) return null;
138+
139+
console.log(
140+
`[api-e2e] START PGlite TCP server at ${pgliteHost}:${pglitePort}`,
141+
);
142+
const child = spawn(
143+
bun,
144+
["run", "packages/scripts/cloud/admin/dev/pglite-server.ts"],
145+
{
146+
cwd: repoRoot,
147+
stdio: ["ignore", "inherit", "inherit"],
148+
env: {
149+
...e2eEnv,
150+
PGLITE_HOST: pgliteHost,
151+
PGLITE_PORT: pglitePort,
152+
PGLITE_MAX_CONNECTIONS: pgliteMaxConnections,
153+
...(dataDir ? { PGLITE_DATA_DIR: dataDir } : {}),
154+
},
155+
},
156+
);
157+
await waitForTcp(child, pgliteHost, pglitePort);
158+
return child;
159+
}
160+
64161
async function ensureServer() {
65162
if (process.env.REQUIRE_E2E_SERVER === "0") return null;
66163
if (await isHealthy()) return null;
@@ -102,6 +199,7 @@ const testFiles = readdirSync(testDir)
102199
.sort()
103200
.map((name) => relative(appRoot, join(testDir, name)));
104201

202+
const pgliteServer = await ensurePGliteBridge();
105203
ensureDatabase();
106204
const server = await ensureServer();
107205
try {
@@ -138,4 +236,5 @@ try {
138236
}
139237
} finally {
140238
stopServer(server);
239+
stopServer(pgliteServer);
141240
}

packages/cloud-frontend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
"preview": "bun --bun vite preview --port 3000 --strictPort",
1212
"typecheck": "tsc --noEmit",
1313
"test": "vitest run",
14-
"test:e2e": "../../../node_modules/.bin/playwright test",
15-
"test:e2e:update": "../../../node_modules/.bin/playwright test --update-snapshots",
14+
"test:e2e": "node scripts/run-e2e.mjs",
15+
"test:e2e:update": "node scripts/run-e2e.mjs --update-snapshots",
1616
"lint": "biome check .",
1717
"lint:fix": "biome check --write .",
1818
"format": "biome format --write src",

packages/cloud-frontend/playwright.config.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ export default defineConfig({
1616
},
1717
webServer: {
1818
command:
19-
"VITE_PLAYWRIGHT_TEST_AUTH=true VITE_ELIZA_RENDER_TELEMETRY=true bun run dev -- --host 127.0.0.1 --port 4173",
19+
"env -u FORCE_COLOR VITE_PLAYWRIGHT_TEST_AUTH=true VITE_ELIZA_RENDER_TELEMETRY=true bun --bun vite --host 127.0.0.1 --port 4173",
2020
url: "http://127.0.0.1:4173",
21-
reuseExistingServer: !process.env.CI,
21+
reuseExistingServer:
22+
process.env.CLOUD_FRONTEND_E2E_SERVER_STARTED === "1" || !process.env.CI,
2223
timeout: 120_000,
2324
},
2425
projects: [

0 commit comments

Comments
 (0)