chore(issue-templates): split bug_report into 3 focused templates

Replaces the single bug_report.yml with 3 templates that each require
only the fields relevant to their bug category. The old form asked every
reporter for URL / selector / runnable repro snippet, which made no sense
for launch failures (no browser to navigate, no element to select) and
overshot for detection reports (proxy region matters more than selector).

  01-launch-failure.yml      browser or wrapper never reaches new_page
  02-site-or-action-bug.yml  browser starts, an op (click / navigate / eval) fails
  03-stealth-detection.yml   a detector flags the browser (FpJS, CreepJS, BotD, ...)

Each template asks for the env basics plus the fields specific to its
category. The site/action one keeps the strict requirements introduced in
the previous template revision (headless, proxy, profile_dir, URL, selector,
runnable repro). The detection one drops selector/profile and asks for
detector name + verdict paste + screenshot. The launch one drops URL /
selector / proxy and asks for install command + full traceback.

Also fixes the contact_links: the old "Bug in the patched Firefox itself"
link pointed to feder-cr/firefox-stealth, a repo that was deleted on
2026-05-19 when source moved to feder-cr/invisible-firefox. Updated to
the new URL and clarified the boundary with the new stealth detection
template (detection results stay in this repo, source-level C++/IDL
patches go in invisible-firefox).
This commit is contained in:
feder-cr 2026-05-22 20:28:31 -07:00
parent 9571c3049d
commit cb3755cdd5
5 changed files with 410 additions and 208 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 (`<EVOMI_PASSWORD>`) 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": "<REDACTED>"},
# 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

View file

@ -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.