Skip to content

Reports API

Three report renderers are provided — console text, an interactive HTML dashboard, and JSON export.


ReportConsole

Render a plain-text health summary from the Breadcrumb database.

Source code in breadcrumb/report/console.py
class ReportConsole:
    """Render a plain-text health summary from the Breadcrumb database."""

    def render(self, store: FingerprintStore, days: int = 30) -> str:
        """Build and return the console report string."""
        conn = store._get_conn()
        cutoff = time.time() - days * 86400

        has_test_runs = _table_exists(store, "test_runs")
        has_quarantine = _table_exists(store, "quarantine")

        # --- Total tests ---
        if has_test_runs:
            row = conn.execute(
                "SELECT COUNT(DISTINCT test_id) FROM test_runs WHERE timestamp >= ?",
                (cutoff,),
            ).fetchone()
            total = row[0] if row else 0
        else:
            row = conn.execute(
                "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
                (cutoff,),
            ).fetchone()
            total = row[0] if row else 0

        # --- Healed tests ---
        row = conn.execute(
            "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        ).fetchone()
        healed = row[0] if row else 0

        # --- Flaky tests ---
        if has_quarantine:
            row = conn.execute("SELECT COUNT(*) FROM quarantine").fetchone()
            flaky = row[0] if row else 0
        else:
            flaky = 0

        # --- Failing tests ---
        if has_test_runs:
            # Tests whose most recent run in the window has status='failed'
            rows = conn.execute(
                """
                SELECT test_id FROM test_runs t1
                WHERE timestamp >= ?
                  AND timestamp = (
                      SELECT MAX(t2.timestamp) FROM test_runs t2
                      WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                  )
                  AND status = 'failed'
                GROUP BY test_id
                """,
                (cutoff, cutoff),
            ).fetchall()
            failing = len(rows)
        else:
            failing = 0

        # --- Stable ---
        healed_ids = {
            r[0]
            for r in conn.execute(
                "SELECT DISTINCT test_id FROM healing_events WHERE timestamp >= ?",
                (cutoff,),
            ).fetchall()
        }
        failing_ids: set[str] = set()
        if has_test_runs:
            failing_ids = {
                r[0]
                for r in conn.execute(
                    """
                    SELECT test_id FROM test_runs t1
                    WHERE timestamp >= ?
                      AND timestamp = (
                          SELECT MAX(t2.timestamp) FROM test_runs t2
                          WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                      )
                      AND status = 'failed'
                    GROUP BY test_id
                    """,
                    (cutoff, cutoff),
                ).fetchall()
            }
        flaky_ids: set[str] = set()
        if has_quarantine:
            flaky_ids = {r[0] for r in conn.execute("SELECT test_id FROM quarantine").fetchall()}

        unstable = healed_ids | failing_ids | flaky_ids
        stable = max(0, total - len(unstable))

        # --- Percentages ---
        def pct(n: int) -> str:
            if total == 0:
                return "0.0%"
            return f"{n / total * 100:.1f}%"

        lines: list[str] = []
        lines.append(f"Test Health Summary (last {days} days)")
        lines.append(f"Total tests: {total}")
        lines.append(f"Stable: {stable} ({pct(stable)})")
        lines.append(f"Healed: {healed} ({pct(healed)})")
        lines.append(f"Flaky: {flaky} ({pct(flaky)})")
        lines.append(f"Failing: {failing} ({pct(failing)})")

        # --- Top healed locators ---
        top_rows = conn.execute(
            """
            SELECT test_id, locator, COUNT(*) as cnt, AVG(confidence) as avg_conf
            FROM healing_events
            WHERE timestamp >= ?
            GROUP BY test_id, locator
            ORDER BY cnt DESC
            LIMIT 5
            """,
            (cutoff,),
        ).fetchall()

        if top_rows:
            lines.append("")
            lines.append("Top healed locators:")
            for r in top_rows:
                locator_val = r[1]
                cnt = r[2]
                avg_conf = r[3]
                label = str(locator_val)
                lines.append(f"  {label:<20s} healed {cnt}x  avg confidence: {avg_conf:.2f}")

        # --- Flaky tests section ---
        if has_quarantine and has_test_runs:
            quarantined = conn.execute("SELECT test_id, reason FROM quarantine").fetchall()
            if quarantined:
                lines.append("")
                lines.append("Flaky tests:")
                for q in quarantined:
                    q_test_id = q[0]
                    runs = conn.execute(
                        """
                        SELECT status FROM test_runs
                        WHERE test_id = ? AND timestamp >= ?
                        ORDER BY timestamp ASC
                        """,
                        (q_test_id, cutoff),
                    ).fetchall()
                    fliprate = _compute_fliprate(runs)
                    classification = _classify_fliprate(fliprate)
                    lines.append(f"  {q_test_id:<20s} fliprate: {fliprate:.2f}  status: {classification}")

        return "\n".join(lines) + "\n"
render(store: FingerprintStore, days: int = 30) -> str

Build and return the console report string.

Source code in breadcrumb/report/console.py
def render(self, store: FingerprintStore, days: int = 30) -> str:
    """Build and return the console report string."""
    conn = store._get_conn()
    cutoff = time.time() - days * 86400

    has_test_runs = _table_exists(store, "test_runs")
    has_quarantine = _table_exists(store, "quarantine")

    # --- Total tests ---
    if has_test_runs:
        row = conn.execute(
            "SELECT COUNT(DISTINCT test_id) FROM test_runs WHERE timestamp >= ?",
            (cutoff,),
        ).fetchone()
        total = row[0] if row else 0
    else:
        row = conn.execute(
            "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        ).fetchone()
        total = row[0] if row else 0

    # --- Healed tests ---
    row = conn.execute(
        "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
        (cutoff,),
    ).fetchone()
    healed = row[0] if row else 0

    # --- Flaky tests ---
    if has_quarantine:
        row = conn.execute("SELECT COUNT(*) FROM quarantine").fetchone()
        flaky = row[0] if row else 0
    else:
        flaky = 0

    # --- Failing tests ---
    if has_test_runs:
        # Tests whose most recent run in the window has status='failed'
        rows = conn.execute(
            """
            SELECT test_id FROM test_runs t1
            WHERE timestamp >= ?
              AND timestamp = (
                  SELECT MAX(t2.timestamp) FROM test_runs t2
                  WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
              )
              AND status = 'failed'
            GROUP BY test_id
            """,
            (cutoff, cutoff),
        ).fetchall()
        failing = len(rows)
    else:
        failing = 0

    # --- Stable ---
    healed_ids = {
        r[0]
        for r in conn.execute(
            "SELECT DISTINCT test_id FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        ).fetchall()
    }
    failing_ids: set[str] = set()
    if has_test_runs:
        failing_ids = {
            r[0]
            for r in conn.execute(
                """
                SELECT test_id FROM test_runs t1
                WHERE timestamp >= ?
                  AND timestamp = (
                      SELECT MAX(t2.timestamp) FROM test_runs t2
                      WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                  )
                  AND status = 'failed'
                GROUP BY test_id
                """,
                (cutoff, cutoff),
            ).fetchall()
        }
    flaky_ids: set[str] = set()
    if has_quarantine:
        flaky_ids = {r[0] for r in conn.execute("SELECT test_id FROM quarantine").fetchall()}

    unstable = healed_ids | failing_ids | flaky_ids
    stable = max(0, total - len(unstable))

    # --- Percentages ---
    def pct(n: int) -> str:
        if total == 0:
            return "0.0%"
        return f"{n / total * 100:.1f}%"

    lines: list[str] = []
    lines.append(f"Test Health Summary (last {days} days)")
    lines.append(f"Total tests: {total}")
    lines.append(f"Stable: {stable} ({pct(stable)})")
    lines.append(f"Healed: {healed} ({pct(healed)})")
    lines.append(f"Flaky: {flaky} ({pct(flaky)})")
    lines.append(f"Failing: {failing} ({pct(failing)})")

    # --- Top healed locators ---
    top_rows = conn.execute(
        """
        SELECT test_id, locator, COUNT(*) as cnt, AVG(confidence) as avg_conf
        FROM healing_events
        WHERE timestamp >= ?
        GROUP BY test_id, locator
        ORDER BY cnt DESC
        LIMIT 5
        """,
        (cutoff,),
    ).fetchall()

    if top_rows:
        lines.append("")
        lines.append("Top healed locators:")
        for r in top_rows:
            locator_val = r[1]
            cnt = r[2]
            avg_conf = r[3]
            label = str(locator_val)
            lines.append(f"  {label:<20s} healed {cnt}x  avg confidence: {avg_conf:.2f}")

    # --- Flaky tests section ---
    if has_quarantine and has_test_runs:
        quarantined = conn.execute("SELECT test_id, reason FROM quarantine").fetchall()
        if quarantined:
            lines.append("")
            lines.append("Flaky tests:")
            for q in quarantined:
                q_test_id = q[0]
                runs = conn.execute(
                    """
                    SELECT status FROM test_runs
                    WHERE test_id = ? AND timestamp >= ?
                    ORDER BY timestamp ASC
                    """,
                    (q_test_id, cutoff),
                ).fetchall()
                fliprate = _compute_fliprate(runs)
                classification = _classify_fliprate(fliprate)
                lines.append(f"  {q_test_id:<20s} fliprate: {fliprate:.2f}  status: {classification}")

    return "\n".join(lines) + "\n"

ReportHTML

Render an HTML dashboard from the Breadcrumb database.

Source code in breadcrumb/report/html.py
class ReportHTML:
    """Render an HTML dashboard from the Breadcrumb database."""

    def render(self, store: FingerprintStore, days: int = 30) -> str:
        """Build and return a complete HTML string."""
        conn = store._get_conn()
        cutoff = time.time() - days * 86400

        has_test_runs = _table_exists(store, "test_runs")
        has_quarantine = _table_exists(store, "quarantine")

        # --- Counts ---
        if has_test_runs:
            total = _scalar(
                conn,
                "SELECT COUNT(DISTINCT test_id) FROM test_runs WHERE timestamp >= ?",
                (cutoff,),
            )
        else:
            total = _scalar(
                conn,
                "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
                (cutoff,),
            )

        healed = _scalar(
            conn,
            "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        )

        if has_quarantine:
            flaky = _scalar(conn, "SELECT COUNT(*) FROM quarantine")
        else:
            flaky = 0

        if has_test_runs:
            failing_rows = conn.execute(
                """
                SELECT test_id FROM test_runs t1
                WHERE timestamp >= ?
                  AND timestamp = (
                      SELECT MAX(t2.timestamp) FROM test_runs t2
                      WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                  )
                  AND status = 'failed'
                GROUP BY test_id
                """,
                (cutoff, cutoff),
            ).fetchall()
            failing = len(failing_rows)
        else:
            failing = 0

        # Stable
        healed_ids = {
            r[0]
            for r in conn.execute(
                "SELECT DISTINCT test_id FROM healing_events WHERE timestamp >= ?",
                (cutoff,),
            ).fetchall()
        }
        failing_ids: set[str] = set()
        if has_test_runs:
            failing_ids = {
                r[0]
                for r in conn.execute(
                    """
                    SELECT test_id FROM test_runs t1
                    WHERE timestamp >= ?
                      AND timestamp = (
                          SELECT MAX(t2.timestamp) FROM test_runs t2
                          WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                      )
                      AND status = 'failed'
                    GROUP BY test_id
                    """,
                    (cutoff, cutoff),
                ).fetchall()
            }
        flaky_ids: set[str] = set()
        if has_quarantine:
            flaky_ids = {r[0] for r in conn.execute("SELECT test_id FROM quarantine").fetchall()}

        stable = max(0, total - len(healed_ids | failing_ids | flaky_ids))

        # --- Top healed locators ---
        top_locators = conn.execute(
            """
            SELECT test_id, locator, COUNT(*) as cnt, AVG(confidence) as avg_conf
            FROM healing_events WHERE timestamp >= ?
            GROUP BY test_id, locator ORDER BY cnt DESC LIMIT 5
            """,
            (cutoff,),
        ).fetchall()

        # --- Recent healing events ---
        recent_events = conn.execute(
            """
            SELECT timestamp, test_id, locator, confidence
            FROM healing_events WHERE timestamp >= ?
            ORDER BY timestamp DESC LIMIT 20
            """,
            (cutoff,),
        ).fetchall()

        # --- Flaky tests ---
        flaky_tests: list[tuple[str, float, str]] = []
        if has_quarantine and has_test_runs:
            quarantined = conn.execute("SELECT test_id FROM quarantine").fetchall()
            for q in quarantined:
                q_id = q[0]
                runs = conn.execute(
                    "SELECT status FROM test_runs WHERE test_id = ? AND timestamp >= ? ORDER BY timestamp ASC",
                    (q_id, cutoff),
                ).fetchall()
                fliprate = _compute_fliprate(runs)
                classification = _classify_fliprate(fliprate)
                flaky_tests.append((q_id, fliprate, classification))

        # --- Build HTML ---
        now_str = datetime.now(tz=timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
        parts: list[str] = []
        parts.append("<!DOCTYPE html>")
        parts.append('<html lang="en"><head><meta charset="utf-8">')
        parts.append(f"<title>Breadcrumb Report (last {days} days)</title>")
        parts.append(f"<style>{_CSS}</style>")
        parts.append("</head><body>")
        parts.append(f"<h1>Breadcrumb Test Health (last {days} days)</h1>")

        # Cards
        parts.append('<div class="cards">')
        parts.append(_card("Total", total, ""))
        parts.append(_card("Stable", stable, "stable"))
        parts.append(_card("Healed", healed, "healed"))
        parts.append(_card("Flaky", flaky, "flaky"))
        parts.append(_card("Failing", failing, "failing"))
        parts.append("</div>")

        # Top healed locators
        parts.append("<h2>Top Healed Locators</h2>")
        if top_locators:
            parts.append("<table><thead><tr>")
            parts.append("<th>Test ID</th><th>Locator</th><th>Count</th><th>Avg Confidence</th>")
            parts.append("</tr></thead><tbody>")
            for r in top_locators:
                parts.append(f"<tr><td>{_esc(r[0])}</td><td>{_esc(r[1])}</td><td>{r[2]}</td><td>{r[3]:.2f}</td></tr>")
            parts.append("</tbody></table>")
        else:
            parts.append('<p class="empty">No healing events in this period.</p>')

        # Recent healing events
        parts.append("<h2>Recent Healing Events</h2>")
        if recent_events:
            parts.append("<table><thead><tr>")
            parts.append("<th>Timestamp</th><th>Test ID</th><th>Locator</th><th>Confidence</th>")
            parts.append("</tr></thead><tbody>")
            for r in recent_events:
                ts = datetime.fromtimestamp(r[0], tz=timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
                parts.append(f"<tr><td>{ts}</td><td>{_esc(r[1])}</td><td>{_esc(r[2])}</td><td>{r[3]:.2f}</td></tr>")
            parts.append("</tbody></table>")
        else:
            parts.append('<p class="empty">No healing events in this period.</p>')

        # Flaky tests
        if flaky_tests:
            parts.append("<h2>Flaky Tests</h2>")
            parts.append("<table><thead><tr>")
            parts.append("<th>Test ID</th><th>Flip Rate</th><th>Classification</th>")
            parts.append("</tr></thead><tbody>")
            for test_id, fliprate, classification in flaky_tests:
                parts.append(f"<tr><td>{_esc(test_id)}</td><td>{fliprate:.2f}</td><td>{_esc(classification)}</td></tr>")
            parts.append("</tbody></table>")

        parts.append(f"<footer>Generated by Breadcrumb at {now_str}</footer>")
        parts.append("</body></html>")
        return "\n".join(parts)

    def export(self, store: FingerprintStore, path: str | Path, days: int = 30) -> None:
        """Write the HTML report to a file."""
        content = self.render(store, days)
        Path(path).write_text(content, encoding="utf-8")
render(store: FingerprintStore, days: int = 30) -> str

Build and return a complete HTML string.

Source code in breadcrumb/report/html.py
def render(self, store: FingerprintStore, days: int = 30) -> str:
    """Build and return a complete HTML string."""
    conn = store._get_conn()
    cutoff = time.time() - days * 86400

    has_test_runs = _table_exists(store, "test_runs")
    has_quarantine = _table_exists(store, "quarantine")

    # --- Counts ---
    if has_test_runs:
        total = _scalar(
            conn,
            "SELECT COUNT(DISTINCT test_id) FROM test_runs WHERE timestamp >= ?",
            (cutoff,),
        )
    else:
        total = _scalar(
            conn,
            "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        )

    healed = _scalar(
        conn,
        "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
        (cutoff,),
    )

    if has_quarantine:
        flaky = _scalar(conn, "SELECT COUNT(*) FROM quarantine")
    else:
        flaky = 0

    if has_test_runs:
        failing_rows = conn.execute(
            """
            SELECT test_id FROM test_runs t1
            WHERE timestamp >= ?
              AND timestamp = (
                  SELECT MAX(t2.timestamp) FROM test_runs t2
                  WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
              )
              AND status = 'failed'
            GROUP BY test_id
            """,
            (cutoff, cutoff),
        ).fetchall()
        failing = len(failing_rows)
    else:
        failing = 0

    # Stable
    healed_ids = {
        r[0]
        for r in conn.execute(
            "SELECT DISTINCT test_id FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        ).fetchall()
    }
    failing_ids: set[str] = set()
    if has_test_runs:
        failing_ids = {
            r[0]
            for r in conn.execute(
                """
                SELECT test_id FROM test_runs t1
                WHERE timestamp >= ?
                  AND timestamp = (
                      SELECT MAX(t2.timestamp) FROM test_runs t2
                      WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                  )
                  AND status = 'failed'
                GROUP BY test_id
                """,
                (cutoff, cutoff),
            ).fetchall()
        }
    flaky_ids: set[str] = set()
    if has_quarantine:
        flaky_ids = {r[0] for r in conn.execute("SELECT test_id FROM quarantine").fetchall()}

    stable = max(0, total - len(healed_ids | failing_ids | flaky_ids))

    # --- Top healed locators ---
    top_locators = conn.execute(
        """
        SELECT test_id, locator, COUNT(*) as cnt, AVG(confidence) as avg_conf
        FROM healing_events WHERE timestamp >= ?
        GROUP BY test_id, locator ORDER BY cnt DESC LIMIT 5
        """,
        (cutoff,),
    ).fetchall()

    # --- Recent healing events ---
    recent_events = conn.execute(
        """
        SELECT timestamp, test_id, locator, confidence
        FROM healing_events WHERE timestamp >= ?
        ORDER BY timestamp DESC LIMIT 20
        """,
        (cutoff,),
    ).fetchall()

    # --- Flaky tests ---
    flaky_tests: list[tuple[str, float, str]] = []
    if has_quarantine and has_test_runs:
        quarantined = conn.execute("SELECT test_id FROM quarantine").fetchall()
        for q in quarantined:
            q_id = q[0]
            runs = conn.execute(
                "SELECT status FROM test_runs WHERE test_id = ? AND timestamp >= ? ORDER BY timestamp ASC",
                (q_id, cutoff),
            ).fetchall()
            fliprate = _compute_fliprate(runs)
            classification = _classify_fliprate(fliprate)
            flaky_tests.append((q_id, fliprate, classification))

    # --- Build HTML ---
    now_str = datetime.now(tz=timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
    parts: list[str] = []
    parts.append("<!DOCTYPE html>")
    parts.append('<html lang="en"><head><meta charset="utf-8">')
    parts.append(f"<title>Breadcrumb Report (last {days} days)</title>")
    parts.append(f"<style>{_CSS}</style>")
    parts.append("</head><body>")
    parts.append(f"<h1>Breadcrumb Test Health (last {days} days)</h1>")

    # Cards
    parts.append('<div class="cards">')
    parts.append(_card("Total", total, ""))
    parts.append(_card("Stable", stable, "stable"))
    parts.append(_card("Healed", healed, "healed"))
    parts.append(_card("Flaky", flaky, "flaky"))
    parts.append(_card("Failing", failing, "failing"))
    parts.append("</div>")

    # Top healed locators
    parts.append("<h2>Top Healed Locators</h2>")
    if top_locators:
        parts.append("<table><thead><tr>")
        parts.append("<th>Test ID</th><th>Locator</th><th>Count</th><th>Avg Confidence</th>")
        parts.append("</tr></thead><tbody>")
        for r in top_locators:
            parts.append(f"<tr><td>{_esc(r[0])}</td><td>{_esc(r[1])}</td><td>{r[2]}</td><td>{r[3]:.2f}</td></tr>")
        parts.append("</tbody></table>")
    else:
        parts.append('<p class="empty">No healing events in this period.</p>')

    # Recent healing events
    parts.append("<h2>Recent Healing Events</h2>")
    if recent_events:
        parts.append("<table><thead><tr>")
        parts.append("<th>Timestamp</th><th>Test ID</th><th>Locator</th><th>Confidence</th>")
        parts.append("</tr></thead><tbody>")
        for r in recent_events:
            ts = datetime.fromtimestamp(r[0], tz=timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
            parts.append(f"<tr><td>{ts}</td><td>{_esc(r[1])}</td><td>{_esc(r[2])}</td><td>{r[3]:.2f}</td></tr>")
        parts.append("</tbody></table>")
    else:
        parts.append('<p class="empty">No healing events in this period.</p>')

    # Flaky tests
    if flaky_tests:
        parts.append("<h2>Flaky Tests</h2>")
        parts.append("<table><thead><tr>")
        parts.append("<th>Test ID</th><th>Flip Rate</th><th>Classification</th>")
        parts.append("</tr></thead><tbody>")
        for test_id, fliprate, classification in flaky_tests:
            parts.append(f"<tr><td>{_esc(test_id)}</td><td>{fliprate:.2f}</td><td>{_esc(classification)}</td></tr>")
        parts.append("</tbody></table>")

    parts.append(f"<footer>Generated by Breadcrumb at {now_str}</footer>")
    parts.append("</body></html>")
    return "\n".join(parts)
export(store: FingerprintStore, path: str | Path, days: int = 30) -> None

Write the HTML report to a file.

Source code in breadcrumb/report/html.py
def export(self, store: FingerprintStore, path: str | Path, days: int = 30) -> None:
    """Write the HTML report to a file."""
    content = self.render(store, days)
    Path(path).write_text(content, encoding="utf-8")

ReportJSON

Render a JSON report from the Breadcrumb database.

Source code in breadcrumb/report/json.py
class ReportJSON:
    """Render a JSON report from the Breadcrumb database."""

    def render(self, store: FingerprintStore, days: int = 30) -> dict[str, Any]:
        """Build and return a report dict."""
        conn = store._get_conn()
        now = time.time()
        cutoff = now - days * 86400

        has_test_runs = _table_exists(store, "test_runs")
        has_quarantine = _table_exists(store, "quarantine")

        # --- Counts ---
        if has_test_runs:
            total = _scalar(
                conn,
                "SELECT COUNT(DISTINCT test_id) FROM test_runs WHERE timestamp >= ?",
                (cutoff,),
            )
        else:
            total = _scalar(
                conn,
                "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
                (cutoff,),
            )

        healed = _scalar(
            conn,
            "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        )

        if has_quarantine:
            flaky = _scalar(conn, "SELECT COUNT(*) FROM quarantine")
        else:
            flaky = 0

        if has_test_runs:
            failing_rows = conn.execute(
                """
                SELECT test_id FROM test_runs t1
                WHERE timestamp >= ?
                  AND timestamp = (
                      SELECT MAX(t2.timestamp) FROM test_runs t2
                      WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                  )
                  AND status = 'failed'
                GROUP BY test_id
                """,
                (cutoff, cutoff),
            ).fetchall()
            failing = len(failing_rows)
        else:
            failing = 0

        # Stable
        healed_ids = {
            r[0]
            for r in conn.execute(
                "SELECT DISTINCT test_id FROM healing_events WHERE timestamp >= ?",
                (cutoff,),
            ).fetchall()
        }
        failing_ids: set[str] = set()
        if has_test_runs:
            failing_ids = {
                r[0]
                for r in conn.execute(
                    """
                    SELECT test_id FROM test_runs t1
                    WHERE timestamp >= ?
                      AND timestamp = (
                          SELECT MAX(t2.timestamp) FROM test_runs t2
                          WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                      )
                      AND status = 'failed'
                    GROUP BY test_id
                    """,
                    (cutoff, cutoff),
                ).fetchall()
            }
        flaky_ids: set[str] = set()
        if has_quarantine:
            flaky_ids = {r[0] for r in conn.execute("SELECT test_id FROM quarantine").fetchall()}

        stable = max(0, total - len(healed_ids | failing_ids | flaky_ids))

        # --- Healing events ---
        event_rows = conn.execute(
            """
            SELECT timestamp, test_id, locator, confidence,
                   original_json, healed_json
            FROM healing_events WHERE timestamp >= ?
            ORDER BY timestamp DESC
            """,
            (cutoff,),
        ).fetchall()
        healing_events: list[dict[str, Any]] = []
        for r in event_rows:
            healing_events.append(
                {
                    "timestamp": r[0],
                    "test_id": r[1],
                    "locator": r[2],
                    "confidence": r[3],
                    "original": json.loads(r[4]),
                    "healed": json.loads(r[5]),
                }
            )

        # --- Top locators ---
        top_rows = conn.execute(
            """
            SELECT test_id, locator, COUNT(*) as cnt,
                   AVG(confidence) as avg_conf
            FROM healing_events WHERE timestamp >= ?
            GROUP BY test_id, locator ORDER BY cnt DESC LIMIT 5
            """,
            (cutoff,),
        ).fetchall()
        top_locators: list[dict[str, Any]] = []
        for r in top_rows:
            top_locators.append(
                {
                    "test_id": r[0],
                    "locator": r[1],
                    "count": r[2],
                    "avg_confidence": round(r[3], 4),
                }
            )

        # --- Flaky tests ---
        flaky_tests: list[dict[str, Any]] = []
        if has_quarantine and has_test_runs:
            quarantined = conn.execute("SELECT test_id, reason FROM quarantine").fetchall()
            for q in quarantined:
                q_id = q[0]
                q_reason = q[1]
                runs = conn.execute(
                    "SELECT status FROM test_runs WHERE test_id = ? AND timestamp >= ? ORDER BY timestamp ASC",
                    (q_id, cutoff),
                ).fetchall()
                fliprate = _compute_fliprate(runs)
                flaky_tests.append(
                    {
                        "test_id": q_id,
                        "reason": q_reason,
                        "fliprate": round(fliprate, 4),
                    }
                )
        elif has_quarantine:
            quarantined = conn.execute("SELECT test_id, reason FROM quarantine").fetchall()
            for q in quarantined:
                flaky_tests.append(
                    {
                        "test_id": q[0],
                        "reason": q[1],
                        "fliprate": 0.0,
                    }
                )

        return {
            "generated_at": now,
            "period_days": days,
            "summary": {
                "total": total,
                "stable": stable,
                "healed": healed,
                "flaky": flaky,
                "failing": failing,
            },
            "healing_events": healing_events,
            "flaky_tests": flaky_tests,
            "top_locators": top_locators,
        }

    def export(self, store: FingerprintStore, path: str | Path, days: int = 30) -> None:
        """Write the JSON report to a file."""
        data = self.render(store, days)
        Path(path).write_text(json.dumps(data, indent=2), encoding="utf-8")
render(store: FingerprintStore, days: int = 30) -> dict[str, Any]

Build and return a report dict.

Source code in breadcrumb/report/json.py
def render(self, store: FingerprintStore, days: int = 30) -> dict[str, Any]:
    """Build and return a report dict."""
    conn = store._get_conn()
    now = time.time()
    cutoff = now - days * 86400

    has_test_runs = _table_exists(store, "test_runs")
    has_quarantine = _table_exists(store, "quarantine")

    # --- Counts ---
    if has_test_runs:
        total = _scalar(
            conn,
            "SELECT COUNT(DISTINCT test_id) FROM test_runs WHERE timestamp >= ?",
            (cutoff,),
        )
    else:
        total = _scalar(
            conn,
            "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        )

    healed = _scalar(
        conn,
        "SELECT COUNT(DISTINCT test_id) FROM healing_events WHERE timestamp >= ?",
        (cutoff,),
    )

    if has_quarantine:
        flaky = _scalar(conn, "SELECT COUNT(*) FROM quarantine")
    else:
        flaky = 0

    if has_test_runs:
        failing_rows = conn.execute(
            """
            SELECT test_id FROM test_runs t1
            WHERE timestamp >= ?
              AND timestamp = (
                  SELECT MAX(t2.timestamp) FROM test_runs t2
                  WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
              )
              AND status = 'failed'
            GROUP BY test_id
            """,
            (cutoff, cutoff),
        ).fetchall()
        failing = len(failing_rows)
    else:
        failing = 0

    # Stable
    healed_ids = {
        r[0]
        for r in conn.execute(
            "SELECT DISTINCT test_id FROM healing_events WHERE timestamp >= ?",
            (cutoff,),
        ).fetchall()
    }
    failing_ids: set[str] = set()
    if has_test_runs:
        failing_ids = {
            r[0]
            for r in conn.execute(
                """
                SELECT test_id FROM test_runs t1
                WHERE timestamp >= ?
                  AND timestamp = (
                      SELECT MAX(t2.timestamp) FROM test_runs t2
                      WHERE t2.test_id = t1.test_id AND t2.timestamp >= ?
                  )
                  AND status = 'failed'
                GROUP BY test_id
                """,
                (cutoff, cutoff),
            ).fetchall()
        }
    flaky_ids: set[str] = set()
    if has_quarantine:
        flaky_ids = {r[0] for r in conn.execute("SELECT test_id FROM quarantine").fetchall()}

    stable = max(0, total - len(healed_ids | failing_ids | flaky_ids))

    # --- Healing events ---
    event_rows = conn.execute(
        """
        SELECT timestamp, test_id, locator, confidence,
               original_json, healed_json
        FROM healing_events WHERE timestamp >= ?
        ORDER BY timestamp DESC
        """,
        (cutoff,),
    ).fetchall()
    healing_events: list[dict[str, Any]] = []
    for r in event_rows:
        healing_events.append(
            {
                "timestamp": r[0],
                "test_id": r[1],
                "locator": r[2],
                "confidence": r[3],
                "original": json.loads(r[4]),
                "healed": json.loads(r[5]),
            }
        )

    # --- Top locators ---
    top_rows = conn.execute(
        """
        SELECT test_id, locator, COUNT(*) as cnt,
               AVG(confidence) as avg_conf
        FROM healing_events WHERE timestamp >= ?
        GROUP BY test_id, locator ORDER BY cnt DESC LIMIT 5
        """,
        (cutoff,),
    ).fetchall()
    top_locators: list[dict[str, Any]] = []
    for r in top_rows:
        top_locators.append(
            {
                "test_id": r[0],
                "locator": r[1],
                "count": r[2],
                "avg_confidence": round(r[3], 4),
            }
        )

    # --- Flaky tests ---
    flaky_tests: list[dict[str, Any]] = []
    if has_quarantine and has_test_runs:
        quarantined = conn.execute("SELECT test_id, reason FROM quarantine").fetchall()
        for q in quarantined:
            q_id = q[0]
            q_reason = q[1]
            runs = conn.execute(
                "SELECT status FROM test_runs WHERE test_id = ? AND timestamp >= ? ORDER BY timestamp ASC",
                (q_id, cutoff),
            ).fetchall()
            fliprate = _compute_fliprate(runs)
            flaky_tests.append(
                {
                    "test_id": q_id,
                    "reason": q_reason,
                    "fliprate": round(fliprate, 4),
                }
            )
    elif has_quarantine:
        quarantined = conn.execute("SELECT test_id, reason FROM quarantine").fetchall()
        for q in quarantined:
            flaky_tests.append(
                {
                    "test_id": q[0],
                    "reason": q[1],
                    "fliprate": 0.0,
                }
            )

    return {
        "generated_at": now,
        "period_days": days,
        "summary": {
            "total": total,
            "stable": stable,
            "healed": healed,
            "flaky": flaky,
            "failing": failing,
        },
        "healing_events": healing_events,
        "flaky_tests": flaky_tests,
        "top_locators": top_locators,
    }
export(store: FingerprintStore, path: str | Path, days: int = 30) -> None

Write the JSON report to a file.

Source code in breadcrumb/report/json.py
def export(self, store: FingerprintStore, path: str | Path, days: int = 30) -> None:
    """Write the JSON report to a file."""
    data = self.render(store, days)
    Path(path).write_text(json.dumps(data, indent=2), encoding="utf-8")