mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 01:29:56 +00:00
feat(browser): verify Chromium headless shell across platforms (#154396)
* docs(browser): audit engine licenses and non-AGPL alternatives Preserve the reviewed browser-stack change while incorporating the landed prerequisites. Original revision: 8f41f08a1e92c079ad19ab9f3b849be26cf1559b * feat(browser): verify Chromium headless shell across platforms Preserve the reviewed browser-stack change while incorporating the landed prerequisites. Original revision: b11dd7173db731e026b7abae9d3b4064ac30d300 * test(gateway): complete prepared placement read fixture Supply the required empty policyConfig in the placement lifecycle read fixture. This repairs the inherited check-test-types-core-4 failure while keeping the production browser-stack changes unchanged.
This commit is contained in:
parent
f7dc8adeee
commit
f5cf1b31e1
2 changed files with 52 additions and 9 deletions
|
|
@ -232,6 +232,42 @@ Engine startup, CDP connectivity, task completion, and full OpenClaw integration
|
|||
are separate checks. A running container or a successful `Browser.getVersion`
|
||||
does not prove that snapshots, references, and actions work through OpenClaw.
|
||||
|
||||
### Chromium headless shell baseline
|
||||
|
||||
For an alternative without Lightpanda's AGPL engine, first test Chromium's
|
||||
headless shell through the existing Chromium profile. It retains Chromium's
|
||||
third-party license obligations; this is not an MIT-only binary. It does not
|
||||
require another automation daemon or an OpenClaw engine adapter.
|
||||
|
||||
Use the repository-pinned Playwright installer rather than an unpinned wrapper:
|
||||
|
||||
```sh
|
||||
node node_modules/playwright-core/cli.js install chromium-headless-shell
|
||||
node node_modules/playwright-core/cli.js install --dry-run chromium-headless-shell
|
||||
```
|
||||
|
||||
The second command prints the selected version, platform download, and install
|
||||
directory. Locate `chrome-headless-shell` (or `chrome-headless-shell.exe` on
|
||||
Windows) in that directory. Linux also needs the browser's system libraries and
|
||||
fonts; see [Linux troubleshooting](/tools/browser-linux-troubleshooting).
|
||||
Run from the repository root, quoting paths that contain spaces:
|
||||
|
||||
```sh
|
||||
node --import ./scripts/tsx.mjs extensions/browser/scripts/bench-lightweight.ts --headless-shell "/path/to/chrome-headless-shell" --iterations 10 --output headless-shell-benchmark.json
|
||||
```
|
||||
|
||||
The report labels the requested distribution separately from its Chromium
|
||||
protocol engine and the observed browser version. `--headless-shell` selects
|
||||
the benchmark executable only: it does not install a production browser,
|
||||
change a profile, or establish binary provenance. Preserve its complete
|
||||
distribution and `LICENSE.headless_shell` when reviewing deployment. The installer
|
||||
also downloads platform helper assets, including FFmpeg; review and retain their
|
||||
own notices separately. Use
|
||||
separate invocations for the full Chromium and headless-shell comparisons;
|
||||
memory or startup savings must be measured, not inferred from download size.
|
||||
|
||||
### Native engine comparison
|
||||
|
||||
Run the opt-in synthetic route benchmark from the repository root after
|
||||
installing development dependencies:
|
||||
|
||||
|
|
@ -239,7 +275,7 @@ installing development dependencies:
|
|||
node --import ./scripts/tsx.mjs extensions/browser/scripts/bench-lightweight.ts --lightpanda /path/to/lightpanda --chromium /path/to/chrome --iterations 10 --output lightweight-benchmark.json
|
||||
```
|
||||
|
||||
Either binary flag can be used alone. The script creates isolated OpenClaw
|
||||
Any binary flag can be used alone. The script creates isolated OpenClaw
|
||||
state and browser data, serves a local form, then verifies navigation, the default
|
||||
efficient AI snapshot, reference-based typing/clicking, exactly one form
|
||||
submission, waiting, and text extraction through the browser route dispatcher.
|
||||
|
|
|
|||
|
|
@ -11,12 +11,16 @@ import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
|||
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
||||
|
||||
type Engine = "chromium" | "lightpanda";
|
||||
type Run = { engine: Engine; executable: string } | { engine: Engine; endpoint: string };
|
||||
type Distribution = "chromium" | "chromium-headless-shell" | "lightpanda";
|
||||
type Run =
|
||||
| { engine: Engine; distribution: Distribution; executable: string }
|
||||
| { engine: Engine; endpoint: string };
|
||||
|
||||
const { values } = parseArgs({
|
||||
options: {
|
||||
lightpanda: { type: "string" },
|
||||
chromium: { type: "string" },
|
||||
"headless-shell": { type: "string" },
|
||||
endpoint: { type: "string" },
|
||||
engine: { type: "string" },
|
||||
"fixture-bind": { type: "string", default: "127.0.0.1" },
|
||||
|
|
@ -33,7 +37,7 @@ assert(
|
|||
const runs: Run[] = [];
|
||||
if (values.endpoint) {
|
||||
assert(
|
||||
!values.lightpanda && !values.chromium,
|
||||
!values.lightpanda && !values.chromium && !values["headless-shell"],
|
||||
"Use either native binaries or an external --endpoint, not both.",
|
||||
);
|
||||
assert(
|
||||
|
|
@ -47,18 +51,19 @@ if (values.endpoint) {
|
|||
runs.push({ engine: values.engine, endpoint: values.endpoint });
|
||||
} else {
|
||||
assert(!values.engine, "--engine requires --endpoint.");
|
||||
for (const [engine, executable] of [
|
||||
["chromium", values.chromium],
|
||||
["lightpanda", values.lightpanda],
|
||||
for (const [engine, distribution, executable] of [
|
||||
["chromium", "chromium", values.chromium],
|
||||
["chromium", "chromium-headless-shell", values["headless-shell"]],
|
||||
["lightpanda", "lightpanda", values.lightpanda],
|
||||
] as const) {
|
||||
if (executable) {
|
||||
runs.push({ engine, executable: path.resolve(executable) });
|
||||
runs.push({ engine, distribution, executable: path.resolve(executable) });
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(
|
||||
runs.length > 0,
|
||||
"Pass --lightpanda <binary>, --chromium <binary>, or --endpoint <url> --engine <engine>.",
|
||||
"Pass --lightpanda <binary>, --chromium <binary>, --headless-shell <binary>, or --endpoint <url> --engine <engine>.",
|
||||
);
|
||||
|
||||
async function freePort() {
|
||||
|
|
@ -265,7 +270,7 @@ async function main() {
|
|||
let startupMs: number | null = null;
|
||||
let engineVersion: string | null = null;
|
||||
if ("executable" in spec) {
|
||||
const engineHome = path.join(scratchDir, engine);
|
||||
const engineHome = path.join(scratchDir, spec.distribution);
|
||||
await fs.mkdir(engineHome);
|
||||
const args =
|
||||
engine === "lightpanda"
|
||||
|
|
@ -513,6 +518,7 @@ async function main() {
|
|||
const sorted = tasks.map((item) => item.durationMs).toSorted((a, b) => a - b);
|
||||
return {
|
||||
engine,
|
||||
distribution: "distribution" in spec ? spec.distribution : null,
|
||||
engineVersion,
|
||||
connectionMode: proc ? "spawned" : "external",
|
||||
warmIterations: iterations,
|
||||
|
|
@ -586,6 +592,7 @@ async function main() {
|
|||
workload:
|
||||
"Local synthetic form through OpenClaw routes, no LLM. One first task includes initial page open/attachment; each measured warm task includes navigation, default efficient AI snapshot (Lightpanda selects aria refs), typing, exactly one submission, wait and text extraction. Capability/session checks run after measurement.",
|
||||
engineOrder: runs.map((spec) => spec.engine),
|
||||
distributionOrder: runs.map((spec) => ("distribution" in spec ? spec.distribution : null)),
|
||||
results,
|
||||
},
|
||||
null,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue