Files
lemana-vpn/tests/smoke.sh

185 lines
7.0 KiB
Bash
Executable File

#!/bin/sh
set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT INT TERM
export HOME="$TMP_DIR/home"
export LEMANA_VPN_BIN_DIR="$HOME/bin"
export LEMANA_VPN_CONFIG_DIR="$HOME/.config/lemana-vpn"
export OPENCONNECT_LITE_CONFIG_DIR="$HOME/.config/openconnect-lite"
mkdir -p "$HOME"
output="$(cd "$ROOT" && sh install.sh --dry-run --non-interactive --minimal)"
printf '%s\n' "$output" | grep -q 'Detected state:'
printf '%s\n' "$output" | grep -q 'Interactive prompts: off'
printf '%s\n' "$output" | grep -q 'Modules: bitwarden=0 touchid=0 sudoers=1 shell=1 app=1 autostart=1'
printf '%s\n' "$output" | grep -q 'Проверяю Homebrew-зависимости'
printf '%s\n' "$output" | grep -q 'Swift build может занять минуту'
printf '%s\n' "$output" | grep -q 'sudo install -d -m 755 -o root -g wheel /usr/local/sbin'
printf '%s\n' "$output" | grep -q 'swift build -c release --package-path'
printf '%s\n' "$output" | grep -q 'launchctl load'
printf '%s\n' "$output" | grep -q 'restart LemanaVPN.app if running'
esc="$(printf '\033')"
if printf '%s\n' "$output" | grep -q "$esc"; then
echo "non-tty dry-run output contains ANSI color codes" >&2
exit 1
fi
status_json="$(bash "$ROOT/bin/vpn-lemanapro.sh" --status --json)"
printf '%s\n' "$status_json" | grep -q '"modules":'
printf '%s\n' "$status_json" | grep -q '"app":'
grep -q 'LemanaVPN-openconnect-lite.log' "$ROOT/bin/vpn-lemanapro.sh"
grep -q '"event":"waiting"' "$ROOT/bin/vpn-lemanapro.sh"
grep -q -- '--patch-only' "$ROOT/bin/vpn-lemanapro.sh"
grep -q -- '--manual-sso' "$ROOT/bin/vpn-lemanapro.sh"
grep -q 'LEMANA_VPN_AUTOFILL_DISABLE' "$ROOT/bin/vpn-lemanapro.sh"
fake_webengine="$TMP_DIR/webengine_process.py"
cat > "$fake_webengine" <<'PY'
import json
import sys
class Browser:
def run(self, display_mode, credentials, url_pattern, rules):
argv = sys.argv.copy()
if display_mode == "hidden":
argv += ["-platform", "minimal"]
if credentials:
logger.info("Initiating autologin", cred=credentials)
for url_pattern, rules in auto_fill_rules.items():
script = QWebEngineScript()
script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
script.setWorldId(QWebEngineScript.ScriptWorldId.ApplicationWorld)
script.setSourceCode(
f"""
// ==UserScript==
// @include {url_pattern}
// ==/UserScript==
function autoFill() {{
{get_selectors(rules, credentials)}
setTimeout(autoFill, 1000);
}}
autoFill();
"""
)
self.page().scripts().insert(script)
def get_selectors(rules, credentials):
statements = []
for rule in rules:
selector = json.dumps(rule.selector)
if rule.action == "stop":
statements.append(
f"""var elem = document.querySelector({selector}); if (elem) {{ return; }}"""
)
elif rule.fill:
value = json.dumps(getattr(credentials, rule.fill, None))
if value:
statements.append(
f"""var elem = document.querySelector({selector}); if (elem) {{ elem.dispatchEvent(new Event("focus")); elem.value = {value}; elem.dispatchEvent(new Event("blur")); }}"""
)
else:
logger.warning(
"Credential info not available",
type=rule.fill,
possibilities=dir(credentials),
)
elif rule.action == "click":
statements.append(
f"""var elem = document.querySelector({selector}); if (elem) {{ elem.dispatchEvent(new Event("focus")); elem.click(); }}"""
)
return "\n".join(statements)
PY
LEMANA_VPN_WEBENGINE_PROCESS="$fake_webengine" \
LEMANA_VPN_OC_PYTHON=python3 \
LEMANA_VPN_PATCH_BACKUP_DIR="$TMP_DIR/patch-backups" \
bash "$ROOT/bin/vpn-lemanapro.sh" --patch-only >/dev/null
grep -q '"offscreen"' "$fake_webengine"
grep -q 'LEMANA_VPN_AUTOFILL_DISABLE' "$fake_webengine"
grep -q 'new RegExp' "$fake_webengine"
grep -q 'script.setWorldId(QWebEngineScript.ScriptWorldId.ApplicationWorld)' "$fake_webengine"
grep -q 'new Event("input", {{bubbles: true}})' "$fake_webengine"
if grep -q 'ScriptWorldId.MainWorld' "$fake_webengine"; then
echo "patched auto-fill should keep the original ApplicationWorld behavior" >&2
exit 1
fi
if grep -q '__lemanaVpnClicked' "$fake_webengine"; then
echo "patched auto-fill should stay stateless like the original working setup" >&2
exit 1
fi
if grep -q 'valueSetter' "$fake_webengine"; then
echo "patched auto-fill should use the original direct value assignment with input/change events" >&2
exit 1
fi
status_text="$(bash "$ROOT/bin/vpn-lemanapro.sh" --status)"
printf '%s\n' "$status_text" | grep -q 'Modules:'
printf '%s\n' "$status_text" | grep -q 'core='
printf '%s\n' "$status_text" | grep -q 'app='
printf '%s\n' "$status_text" | grep -q 'autostart='
uninstall_home="$TMP_DIR/uninstall-home"
mkdir -p "$uninstall_home"
uninstall_output="$(
HOME="$uninstall_home" \
LEMANA_VPN_BIN_DIR="$uninstall_home/bin" \
LEMANA_VPN_CONFIG_DIR="$uninstall_home/.config/lemana-vpn" \
OPENCONNECT_LITE_CONFIG_DIR="$uninstall_home/.config/openconnect-lite" \
sh "$ROOT/uninstall.sh" --dry-run --remove-keychain --remove-touchid-helper --remove-openconnect-lite
)"
printf '%s\n' "$uninstall_output" | grep -q 'Начинаю удаление Lemana VPN'
printf '%s\n' "$uninstall_output" | grep -q 'Проверяю runtime-патчи openconnect-lite'
printf '%s\n' "$uninstall_output" | grep -q 'Удаляю sudoers и DNS cleanup wrapper'
printf '%s\n' "$uninstall_output" | grep -q 'killall LemanaVPN # if running'
printf '%s\n' "$uninstall_output" | grep -q 'Удаляю VPN-записи из macOS Keychain'
if printf '%s\n' "$uninstall_output" | grep -q "$esc"; then
echo "non-tty uninstall dry-run output contains ANSI color codes" >&2
exit 1
fi
missing_user="lemana-smoke-missing-$$"
set +e
manual_output="$(
HOME="$HOME" \
LEMANA_VPN_USERNAME="$missing_user" \
LEMANA_VPN_USE_BITWARDEN=0 \
bash "$ROOT/bin/vpn-lemanapro.sh" --json 2>&1
)"
manual_code=$?
set -e
[ "$manual_code" -ne 0 ]
printf '%s\n' "$manual_output" | grep -q '"event":"keychain_required"'
printf '%s\n' "$manual_output" | grep -q 'vpn --configure-keychain'
if printf '%s\n' "$manual_output" | grep -q 'Cleaning up VPN DNS'; then
echo "missing manual credentials should fail before VPN cleanup trap is installed" >&2
exit 1
fi
fake_pwd="$TMP_DIR/fake-pwd"
mkdir -p "$fake_pwd/bin"
printf 'stale local cli\n' > "$fake_pwd/bin/vpn-lemanapro.sh"
piped_output="$(
cd "$fake_pwd" &&
LEMANA_VPN_RAW_BASE_URL="file://$ROOT" sh -s -- --dry-run --non-interactive --minimal --without-app < "$ROOT/install.sh"
)"
printf '%s\n' "$piped_output" | grep -q "curl -fsSL file://$ROOT/bin/vpn-lemanapro.sh"
if printf '%s\n' "$piped_output" | grep -q "$fake_pwd/bin/vpn-lemanapro.sh"; then
echo "piped install used stale PWD/bin/vpn-lemanapro.sh" >&2
exit 1
fi
printf 'smoke ok\n'