Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
1051
scripts/e2e/lib/plugins/assertions.mjs
Normal file
1051
scripts/e2e/lib/plugins/assertions.mjs
Normal file
File diff suppressed because it is too large
Load Diff
76
scripts/e2e/lib/plugins/clawhub.sh
Normal file
76
scripts/e2e/lib/plugins/clawhub.sh
Normal file
@@ -0,0 +1,76 @@
|
||||
run_plugins_clawhub_scenario() {
|
||||
if [ "${OPENCLAW_PLUGINS_E2E_CLAWHUB:-1}" = "0" ]; then
|
||||
echo "Skipping ClawHub plugin install and uninstall (OPENCLAW_PLUGINS_E2E_CLAWHUB=0)."
|
||||
else
|
||||
echo "Testing ClawHub plugin install and uninstall..."
|
||||
CLAWHUB_PLUGIN_SPEC="${OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC:-clawhub:@openclaw/kitchen-sink}"
|
||||
CLAWHUB_PLUGIN_ID="${OPENCLAW_PLUGINS_E2E_CLAWHUB_ID:-openclaw-kitchen-sink-fixture}"
|
||||
export CLAWHUB_PLUGIN_SPEC CLAWHUB_PLUGIN_ID
|
||||
|
||||
start_clawhub_fixture_server() {
|
||||
local fixture_dir="$1"
|
||||
local server_log="$fixture_dir/clawhub-fixture.log"
|
||||
local server_port_file="$fixture_dir/clawhub-fixture-port"
|
||||
local server_pid_file="$fixture_dir/clawhub-fixture-pid"
|
||||
|
||||
openclaw_plugins_validate_fixture_log_print_bytes || return $?
|
||||
|
||||
node scripts/e2e/lib/clawhub-fixture-server.cjs plugins "$server_port_file" >"$server_log" 2>&1 &
|
||||
local server_pid="$!"
|
||||
echo "$server_pid" >"$server_pid_file"
|
||||
openclaw_plugins_register_fixture_pid_file "$server_pid_file"
|
||||
|
||||
for _ in $(seq 1 100); do
|
||||
if [[ -s "$server_port_file" ]]; then
|
||||
export OPENCLAW_CLAWHUB_URL="http://127.0.0.1:$(cat "$server_port_file")"
|
||||
return 0
|
||||
fi
|
||||
if ! kill -0 "$server_pid" 2>/dev/null; then
|
||||
openclaw_plugins_print_fixture_log "$server_log"
|
||||
return 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
openclaw_plugins_print_fixture_log "$server_log"
|
||||
echo "Timed out waiting for ClawHub fixture server." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
if [[ "${OPENCLAW_PLUGINS_E2E_LIVE_CLAWHUB:-0}" = "1" ]]; then
|
||||
export OPENCLAW_CLAWHUB_URL="${OPENCLAW_CLAWHUB_URL:-${CLAWHUB_URL:-https://clawhub.ai}}"
|
||||
export NPM_CONFIG_REGISTRY="${OPENCLAW_PLUGINS_E2E_LIVE_NPM_REGISTRY:-https://registry.npmjs.org/}"
|
||||
else
|
||||
# Keep the release-path smoke hermetic; live ClawHub can rate-limit CI.
|
||||
if [[ -n "${OPENCLAW_CLAWHUB_URL:-}" || -n "${CLAWHUB_URL:-}" ]]; then
|
||||
echo "Ignoring ambient ClawHub URL for fixture-mode plugin E2E; set OPENCLAW_PLUGINS_E2E_LIVE_CLAWHUB=1 for live ClawHub."
|
||||
fi
|
||||
unset OPENCLAW_CLAWHUB_URL CLAWHUB_URL
|
||||
clawhub_fixture_dir="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-clawhub-fixture.XXXXXX")"
|
||||
local fixture_status=0
|
||||
start_clawhub_fixture_server "$clawhub_fixture_dir" || fixture_status="$?"
|
||||
if [[ "$fixture_status" -ne 0 ]]; then
|
||||
return "$fixture_status"
|
||||
fi
|
||||
fi
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs clawhub-preflight
|
||||
|
||||
run_plugins_openclaw_logged install-clawhub plugins install "$CLAWHUB_PLUGIN_SPEC"
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-clawhub-installed.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-clawhub-inspect.json" plugins inspect "$CLAWHUB_PLUGIN_ID" --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs clawhub-installed
|
||||
|
||||
openclaw_e2e_maybe_timeout "$OPENCLAW_PLUGINS_CLI_TIMEOUT" node "$OPENCLAW_ENTRY" plugins update "$CLAWHUB_PLUGIN_ID" >"$OPENCLAW_PLUGINS_TMP_DIR/plugins-clawhub-update.log" 2>&1
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-clawhub-updated.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-clawhub-updated-inspect.json" plugins inspect "$CLAWHUB_PLUGIN_ID" --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs clawhub-updated
|
||||
|
||||
run_plugins_openclaw_logged uninstall-clawhub plugins uninstall "$CLAWHUB_PLUGIN_SPEC" --force
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-clawhub-uninstalled.json" plugins list --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs clawhub-removed
|
||||
fi
|
||||
}
|
||||
284
scripts/e2e/lib/plugins/fixtures.sh
Normal file
284
scripts/e2e/lib/plugins/fixtures.sh
Normal file
@@ -0,0 +1,284 @@
|
||||
OPENCLAW_PLUGINS_FIXTURE_PID_FILES=()
|
||||
OPENCLAW_PLUGINS_FIXTURE_EXIT_TRAP_INSTALLED=0
|
||||
OPENCLAW_PLUGINS_FIXTURE_PREVIOUS_EXIT_ACTION=""
|
||||
|
||||
openclaw_plugins_read_positive_int_env() {
|
||||
local name="${1:?missing environment variable name}"
|
||||
local fallback="${2:?missing fallback value}"
|
||||
local value="${!name-}"
|
||||
if [[ -z "${!name+x}" ]]; then
|
||||
value="$fallback"
|
||||
fi
|
||||
if [[ ! "$value" =~ ^[0-9]+$ ]] || (( 10#$value < 1 )); then
|
||||
echo "invalid $name: $value" >&2
|
||||
return 2
|
||||
fi
|
||||
printf "%s\n" "$((10#$value))"
|
||||
}
|
||||
|
||||
openclaw_plugins_read_nonnegative_decimal_env() {
|
||||
local name="${1:?missing environment variable name}"
|
||||
local fallback="${2:?missing fallback value}"
|
||||
local value="${!name-}"
|
||||
if [[ -z "${!name+x}" ]]; then
|
||||
value="$fallback"
|
||||
fi
|
||||
if [[ ! "$value" =~ ^[0-9]+([.][0-9]+)?$ ]]; then
|
||||
echo "invalid $name: $value" >&2
|
||||
return 2
|
||||
fi
|
||||
printf "%s\n" "$value"
|
||||
}
|
||||
|
||||
openclaw_plugins_cleanup_fixture_servers() {
|
||||
local pid_file
|
||||
local pid
|
||||
for pid_file in "${OPENCLAW_PLUGINS_FIXTURE_PID_FILES[@]:-}"; do
|
||||
[[ -f "$pid_file" ]] || continue
|
||||
pid="$(cat "$pid_file" 2>/dev/null || true)"
|
||||
if [[ "$pid" =~ ^[0-9]+$ ]]; then
|
||||
openclaw_plugins_stop_fixture_process "$pid"
|
||||
fi
|
||||
rm -f "$pid_file"
|
||||
done
|
||||
}
|
||||
|
||||
openclaw_plugins_signal_fixture_process() {
|
||||
local pid="$1"
|
||||
local signal="$2"
|
||||
if kill -0 -- "-$pid" >/dev/null 2>&1; then
|
||||
kill "-$signal" -- "-$pid" >/dev/null 2>&1 || true
|
||||
return
|
||||
fi
|
||||
kill "-$signal" "$pid" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
openclaw_plugins_fixture_process_alive() {
|
||||
local pid="$1"
|
||||
kill -0 "$pid" >/dev/null 2>&1 || kill -0 -- "-$pid" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
openclaw_plugins_stop_fixture_process() {
|
||||
local pid="$1"
|
||||
local _
|
||||
local attempts interval
|
||||
attempts="$(openclaw_plugins_read_positive_int_env OPENCLAW_PLUGINS_FIXTURE_STOP_ATTEMPTS 40)" || return $?
|
||||
interval="$(openclaw_plugins_read_nonnegative_decimal_env OPENCLAW_PLUGINS_FIXTURE_STOP_INTERVAL_SECONDS 0.25)" || return $?
|
||||
if declare -F openclaw_e2e_stop_process >/dev/null 2>&1; then
|
||||
openclaw_e2e_stop_process "$pid"
|
||||
return
|
||||
fi
|
||||
openclaw_plugins_signal_fixture_process "$pid" TERM
|
||||
for _ in $(seq 1 "$attempts"); do
|
||||
! openclaw_plugins_fixture_process_alive "$pid" && { wait "$pid" >/dev/null 2>&1 || true; return; }
|
||||
sleep "$interval"
|
||||
done
|
||||
openclaw_plugins_signal_fixture_process "$pid" KILL
|
||||
wait "$pid" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
openclaw_plugins_print_fixture_log() {
|
||||
local log_file="$1"
|
||||
if declare -F docker_e2e_print_log >/dev/null 2>&1; then
|
||||
docker_e2e_print_log "$log_file"
|
||||
return
|
||||
fi
|
||||
if [ ! -f "$log_file" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local max_bytes
|
||||
max_bytes="$(openclaw_plugins_read_positive_int_env OPENCLAW_DOCKER_E2E_LOG_PRINT_BYTES 65536)" || return $?
|
||||
|
||||
local log_bytes
|
||||
log_bytes="$(wc -c <"$log_file" 2>/dev/null || echo 0)"
|
||||
log_bytes="${log_bytes//[[:space:]]/}"
|
||||
if ! [[ "$log_bytes" =~ ^[0-9]+$ ]]; then
|
||||
log_bytes="0"
|
||||
fi
|
||||
if [ "$log_bytes" -le "$max_bytes" ]; then
|
||||
cat "$log_file"
|
||||
return
|
||||
fi
|
||||
echo "--- ${log_file} truncated: showing last ${max_bytes} of ${log_bytes} bytes ---"
|
||||
tail -c "$max_bytes" "$log_file"
|
||||
}
|
||||
|
||||
openclaw_plugins_validate_fixture_log_print_bytes() {
|
||||
openclaw_plugins_read_positive_int_env OPENCLAW_DOCKER_E2E_LOG_PRINT_BYTES 65536 >/dev/null
|
||||
}
|
||||
|
||||
openclaw_plugins_register_fixture_pid_file() {
|
||||
local pid_file="$1"
|
||||
OPENCLAW_PLUGINS_FIXTURE_PID_FILES+=("$pid_file")
|
||||
openclaw_plugins_install_fixture_cleanup_trap
|
||||
}
|
||||
|
||||
openclaw_plugins_install_fixture_cleanup_trap() {
|
||||
if [[ "${OPENCLAW_PLUGINS_FIXTURE_EXIT_TRAP_INSTALLED:-0}" = "1" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local existing_trap
|
||||
existing_trap="$(trap -p EXIT || true)"
|
||||
if [[ -n "$existing_trap" && "$existing_trap" != *openclaw_plugins_fixture_exit_trap* ]]; then
|
||||
local existing_action="${existing_trap#trap -- }"
|
||||
existing_action="${existing_action% EXIT}"
|
||||
eval "OPENCLAW_PLUGINS_FIXTURE_PREVIOUS_EXIT_ACTION=$existing_action"
|
||||
fi
|
||||
|
||||
OPENCLAW_PLUGINS_FIXTURE_EXIT_TRAP_INSTALLED=1
|
||||
trap openclaw_plugins_fixture_exit_trap EXIT
|
||||
}
|
||||
|
||||
openclaw_plugins_fixture_exit_trap() {
|
||||
local status="$?"
|
||||
openclaw_plugins_cleanup_fixture_servers
|
||||
if [[ -n "${OPENCLAW_PLUGINS_FIXTURE_PREVIOUS_EXIT_ACTION:-}" ]]; then
|
||||
eval "$OPENCLAW_PLUGINS_FIXTURE_PREVIOUS_EXIT_ACTION"
|
||||
fi
|
||||
exit "$status"
|
||||
}
|
||||
|
||||
record_fixture_plugin_trust() {
|
||||
local plugin_id="$1"
|
||||
local plugin_root="$2"
|
||||
local enabled="$3"
|
||||
node scripts/e2e/lib/plugins/assertions.mjs record-fixture-plugin-trust "$plugin_id" "$plugin_root" "$enabled"
|
||||
}
|
||||
|
||||
write_demo_fixture_plugin() {
|
||||
local dir="$1"
|
||||
node scripts/e2e/lib/fixture.mjs plugin-demo "$dir"
|
||||
}
|
||||
|
||||
write_fixture_plugin() {
|
||||
local dir="$1"
|
||||
local id="$2"
|
||||
local version="$3"
|
||||
local method="$4"
|
||||
local name="$5"
|
||||
|
||||
node scripts/e2e/lib/fixture.mjs plugin "$dir" "$id" "$version" "$method" "$name"
|
||||
}
|
||||
|
||||
write_fixture_plugin_with_cli() {
|
||||
local dir="$1"
|
||||
local id="$2"
|
||||
local version="$3"
|
||||
local method="$4"
|
||||
local name="$5"
|
||||
local cli_root="$6"
|
||||
local cli_output="$7"
|
||||
|
||||
node scripts/e2e/lib/fixture.mjs plugin-cli "$dir" "$id" "$version" "$method" "$name" "$cli_root" "$cli_output"
|
||||
}
|
||||
|
||||
pack_fixture_plugin_with_cli_registry_dependency() {
|
||||
local pack_dir="$1"
|
||||
local output_tgz="$2"
|
||||
local id="$3"
|
||||
local version="$4"
|
||||
local method="$5"
|
||||
local name="$6"
|
||||
local cli_root="$7"
|
||||
local cli_output="$8"
|
||||
|
||||
mkdir -p "$pack_dir/package"
|
||||
node scripts/e2e/lib/fixture.mjs plugin-cli-registry-dep "$pack_dir/package" "$id" "$version" "$method" "$name" "$cli_root" "$cli_output"
|
||||
tar -czf "$output_tgz" -C "$pack_dir" package
|
||||
}
|
||||
|
||||
pack_fake_is_number_package() {
|
||||
local pack_dir="$1"
|
||||
local output_tgz="$2"
|
||||
|
||||
mkdir -p "$pack_dir/package"
|
||||
node scripts/e2e/lib/fixture.mjs fake-is-number-package "$pack_dir/package"
|
||||
tar -czf "$output_tgz" -C "$pack_dir" package
|
||||
}
|
||||
|
||||
write_fixture_plugin_with_vendored_dependency() {
|
||||
local dir="$1"
|
||||
local id="$2"
|
||||
local version="$3"
|
||||
local method="$4"
|
||||
local name="$5"
|
||||
|
||||
node scripts/e2e/lib/fixture.mjs plugin-vendored-dep "$dir" "$id" "$version" "$method" "$name"
|
||||
}
|
||||
|
||||
pack_fixture_plugin() {
|
||||
local pack_dir="$1"
|
||||
local output_tgz="$2"
|
||||
local id="$3"
|
||||
local version="$4"
|
||||
local method="$5"
|
||||
local name="$6"
|
||||
|
||||
mkdir -p "$pack_dir/package"
|
||||
write_fixture_plugin "$pack_dir/package" "$id" "$version" "$method" "$name"
|
||||
tar -czf "$output_tgz" -C "$pack_dir" package
|
||||
}
|
||||
|
||||
pack_fixture_plugin_with_invalid_extension_entry() {
|
||||
local pack_dir="$1"
|
||||
local output_tgz="$2"
|
||||
local id="$3"
|
||||
local version="$4"
|
||||
local method="$5"
|
||||
local name="$6"
|
||||
|
||||
mkdir -p "$pack_dir/package"
|
||||
write_fixture_plugin "$pack_dir/package" "$id" "$version" "$method" "$name"
|
||||
node --input-type=module - "$pack_dir/package/package.json" <<'NODE'
|
||||
import fs from "node:fs";
|
||||
|
||||
const packageJsonPath = process.argv[2];
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
||||
packageJson.openclaw.extensions = ["./index.js", " "];
|
||||
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, "utf8");
|
||||
NODE
|
||||
tar -czf "$output_tgz" -C "$pack_dir" package
|
||||
}
|
||||
|
||||
start_npm_fixture_registry() {
|
||||
local package_name="$1"
|
||||
local version="$2"
|
||||
local tarball="$3"
|
||||
local fixture_dir="$4"
|
||||
local server_log="$fixture_dir/npm-registry.log"
|
||||
local server_port_file="$fixture_dir/npm-registry-port"
|
||||
local server_pid_file="$fixture_dir/npm-registry-pid"
|
||||
|
||||
shift 4
|
||||
|
||||
openclaw_plugins_validate_fixture_log_print_bytes || return $?
|
||||
|
||||
node scripts/e2e/lib/plugins/npm-registry-server.mjs "$server_port_file" "$package_name" "$version" "$tarball" "$@" >"$server_log" 2>&1 &
|
||||
local server_pid="$!"
|
||||
echo "$server_pid" >"$server_pid_file"
|
||||
openclaw_plugins_register_fixture_pid_file "$server_pid_file"
|
||||
|
||||
for _ in $(seq 1 100); do
|
||||
if [[ -s "$server_port_file" ]]; then
|
||||
export NPM_CONFIG_REGISTRY="http://127.0.0.1:$(cat "$server_port_file")"
|
||||
return 0
|
||||
fi
|
||||
if ! kill -0 "$server_pid" 2>/dev/null; then
|
||||
openclaw_plugins_print_fixture_log "$server_log"
|
||||
return 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
openclaw_plugins_print_fixture_log "$server_log"
|
||||
echo "Timed out waiting for npm fixture registry." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
write_claude_bundle_fixture() {
|
||||
local bundle_root="$1"
|
||||
|
||||
node scripts/e2e/lib/fixture.mjs claude-bundle "$bundle_root"
|
||||
}
|
||||
45
scripts/e2e/lib/plugins/marketplace.sh
Normal file
45
scripts/e2e/lib/plugins/marketplace.sh
Normal file
@@ -0,0 +1,45 @@
|
||||
run_plugins_marketplace_scenario() {
|
||||
echo "Testing marketplace install and update flows..."
|
||||
marketplace_root="$HOME/.claude/plugins/marketplaces/fixture-marketplace"
|
||||
mkdir -p "$HOME/.claude/plugins" "$marketplace_root/.claude-plugin"
|
||||
write_fixture_plugin \
|
||||
"$marketplace_root/plugins/marketplace-shortcut" \
|
||||
"marketplace-shortcut" \
|
||||
"0.0.1" \
|
||||
"demo.marketplace.shortcut.v1" \
|
||||
"Marketplace Shortcut"
|
||||
write_fixture_plugin \
|
||||
"$marketplace_root/plugins/marketplace-direct" \
|
||||
"marketplace-direct" \
|
||||
"0.0.1" \
|
||||
"demo.marketplace.direct.v1" \
|
||||
"Marketplace Direct"
|
||||
node scripts/e2e/lib/fixture.mjs marketplace "$marketplace_root"
|
||||
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/marketplace-list.json" plugins marketplace list claude-fixtures --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs marketplace-list
|
||||
|
||||
run_plugins_openclaw_logged install-marketplace-shortcut plugins install marketplace-shortcut@claude-fixtures
|
||||
run_plugins_openclaw_logged install-marketplace-direct plugins install marketplace-direct --marketplace claude-fixtures
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-marketplace.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-marketplace-shortcut-inspect.json" plugins inspect marketplace-shortcut --runtime --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-marketplace-direct-inspect.json" plugins inspect marketplace-direct --runtime --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs marketplace-installed
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs marketplace-records
|
||||
|
||||
write_fixture_plugin \
|
||||
"$marketplace_root/plugins/marketplace-shortcut" \
|
||||
"marketplace-shortcut" \
|
||||
"0.0.2" \
|
||||
"demo.marketplace.shortcut.v2" \
|
||||
"Marketplace Shortcut"
|
||||
run_plugins_openclaw_logged update-marketplace-shortcut-dry-run plugins update marketplace-shortcut --dry-run
|
||||
run_plugins_openclaw_logged update-marketplace-shortcut plugins update marketplace-shortcut
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-marketplace-updated.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-marketplace-updated-inspect.json" plugins inspect marketplace-shortcut --runtime --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs marketplace-updated
|
||||
}
|
||||
120
scripts/e2e/lib/plugins/npm-registry-server.mjs
Normal file
120
scripts/e2e/lib/plugins/npm-registry-server.mjs
Normal file
@@ -0,0 +1,120 @@
|
||||
// Fixture npm registry server for plugin E2E scenarios.
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import http from "node:http";
|
||||
import path from "node:path";
|
||||
|
||||
const [portFile, ...packageArgs] = process.argv.slice(2);
|
||||
|
||||
if (!portFile || packageArgs.length === 0 || packageArgs.length % 3 !== 0) {
|
||||
console.error(
|
||||
"usage: npm-registry-server.mjs <port-file> <package-name> <version> <tarball-path> [...]",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const packages = new Map();
|
||||
for (let index = 0; index < packageArgs.length; index += 3) {
|
||||
const packageName = packageArgs[index];
|
||||
const version = packageArgs[index + 1];
|
||||
const tarballPath = packageArgs[index + 2];
|
||||
const archive = fs.readFileSync(tarballPath);
|
||||
const existing = packages.get(packageName) ?? {
|
||||
encodedPackageName: encodeURIComponent(packageName).replace("%40", "@"),
|
||||
packageName,
|
||||
latestVersion: version,
|
||||
versions: new Map(),
|
||||
};
|
||||
existing.latestVersion = version;
|
||||
existing.versions.set(version, {
|
||||
archive,
|
||||
dependencies: packageName === "@openclaw/demo-plugin-npm" ? { "is-number": "7.0.0" } : {},
|
||||
integrity: `sha512-${crypto.createHash("sha512").update(archive).digest("base64")}`,
|
||||
shasum: crypto.createHash("sha1").update(archive).digest("hex"),
|
||||
tarballName: path.basename(tarballPath),
|
||||
version,
|
||||
});
|
||||
packages.set(packageName, existing);
|
||||
}
|
||||
|
||||
const metadataFor = (entry, baseUrl) => ({
|
||||
name: entry.packageName,
|
||||
"dist-tags": { latest: entry.latestVersion },
|
||||
versions: Object.fromEntries(
|
||||
[...entry.versions.entries()].map(([version, versionEntry]) => [
|
||||
version,
|
||||
{
|
||||
dependencies: versionEntry.dependencies,
|
||||
name: entry.packageName,
|
||||
version,
|
||||
dist: {
|
||||
integrity: versionEntry.integrity,
|
||||
shasum: versionEntry.shasum,
|
||||
tarball: `${baseUrl}/${entry.encodedPackageName}/-/${versionEntry.tarballName}`,
|
||||
},
|
||||
},
|
||||
]),
|
||||
),
|
||||
});
|
||||
|
||||
function decodePackagePath(pathname) {
|
||||
try {
|
||||
return decodeURIComponent(pathname.slice(1));
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function findPackageForPath(pathname) {
|
||||
const packageName = decodePackagePath(pathname);
|
||||
return packageName === undefined ? undefined : packages.get(packageName);
|
||||
}
|
||||
|
||||
function findTarballForPath(pathname) {
|
||||
for (const entry of packages.values()) {
|
||||
const prefix = `/${entry.encodedPackageName}/-/`;
|
||||
if (!pathname.toLowerCase().startsWith(prefix.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
for (const versionEntry of entry.versions.values()) {
|
||||
if (pathname.endsWith(`/${versionEntry.tarballName}`)) {
|
||||
return versionEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
const url = new URL(request.url ?? "/", "http://127.0.0.1");
|
||||
const baseUrl = `http://127.0.0.1:${server.address().port}`;
|
||||
if (request.method !== "GET") {
|
||||
response.writeHead(405, { "content-type": "text/plain" });
|
||||
response.end("method not allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
const packageEntry = findPackageForPath(url.pathname);
|
||||
if (packageEntry) {
|
||||
response.writeHead(200, { "content-type": "application/json" });
|
||||
response.end(`${JSON.stringify(metadataFor(packageEntry, baseUrl))}\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
const tarballEntry = findTarballForPath(url.pathname);
|
||||
if (tarballEntry) {
|
||||
response.writeHead(200, {
|
||||
"content-type": "application/octet-stream",
|
||||
"content-length": String(tarballEntry.archive.length),
|
||||
});
|
||||
response.end(tarballEntry.archive);
|
||||
return;
|
||||
}
|
||||
|
||||
response.writeHead(404, { "content-type": "text/plain" });
|
||||
response.end(`not found: ${url.pathname}`);
|
||||
});
|
||||
|
||||
server.listen(0, "127.0.0.1", () => {
|
||||
fs.writeFileSync(portFile, String(server.address().port));
|
||||
});
|
||||
236
scripts/e2e/lib/plugins/sweep.sh
Normal file
236
scripts/e2e/lib/plugins/sweep.sh
Normal file
@@ -0,0 +1,236 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
source scripts/lib/openclaw-e2e-instance.sh
|
||||
source scripts/lib/docker-e2e-logs.sh
|
||||
OPENCLAW_PLUGINS_SWEEP_SOURCE_ONLY="${OPENCLAW_PLUGINS_SWEEP_SOURCE_ONLY:-0}"
|
||||
if [[ -z "${OPENCLAW_ENTRY:-}" && "$OPENCLAW_PLUGINS_SWEEP_SOURCE_ONLY" != "1" ]]; then
|
||||
OPENCLAW_ENTRY="$(openclaw_e2e_resolve_entrypoint)"
|
||||
fi
|
||||
export OPENCLAW_ENTRY
|
||||
OPENCLAW_PLUGINS_CREATED_TMP_DIR=0
|
||||
if [[ -z "${OPENCLAW_PLUGINS_TMP_DIR:-}" ]]; then
|
||||
OPENCLAW_PLUGINS_TMP_DIR="$(mktemp -d "/tmp/openclaw-plugins.XXXXXX")"
|
||||
OPENCLAW_PLUGINS_CREATED_TMP_DIR=1
|
||||
fi
|
||||
export OPENCLAW_PLUGINS_TMP_DIR
|
||||
OPENCLAW_PLUGINS_CLI_TIMEOUT="${OPENCLAW_PLUGINS_CLI_TIMEOUT:-180s}"
|
||||
mkdir -p "$OPENCLAW_PLUGINS_TMP_DIR"
|
||||
|
||||
run_plugins_openclaw_logged() {
|
||||
local label="$1"
|
||||
shift
|
||||
run_logged "$label" openclaw_e2e_maybe_timeout "$OPENCLAW_PLUGINS_CLI_TIMEOUT" node "$OPENCLAW_ENTRY" "$@"
|
||||
}
|
||||
|
||||
run_plugins_openclaw_capture() {
|
||||
local output_file="$1"
|
||||
shift
|
||||
openclaw_e2e_maybe_timeout "$OPENCLAW_PLUGINS_CLI_TIMEOUT" node "$OPENCLAW_ENTRY" "$@" >"$output_file"
|
||||
}
|
||||
|
||||
run_plugins_shell_logged() {
|
||||
local label="$1"
|
||||
shift
|
||||
local command="$1"
|
||||
run_logged "$label" openclaw_e2e_maybe_timeout "$OPENCLAW_PLUGINS_CLI_TIMEOUT" bash -c "$command"
|
||||
}
|
||||
|
||||
source scripts/e2e/lib/plugins/fixtures.sh
|
||||
source scripts/e2e/lib/plugins/marketplace.sh
|
||||
source scripts/e2e/lib/plugins/clawhub.sh
|
||||
|
||||
cleanup_openclaw_plugins_sweep() {
|
||||
openclaw_plugins_cleanup_fixture_servers
|
||||
if [[ "${OPENCLAW_PLUGINS_CREATED_TMP_DIR:-0}" = "1" ]]; then
|
||||
rm -rf "$OPENCLAW_PLUGINS_TMP_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$OPENCLAW_PLUGINS_SWEEP_SOURCE_ONLY" = "1" ]]; then
|
||||
return 0 2>/dev/null || { cleanup_openclaw_plugins_sweep; exit 0; }
|
||||
fi
|
||||
|
||||
trap cleanup_openclaw_plugins_sweep EXIT
|
||||
|
||||
openclaw_e2e_eval_test_state_from_b64 "${OPENCLAW_TEST_STATE_SCRIPT_B64:?missing OPENCLAW_TEST_STATE_SCRIPT_B64}"
|
||||
PACKAGE_VERSION="$(node -p 'require("./package.json").version')"
|
||||
OPENCLAW_PACKAGE_ACCEPTANCE_LEGACY_COMPAT="$(node scripts/e2e/lib/package-compat.mjs "$PACKAGE_VERSION")"
|
||||
export OPENCLAW_PACKAGE_ACCEPTANCE_LEGACY_COMPAT
|
||||
BUNDLED_PLUGIN_ROOT_DIR="extensions"
|
||||
OPENCLAW_PLUGIN_HOME="$HOME/.openclaw/$BUNDLED_PLUGIN_ROOT_DIR"
|
||||
|
||||
demo_plugin_id="demo-plugin"
|
||||
demo_plugin_root="$OPENCLAW_PLUGIN_HOME/$demo_plugin_id"
|
||||
write_demo_fixture_plugin "$demo_plugin_root"
|
||||
record_fixture_plugin_trust "$demo_plugin_id" "$demo_plugin_root" 1
|
||||
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-inspect.json" plugins inspect demo-plugin --runtime --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs demo-plugin
|
||||
|
||||
echo "Testing tgz install flow..."
|
||||
pack_dir="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-pack.XXXXXX")"
|
||||
pack_fixture_plugin "$pack_dir" "$OPENCLAW_PLUGINS_TMP_DIR/demo-plugin-tgz.tgz" demo-plugin-tgz 0.0.1 demo.tgz "Demo Plugin TGZ"
|
||||
|
||||
run_plugins_openclaw_logged install-tgz plugins install "$OPENCLAW_PLUGINS_TMP_DIR/demo-plugin-tgz.tgz"
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins2.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins2-inspect.json" plugins inspect demo-plugin-tgz --runtime --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-tgz
|
||||
|
||||
run_plugins_openclaw_logged uninstall-tgz plugins uninstall demo-plugin-tgz --force
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins2-uninstalled.json" plugins list --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-tgz-removed
|
||||
|
||||
echo "Testing install from local folder (plugins.load.paths)..."
|
||||
dir_plugin="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-dir.XXXXXX")"
|
||||
write_fixture_plugin "$dir_plugin" demo-plugin-dir 0.0.1 demo.dir "Demo Plugin DIR"
|
||||
|
||||
run_plugins_openclaw_logged install-dir plugins install "$dir_plugin"
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins3.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins3-inspect.json" plugins inspect demo-plugin-dir --runtime --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-dir "$dir_plugin"
|
||||
|
||||
openclaw_e2e_maybe_timeout "$OPENCLAW_PLUGINS_CLI_TIMEOUT" node "$OPENCLAW_ENTRY" plugins update demo-plugin-dir >"$OPENCLAW_PLUGINS_TMP_DIR/plugins-dir-update.log" 2>&1
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-dir-update-skipped
|
||||
|
||||
run_plugins_openclaw_logged uninstall-dir plugins uninstall demo-plugin-dir --force
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins3-uninstalled.json" plugins list --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-dir-removed
|
||||
|
||||
echo "Testing install from local folder with preinstalled dependencies..."
|
||||
dir_deps_plugin="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-dir-deps.XXXXXX")"
|
||||
write_fixture_plugin_with_vendored_dependency "$dir_deps_plugin" demo-plugin-dir-deps 0.0.1 demo.dir.deps "Demo Plugin DIR Deps"
|
||||
|
||||
run_plugins_openclaw_logged install-dir-deps plugins install "$dir_deps_plugin"
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-dir-deps.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-dir-deps-inspect.json" plugins inspect demo-plugin-dir-deps --runtime --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-dir-deps "$dir_deps_plugin"
|
||||
|
||||
run_plugins_openclaw_logged uninstall-dir-deps plugins uninstall demo-plugin-dir-deps --force
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-dir-deps-uninstalled.json" plugins list --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-dir-deps-removed
|
||||
|
||||
echo "Testing install from npm spec (file:)..."
|
||||
file_pack_dir="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-filepack.XXXXXX")"
|
||||
write_fixture_plugin "$file_pack_dir/package" demo-plugin-file 0.0.1 demo.file "Demo Plugin FILE"
|
||||
|
||||
run_plugins_openclaw_logged install-file plugins install "file:$file_pack_dir/package"
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins4.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins4-inspect.json" plugins inspect demo-plugin-file --runtime --json
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-file "$file_pack_dir/package"
|
||||
|
||||
run_plugins_openclaw_logged uninstall-file plugins uninstall demo-plugin-file --force
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins4-uninstalled.json" plugins list --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-file-removed
|
||||
|
||||
echo "Testing install and update from npm registry..."
|
||||
npm_pack_dir="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-npm-pack.XXXXXX")"
|
||||
npm_dep_pack_dir="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-npm-dep-pack.XXXXXX")"
|
||||
invalid_npm_pack_dir="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-invalid-metadata-pack.XXXXXX")"
|
||||
npm_registry_dir="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-npm-registry.XXXXXX")"
|
||||
pack_fixture_plugin_with_cli_registry_dependency "$npm_pack_dir" "$OPENCLAW_PLUGINS_TMP_DIR/demo-plugin-npm.tgz" demo-plugin-npm 0.0.1 demo.npm "Demo Plugin NPM" demo-npm "demo-plugin-npm:pong"
|
||||
pack_fake_is_number_package "$npm_dep_pack_dir" "$OPENCLAW_PLUGINS_TMP_DIR/is-number-7.0.0.tgz"
|
||||
pack_fixture_plugin_with_invalid_extension_entry "$invalid_npm_pack_dir" "$OPENCLAW_PLUGINS_TMP_DIR/demo-plugin-invalid-metadata.tgz" demo-plugin-invalid-metadata 0.0.1 demo.invalid.metadata "Demo Plugin Invalid Metadata"
|
||||
start_npm_fixture_registry "@openclaw/demo-plugin-npm" "0.0.1" "$OPENCLAW_PLUGINS_TMP_DIR/demo-plugin-npm.tgz" "$npm_registry_dir" "is-number" "7.0.0" "$OPENCLAW_PLUGINS_TMP_DIR/is-number-7.0.0.tgz" "@openclaw/demo-plugin-invalid-metadata" "0.0.1" "$OPENCLAW_PLUGINS_TMP_DIR/demo-plugin-invalid-metadata.tgz"
|
||||
|
||||
run_plugins_openclaw_logged install-npm plugins install "npm:@openclaw/demo-plugin-npm@0.0.1"
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-npm.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-npm-inspect.json" plugins inspect demo-plugin-npm --runtime --json
|
||||
run_plugins_shell_logged exec-npm-plugin-cli 'node "$OPENCLAW_ENTRY" demo-npm ping >"$OPENCLAW_PLUGINS_TMP_DIR/plugins-npm-cli.txt"'
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-npm
|
||||
|
||||
openclaw_e2e_maybe_timeout "$OPENCLAW_PLUGINS_CLI_TIMEOUT" node "$OPENCLAW_ENTRY" plugins update demo-plugin-npm >"$OPENCLAW_PLUGINS_TMP_DIR/plugins-npm-update.log" 2>&1
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-npm-update
|
||||
|
||||
run_plugins_openclaw_logged uninstall-npm plugins uninstall demo-plugin-npm --force
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-npm-uninstalled.json" plugins list --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-npm-removed
|
||||
|
||||
echo "Testing npm install rejects malformed package metadata..."
|
||||
if openclaw_e2e_maybe_timeout "$OPENCLAW_PLUGINS_CLI_TIMEOUT" node "$OPENCLAW_ENTRY" plugins install "npm:@openclaw/demo-plugin-invalid-metadata@0.0.1" >"$OPENCLAW_PLUGINS_TMP_DIR/plugins-invalid-openclaw-extensions.log" 2>&1; then
|
||||
cat "$OPENCLAW_PLUGINS_TMP_DIR/plugins-invalid-openclaw-extensions.log"
|
||||
echo "Expected malformed package metadata install to fail." >&2
|
||||
exit 1
|
||||
fi
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-invalid-openclaw-extensions-list.json" plugins list --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs invalid-openclaw-extensions
|
||||
|
||||
echo "Testing install from git repo and plugin CLI execution..."
|
||||
git_fixture_root="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-git.XXXXXX")"
|
||||
git_repo="$git_fixture_root/repo"
|
||||
git_repo_url="file://$git_repo"
|
||||
write_fixture_plugin_with_cli "$git_repo" demo-plugin-git 0.0.1 demo.git "Demo Plugin Git" demo-git "demo-plugin-git:pong"
|
||||
git -C "$git_repo" init -q
|
||||
git -C "$git_repo" config user.email "docker-e2e@openclaw.local"
|
||||
git -C "$git_repo" config user.name "OpenClaw Docker E2E"
|
||||
git -C "$git_repo" add -A
|
||||
git -C "$git_repo" commit -qm "test fixture"
|
||||
git_ref="$(git -C "$git_repo" rev-parse HEAD)"
|
||||
|
||||
run_plugins_openclaw_logged install-git plugins install "git:$git_repo_url@$git_ref"
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-git.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-git-inspect.json" plugins inspect demo-plugin-git --runtime --json
|
||||
run_plugins_shell_logged exec-git-plugin-cli 'node "$OPENCLAW_ENTRY" demo-git ping >"$OPENCLAW_PLUGINS_TMP_DIR/plugins-git-cli.txt"'
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-git "$git_repo_url" "$git_ref"
|
||||
|
||||
run_plugins_openclaw_logged uninstall-git plugins uninstall demo-plugin-git --force
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-git-uninstalled.json" plugins list --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-git-removed
|
||||
|
||||
echo "Testing git plugin update from moving ref..."
|
||||
git_update_fixture_root="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-git-update.XXXXXX")"
|
||||
git_update_repo="$git_update_fixture_root/repo"
|
||||
git_update_repo_url="file://$git_update_repo"
|
||||
write_fixture_plugin_with_cli "$git_update_repo" demo-plugin-git-update 0.0.1 demo.git.update.v1 "Demo Plugin Git Update" demo-git-update "demo-plugin-git-update:pong-v1"
|
||||
git -C "$git_update_repo" init -q
|
||||
git -C "$git_update_repo" config user.email "docker-e2e@openclaw.local"
|
||||
git -C "$git_update_repo" config user.name "OpenClaw Docker E2E"
|
||||
git -C "$git_update_repo" checkout -qb main
|
||||
git -C "$git_update_repo" add -A
|
||||
git -C "$git_update_repo" commit -qm "test fixture v1"
|
||||
git_update_ref_v1="$(git -C "$git_update_repo" rev-parse HEAD)"
|
||||
|
||||
run_plugins_openclaw_logged install-git-update plugins install "git:$git_update_repo_url@main"
|
||||
write_fixture_plugin_with_cli "$git_update_repo" demo-plugin-git-update 0.0.2 demo.git.update.v2 "Demo Plugin Git Update" demo-git-update "demo-plugin-git-update:pong-v2"
|
||||
git -C "$git_update_repo" add -A
|
||||
git -C "$git_update_repo" commit -qm "test fixture v2"
|
||||
|
||||
openclaw_e2e_maybe_timeout "$OPENCLAW_PLUGINS_CLI_TIMEOUT" node "$OPENCLAW_ENTRY" plugins update demo-plugin-git-update >"$OPENCLAW_PLUGINS_TMP_DIR/plugins-git-update.log" 2>&1
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-git-update.json" plugins list --json
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-git-update-inspect.json" plugins inspect demo-plugin-git-update --runtime --json
|
||||
run_plugins_shell_logged exec-updated-git-plugin-cli 'node "$OPENCLAW_ENTRY" demo-git-update ping >"$OPENCLAW_PLUGINS_TMP_DIR/plugins-git-update-cli.txt"'
|
||||
|
||||
node scripts/e2e/lib/plugins/assertions.mjs plugin-git-updated "$git_update_ref_v1"
|
||||
|
||||
echo "Testing Claude bundle enable and inspect flow..."
|
||||
bundle_plugin_id="claude-bundle-e2e"
|
||||
bundle_root="$OPENCLAW_PLUGIN_HOME/$bundle_plugin_id"
|
||||
write_claude_bundle_fixture "$bundle_root"
|
||||
record_fixture_plugin_trust "$bundle_plugin_id" "$bundle_root" 0
|
||||
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-bundle-disabled.json" plugins list --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs bundle-disabled
|
||||
|
||||
run_plugins_openclaw_logged enable-claude-bundle plugins enable claude-bundle-e2e
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugins-bundle-inspect.json" plugins inspect claude-bundle-e2e --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs bundle-inspect
|
||||
|
||||
echo "Testing plugin install visible after explicit restart..."
|
||||
slash_install_dir="$(mktemp -d "$OPENCLAW_PLUGINS_TMP_DIR/openclaw-plugin-slash-install.XXXXXX")"
|
||||
write_fixture_plugin "$slash_install_dir" slash-install-plugin 0.0.1 demo.slash.install "Slash Install Plugin"
|
||||
|
||||
run_plugins_openclaw_logged install-slash-plugin plugins install "$slash_install_dir"
|
||||
run_plugins_openclaw_capture "$OPENCLAW_PLUGINS_TMP_DIR/plugin-command-install-show.json" plugins inspect slash-install-plugin --runtime --json
|
||||
node scripts/e2e/lib/plugins/assertions.mjs slash-install
|
||||
|
||||
run_plugins_marketplace_scenario
|
||||
|
||||
run_plugins_clawhub_scenario
|
||||
Reference in New Issue
Block a user