Packages

Phoenix test harness with one API across static, LiveView, and browser drivers

Current section

Files

Jump to
cerberus bin firefox.sh
Raw

bin/firefox.sh

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
TMP_DIR="$ROOT_DIR/tmp"
CLI_FIREFOX_VERSION=""
CLI_GECKODRIVER_VERSION=""
PLATFORM_KEY=""
usage() {
cat <<'USAGE'
Usage: bin/firefox.sh [--firefox-version VERSION] [--geckodriver-version VERSION]
Ensures Firefox runtime binaries for Cerberus:
- ensures Firefox + GeckoDriver are installed under tmp,
- reuses existing binaries when already installed,
- prints resolved binary paths.
Options:
--firefox-version VERSION Override Firefox version for this run.
--geckodriver-version VERSION Override GeckoDriver version for this run.
-h, --help Show this help.
Environment:
CERBERUS_FIREFOX_VERSION Default Firefox version when --firefox-version is not provided.
CERBERUS_GECKODRIVER_VERSION Default GeckoDriver version when --geckodriver-version is not provided.
USAGE
}
fail() {
echo "ERROR: $*" >&2
exit 1
}
platform() {
case "$(uname -s):$(uname -m)" in
Darwin:arm64) echo "mac-arm64" ;;
Darwin:x86_64) echo "mac-x64" ;;
Linux:x86_64) echo "linux64" ;;
Linux:amd64) echo "linux64" ;;
Linux:aarch64) echo "linux-arm64" ;;
*) fail "unsupported platform $(uname -s):$(uname -m)" ;;
esac
}
resolve_default_firefox_version() {
local version
version="$(curl -fsSL "https://product-details.mozilla.org/1.0/firefox_versions.json" | jq -r '.LATEST_FIREFOX_VERSION // empty')"
[[ -n "$version" ]] || fail "unable to resolve latest Firefox version"
echo "$version"
}
resolve_firefox_version() {
if [[ -n "$CLI_FIREFOX_VERSION" ]]; then
echo "$CLI_FIREFOX_VERSION"
return
fi
if [[ -n "${CERBERUS_FIREFOX_VERSION:-}" ]]; then
echo "$CERBERUS_FIREFOX_VERSION"
return
fi
resolve_default_firefox_version
}
resolve_geckodriver_version() {
if [[ -n "$CLI_GECKODRIVER_VERSION" ]]; then
echo "$CLI_GECKODRIVER_VERSION"
return
fi
if [[ -n "${CERBERUS_GECKODRIVER_VERSION:-}" ]]; then
echo "$CERBERUS_GECKODRIVER_VERSION"
return
fi
echo "0.36.0"
}
firefox_download_url() {
local version="$1"
local platform_key="$2"
case "$platform_key" in
mac-arm64|mac-x64)
echo "https://archive.mozilla.org/pub/firefox/releases/${version}/mac/en-US/Firefox%20${version}.dmg"
;;
linux64)
echo "https://archive.mozilla.org/pub/firefox/releases/${version}/linux-x86_64/en-US/firefox-${version}.tar.xz"
;;
linux-arm64)
echo "https://archive.mozilla.org/pub/firefox/releases/${version}/linux-aarch64/en-US/firefox-${version}.tar.xz"
;;
*)
fail "unsupported Firefox platform key: $platform_key"
;;
esac
}
geckodriver_platform_key() {
local platform_key="$1"
case "$platform_key" in
mac-arm64) echo "macos-aarch64" ;;
mac-x64) echo "macos" ;;
linux64) echo "linux64" ;;
linux-arm64) echo "linux-aarch64" ;;
*) fail "unsupported GeckoDriver platform key: $platform_key" ;;
esac
}
geckodriver_download_url() {
local version="$1"
local platform_key="$2"
echo "https://github.com/mozilla/geckodriver/releases/download/v${version}/geckodriver-v${version}-${platform_key}.tar.gz"
}
version_of() {
local binary="$1"
"$binary" --version 2>/dev/null | grep -Eo '[0-9]+\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?' | head -n1 || true
}
install_firefox() {
local version="$1"
local platform_key="$2"
local install_dir="$TMP_DIR/firefox-${version}"
local payload_dir="$install_dir/payload"
local firefox_bin
local stable_firefox_bin="$install_dir/firefox"
local archive_file
local download_url
case "$platform_key" in
mac-arm64|mac-x64)
firefox_bin="$payload_dir/Firefox.app/Contents/MacOS/firefox"
if [[ ! -x "$firefox_bin" ]]; then
archive_file="$TMP_DIR/firefox-${version}-${platform_key}.dmg"
download_url="$(firefox_download_url "$version" "$platform_key")"
mkdir -p "$TMP_DIR"
curl -fsSL "$download_url" -o "$archive_file"
rm -rf "$install_dir"
mkdir -p "$payload_dir"
local mount_dir
mount_dir="$TMP_DIR/firefox-mount-${version}-${platform_key}"
mkdir -p "$mount_dir"
hdiutil attach "$archive_file" -nobrowse -readonly -mountpoint "$mount_dir" >/dev/null
cp -R "$mount_dir/Firefox.app" "$payload_dir/Firefox.app"
hdiutil detach "$mount_dir" >/dev/null || true
rmdir "$mount_dir" >/dev/null 2>&1 || true
fi
;;
linux64|linux-arm64)
firefox_bin="$payload_dir/firefox/firefox"
if [[ ! -x "$firefox_bin" ]]; then
archive_file="$TMP_DIR/firefox-${version}-${platform_key}.tar.xz"
download_url="$(firefox_download_url "$version" "$platform_key")"
mkdir -p "$TMP_DIR"
curl -fsSL "$download_url" -o "$archive_file"
rm -rf "$install_dir"
mkdir -p "$payload_dir"
tar -xf "$archive_file" -C "$payload_dir"
fi
;;
*)
fail "unsupported Firefox platform key: $platform_key"
;;
esac
[[ -x "$firefox_bin" ]] || fail "installed Firefox binary is not executable: $firefox_bin"
ln -sf "$firefox_bin" "$stable_firefox_bin"
[[ -x "$stable_firefox_bin" ]] || fail "stable firefox binary path is not executable: $stable_firefox_bin"
FIREFOX_BIN="$firefox_bin"
}
install_geckodriver() {
local version="$1"
local platform_key="$2"
local gecko_platform
local install_dir="$TMP_DIR/geckodriver-${version}"
local geckodriver_bin="$install_dir/geckodriver"
local archive_file
local download_url
gecko_platform="$(geckodriver_platform_key "$platform_key")"
if [[ ! -x "$geckodriver_bin" ]]; then
archive_file="$TMP_DIR/geckodriver-${version}-${gecko_platform}.tar.gz"
download_url="$(geckodriver_download_url "$version" "$gecko_platform")"
mkdir -p "$TMP_DIR"
curl -fsSL "$download_url" -o "$archive_file"
rm -rf "$install_dir"
mkdir -p "$install_dir"
tar -xzf "$archive_file" -C "$install_dir"
chmod +x "$geckodriver_bin"
fi
[[ -x "$geckodriver_bin" ]] || fail "installed GeckoDriver is not executable: $geckodriver_bin"
GECKODRIVER_BIN="$geckodriver_bin"
}
while [[ $# -gt 0 ]]; do
case "$1" in
--firefox-version)
[[ $# -ge 2 ]] || fail "missing value for --firefox-version"
CLI_FIREFOX_VERSION="$2"
shift 2
;;
--geckodriver-version)
[[ $# -ge 2 ]] || fail "missing value for --geckodriver-version"
CLI_GECKODRIVER_VERSION="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
fail "unknown argument: $1"
;;
esac
done
PLATFORM_KEY="$(platform)"
FIREFOX_VERSION_REQUESTED="$(resolve_firefox_version)"
GECKODRIVER_VERSION_REQUESTED="$(resolve_geckodriver_version)"
install_firefox "$FIREFOX_VERSION_REQUESTED" "$PLATFORM_KEY"
install_geckodriver "$GECKODRIVER_VERSION_REQUESTED" "$PLATFORM_KEY"
FIREFOX_VERSION="$(version_of "$FIREFOX_BIN")"
GECKODRIVER_VERSION="$(version_of "$GECKODRIVER_BIN")"
[[ -n "$FIREFOX_VERSION" ]] || fail "unable to determine Firefox version from $FIREFOX_BIN"
[[ -n "$GECKODRIVER_VERSION" ]] || fail "unable to determine GeckoDriver version from $GECKODRIVER_BIN"
echo "Firefox runtime ready"
echo "firefox_binary=$FIREFOX_BIN"
echo "firefox_version=$FIREFOX_VERSION"
echo "geckodriver_binary=$GECKODRIVER_BIN"
echo "geckodriver_version=$GECKODRIVER_VERSION"