Back to Knowledge Hub
Getting Started

How to Write a Reproducible Browser Bug Report

Turn a browser failure into a useful, privacy-safe report with expected behavior, minimal reproduction steps, and environment facts.

BotBrowser Team

Documentation

Want the structured docs for Getting Started?

This article lives in the editorial library. For step-by-step setup, reference material, and ongoing updates, jump into the docs section.

A useful browser bug report lets another person see the same failure without guessing. It states what should happen, what actually happened, the smallest reliable reproduction, the environment that matters, and the evidence safe to share. It is a triage artifact, not a root-cause verdict or a request for private browser state. The article explains how to reduce a report while preserving the information needed to act.

Expected and actual behavior

Start with the user-visible contract. Write the expected result as an observable statement: “After selecting Save, the confirmation appears and focus moves to the heading.” Write the actual result with the same nouns: “The request completes, but the confirmation is absent and focus remains on the Save button.” Avoid conclusions such as “the browser broke focus” until the evidence supports them.

Use one report for one coherent failure. A login error, a layout shift, and a download problem may share a release but need separate reproduction paths and owners. Link related reports by their public identifiers rather than copying private traces into each report.

The Chromium bug-reporting guidance and Mozilla bug-writing guidance both emphasize clear steps, expected and actual behavior, and enough environment context to reproduce a problem. They do not require credentials, account history, or a complete browser dump.

Minimal reproduction

Reduce the path until removing one step makes the failure disappear. Record the starting URL or a safe local fixture, the exact action, the visible result, and the cleanup. Prefer synthetic data and an owned test page. If a public page is necessary, share only its public URL and avoid reproductions that probe or target a service you do not own.

Title: Save confirmation is absent after editing a test profile

Expected:
1. Open the owned profile fixture.
2. Change the display name to "Example".
3. Select Save.
4. See "Saved" and move focus to the status heading.

Actual:
The request completes, no status appears, and focus remains on Save.

Environment:
Browser: Chromium 154, Linux profile fixture
Viewport: 1280x800, keyboard and pointer
Release: app 2026.10.06
Reproducibility: 5/5 runs

Keep the fixture deterministic. Name the data state, feature flags, locale, viewport, browser release, profile revision, and network class only when they affect the outcome. A report that says “latest browser” cannot establish a stable baseline. A report that includes every available setting buries the difference that matters.

Report stateEvidenceNext action
Blocker and reproducibleminimal steps fail consistentlyassign owner and pause affected release path
Reproducible but scopedone route or environment failscompare a known-good neighbor and triage
Intermittentbounded run count and frequencyadd timing/context, then repeat safely
Cannot reproduceexact fixture and environment recordedrequest one missing fact, not a private dump
Privacy-redactedsensitive evidence removedcontinue with visible facts or approved channel

Environment information

Report only environment facts that can change the result. Include browser family and release, operating system or platform class, viewport, input mode, application release, route state, locale, profile or permission mode, and network condition when relevant. State whether the run was cold or warm and whether the page was visible. These labels describe a test condition; they do not identify a person or hardware.

Separate application build, browser build, and profile revision. A profile can change permissions and stored data. A browser release can change engine behavior. An application build can change the page. If all three changed together, report the combination and mark the cause unknown. Re-run with one variable held constant before assigning blame.

BotBrowser controlled contexts can repeat authorized reproduction journeys with declared profile, platform, release, viewport, route, and test data labels. This capability helps confirm visible behavior in a named setup. BotBrowser does not infer root cause, collect private browser logs, expose customer credentials, guarantee a fix, or authorize reproductions against third-party services. Keep that limitation in the report.

Privacy review before sharing

Read every attachment as if it will be published. Remove cookies, authorization headers, tokens, passwords, account identifiers, private URLs, query strings, personal text, screenshots of unrelated tabs, and downloaded files that contain customer data. Replace real names with synthetic values. Crop screenshots to the failing control and include the visible state needed to understand it.

Prefer a short reproduction video or screenshot only when it adds information that text cannot provide. Blur addresses, notifications, and account details. If a trace or console excerpt is required, keep the smallest lines around the failure and redact values before transfer. Do not upload a complete profile, browser directory, network capture, or storage dump to a public tracker.

Keep evidence in an approved access-controlled channel when the failure cannot be reproduced without private data. The public report can state that a redacted artifact exists and identify its retention owner. A private attachment is not a reason to include credentials in the public description.

Triage and follow-up

A report is ready for triage when another person can run the steps, observe the expected/actual difference, identify the environment, and understand the privacy boundary. Add a frequency such as “5/5 clean runs” or “2/20 runs after a cold navigation,” not an unsupported severity label. Record the first failing step and the user-visible recovery action.

When triage cannot reproduce the failure, compare the report's fixture with a known-good route and ask for one missing condition at a time. Do not request a full browser dump. A useful follow-up may be a new app build, a different viewport, a cold cache, or a permission state. If the report is intermittent, preserve the run count and timing window so the next experiment can be comparable.

For release work, link the report to the candidate, matrix cell, or regression check that found it. A fix should add a regression fixture or update an existing journey card. A release decision should state whether the issue blocks, receives a bounded waiver, ships with a fallback, or is out of scope. Keep the original failure and the verified correction in history.

For adjacent workflow guidance, see the browser release validation checklist and the browser test matrix guide. This report focuses on handing one observed failure to the right owner as a reproducible, privacy-reviewed artifact.

Report anatomy in practice

A report should be readable by the reproducer, route owner, and release owner. Use a short title naming the visible symptom and route. Put expected and actual near the top, reproduction steps before long logs, and environment labels beside the steps. Keep reset steps explicit when a seed, fixture, permission, cold cache, new context, or fresh page is required.

Use visible checkpoints after opening the route and after the action. State expected status, focus, navigation, download, or error so the first divergence is clear. Record frequency honestly with numerator, denominator, and run conditions. Minimize attachments: crop screenshots, keep only relevant console lines, redact traces, and never publish cookies, storage, private URLs, tokens, or customer files.

Separate runtime, platform, application, profile, and network labels so owners can reproduce the condition without treating them as an identity. Describe workarounds separately from fixes, and identify last known-good and first known-bad releases only when fixture and data stayed constant. Accessibility reports should include input method, focus, accessible name, status announcement, and recovery. Visual reports should include viewport, scale, color scheme, fonts, and route state. Download or upload reports should use synthetic files and verify cleanup.

End with a clear ask: reproduce, classify, fix, add a regression test, approve a waiver, or close as unsupported. A triager should not infer the next step from a long report.

The report owner should state when the next review will run and which evidence will close it. A short dated follow-up with the same fixture is more useful than a complete browser dump. Keep the public description stable while adding a correction result, preserving the original symptom for older releases.

Use severity vocabulary owned by the release process. A blocker stops a declared journey or needs a waiver. A high-impact issue affects a supported path but has a safe workaround. A scoped issue affects one environment. An informational report records a concern without changing release policy. The label never replaces expected and actual behavior, frequency, and evidence.

When a browser update appears related, reproduce on the previous supported release and candidate with the same application build and fixture. When an application update appears related, hold browser and profile constant. When a platform setup appears related, repeat with a neighboring cell. These comparisons make a report actionable without claiming a browser label is the cause.

Review reports for accessibility, security, and privacy before publication. Replace sensitive labels, private endpoints, and stored identifiers with synthetic examples. Keep necessary private evidence in the approved channel. Public reproducibility does not require public disclosure of secrets.

Report review checklist

Before submitting, read the title aloud and confirm it names the visible symptom rather than a guessed cause. Confirm expected and actual use the same nouns. Run the reproduction from a clean context and note the count. Confirm the first failing step, visible recovery, and whether the problem blocks a supported task.

Check the environment section for browser family, release, platform, viewport, input mode, application build, route, locale, profile, permissions, cache, and network where relevant. Remove labels that do not change the result. A smaller environment record is easier to repeat and less likely to expose a private condition.

Check every attachment for credentials, tokens, cookies, account identifiers, private URLs, query parameters, personal text, unrelated tabs, and customer files. Replace values with synthetic examples. Crop screenshots to the control and state that matter. Keep private artifacts in an approved channel with an owner and expiry.

Check triage ownership. The route owner should know the first failing step. The release owner should know whether the issue blocks, receives a waiver, ships with a fallback, or is unsupported. The privacy owner should know where any redacted evidence lives and when it will be deleted.

Check regression coverage. A verified fix should add a small fixture or update a journey card. The fixture should assert the visible correction and the recovery path, not only the absence of an exception. Keep the original report linked so a later release can explain why the check exists.

Check intermittent reports with a bounded experiment. Keep the same fixture, count clean and failing runs, and change one condition at a time. Do not ask for a complete profile or broad capture merely because the first run was inconclusive. A missing condition should be named and requested narrowly.

Check accessibility and localization. Reproduce with keyboard input where relevant, inspect focus and status, and repeat translated labels when copy length can change layout. Do not treat a translated screenshot or an accessibility tree containing user text as a public artifact by default.

Check release timing. Note whether the first known-bad run follows a browser, platform, profile, application, data, or permission change. If several changed together, label the cause unknown and plan a comparison. A report that preserves uncertainty is more useful than a confident but untested attribution.

The final report should fit on a screen before its optional evidence. That shape helps triagers act quickly and gives support a safe explanation to share. Add detail only when it changes reproduction, ownership, privacy, or the release decision.

When a report crosses team boundaries, include a short handoff note. Name the route owner, the release owner, and the person who can provide a redacted private artifact. State the next decision date and the smallest experiment that will change the decision. This prevents a report from becoming an unowned collection of observations. The handoff should not repeat credentials or paste a private conversation; it should point to the approved location and explain the retention limit.

Use a stable vocabulary for reproduction conditions. “Clean context” should mean a new profile or an explicitly reset fixture, not an informal guess. “Cold navigation” should identify whether the browser, application, or network cache was cleared. “Known good” should name the release and fixture that passed. These definitions make a follow-up run comparable when another engineer works in a different time zone or on a different platform.

For timing-sensitive failures, record the action sequence and the observation window. Say whether the failure occurs immediately, after a navigation, after an idle period, or after repeated submissions. If a timeout is involved, include the visible timeout and the configured boundary only when it is safe to disclose. A bounded run such as 20 attempts with 3 failures is more useful than “sometimes.” Keep the experiment small enough that the next owner can repeat it before changing several variables.

For network-related symptoms, describe the class of connection and the controlled response, not a customer address. A fixture can use a local server or a documented test endpoint. Record whether requests were blocked, delayed, redirected, or completed with an error status. Avoid attaching a full packet capture when a single redacted request and response explain the visible result. The purpose of the environment section is to reproduce the contract, not to inventory every system detail.

For storage or permission bugs, state the starting state and the reset action. A report should say whether storage was empty, seeded, expired, or migrated, and whether the permission was granted, denied, or prompted. Use synthetic account names and test keys. If a private state is essential, describe its shape publicly and keep the value in the approved channel. This lets a reviewer assess the report without receiving data that they should not retain.

For accessibility and localization issues, capture the user-visible interaction in the same terms as other browser failures. Identify the input method, focused control, accessible name, status announcement, language, text direction, and viewport when they affect the result. A screenshot can support the report, but it should not replace the expected and actual statements. Check translated strings with representative lengths and keep personal text out of examples.

For downloads and uploads, use a synthetic file with a known size and harmless contents. Record the visible filename, progress state, completion state, and cleanup result. Do not attach a customer document merely to demonstrate that a transfer failed. If the failure depends on a large file or a specific MIME type, document that condition and keep the test asset in an access-controlled fixture store.

The final review should ask whether each sentence changes reproduction, ownership, privacy, or release handling. Delete speculation, duplicate history, and broad requests for diagnostic dumps. Keep uncertainty explicit: “observed after the browser update; cause unknown” is a useful fact, while “the browser caused it” is a claim that requires a controlled comparison. A concise report with a reproducible fixture gives engineering and support a shared starting point. Keep the title stable when adding follow-up results so links and release notes remain useful. A clear owner and dated next check make the report actionable even when the first investigation is inconclusive. This discipline also makes later release reviews faster.

Public sources

A bug report checklist connects expected behavior, reproduction, environment, and privacy review.

#Bug Reports#Browser Testing#Reproduction#Release Validation

Take BotBrowser from research to production

The guides cover the model first, then move into cross-platform validation, isolated contexts, and scale-ready browser deployment.