diff --git a/.github/ISSUE_TEMPLATE/01-launch-failure.yml b/.github/ISSUE_TEMPLATE/01-launch-failure.yml new file mode 100644 index 0000000..2c5451f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01-launch-failure.yml @@ -0,0 +1,98 @@ +name: Launch failure +description: Browser or wrapper fails to start (install errors, missing deps, profile load fails, never reaches new_page) +title: "[launch] " +labels: ["bug", "launch-failure"] +body: + - type: markdown + attributes: + value: | + Use this when the browser never reaches a usable state. + If it starts and the bug appears on a site or clicking something, use the site/action template instead. + + - type: input + id: version + attributes: + label: Version + description: Output of `python -m invisible_playwright version`. + placeholder: 0.1.7 (binary firefox-7) + validations: + required: true + + - type: dropdown + id: os + attributes: + label: OS + options: + - Windows 10/11 x86_64 + - Linux x86_64 + - macOS (unsupported) + - Other + validations: + required: true + + - type: input + id: python + attributes: + label: Python + placeholder: 3.11.7 + validations: + required: true + + - type: input + id: install_cmd + attributes: + label: How you installed + placeholder: pip install invisible_playwright + validations: + required: true + + - type: textarea + id: snippet + attributes: + label: What you ran + description: Stop at the line that errors out. Redact creds. + render: python + value: | + from invisible_playwright import InvisiblePlaywright + with InvisiblePlaywright(seed=42) as browser: + ctx = browser.new_context() + validations: + required: true + + - type: textarea + id: traceback + attributes: + label: Full traceback + description: The whole stack trace verbatim. Don't summarize. + render: text + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Extra logs + description: Output of `DEBUG=pw:browser* python yourscript.py 2>&1`. Optional but speeds things up. + render: text + validations: + required: false + + - type: textarea + id: tried + attributes: + label: What you already tried + description: Reinstall, clear cache, different Python version, different proxy, etc. + validations: + required: false + + - type: checkboxes + id: confirm + attributes: + label: Before submitting + options: + - label: Searched existing issues. + required: true + - label: On the latest released version. + required: true + - label: Removed credentials and personal paths from the snippet and logs. + required: true diff --git a/.github/ISSUE_TEMPLATE/02-site-or-action-bug.yml b/.github/ISSUE_TEMPLATE/02-site-or-action-bug.yml new file mode 100644 index 0000000..6c38de6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02-site-or-action-bug.yml @@ -0,0 +1,167 @@ +name: Site or action bug +description: Browser starts fine but a navigation, click, evaluate, or other operation fails or behaves wrong +title: "[bug] " +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + For bugs that happen after the browser is up. + If the browser never launches, use the launch failure template. + If a fingerprint detector flags the browser, use the stealth detection template. + + - type: input + id: version + attributes: + label: Version + description: Output of `python -m invisible_playwright version`. + placeholder: 0.1.7 (binary firefox-7) + validations: + required: true + + - type: dropdown + id: os + attributes: + label: OS + options: + - Windows 10/11 x86_64 + - Linux x86_64 + - macOS (unsupported) + - Other + validations: + required: true + + - type: input + id: python + attributes: + label: Python + placeholder: 3.11.7 + validations: + required: true + + - type: dropdown + id: headless + attributes: + label: headless= + description: Some bugs only repro on Windows headless=True (hidden alt-desktop path). + options: + - "True" + - "False" + validations: + required: true + + - type: dropdown + id: proxy + attributes: + label: Proxy + description: Sites often vary by IP geo (e.g. GDPR consent shows only on UK/EU). + options: + - No proxy (host network) + - Residential, UK/GB + - Residential, US + - Residential, other country (specify in notes) + - Datacenter (specify provider in notes) + validations: + required: true + + - type: dropdown + id: profile + attributes: + label: Profile dir + options: + - Fresh each run (no profile_dir) + - Persistent profile_dir, reusing across runs + - Persistent profile_dir, first run creating it + validations: + required: true + + - type: input + id: url + attributes: + label: URL + description: The exact URL passed to `page.goto`. Not "the homepage" — the literal string. + placeholder: https://id.sky.com/ + validations: + required: true + + - type: textarea + id: snippet + attributes: + label: Runnable reproduction + description: A complete snippet we can copy, paste, run. Stub creds with placeholders, keep everything else literal. + render: python + value: | + from invisible_playwright import InvisiblePlaywright + + with InvisiblePlaywright(seed=42, headless=True) as browser: + ctx = browser.new_context() + page = ctx.new_page() + page.goto("https://example.com/") + # the exact operation that fails: + page.click("button:has-text('Accept all')") + validations: + required: true + + - type: input + id: selector + attributes: + label: Selector or locator + description: The exact string passed to locator/click/frame_locator. Write N/A if not a selector bug. + placeholder: page.frame_locator("iframe[id^='sp_message_iframe_']").get_by_text("Accept all") + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected + description: What should happen when the snippet runs? + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual + description: What happens instead? Full traceback, error string verbatim, any page.on('crash') firing. + validations: + required: true + + - type: textarea + id: screenshot + attributes: + label: Screenshot + description: Drag-drop a screenshot if the bug is visual. Optional but useful. + validations: + required: false + + - type: textarea + id: logs + attributes: + label: Browser logs + description: Output of `DEBUG=pw:browser* python yourscript.py 2>&1 | tail -200`. Redact creds and real IPs. + render: text + validations: + required: false + + - type: textarea + id: notes + attributes: + label: Notes + description: Anything else, hypotheses, related issues, things you've already tried. + validations: + required: false + + - type: checkboxes + id: confirm + attributes: + label: Before submitting + options: + - label: Searched existing issues. + required: true + - label: On the latest released version. + required: true + - label: The snippet above runs end-to-end on a clean Python install. + required: true + - label: Removed credentials, proxy passwords, real IPs, personal file paths. + required: true diff --git a/.github/ISSUE_TEMPLATE/03-stealth-detection.yml b/.github/ISSUE_TEMPLATE/03-stealth-detection.yml new file mode 100644 index 0000000..b2c5e1d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03-stealth-detection.yml @@ -0,0 +1,141 @@ +name: Stealth detection +description: A fingerprint detector flagged the browser as a bot, VM, VPN, anti-detect, tampered, or otherwise non-human +title: "[detect] " +labels: ["bug", "stealth"] +body: + - type: markdown + attributes: + value: | + Use this when something detects the browser (Fingerprint Pro, CreepJS, BotD, reCAPTCHA, Cloudflare, sannysoft, etc). + Bugs in operations (clicks, navigation) go to the site/action template. + Browser failing to start goes to the launch failure template. + + - type: input + id: version + attributes: + label: Version + placeholder: 0.1.7 (binary firefox-7) + validations: + required: true + + - type: dropdown + id: os + attributes: + label: OS + options: + - Windows 10/11 x86_64 + - Linux x86_64 + - macOS (unsupported) + - Other + validations: + required: true + + - type: dropdown + id: headless + attributes: + label: headless= + options: + - "True" + - "False" + validations: + required: true + + - type: dropdown + id: proxy + attributes: + label: Proxy + description: Datacenter or wrong-country proxies trip most detectors regardless of the browser. Be honest about what you used. + options: + - No proxy (host network) + - Residential, matching target geo + - Residential, different geo than target + - Datacenter (specify provider in notes) + - Mobile / 4G + validations: + required: true + + - type: input + id: detector + attributes: + label: Detector name and URL + description: Exact site / service / product that flagged us. + placeholder: Fingerprint Pro — https://demo.fingerprint.com/playground + validations: + required: true + + - type: textarea + id: scores + attributes: + label: Detector verdict + description: Paste the relevant flags / scores verbatim. For Fingerprint Pro paste `bot`, `vpn`, `virtual_machine`, `tampering*`, `vm_ml_score`, `suspect_score`. For CreepJS the headless / lies / trust scores. For reCAPTCHA v3 the score number. + render: text + placeholder: | + bot: bad + vpn: true + virtual_machine: true + vm_ml_score: 0.74 + suspect_score: 22 + validations: + required: true + + - type: textarea + id: screenshot + attributes: + label: Screenshot of the detector result + description: Drag-drop a screenshot of the detector page so we see what you see. + validations: + required: true + + - type: textarea + id: snippet + attributes: + label: How you launched + description: The InvisiblePlaywright launch + navigation that produced the result above. Redact creds. + render: python + value: | + from invisible_playwright import InvisiblePlaywright + + with InvisiblePlaywright(seed=42, headless=True) as browser: + ctx = browser.new_context() + page = ctx.new_page() + page.goto("https://demo.fingerprint.com/playground") + validations: + required: true + + - type: textarea + id: expected + attributes: + label: What you expected + description: Most detectors will never give a perfect score for any browser. Tell us what threshold you'd accept (e.g. bot=not_detected, vm_ml_score < 0.3). + validations: + required: true + + - type: textarea + id: full_report + attributes: + label: Full detector response + description: For Fingerprint Pro paste the JSON from /api/event/v4/ if you have it. For CreepJS paste the full Smart Signals block. Optional but speeds things up a lot. + render: json + validations: + required: false + + - type: textarea + id: notes + attributes: + label: Notes + validations: + required: false + + - type: checkboxes + id: confirm + attributes: + label: Before submitting + options: + - label: Searched existing issues. + required: true + - label: On the latest released version. + required: true + - label: The detector verdict above is from a real run, not a hypothesis. + required: true + - label: Removed credentials, real IPs, FpJS visitor_id values, personal file paths from the snippet and full report. + required: true diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml deleted file mode 100644 index 9c1cf89..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ /dev/null @@ -1,204 +0,0 @@ -name: Bug report -description: Report a bug in the invisible_playwright Python wrapper -title: "[bug] " -labels: ["bug"] -body: - - type: markdown - attributes: - value: | - Thanks for filing a bug report. - - **Read first:** every field below is required unless explicitly marked optional. - Vague reports waste both your time and ours. Bugs reproducible on a vanilla - `playwright.firefox.launch()` are upstream Playwright / site-behavior issues — - please test that too before submitting (one of the required fields). - - - Search [existing issues](https://github.com/feder-cr/invisible_playwright/issues?q=is%3Aissue) to avoid duplicates. - - Stealth detection / fingerprint surface bugs go to [feder-cr/invisible-firefox](https://github.com/feder-cr/invisible-firefox/issues). - - Security vulnerabilities: see [SECURITY.md](https://github.com/feder-cr/invisible_playwright/blob/main/SECURITY.md). - - # ─── ENV ────────────────────────────────────────────────── - - type: input - id: version - attributes: - label: invisible_playwright version - description: Output of `python -m invisible_playwright version`. Include both wrapper version AND binary tag. - placeholder: "0.1.7 (binary firefox-7 / 150.0.1)" - validations: - required: true - - - type: dropdown - id: os - attributes: - label: Operating system - options: - - Windows 10/11 x86_64 - - Linux x86_64 - - macOS (unsupported — confirm if you want to try anyway) - - Other (specify in description) - validations: - required: true - - - type: input - id: python - attributes: - label: Python version - placeholder: "3.11.7" - validations: - required: true - - # ─── LAUNCH CONFIG (the axis that matters for stealth bugs) ── - - type: dropdown - id: headless - attributes: - label: headless= - description: | - Critical — many bugs only repro on `headless=True` on Windows - (we run Firefox headed on a hidden alt-desktop via CreateDesktop in that case). - options: - - "True" - - "False" - - "Not applicable (no browser launch involved)" - validations: - required: true - - - type: dropdown - id: proxy - attributes: - label: Proxy - description: Sites often behave differently by IP geo (e.g. UK shows GDPR consent that US doesn't). Tell us what proxy region you used. REDACT credentials. - options: - - "No proxy (direct host network)" - - "Residential proxy — UK/GB" - - "Residential proxy — US" - - "Residential proxy — other country (specify in description)" - - "Datacenter proxy (specify provider in description)" - - "SOCKS5" - - "HTTP(S)" - validations: - required: true - - - type: dropdown - id: profile - attributes: - label: Profile directory - description: Whether you used a persistent profile (`profile_dir=...`) or a fresh one each run. - options: - - "Fresh profile each run (default — no profile_dir set)" - - "Persistent profile_dir (reused across runs)" - - "Persistent profile_dir, first time creating it" - validations: - required: true - - # ─── REPRODUCTION ───────────────────────────────────────── - - type: input - id: url - attributes: - label: Exact URL that triggers the bug - description: The full URL string. Not "the homepage" — the literal URL you passed to `page.goto()`. - placeholder: "https://id.sky.com/" - validations: - required: true - - - type: textarea - id: repro - attributes: - label: Minimal runnable reproduction - description: | - A self-contained Python snippet that, when run, triggers the bug. We must be able to - copy-paste it and run. Stub creds with placeholders (``) but keep the - structure complete. "just open the link" is NOT a reproduction. - value: | - from invisible_playwright import InvisiblePlaywright - - with InvisiblePlaywright( - seed=42, - headless=True, # or False — pick whatever triggers your bug - # proxy={"server": "...", "username": "...", "password": ""}, - # profile_dir="c:/tmp/my-profile", - ) as browser: - ctx = browser.new_context() - page = ctx.new_page() - page.goto("https://example.com/") - # ... the exact operation that fails: - # page.click("button:has-text('Accept all')") - render: python - validations: - required: true - - - type: input - id: selector - attributes: - label: Exact selector / locator (if the bug is about clicking, typing, finding an element) - description: | - The actual selector string passed to `page.locator()`, `page.click()`, `page.frame_locator()`, etc. - If not relevant to your bug, write "N/A". - placeholder: "page.frame_locator(\"iframe[id^='sp_message_iframe_']\").get_by_text('Accept all')" - validations: - required: true - - # ─── OBSERVED vs EXPECTED ───────────────────────────────── - - type: textarea - id: expected - attributes: - label: Expected behavior - description: What should happen when the repro runs? - validations: - required: true - - - type: textarea - id: actual - attributes: - label: Actual behavior - description: | - What actually happens? Include full Python tracebacks if any, the error message - string verbatim, any `page.on('crash')` event firing. - validations: - required: true - - # ─── CONTEXT ────────────────────────────────────────────── - - type: textarea - id: screenshot - attributes: - label: Screenshot / visual evidence - description: | - Drag-and-drop a screenshot showing the bug. Especially important for UI bugs - (button not clickable, consent missing, layout wrong). For crash bugs, a screenshot - is optional but appreciated. - validations: - required: false - - - type: textarea - id: logs - attributes: - label: Browser / Playwright logs - description: | - Output of `DEBUG=pw:browser* python your_script.py 2>&1 | tail -200`. Especially - helpful for crashes, protocol errors, navigation failures. - REDACT credentials, real IPs, and personal paths before pasting. - render: text - validations: - required: false - - - type: textarea - id: notes - attributes: - label: Anything else - description: Additional context, hypotheses, things you've already tried, related issues. - validations: - required: false - - # ─── PRE-SUBMIT GATE ────────────────────────────────────── - - type: checkboxes - id: confirm - attributes: - label: Confirmations - options: - - label: I have searched existing issues and this bug has not been reported. - required: true - - label: I am on the latest released invisible_playwright version (or explained why I'm on an older one). - required: true - - label: The reproduction snippet runs end-to-end on a clean Python install (no missing imports, no truncation). - required: true - - label: I have removed credentials, proxy passwords, real IPs, and personal file paths from the snippet and logs. - required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 6d3dace..9bea633 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -3,9 +3,9 @@ contact_links: - name: Security vulnerability url: https://github.com/feder-cr/invisible_playwright/security/advisories/new about: Report a security issue privately. Do NOT open a public issue. - - name: Bug in the patched Firefox itself (canvas / WebGL / fonts / WebRTC / etc.) - url: https://github.com/feder-cr/firefox-stealth/issues - about: Spoofing/fingerprint bugs belong in the firefox-stealth repo. + - name: Bug in the patched Firefox source (C++, IDL, Juggler JS) + url: https://github.com/feder-cr/invisible-firefox/issues + about: Source-level patches in the Firefox fork go in the invisible-firefox repo. Detection results (FpJS, CreepJS, etc.) use the stealth detection template here. - name: Question or general discussion url: https://github.com/feder-cr/invisible_playwright/discussions - about: For usage questions, ideas, and chat. Bugs and features still go in issues. + about: Usage questions, ideas, chat. Bugs and features still go in issues.