invisible_playwright/scripts/run_e2e.py

68 lines
2.7 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""Run the FULL e2e suite (every test that opens the browser) against a binary.
The 127 ``@pytest.mark.e2e`` tests are excluded from the default `pytest` run
(`addopts = -m 'not slow and not e2e'`) because they need a real Firefox binary
and a display, and they skip themselves when no binary is available. That makes
them easy to forget and "we can't afford for something to not work". This is
the gate that runs them all, deliberately, against a chosen binary.
It is the MANDATORY pre-release e2e gate: run it green against the freshly-built
release binary BEFORE un-drafting a firefox-N (alongside the fppro + WebRTC
realness gates). It is NOT in the public CI drive-gate the hosted runners are
content-process unstable under a heavy headless interaction sequence (see
70-known-bugs / 60-ci-release-pipeline); this runs locally on reliable hardware.
Flake-resilience: under full-suite load a couple of interaction tests (dblclick,
hover/mouseenter) can flake even though they pass 3/3 in isolation, so failures
are reran up to twice on the known transient signatures. A genuinely broken
binary fails all attempts. The webrtc e2e fake a TCP-only SOCKS locally (no
proxy/secrets), so the whole suite is offline.
Usage:
python scripts/run_e2e.py <firefox-binary>
python scripts/run_e2e.py # uses $INVPW_BINARY_PATH
"""
from __future__ import annotations
import os
import subprocess
import sys
from pathlib import Path
_RERUN_SIGNATURES = "Timeout|context was destroyed|was detached|not visible|because of a navigation|TargetClosed"
def main() -> int:
binary = sys.argv[1] if len(sys.argv) > 1 else os.environ.get("INVPW_BINARY_PATH")
if not binary:
print("usage: run_e2e.py <firefox-binary> (or set INVPW_BINARY_PATH)", file=sys.stderr)
return 2
if not Path(binary).exists():
print(f"ERROR: binary not found: {binary}", file=sys.stderr)
return 2
env = dict(os.environ)
# One setting drives the whole suite: conftest's firefox_binary fixture and
# the webrtc e2e both resolve from these.
env["INVPW_BINARY_PATH"] = binary
env["STEALTHFOX_E2E_BINARY"] = binary
repo = Path(__file__).resolve().parent.parent
cmd = [
sys.executable, "-m", "pytest",
"-m", "e2e",
"-o", "addopts=", # override the default 'not e2e' deselection
"--reruns", "2", "--reruns-delay", "1",
"--only-rerun", _RERUN_SIGNATURES,
"-p", "no:cacheprovider",
"-q", "--tb=short",
] + sys.argv[2:]
print(f"[run_e2e] binary={binary}")
print(f"[run_e2e] {' '.join(cmd)}")
return subprocess.run(cmd, cwd=repo, env=env).returncode
if __name__ == "__main__":
sys.exit(main())