Skip to content

Browser Support Test — Python source

Audit your real browser against 30 modern web capabilities - WebGPU, WASM, WebAuthn, Service Workers and more. Get a weighted readiness score, copy-paste detection snippets, and a shareable link.

This is the Python implementation — the same logic the interactive tool runs, in a shareable, citable form.

"""Browser Support Test — runtime capability probe, weighted score, tier.

Language: Python
CosmoDev polyglot showcase port of the ``browser-support-test`` tool.
Ported from src/tools/BrowserSupportTest.tsx (+ browser-support/* modules) —
display source, part of CosmoDev's polyglot tool pages.

ILLUSTRATIVE PORT: the live tool detects *browser* features at runtime
(navigator/window probes) — a browser-only concern that cannot run in a
server-side Python process. This port shows the ANALOGOUS pattern for Python:
``importlib.util.find_spec`` reports whether a stdlib module is importable in
THIS interpreter, ``hasattr`` probes version-gated attributes, and
``sys.version_info`` gates language features — together the direct equivalent
of ``'feature' in window``. The scoring algorithm and tier thresholds below are
byte-for-byte the same as the TypeScript lib's; only the probe targets differ.
"""

from __future__ import annotations

import importlib.util
import sys
from dataclasses import dataclass
from typing import Callable, List

SUPPORTED = "supported"
LIMITED = "limited"
UNSUPPORTED = "unsupported"
UNKNOWN = "unknown"

Status = str


def _contribution(status: Status) -> float:
    """Contribution x weight. Same values as src/tools/browser-support/score.ts."""
    return {
        "supported": 1.0,
        "limited": 0.5,
        "needs-https": 0.3,
    }.get(status, 0.0)  # unsupported, unknown -> 0


@dataclass
class Check:
    id: str
    title: str
    category: str
    weight: float
    probe: Callable[[], bool]


@dataclass
class FeatureResult:
    id: str
    status: Status


def _has_module(name: str) -> bool:
    """True when a module is importable in this interpreter (no import side effects)."""
    return importlib.util.find_spec(name) is not None


def checks() -> List[Check]:
    """Representative catalog of Python capability probes."""
    return [
        Check("ssl", "ssl", "Crypto", 3.0, lambda: _has_module("ssl")),
        Check("hashlib-md5", "hashlib", "Crypto", 2.0, lambda: _has_module("hashlib")),
        Check("sqlite3", "sqlite3", "Data", 3.0, lambda: _has_module("sqlite3")),
        Check("venv", "venv", "Runtime", 2.0, lambda: _has_module("venv")),
        Check("zoneinfo", "zoneinfo", "Data", 2.0, lambda: _has_module("zoneinfo")),
        Check("tomllib", "tomllib", "Data", 2.0, lambda: _has_module("tomllib")),
        Check("match-stmt", "match statement", "Language", 2.0,
              lambda: sys.version_info >= (3, 10)),
        Check("exception-group", "ExceptionGroup", "Language", 1.0,
              lambda: sys.version_info >= (3, 11)),
    ]


def compute_score(results: List[FeatureResult], catalog: List[Check]) -> int:
    """Weighted readiness 0-100; matches computeScore() exactly.

    Results whose id isn't in ``catalog`` are ignored.
    """
    weights = {c.id: c.weight for c in catalog}
    earned = 0.0
    possible = 0.0
    for r in results:
        w = weights.get(r.id)
        if w is None:
            continue
        earned += _contribution(r.status) * w
        possible += w
    if possible == 0.0:
        return 0
    return round(earned / possible * 100)


def tier_for(score: int) -> tuple[str, str]:
    """tier_for mirrors tierFor() in the island -- same thresholds."""
    if score >= 90:
        return ("Fully modern", "text-success")
    if score >= 75:
        return ("Very capable", "text-success")
    if score >= 55:
        return ("Capable, minor gaps", "text-accent")
    if score >= 35:
        return ("Showing its age", "text-fg-muted")
    return ("Legacy browser", "text-danger")


def run_checks(catalog: List[Check]) -> List[FeatureResult]:
    """Run probes; a throw degrades to 'unknown' so one failure can't abort the audit."""
    out: List[FeatureResult] = []
    for c in catalog:
        try:
            ok = c.probe()
            out.append(FeatureResult(c.id, SUPPORTED if ok else UNSUPPORTED))
        except Exception:
            out.append(FeatureResult(c.id, UNKNOWN))
    return out


def main() -> None:
    catalog = checks()
    results = run_checks(catalog)
    score = compute_score(results, catalog)
    label, _ = tier_for(score)
    supported = sum(1 for r in results if r.status == SUPPORTED)
    print(f"Python {sys.version.split()[0]} · {sys.platform}")
    print(f"{supported}/{len(results)} capabilities · readiness {score} · {label}")


if __name__ == "__main__":
    main()

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →