mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
feat: per-platform Chromium versioning and build number support
- Add PLATFORM_CHROMIUM_VERSIONS map (Linux=v145, macOS=v142) - Add get_chromium_version()/getChromiumVersion() for platform-specific version - Make auto-update check release assets before offering updates - Scope version markers per-platform (latest_version_linux-x64) - Support 5th version segment for hotfix builds (e.g. 145.0.7632.109.2) - Derive AVAILABLE_PLATFORMS from version map
This commit is contained in:
+29
-13
@@ -10,10 +10,20 @@ from pathlib import Path
|
|||||||
from ._version import __version__
|
from ._version import __version__
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Chromium version shipped with this release
|
# Chromium version shipped with this release.
|
||||||
|
# Different platforms may ship different versions (e.g. Linux gets v145 first,
|
||||||
|
# macOS stays on v142 until Mac builds are ready).
|
||||||
|
# CHROMIUM_VERSION is the latest across all platforms (for display/reference).
|
||||||
|
# Use get_chromium_version() for the current platform's actual version.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
CHROMIUM_VERSION = "145.0.7632.109"
|
CHROMIUM_VERSION = "145.0.7632.109"
|
||||||
|
|
||||||
|
PLATFORM_CHROMIUM_VERSIONS: dict[str, str] = {
|
||||||
|
"linux-x64": "145.0.7632.109",
|
||||||
|
"darwin-arm64": "142.0.7444.175",
|
||||||
|
"darwin-x64": "142.0.7444.175",
|
||||||
|
}
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Default stealth arguments passed to the patched Chromium binary.
|
# Default stealth arguments passed to the patched Chromium binary.
|
||||||
# These activate source-level fingerprint patches compiled into the binary.
|
# These activate source-level fingerprint patches compiled into the binary.
|
||||||
@@ -70,9 +80,14 @@ SUPPORTED_PLATFORMS: dict[tuple[str, str], str] = {
|
|||||||
("Darwin", "x86_64"): "darwin-x64",
|
("Darwin", "x86_64"): "darwin-x64",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Platforms with pre-built binaries available for download.
|
# Platforms with pre-built binaries available for download (derived from version map).
|
||||||
# Update this set as new platform builds are released.
|
AVAILABLE_PLATFORMS: set[str] = set(PLATFORM_CHROMIUM_VERSIONS.keys())
|
||||||
AVAILABLE_PLATFORMS: set[str] = {"linux-x64", "darwin-arm64", "darwin-x64"}
|
|
||||||
|
|
||||||
|
def get_chromium_version() -> str:
|
||||||
|
"""Return the Chromium version for the current platform."""
|
||||||
|
tag = get_platform_tag()
|
||||||
|
return PLATFORM_CHROMIUM_VERSIONS.get(tag, CHROMIUM_VERSION)
|
||||||
|
|
||||||
|
|
||||||
def get_platform_tag() -> str:
|
def get_platform_tag() -> str:
|
||||||
@@ -105,7 +120,7 @@ def get_cache_dir() -> Path:
|
|||||||
|
|
||||||
def get_binary_dir(version: str | None = None) -> Path:
|
def get_binary_dir(version: str | None = None) -> Path:
|
||||||
"""Return the directory for a Chromium version binary."""
|
"""Return the directory for a Chromium version binary."""
|
||||||
v = version or CHROMIUM_VERSION
|
v = version or get_chromium_version()
|
||||||
return get_cache_dir() / f"chromium-{v}"
|
return get_cache_dir() / f"chromium-{v}"
|
||||||
|
|
||||||
|
|
||||||
@@ -141,23 +156,24 @@ def check_platform_available() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def get_effective_version() -> str:
|
def get_effective_version() -> str:
|
||||||
"""Return the best available version: auto-updated if available, else hardcoded.
|
"""Return the best available version: auto-updated if available, else platform default.
|
||||||
|
|
||||||
Reads the latest_version marker file from the cache directory.
|
Reads a platform-scoped marker file from the cache directory.
|
||||||
Returns CHROMIUM_VERSION if no update has been downloaded.
|
Returns the platform's hardcoded version if no update has been downloaded.
|
||||||
"""
|
"""
|
||||||
marker = get_cache_dir() / "latest_version"
|
base = get_chromium_version()
|
||||||
|
marker = get_cache_dir() / f"latest_version_{get_platform_tag()}"
|
||||||
if marker.exists():
|
if marker.exists():
|
||||||
try:
|
try:
|
||||||
version = marker.read_text().strip()
|
version = marker.read_text().strip()
|
||||||
if version and _version_newer(version, CHROMIUM_VERSION):
|
if version and _version_newer(version, base):
|
||||||
# Verify the binary actually exists
|
# Verify the binary actually exists
|
||||||
binary = get_binary_path(version)
|
binary = get_binary_path(version)
|
||||||
if binary.exists():
|
if binary.exists():
|
||||||
return version
|
return version
|
||||||
except (ValueError, OSError):
|
except (ValueError, OSError):
|
||||||
pass
|
pass
|
||||||
return CHROMIUM_VERSION
|
return base
|
||||||
|
|
||||||
|
|
||||||
def _version_tuple(v: str) -> tuple[int, ...]:
|
def _version_tuple(v: str) -> tuple[int, ...]:
|
||||||
@@ -187,14 +203,14 @@ GITHUB_DOWNLOAD_BASE_URL = (
|
|||||||
|
|
||||||
def get_download_url(version: str | None = None) -> str:
|
def get_download_url(version: str | None = None) -> str:
|
||||||
"""Return the full download URL for the current platform's binary archive."""
|
"""Return the full download URL for the current platform's binary archive."""
|
||||||
v = version or CHROMIUM_VERSION
|
v = version or get_chromium_version()
|
||||||
tag = get_platform_tag()
|
tag = get_platform_tag()
|
||||||
return f"{DOWNLOAD_BASE_URL}/chromium-v{v}/cloakbrowser-{tag}.tar.gz"
|
return f"{DOWNLOAD_BASE_URL}/chromium-v{v}/cloakbrowser-{tag}.tar.gz"
|
||||||
|
|
||||||
|
|
||||||
def get_fallback_download_url(version: str | None = None) -> str:
|
def get_fallback_download_url(version: str | None = None) -> str:
|
||||||
"""Return the GitHub Releases fallback URL for the binary archive."""
|
"""Return the GitHub Releases fallback URL for the binary archive."""
|
||||||
v = version or CHROMIUM_VERSION
|
v = version or get_chromium_version()
|
||||||
tag = get_platform_tag()
|
tag = get_platform_tag()
|
||||||
return f"{GITHUB_DOWNLOAD_BASE_URL}/chromium-v{v}/cloakbrowser-{tag}.tar.gz"
|
return f"{GITHUB_DOWNLOAD_BASE_URL}/chromium-v{v}/cloakbrowser-{tag}.tar.gz"
|
||||||
|
|
||||||
|
|||||||
+21
-11
@@ -30,6 +30,7 @@ from .config import (
|
|||||||
get_binary_dir,
|
get_binary_dir,
|
||||||
get_binary_path,
|
get_binary_path,
|
||||||
get_cache_dir,
|
get_cache_dir,
|
||||||
|
get_chromium_version,
|
||||||
get_download_url,
|
get_download_url,
|
||||||
get_effective_version,
|
get_effective_version,
|
||||||
get_fallback_download_url,
|
get_fallback_download_url,
|
||||||
@@ -76,18 +77,19 @@ def ensure_binary() -> str:
|
|||||||
_maybe_trigger_update_check()
|
_maybe_trigger_update_check()
|
||||||
return str(binary_path)
|
return str(binary_path)
|
||||||
|
|
||||||
# Fall back to hardcoded version if effective version binary doesn't exist
|
# Fall back to platform's hardcoded version if effective version binary doesn't exist
|
||||||
if effective != CHROMIUM_VERSION:
|
platform_version = get_chromium_version()
|
||||||
|
if effective != platform_version:
|
||||||
fallback_path = get_binary_path()
|
fallback_path = get_binary_path()
|
||||||
if fallback_path.exists() and _is_executable(fallback_path):
|
if fallback_path.exists() and _is_executable(fallback_path):
|
||||||
logger.debug("Binary found in cache: %s", fallback_path)
|
logger.debug("Binary found in cache: %s", fallback_path)
|
||||||
_maybe_trigger_update_check()
|
_maybe_trigger_update_check()
|
||||||
return str(fallback_path)
|
return str(fallback_path)
|
||||||
|
|
||||||
# Download hardcoded version
|
# Download platform's hardcoded version
|
||||||
logger.info(
|
logger.info(
|
||||||
"Stealth Chromium %s not found. Downloading for %s...",
|
"Stealth Chromium %s not found. Downloading for %s...",
|
||||||
CHROMIUM_VERSION,
|
platform_version,
|
||||||
get_platform_tag(),
|
get_platform_tag(),
|
||||||
)
|
)
|
||||||
_download_and_extract()
|
_download_and_extract()
|
||||||
@@ -168,7 +170,7 @@ def _verify_download_checksum(file_path: Path, version: str | None = None) -> No
|
|||||||
|
|
||||||
def _fetch_checksums(version: str | None = None) -> dict[str, str] | None:
|
def _fetch_checksums(version: str | None = None) -> dict[str, str] | None:
|
||||||
"""Fetch SHA256SUMS file for a version. Returns {filename: hash} or None."""
|
"""Fetch SHA256SUMS file for a version. Returns {filename: hash} or None."""
|
||||||
v = version or CHROMIUM_VERSION
|
v = version or get_chromium_version()
|
||||||
has_custom_url = os.environ.get("CLOAKBROWSER_DOWNLOAD_URL")
|
has_custom_url = os.environ.get("CLOAKBROWSER_DOWNLOAD_URL")
|
||||||
|
|
||||||
# Build URL list — respect custom URL contract (no GitHub fallback)
|
# Build URL list — respect custom URL contract (no GitHub fallback)
|
||||||
@@ -384,7 +386,7 @@ def check_for_update() -> str | None:
|
|||||||
latest = _get_latest_chromium_version()
|
latest = _get_latest_chromium_version()
|
||||||
if latest is None:
|
if latest is None:
|
||||||
return None
|
return None
|
||||||
if not _version_newer(latest, CHROMIUM_VERSION):
|
if not _version_newer(latest, get_chromium_version()):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
binary_dir = get_binary_dir(latest)
|
binary_dir = get_binary_dir(latest)
|
||||||
@@ -420,15 +422,22 @@ def _should_check_for_update() -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def _get_latest_chromium_version() -> str | None:
|
def _get_latest_chromium_version() -> str | None:
|
||||||
"""Hit GitHub Releases API, return latest chromium-v* version string or None."""
|
"""Hit GitHub Releases API, return latest chromium-v* version for this platform.
|
||||||
|
|
||||||
|
Checks that the release has a binary asset for the current platform,
|
||||||
|
so Linux-only releases won't be offered to macOS users.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
resp = httpx.get(
|
resp = httpx.get(
|
||||||
GITHUB_API_URL, params={"per_page": 10}, timeout=10.0
|
GITHUB_API_URL, params={"per_page": 10}, timeout=10.0
|
||||||
)
|
)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
|
platform_tarball = f"cloakbrowser-{get_platform_tag()}.tar.gz"
|
||||||
for release in resp.json():
|
for release in resp.json():
|
||||||
tag = release.get("tag_name", "")
|
tag = release.get("tag_name", "")
|
||||||
if tag.startswith("chromium-v") and not release.get("draft"):
|
if tag.startswith("chromium-v") and not release.get("draft"):
|
||||||
|
asset_names = {a["name"] for a in release.get("assets", [])}
|
||||||
|
if platform_tarball in asset_names:
|
||||||
return tag.removeprefix("chromium-v")
|
return tag.removeprefix("chromium-v")
|
||||||
return None
|
return None
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -437,10 +446,10 @@ def _get_latest_chromium_version() -> str | None:
|
|||||||
|
|
||||||
|
|
||||||
def _write_version_marker(version: str) -> None:
|
def _write_version_marker(version: str) -> None:
|
||||||
"""Write the latest version marker to cache dir."""
|
"""Write the latest version marker for this platform to cache dir."""
|
||||||
cache_dir = get_cache_dir()
|
cache_dir = get_cache_dir()
|
||||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||||
marker = cache_dir / "latest_version"
|
marker = cache_dir / f"latest_version_{get_platform_tag()}"
|
||||||
# Write to temp file then rename for atomicity
|
# Write to temp file then rename for atomicity
|
||||||
tmp = marker.with_suffix(".tmp")
|
tmp = marker.with_suffix(".tmp")
|
||||||
tmp.write_text(version)
|
tmp.write_text(version)
|
||||||
@@ -455,10 +464,11 @@ def _check_and_download_update() -> None:
|
|||||||
check_file.parent.mkdir(parents=True, exist_ok=True)
|
check_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
check_file.write_text(str(time.time()))
|
check_file.write_text(str(time.time()))
|
||||||
|
|
||||||
|
platform_version = get_chromium_version()
|
||||||
latest = _get_latest_chromium_version()
|
latest = _get_latest_chromium_version()
|
||||||
if latest is None:
|
if latest is None:
|
||||||
return
|
return
|
||||||
if not _version_newer(latest, CHROMIUM_VERSION):
|
if not _version_newer(latest, platform_version):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Already downloaded?
|
# Already downloaded?
|
||||||
@@ -469,7 +479,7 @@ def _check_and_download_update() -> None:
|
|||||||
logger.info(
|
logger.info(
|
||||||
"Newer Chromium available: %s (current: %s). Downloading in background...",
|
"Newer Chromium available: %s (current: %s). Downloading in background...",
|
||||||
latest,
|
latest,
|
||||||
CHROMIUM_VERSION,
|
platform_version,
|
||||||
)
|
)
|
||||||
_download_and_extract(version=latest)
|
_download_and_extract(version=latest)
|
||||||
_write_version_marker(latest)
|
_write_version_marker(latest)
|
||||||
|
|||||||
+25
-10
@@ -8,10 +8,20 @@ import os from "node:os";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Chromium version shipped with this release
|
// Chromium version shipped with this release.
|
||||||
|
// Different platforms may ship different versions (e.g. Linux gets v145 first,
|
||||||
|
// macOS stays on v142 until Mac builds are ready).
|
||||||
|
// CHROMIUM_VERSION is the latest across all platforms (for display/reference).
|
||||||
|
// Use getChromiumVersion() for the current platform's actual version.
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
export const CHROMIUM_VERSION = "145.0.7632.109";
|
export const CHROMIUM_VERSION = "145.0.7632.109";
|
||||||
|
|
||||||
|
export const PLATFORM_CHROMIUM_VERSIONS: Record<string, string> = {
|
||||||
|
"linux-x64": "145.0.7632.109",
|
||||||
|
"darwin-arm64": "142.0.7444.175",
|
||||||
|
"darwin-x64": "142.0.7444.175",
|
||||||
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Platform detection
|
// Platform detection
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -22,9 +32,13 @@ const SUPPORTED_PLATFORMS: Record<string, string> = {
|
|||||||
"darwin-x64": "darwin-x64",
|
"darwin-x64": "darwin-x64",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Platforms with pre-built binaries available for download.
|
// Platforms with pre-built binaries available for download (derived from version map).
|
||||||
// Update this set as new platform builds are released.
|
const AVAILABLE_PLATFORMS = new Set(Object.keys(PLATFORM_CHROMIUM_VERSIONS));
|
||||||
const AVAILABLE_PLATFORMS = new Set(["linux-x64", "darwin-arm64", "darwin-x64"]);
|
|
||||||
|
export function getChromiumVersion(): string {
|
||||||
|
const tag = getPlatformTag();
|
||||||
|
return PLATFORM_CHROMIUM_VERSIONS[tag] ?? CHROMIUM_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
export function getPlatformTag(): string {
|
export function getPlatformTag(): string {
|
||||||
const platform = process.platform;
|
const platform = process.platform;
|
||||||
@@ -56,7 +70,7 @@ export function getCacheDir(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getBinaryDir(version?: string): string {
|
export function getBinaryDir(version?: string): string {
|
||||||
return path.join(getCacheDir(), `chromium-${version || CHROMIUM_VERSION}`);
|
return path.join(getCacheDir(), `chromium-${version || getChromiumVersion()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBinaryPath(version?: string): string {
|
export function getBinaryPath(version?: string): string {
|
||||||
@@ -95,23 +109,24 @@ export const GITHUB_DOWNLOAD_BASE_URL =
|
|||||||
"https://github.com/CloakHQ/cloakbrowser/releases/download";
|
"https://github.com/CloakHQ/cloakbrowser/releases/download";
|
||||||
|
|
||||||
export function getDownloadUrl(version?: string): string {
|
export function getDownloadUrl(version?: string): string {
|
||||||
const v = version || CHROMIUM_VERSION;
|
const v = version || getChromiumVersion();
|
||||||
const tag = getPlatformTag();
|
const tag = getPlatformTag();
|
||||||
return `${DOWNLOAD_BASE_URL}/chromium-v${v}/cloakbrowser-${tag}.tar.gz`;
|
return `${DOWNLOAD_BASE_URL}/chromium-v${v}/cloakbrowser-${tag}.tar.gz`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFallbackDownloadUrl(version?: string): string {
|
export function getFallbackDownloadUrl(version?: string): string {
|
||||||
const v = version || CHROMIUM_VERSION;
|
const v = version || getChromiumVersion();
|
||||||
const tag = getPlatformTag();
|
const tag = getPlatformTag();
|
||||||
return `${GITHUB_DOWNLOAD_BASE_URL}/chromium-v${v}/cloakbrowser-${tag}.tar.gz`;
|
return `${GITHUB_DOWNLOAD_BASE_URL}/chromium-v${v}/cloakbrowser-${tag}.tar.gz`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEffectiveVersion(): string {
|
export function getEffectiveVersion(): string {
|
||||||
const marker = path.join(getCacheDir(), "latest_version");
|
const base = getChromiumVersion();
|
||||||
|
const marker = path.join(getCacheDir(), `latest_version_${getPlatformTag()}`);
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(marker)) {
|
if (fs.existsSync(marker)) {
|
||||||
const version = fs.readFileSync(marker, "utf-8").trim();
|
const version = fs.readFileSync(marker, "utf-8").trim();
|
||||||
if (version && versionNewer(version, CHROMIUM_VERSION)) {
|
if (version && versionNewer(version, base)) {
|
||||||
const binary = getBinaryPath(version);
|
const binary = getBinaryPath(version);
|
||||||
if (fs.existsSync(binary)) {
|
if (fs.existsSync(binary)) {
|
||||||
return version;
|
return version;
|
||||||
@@ -121,7 +136,7 @@ export function getEffectiveVersion(): string {
|
|||||||
} catch {
|
} catch {
|
||||||
// Marker unreadable — fall back to hardcoded
|
// Marker unreadable — fall back to hardcoded
|
||||||
}
|
}
|
||||||
return CHROMIUM_VERSION;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseVersion(v: string): number[] {
|
export function parseVersion(v: string): number[] {
|
||||||
|
|||||||
+22
-12
@@ -14,7 +14,6 @@ import { extract as tarExtract } from "tar";
|
|||||||
|
|
||||||
import type { BinaryInfo } from "./types.js";
|
import type { BinaryInfo } from "./types.js";
|
||||||
import {
|
import {
|
||||||
CHROMIUM_VERSION,
|
|
||||||
DOWNLOAD_BASE_URL,
|
DOWNLOAD_BASE_URL,
|
||||||
GITHUB_API_URL,
|
GITHUB_API_URL,
|
||||||
GITHUB_DOWNLOAD_BASE_URL,
|
GITHUB_DOWNLOAD_BASE_URL,
|
||||||
@@ -22,6 +21,7 @@ import {
|
|||||||
getBinaryDir,
|
getBinaryDir,
|
||||||
getBinaryPath,
|
getBinaryPath,
|
||||||
getCacheDir,
|
getCacheDir,
|
||||||
|
getChromiumVersion,
|
||||||
getDownloadUrl,
|
getDownloadUrl,
|
||||||
getEffectiveVersion,
|
getEffectiveVersion,
|
||||||
getFallbackDownloadUrl,
|
getFallbackDownloadUrl,
|
||||||
@@ -66,8 +66,9 @@ export async function ensureBinary(): Promise<string> {
|
|||||||
return binaryPath;
|
return binaryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to hardcoded version if effective version binary doesn't exist
|
// Fall back to platform's hardcoded version if effective version binary doesn't exist
|
||||||
if (effective !== CHROMIUM_VERSION) {
|
const platformVersion = getChromiumVersion();
|
||||||
|
if (effective !== platformVersion) {
|
||||||
const fallbackPath = getBinaryPath();
|
const fallbackPath = getBinaryPath();
|
||||||
if (fs.existsSync(fallbackPath) && isExecutable(fallbackPath)) {
|
if (fs.existsSync(fallbackPath) && isExecutable(fallbackPath)) {
|
||||||
maybeTriggerUpdateCheck();
|
maybeTriggerUpdateCheck();
|
||||||
@@ -75,9 +76,9 @@ export async function ensureBinary(): Promise<string> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download hardcoded version
|
// Download platform's hardcoded version
|
||||||
console.log(
|
console.log(
|
||||||
`[cloakbrowser] Stealth Chromium ${CHROMIUM_VERSION} not found. Downloading for ${getPlatformTag()}...`
|
`[cloakbrowser] Stealth Chromium ${platformVersion} not found. Downloading for ${getPlatformTag()}...`
|
||||||
);
|
);
|
||||||
await downloadAndExtract();
|
await downloadAndExtract();
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ export function binaryInfo(): BinaryInfo {
|
|||||||
/** Manually check for a newer Chromium version. Returns new version or null. */
|
/** Manually check for a newer Chromium version. Returns new version or null. */
|
||||||
export async function checkForUpdate(): Promise<string | null> {
|
export async function checkForUpdate(): Promise<string | null> {
|
||||||
const latest = await getLatestChromiumVersion();
|
const latest = await getLatestChromiumVersion();
|
||||||
if (!latest || !versionNewer(latest, CHROMIUM_VERSION)) return null;
|
if (!latest || !versionNewer(latest, getChromiumVersion())) return null;
|
||||||
|
|
||||||
const binaryDir = getBinaryDir(latest);
|
const binaryDir = getBinaryDir(latest);
|
||||||
if (fs.existsSync(binaryDir)) {
|
if (fs.existsSync(binaryDir)) {
|
||||||
@@ -209,7 +210,7 @@ async function verifyDownloadChecksum(filePath: string, version?: string): Promi
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchChecksums(version?: string): Promise<Map<string, string> | null> {
|
async function fetchChecksums(version?: string): Promise<Map<string, string> | null> {
|
||||||
const v = version || CHROMIUM_VERSION;
|
const v = version || getChromiumVersion();
|
||||||
const hasCustomUrl = !!process.env.CLOAKBROWSER_DOWNLOAD_URL;
|
const hasCustomUrl = !!process.env.CLOAKBROWSER_DOWNLOAD_URL;
|
||||||
|
|
||||||
// Respect custom URL contract — no GitHub fallback when custom URL is set
|
// Respect custom URL contract — no GitHub fallback when custom URL is set
|
||||||
@@ -437,7 +438,8 @@ function shouldCheckForUpdate(): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getLatestChromiumVersion(): Promise<string | null> {
|
/** @internal Exported for testing only. */
|
||||||
|
export async function getLatestChromiumVersion(): Promise<string | null> {
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(`${GITHUB_API_URL}?per_page=10`, {
|
const resp = await fetch(`${GITHUB_API_URL}?per_page=10`, {
|
||||||
signal: AbortSignal.timeout(10_000),
|
signal: AbortSignal.timeout(10_000),
|
||||||
@@ -446,10 +448,17 @@ async function getLatestChromiumVersion(): Promise<string | null> {
|
|||||||
const releases = (await resp.json()) as Array<{
|
const releases = (await resp.json()) as Array<{
|
||||||
tag_name: string;
|
tag_name: string;
|
||||||
draft: boolean;
|
draft: boolean;
|
||||||
|
assets: Array<{ name: string }>;
|
||||||
}>;
|
}>;
|
||||||
|
const platformTarball = `cloakbrowser-${getPlatformTag()}.tar.gz`;
|
||||||
for (const release of releases) {
|
for (const release of releases) {
|
||||||
if (release.tag_name.startsWith("chromium-v") && !release.draft) {
|
if (release.tag_name.startsWith("chromium-v") && !release.draft) {
|
||||||
return release.tag_name.replace("chromium-v", "");
|
const assetNames = new Set(
|
||||||
|
(release.assets ?? []).map((a) => a.name)
|
||||||
|
);
|
||||||
|
if (assetNames.has(platformTarball)) {
|
||||||
|
return release.tag_name.replace(/^chromium-v/, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -461,7 +470,7 @@ async function getLatestChromiumVersion(): Promise<string | null> {
|
|||||||
function writeVersionMarker(version: string): void {
|
function writeVersionMarker(version: string): void {
|
||||||
const cacheDir = getCacheDir();
|
const cacheDir = getCacheDir();
|
||||||
fs.mkdirSync(cacheDir, { recursive: true });
|
fs.mkdirSync(cacheDir, { recursive: true });
|
||||||
const marker = path.join(cacheDir, "latest_version");
|
const marker = path.join(cacheDir, `latest_version_${getPlatformTag()}`);
|
||||||
const tmp = `${marker}.tmp`;
|
const tmp = `${marker}.tmp`;
|
||||||
fs.writeFileSync(tmp, version);
|
fs.writeFileSync(tmp, version);
|
||||||
fs.renameSync(tmp, marker);
|
fs.renameSync(tmp, marker);
|
||||||
@@ -477,8 +486,9 @@ async function checkAndDownloadUpdate(): Promise<void> {
|
|||||||
String(Date.now())
|
String(Date.now())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const platformVersion = getChromiumVersion();
|
||||||
const latest = await getLatestChromiumVersion();
|
const latest = await getLatestChromiumVersion();
|
||||||
if (!latest || !versionNewer(latest, CHROMIUM_VERSION)) return;
|
if (!latest || !versionNewer(latest, platformVersion)) return;
|
||||||
|
|
||||||
// Already downloaded?
|
// Already downloaded?
|
||||||
if (fs.existsSync(getBinaryDir(latest))) {
|
if (fs.existsSync(getBinaryDir(latest))) {
|
||||||
@@ -487,7 +497,7 @@ async function checkAndDownloadUpdate(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`[cloakbrowser] Newer Chromium available: ${latest} (current: ${CHROMIUM_VERSION}). Downloading in background...`
|
`[cloakbrowser] Newer Chromium available: ${latest} (current: ${platformVersion}). Downloading in background...`
|
||||||
);
|
);
|
||||||
await downloadAndExtract(latest);
|
await downloadAndExtract(latest);
|
||||||
writeVersionMarker(latest);
|
writeVersionMarker(latest);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import {
|
import {
|
||||||
CHROMIUM_VERSION,
|
CHROMIUM_VERSION,
|
||||||
|
getChromiumVersion,
|
||||||
getDefaultStealthArgs,
|
getDefaultStealthArgs,
|
||||||
getCacheDir,
|
getCacheDir,
|
||||||
getBinaryDir,
|
getBinaryDir,
|
||||||
@@ -10,7 +11,7 @@ import { _buildArgsForTest } from "../src/playwright.js";
|
|||||||
|
|
||||||
describe("config", () => {
|
describe("config", () => {
|
||||||
it("CHROMIUM_VERSION matches expected format", () => {
|
it("CHROMIUM_VERSION matches expected format", () => {
|
||||||
expect(CHROMIUM_VERSION).toMatch(/^\d+\.\d+\.\d+\.\d+$/);
|
expect(CHROMIUM_VERSION).toMatch(/^\d+\.\d+\.\d+\.\d+(\.\d+)?$/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("getDefaultStealthArgs returns expected flags", () => {
|
it("getDefaultStealthArgs returns expected flags", () => {
|
||||||
@@ -53,14 +54,14 @@ describe("config", () => {
|
|||||||
expect(dir).toContain(".cloakbrowser");
|
expect(dir).toContain(".cloakbrowser");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("getBinaryDir includes version", () => {
|
it("getBinaryDir includes platform version", () => {
|
||||||
const dir = getBinaryDir();
|
const dir = getBinaryDir();
|
||||||
expect(dir).toContain(`chromium-${CHROMIUM_VERSION}`);
|
expect(dir).toContain(`chromium-${getChromiumVersion()}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("getDownloadUrl contains version and platform tag", () => {
|
it("getDownloadUrl contains platform version and platform tag", () => {
|
||||||
const url = getDownloadUrl();
|
const url = getDownloadUrl();
|
||||||
expect(url).toContain(CHROMIUM_VERSION);
|
expect(url).toContain(getChromiumVersion());
|
||||||
expect(url).toContain("cloakbrowser-");
|
expect(url).toContain("cloakbrowser-");
|
||||||
expect(url).toContain(".tar.gz");
|
expect(url).toContain(".tar.gz");
|
||||||
expect(url).toContain("cloakbrowser.dev");
|
expect(url).toContain("cloakbrowser.dev");
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import { binaryInfo } from "../src/download.js";
|
import { binaryInfo } from "../src/download.js";
|
||||||
import { CHROMIUM_VERSION } from "../src/config.js";
|
import { getChromiumVersion } from "../src/config.js";
|
||||||
|
|
||||||
describe("binaryInfo", () => {
|
describe("binaryInfo", () => {
|
||||||
it("returns correct structure", () => {
|
it("returns correct structure", () => {
|
||||||
const info = binaryInfo();
|
const info = binaryInfo();
|
||||||
|
|
||||||
expect(info.version).toBe(CHROMIUM_VERSION);
|
expect(info.version).toBe(getChromiumVersion());
|
||||||
expect(info.platform).toMatch(/^(linux|darwin)-(x64|arm64)$/);
|
expect(info.platform).toMatch(/^(linux|darwin)-(x64|arm64)$/);
|
||||||
expect(info.binaryPath).toBeTruthy();
|
expect(info.binaryPath).toBeTruthy();
|
||||||
expect(typeof info.installed).toBe("boolean");
|
expect(typeof info.installed).toBe("boolean");
|
||||||
|
|||||||
+100
-4
@@ -1,11 +1,14 @@
|
|||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect, vi, afterEach } from "vitest";
|
||||||
import {
|
import {
|
||||||
CHROMIUM_VERSION,
|
CHROMIUM_VERSION,
|
||||||
|
getChromiumVersion,
|
||||||
getDownloadUrl,
|
getDownloadUrl,
|
||||||
getEffectiveVersion,
|
getEffectiveVersion,
|
||||||
|
getPlatformTag,
|
||||||
parseVersion,
|
parseVersion,
|
||||||
versionNewer,
|
versionNewer,
|
||||||
} from "../src/config.js";
|
} from "../src/config.js";
|
||||||
|
import { getLatestChromiumVersion } from "../src/download.js";
|
||||||
|
|
||||||
describe("version comparison", () => {
|
describe("version comparison", () => {
|
||||||
it("parseVersion handles 4-part versions", () => {
|
it("parseVersion handles 4-part versions", () => {
|
||||||
@@ -32,13 +35,29 @@ describe("version comparison", () => {
|
|||||||
it("major bump wins over minor", () => {
|
it("major bump wins over minor", () => {
|
||||||
expect(versionNewer("143.0.0.0", "142.9.9999.999")).toBe(true);
|
expect(versionNewer("143.0.0.0", "142.9.9999.999")).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("parseVersion handles 5-part build numbers", () => {
|
||||||
|
expect(parseVersion("145.0.7632.109.2")).toEqual([145, 0, 7632, 109, 2]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("build bump detected", () => {
|
||||||
|
expect(versionNewer("145.0.7632.109.3", "145.0.7632.109.2")).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("build suffix newer than no suffix", () => {
|
||||||
|
expect(versionNewer("145.0.7632.109.2", "145.0.7632.109")).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("no suffix older than build suffix", () => {
|
||||||
|
expect(versionNewer("145.0.7632.109", "145.0.7632.109.2")).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("download URL", () => {
|
describe("download URL", () => {
|
||||||
it("uses chromium-v prefix and cloakbrowser repo", () => {
|
it("uses chromium-v prefix and cloakbrowser repo", () => {
|
||||||
const url = getDownloadUrl();
|
const url = getDownloadUrl();
|
||||||
expect(url).toContain("cloakbrowser.dev");
|
expect(url).toContain("cloakbrowser.dev");
|
||||||
expect(url).toContain(`chromium-v${CHROMIUM_VERSION}`);
|
expect(url).toContain(`chromium-v${getChromiumVersion()}`);
|
||||||
expect(url.endsWith(".tar.gz")).toBe(true);
|
expect(url.endsWith(".tar.gz")).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -53,9 +72,86 @@ describe("download URL", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("latest version (platform-aware)", () => {
|
||||||
|
const platformTarball = `cloakbrowser-${getPlatformTag()}.tar.gz`;
|
||||||
|
|
||||||
|
function makeAssets(platforms: string[]) {
|
||||||
|
return platforms.map((p) => ({ name: `cloakbrowser-${p}.tar.gz` }));
|
||||||
|
}
|
||||||
|
|
||||||
|
function mockFetch(releases: Array<Record<string, unknown>>) {
|
||||||
|
return vi.spyOn(globalThis, "fetch").mockResolvedValue({
|
||||||
|
ok: true,
|
||||||
|
json: async () => releases,
|
||||||
|
} as Response);
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns version when release has platform asset", async () => {
|
||||||
|
mockFetch([
|
||||||
|
{
|
||||||
|
tag_name: "chromium-v145.0.7718.0",
|
||||||
|
draft: false,
|
||||||
|
assets: makeAssets(["linux-x64", "darwin-arm64", "darwin-x64"]),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(await getLatestChromiumVersion()).toBe("145.0.7718.0");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("skips release without platform asset", async () => {
|
||||||
|
const spy = mockFetch([
|
||||||
|
{
|
||||||
|
tag_name: "chromium-v145.0.7718.0",
|
||||||
|
draft: false,
|
||||||
|
assets: makeAssets(["linux-x64"]), // Linux only
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag_name: "chromium-v142.0.7444.175",
|
||||||
|
draft: false,
|
||||||
|
assets: makeAssets(["linux-x64", "darwin-arm64", "darwin-x64"]),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const result = await getLatestChromiumVersion();
|
||||||
|
const tag = getPlatformTag();
|
||||||
|
if (tag === "linux-x64") {
|
||||||
|
expect(result).toBe("145.0.7718.0");
|
||||||
|
} else {
|
||||||
|
expect(result).toBe("142.0.7444.175");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null when no release has platform asset", async () => {
|
||||||
|
mockFetch([
|
||||||
|
{
|
||||||
|
tag_name: "chromium-v145.0.7718.0",
|
||||||
|
draft: false,
|
||||||
|
assets: [{ name: "cloakbrowser-windows-x64.tar.gz" }],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(await getLatestChromiumVersion()).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("skips draft releases", async () => {
|
||||||
|
const all = ["linux-x64", "darwin-arm64", "darwin-x64"];
|
||||||
|
mockFetch([
|
||||||
|
{ tag_name: "chromium-v999.0.0.0", draft: true, assets: makeAssets(all) },
|
||||||
|
{ tag_name: "chromium-v145.0.7718.0", draft: false, assets: makeAssets(all) },
|
||||||
|
]);
|
||||||
|
expect(await getLatestChromiumVersion()).toBe("145.0.7718.0");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns null on network error", async () => {
|
||||||
|
vi.spyOn(globalThis, "fetch").mockRejectedValue(new Error("timeout"));
|
||||||
|
expect(await getLatestChromiumVersion()).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("effective version", () => {
|
describe("effective version", () => {
|
||||||
it("returns CHROMIUM_VERSION when no marker exists", () => {
|
it("returns platform version when no marker exists", () => {
|
||||||
// Default behavior — no marker file in test environment
|
// Default behavior — no marker file in test environment
|
||||||
expect(getEffectiveVersion()).toBe(CHROMIUM_VERSION);
|
expect(getEffectiveVersion()).toBe(getChromiumVersion());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"""Basic launch tests for cloakbrowser."""
|
"""Basic launch tests for cloakbrowser."""
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from cloakbrowser import launch, launch_async, binary_info, CHROMIUM_VERSION
|
from cloakbrowser import launch, launch_async, binary_info
|
||||||
|
from cloakbrowser.config import get_chromium_version
|
||||||
|
|
||||||
|
|
||||||
def test_binary_info():
|
def test_binary_info():
|
||||||
@@ -11,7 +12,7 @@ def test_binary_info():
|
|||||||
assert "platform" in info
|
assert "platform" in info
|
||||||
assert "binary_path" in info
|
assert "binary_path" in info
|
||||||
assert "installed" in info
|
assert "installed" in info
|
||||||
assert info["version"] == CHROMIUM_VERSION
|
assert info["version"] == get_chromium_version()
|
||||||
|
|
||||||
|
|
||||||
def test_launch_and_close():
|
def test_launch_and_close():
|
||||||
|
|||||||
+87
-15
@@ -12,8 +12,10 @@ from cloakbrowser.config import (
|
|||||||
CHROMIUM_VERSION,
|
CHROMIUM_VERSION,
|
||||||
_version_newer,
|
_version_newer,
|
||||||
_version_tuple,
|
_version_tuple,
|
||||||
|
get_chromium_version,
|
||||||
get_download_url,
|
get_download_url,
|
||||||
get_effective_version,
|
get_effective_version,
|
||||||
|
get_platform_tag,
|
||||||
)
|
)
|
||||||
from cloakbrowser.download import (
|
from cloakbrowser.download import (
|
||||||
_get_latest_chromium_version,
|
_get_latest_chromium_version,
|
||||||
@@ -41,12 +43,27 @@ class TestVersionComparison:
|
|||||||
def test_major_bump(self):
|
def test_major_bump(self):
|
||||||
assert _version_newer("143.0.0.0", "142.9.9999.999") is True
|
assert _version_newer("143.0.0.0", "142.9.9999.999") is True
|
||||||
|
|
||||||
|
def test_5th_segment_parsing(self):
|
||||||
|
assert _version_tuple("145.0.7632.109.2") == (145, 0, 7632, 109, 2)
|
||||||
|
|
||||||
|
def test_build_bump(self):
|
||||||
|
assert _version_newer("145.0.7632.109.3", "145.0.7632.109.2") is True
|
||||||
|
|
||||||
|
def test_build_suffix_newer_than_no_suffix(self):
|
||||||
|
assert _version_newer("145.0.7632.109.2", "145.0.7632.109") is True
|
||||||
|
|
||||||
|
def test_no_suffix_older_than_build_suffix(self):
|
||||||
|
assert _version_newer("145.0.7632.109", "145.0.7632.109.2") is False
|
||||||
|
|
||||||
|
def test_new_chromium_beats_old_build(self):
|
||||||
|
assert _version_newer("146.0.0.0", "145.0.7632.109.2") is True
|
||||||
|
|
||||||
|
|
||||||
class TestDownloadUrl:
|
class TestDownloadUrl:
|
||||||
def test_default_url_format(self):
|
def test_default_url_format(self):
|
||||||
url = get_download_url()
|
url = get_download_url()
|
||||||
assert "cloakbrowser.dev" in url
|
assert "cloakbrowser.dev" in url
|
||||||
assert f"chromium-v{CHROMIUM_VERSION}" in url
|
assert f"chromium-v{get_chromium_version()}" in url
|
||||||
assert url.endswith(".tar.gz")
|
assert url.endswith(".tar.gz")
|
||||||
|
|
||||||
def test_custom_version_url(self):
|
def test_custom_version_url(self):
|
||||||
@@ -111,30 +128,42 @@ class TestShouldCheckForUpdate:
|
|||||||
|
|
||||||
|
|
||||||
class TestEffectiveVersion:
|
class TestEffectiveVersion:
|
||||||
def test_no_marker_returns_hardcoded(self, tmp_path):
|
def test_no_marker_returns_platform_version(self, tmp_path):
|
||||||
with patch.dict(os.environ, {"CLOAKBROWSER_CACHE_DIR": str(tmp_path)}):
|
with patch.dict(os.environ, {"CLOAKBROWSER_CACHE_DIR": str(tmp_path)}):
|
||||||
assert get_effective_version() == CHROMIUM_VERSION
|
assert get_effective_version() == get_chromium_version()
|
||||||
|
|
||||||
def test_marker_with_newer_version(self, tmp_path):
|
def test_marker_with_newer_version(self, tmp_path):
|
||||||
with patch.dict(os.environ, {"CLOAKBROWSER_CACHE_DIR": str(tmp_path)}):
|
with patch.dict(os.environ, {"CLOAKBROWSER_CACHE_DIR": str(tmp_path)}):
|
||||||
marker = tmp_path / "latest_version"
|
marker = tmp_path / f"latest_version_{get_platform_tag()}"
|
||||||
marker.write_text("999.0.0.0")
|
marker.write_text("999.0.0.0")
|
||||||
# Binary doesn't exist, so should fall back
|
# Binary doesn't exist, so should fall back
|
||||||
assert get_effective_version() == CHROMIUM_VERSION
|
assert get_effective_version() == get_chromium_version()
|
||||||
|
|
||||||
def test_marker_with_older_version_ignored(self, tmp_path):
|
def test_marker_with_older_version_ignored(self, tmp_path):
|
||||||
with patch.dict(os.environ, {"CLOAKBROWSER_CACHE_DIR": str(tmp_path)}):
|
with patch.dict(os.environ, {"CLOAKBROWSER_CACHE_DIR": str(tmp_path)}):
|
||||||
marker = tmp_path / "latest_version"
|
marker = tmp_path / f"latest_version_{get_platform_tag()}"
|
||||||
marker.write_text("100.0.0.0")
|
marker.write_text("100.0.0.0")
|
||||||
assert get_effective_version() == CHROMIUM_VERSION
|
assert get_effective_version() == get_chromium_version()
|
||||||
|
|
||||||
|
|
||||||
class TestGetLatestVersion:
|
class TestGetLatestVersion:
|
||||||
def test_parses_chromium_tag(self):
|
"""Tests for _get_latest_chromium_version with platform-aware asset checking."""
|
||||||
|
|
||||||
|
def _make_assets(self, platforms: list[str]) -> list[dict]:
|
||||||
|
"""Helper to build asset list from platform tags."""
|
||||||
|
return [{"name": f"cloakbrowser-{p}.tar.gz"} for p in platforms]
|
||||||
|
|
||||||
|
def _platform_tarball(self) -> str:
|
||||||
|
return f"cloakbrowser-{get_platform_tag()}.tar.gz"
|
||||||
|
|
||||||
|
def test_parses_chromium_tag_with_platform_asset(self):
|
||||||
mock_response = MagicMock()
|
mock_response = MagicMock()
|
||||||
mock_response.json.return_value = [
|
mock_response.json.return_value = [
|
||||||
{"tag_name": "chromium-v145.0.7718.0", "draft": False},
|
{
|
||||||
{"tag_name": "chromium-v142.0.7444.175", "draft": False},
|
"tag_name": "chromium-v145.0.7718.0",
|
||||||
|
"draft": False,
|
||||||
|
"assets": self._make_assets(["linux-x64", "darwin-arm64", "darwin-x64"]),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
mock_response.raise_for_status = MagicMock()
|
mock_response.raise_for_status = MagicMock()
|
||||||
|
|
||||||
@@ -142,11 +171,37 @@ class TestGetLatestVersion:
|
|||||||
result = _get_latest_chromium_version()
|
result = _get_latest_chromium_version()
|
||||||
assert result == "145.0.7718.0"
|
assert result == "145.0.7718.0"
|
||||||
|
|
||||||
def test_skips_draft_releases(self):
|
def test_skips_release_without_platform_asset(self):
|
||||||
|
"""If latest release has no asset for our platform, fall back to older release."""
|
||||||
mock_response = MagicMock()
|
mock_response = MagicMock()
|
||||||
mock_response.json.return_value = [
|
mock_response.json.return_value = [
|
||||||
{"tag_name": "chromium-v999.0.0.0", "draft": True},
|
{
|
||||||
{"tag_name": "chromium-v145.0.7718.0", "draft": False},
|
"tag_name": "chromium-v145.0.7718.0",
|
||||||
|
"draft": False,
|
||||||
|
"assets": self._make_assets(["linux-x64"]), # Linux only
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag_name": "chromium-v142.0.7444.175",
|
||||||
|
"draft": False,
|
||||||
|
"assets": self._make_assets(["linux-x64", "darwin-arm64", "darwin-x64"]),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
mock_response.raise_for_status = MagicMock()
|
||||||
|
|
||||||
|
with patch("cloakbrowser.download.httpx.get", return_value=mock_response):
|
||||||
|
result = _get_latest_chromium_version()
|
||||||
|
tag = get_platform_tag()
|
||||||
|
if tag == "linux-x64":
|
||||||
|
assert result == "145.0.7718.0"
|
||||||
|
else:
|
||||||
|
assert result == "142.0.7444.175"
|
||||||
|
|
||||||
|
def test_skips_draft_releases(self):
|
||||||
|
mock_response = MagicMock()
|
||||||
|
all_platforms = ["linux-x64", "darwin-arm64", "darwin-x64"]
|
||||||
|
mock_response.json.return_value = [
|
||||||
|
{"tag_name": "chromium-v999.0.0.0", "draft": True, "assets": self._make_assets(all_platforms)},
|
||||||
|
{"tag_name": "chromium-v145.0.7718.0", "draft": False, "assets": self._make_assets(all_platforms)},
|
||||||
]
|
]
|
||||||
mock_response.raise_for_status = MagicMock()
|
mock_response.raise_for_status = MagicMock()
|
||||||
|
|
||||||
@@ -156,9 +211,10 @@ class TestGetLatestVersion:
|
|||||||
|
|
||||||
def test_skips_non_chromium_tags(self):
|
def test_skips_non_chromium_tags(self):
|
||||||
mock_response = MagicMock()
|
mock_response = MagicMock()
|
||||||
|
all_platforms = ["linux-x64", "darwin-arm64", "darwin-x64"]
|
||||||
mock_response.json.return_value = [
|
mock_response.json.return_value = [
|
||||||
{"tag_name": "v0.2.0", "draft": False},
|
{"tag_name": "v0.2.0", "draft": False, "assets": self._make_assets(all_platforms)},
|
||||||
{"tag_name": "chromium-v145.0.7718.0", "draft": False},
|
{"tag_name": "chromium-v145.0.7718.0", "draft": False, "assets": self._make_assets(all_platforms)},
|
||||||
]
|
]
|
||||||
mock_response.raise_for_status = MagicMock()
|
mock_response.raise_for_status = MagicMock()
|
||||||
|
|
||||||
@@ -166,6 +222,22 @@ class TestGetLatestVersion:
|
|||||||
result = _get_latest_chromium_version()
|
result = _get_latest_chromium_version()
|
||||||
assert result == "145.0.7718.0"
|
assert result == "145.0.7718.0"
|
||||||
|
|
||||||
|
def test_returns_none_when_no_platform_assets(self):
|
||||||
|
"""If no release has our platform, return None."""
|
||||||
|
mock_response = MagicMock()
|
||||||
|
mock_response.json.return_value = [
|
||||||
|
{
|
||||||
|
"tag_name": "chromium-v145.0.7718.0",
|
||||||
|
"draft": False,
|
||||||
|
"assets": [{"name": "cloakbrowser-windows-x64.tar.gz"}],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
mock_response.raise_for_status = MagicMock()
|
||||||
|
|
||||||
|
with patch("cloakbrowser.download.httpx.get", return_value=mock_response):
|
||||||
|
result = _get_latest_chromium_version()
|
||||||
|
assert result is None
|
||||||
|
|
||||||
def test_network_error_returns_none(self):
|
def test_network_error_returns_none(self):
|
||||||
with patch("cloakbrowser.download.httpx.get", side_effect=Exception("timeout")):
|
with patch("cloakbrowser.download.httpx.get", side_effect=Exception("timeout")):
|
||||||
result = _get_latest_chromium_version()
|
result = _get_latest_chromium_version()
|
||||||
|
|||||||
Reference in New Issue
Block a user