BROWSER USE

- Browser Use Agents: give Browser Use a task and receive completed work. API V4 is current for new integrations.
- Browser Infrastructure: connect your agent or automation to managed browsers through SDK, REST, or CDP. Starts at $0.02/browser-hour.
- Developer tools: Open Source, Browser Harness, SDK, and MCP support the two products above.

[Developer Index](https://browser-use.com/index.md)
[Product Map](https://browser-use.com/llms.txt)
[Full Product Context](https://browser-use.com/llms-full.txt)
[Pricing](https://browser-use.com/pricing.md)
[Cloud Docs](https://docs.browser-use.com/cloud/quickstart)
[Open Source Docs](https://docs.browser-use.com/open-source/introduction)

---

# Automate QuickBooks Online with an AI agent

Source: https://browser-use.com/skills/qbo. One file from github.com/browser-use/browser-harness, MIT licensed. Written for browser-harness: code calls its helpers (http_get, js, goto_url). Sites change; these notes describe what worked when last updated.

---

<!-- https://github.com/browser-use/browser-harness/blob/main/agent-workspace/domain-skills/qbo/report-export.md (updated 2026-08-29) -->

# QuickBooks Online Custom Report PDF Export

Field-tested on QBO custom reports in a logged-in Chromium-family browser on 2026-05-06.

## Fast Path

For clean QBO custom-report PDFs, use the visible QBO export flow, then save the PDF blob directly:

1. Open the saved custom report.
2. Set the visible date inputs, then click `refresh-report`.
3. Set the required report expansion state.
4. Click QBO report toolbar `Export` -> `Export to PDF`.
5. Wait for the generated `blob:https://qbo.intuit.com/<uuid>` PDF target.
6. Fetch that blob from the QBO page origin and write the bytes locally.
7. Validate with `pdftotext` when report content matters.

Do not use CDP `Page.printToPDF` for QBO reports. It prints the surrounding QBO shell, not the clean report body. Do not use the native `Save as PDF` sheet unless the QBO PDF blob is unavailable.

## Browser Attachment

- Use the real logged-in browser profile that has the QBO session.
- If that session is in a non-default Chromium browser, start it with a known remote-debugging port and pass `BU_CDP_URL` or `BU_CDP_WS` to Browser Harness.
- Computer Use is only a fallback for native OS sheets, visual confirmation, or unexpected QBO UI blockers. It is not part of the normal fast path.
- After a browser restart, QBO may restore a stale report tab. Always read the visible report period before exporting.

Example attachment pattern for a dedicated browser endpoint:

```bash
BU_NAME=qbo BU_CDP_URL=http://127.0.0.1:9223 browser-harness <<'PY'
print(page_info())
PY
```

## Report State

- Custom reports list route: `https://qbo.intuit.com/app/customreports`.
- Saved custom report builder routes look like `/app/report/builder?rptId=sbg:<uuid>&type=user`.
- Date fields are normal visible inputs. Their format follows the QBO/user locale; one tested locale used `dd.mm.yyyy`.
- After setting dates, click the report toolbar `refresh-report`.
- Verify report readiness from visible text: `<report name> report is ready`.
- QBO can move toolbar buttons when the report width/state changes. Locate `Export` from the current screenshot/DOM instead of reusing old coordinates.

## Compact Menu

Use the report toolbar `Compact` dropdown. It commonly contains:

- `Compact View`
- `Normal View`
- `Expand All`
- `Collapse All`

For a summary PDF with one visible grouping layer, choose `Collapse All`, then expand the top report group manually. Verify summary rows are visible and transaction-detail rows are not.

For a detailed PDF, choose `Expand All` and verify transaction rows are visible.

Useful post-state check:

```python
rows = js("""
return Array.from(document.querySelectorAll("table tr, [role=row], div"))
  .map(r => r.innerText.trim().replace(/\s+/g, " "))
  .filter(Boolean)
  .slice(0, 200)
""")
```

## PDF Export

- QBO `Export` -> `Export to PDF` produces the clean report PDF.
- This path may not fire a normal Chromium `Browser.downloadProgress` event, so `Browser.setDownloadBehavior` alone is not enough.
- QBO opens an in-page PDF modal using Chromium's built-in PDF viewer. The actual report PDF appears as a child `blob:https://qbo.intuit.com/<uuid>` target.
- The modal's `Save as PDF` button can open a native OS save sheet. Avoid that by fetching the blob directly.
- Fetching the blob too early can return no value; wait briefly after clicking `Export to PDF`.

Blob-save template:

```python
import base64, json, os, time

def latest_qbo_pdf_blob():
    blobs = [
        t["url"]
        for t in cdp("Target.getTargets")["targetInfos"]
        if t.get("url", "").startswith("blob:https://qbo.intuit.com/")
    ]
    return blobs[-1] if blobs else None

def save_qbo_pdf_blob(out_path, timeout=30):
    deadline = time.time() + timeout
    blob = None
    while time.time() < deadline:
        blob = latest_qbo_pdf_blob()
        if blob:
            break
        wait(0.5)
    if not blob:
        raise RuntimeError("QBO PDF blob did not appear")

    wait(2)  # let the PDF viewer finish loading the blob
    meta = js(f"""
    return fetch({json.dumps(blob)}).then(async r => {{
      const b = await r.blob();
      const ab = await b.arrayBuffer();
      const u8 = new Uint8Array(ab);
      let s = "";
      for (let i = 0; i < u8.length; i += 0x8000) {{
        s += String.fromCharCode(...u8.subarray(i, i + 0x8000));
      }}
      window.__qbo_pdf_b64 = btoa(s);
      return {{
        ok: r.ok,
        status: r.status,
        type: b.type,
        size: b.size,
        b64len: window.__qbo_pdf_b64.length
      }};
    }});
    """)
    if not meta or meta.get("type") != "application/pdf":
        raise RuntimeError(f"unexpected QBO blob metadata: {meta}")

    parts = []
    for i in range(0, meta["b64len"], 8000):
        parts.append(js(f"return window.__qbo_pdf_b64.slice({i},{i + 8000})"))

    out_dir = os.path.dirname(out_path)
    if out_dir:
        os.makedirs(out_dir, exist_ok=True)
    pdf = base64.b64decode("".join(parts))
    with open(out_path, "wb") as f:
        f.write(pdf)
    return {"path": out_path, "size": len(pdf), "blob": blob}
```

End-to-end outline:

```python
# 1. Use screenshot/DOM to click report toolbar Export.
# 2. Click menu item "Export to PDF".
# 3. Save the latest QBO PDF blob.
save_qbo_pdf_blob("/abs/output/report.pdf")
```

## Validation

Use local PDF tools for high-confidence runs:

```bash
pdfinfo /abs/output/report.pdf
pdftotext /abs/output/report.pdf -
```

Checks that catch common failures:

- PDF header starts with `%PDF`.
- `pdftotext` includes the expected report title and date range.
- Summary exports include the expected summary rows.
- Detailed exports include transaction-date/detail rows.
- The text does not include QBO shell/navigation labels, which indicates `Page.printToPDF` was used accidentally.
