Files
OpenHands/playwright.live.config.ts
T
bad60ed8de Add live Agent Server E2E framework (#195)
* Add demo flow E2E coverage

* Add live Agent Server E2E

* Stabilize live E2E CI

* Stabilize live Agent Server E2E

* Use default pull request workflow triggers

* Organize Playwright E2E tests

* Comment live E2E results on PR

* Fix live E2E comment permissions

* Stabilize live E2E PR reporting

* Add collapsible live E2E evidence

* Embed live E2E media in PR report

* Use release assets for live E2E media

* Stabilize live E2E media and auth

* Use raw URLs for live E2E media

* Update tests for SDK workspace API

* Use PR artifacts for live E2E media

* Move live E2E scripts under tests

* chore: Update PR QA artifacts

* Clarify live E2E test layout

* Document and simplify live E2E local runs

* Remove unrelated non-test diffs

* Preserve HEAD git ref in workspace client

* Strengthen live Agent Server E2E

* chore: Update PR QA artifacts

* Remove workspace session URL normalization

* Remove obsolete mock E2E regressions

* Disable live E2E trace capture

* Harden live E2E workflow

* Harden live E2E review fixes

* Fix live E2E manual checkout

* chore: Update PR QA artifacts

* Address live E2E re-review feedback

* Address live E2E security review feedback

* Address live E2E approval suggestions

* chore: address PR review feedback (#195)

* chore: address live e2e review followups (#195)

* chore: Remove PR-only artifacts

* chore: address latest live e2e review

* fix(ci): drop --ignore-scripts so typescript-client git dep builds

After merging main (PR #278), source files import directly from
@openhands/typescript-client subpath exports (e.g. /clients,
/workspace/remote-workspace). These resolve to dist/ files that are
generated by the package's prepare script. The --ignore-scripts flag
on npm ci prevented that script from running, so CI's typecheck
failed with TS2307 'Cannot find module' for every subpath import.

Main's CI uses plain 'npm ci' (no --ignore-scripts) and passes.
Align this branch to match.

Co-authored-by: openhands <openhands@all-hands.dev>

* fix: restore avatar-menu and css-isolation regression tests

These were moved from tests/ to tests/e2e/regressions/ in 08b8e12
but then mistakenly deleted in 5c5a39b. The live E2E framework is
additive — it should not remove existing browser regression coverage.

The placeholder.spec.ts is not restored since it was a no-op stub.

Co-authored-by: openhands <openhands@all-hands.dev>

---------

Co-authored-by: allhands-bot <allhands-bot@users.noreply.github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2026-05-12 14:19:24 -04:00

77 lines
2.6 KiB
TypeScript

import { defineConfig, devices } from "@playwright/test";
import { randomBytes } from "node:crypto";
const configuredLiveE2ESessionApiKey =
process.env.LIVE_E2E_SESSION_API_KEY?.trim();
const liveE2ESessionApiKey =
configuredLiveE2ESessionApiKey || randomBytes(32).toString("hex");
process.env.LIVE_E2E_SESSION_API_KEY = liveE2ESessionApiKey;
const liveE2EFrontendPort = process.env.LIVE_E2E_FRONTEND_PORT ?? "3101";
const liveE2EBackendURL =
process.env.LIVE_E2E_BACKEND_URL ?? "http://127.0.0.1:18100";
let liveE2EBackendPort: string;
try {
liveE2EBackendPort = new URL(liveE2EBackendURL).port || "18100";
} catch {
throw new Error("Invalid LIVE_E2E_BACKEND_URL. Expected an absolute URL.");
}
const liveE2EFrontendURL = `http://localhost:${liveE2EFrontendPort}/`;
const liveE2EVideoMode =
process.env.LIVE_E2E_RECORD_VIDEO === "on" ? "on" : "retain-on-failure";
function shellQuote(value: string) {
return `'${value.replaceAll("'", "'\\''")}'`;
}
function envAssignment(name: string, value: string) {
return `${name}=${shellQuote(value)}`;
}
export default defineConfig({
testDir: "./tests/e2e/live",
testMatch: /.*\.spec\.ts/,
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
workers: 1,
timeout: 180_000,
reporter: [
["line"],
["json", { outputFile: "test-results-live/results.json" }],
["html", { outputFolder: "playwright-report-live", open: "never" }],
],
outputDir: "test-results-live",
use: {
baseURL: liveE2EFrontendURL,
screenshot: "only-on-failure",
trace: "off",
video: liveE2EVideoMode,
},
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
],
// This live stack is intended for macOS/Linux shells and Ubuntu CI runners;
// the command below intentionally uses POSIX environment assignment syntax.
webServer: {
command:
"node -e \"const fs=require('node:fs'); for (const p of ['.tmp/live-e2e-state','node_modules/.vite']) fs.rmSync(p,{recursive:true,force:true});\" && " +
[
"OH_CANVAS_SAFE_STATE_DIR=.tmp/live-e2e-state",
envAssignment("SESSION_API_KEY", liveE2ESessionApiKey),
envAssignment("OH_SESSION_API_KEYS_0", liveE2ESessionApiKey),
envAssignment("OH_CANVAS_SAFE_BACKEND_PORT", liveE2EBackendPort),
envAssignment("VITE_SESSION_API_KEY", liveE2ESessionApiKey),
"VITE_DO_NOT_TRACK=1",
"VITE_ENABLE_BROWSER_TOOLS=false",
envAssignment("VITE_FRONTEND_PORT", liveE2EFrontendPort),
"npm run dev:minimal",
].join(" "),
url: liveE2EFrontendURL,
timeout: 120_000,
reuseExistingServer: false,
},
});