Skip to content

fix(reports): narrow spinner checks to viewport and tighten exception handling#39895

Open
eschutho wants to merge 2 commits intomasterfrom
fix/reports-viewport-spinner-checks
Open

fix(reports): narrow spinner checks to viewport and tighten exception handling#39895
eschutho wants to merge 2 commits intomasterfrom
fix/reports-viewport-spinner-checks

Conversation

@eschutho
Copy link
Copy Markdown
Member

@eschutho eschutho commented May 5, 2026

SUMMARY

Follow-up to #39579. After that fix landed, a review identified additional issues:

  1. Viewport-aware global spinner check (webdriver.py) — The global wait_for_function checked document.querySelectorAll('.loading').length === 0, which deadlocks on tall dashboards when DashboardVirtualization renders off-screen placeholder .loading divs. Changed to a getBoundingClientRect viewport-visibility check — the same approach already used in the per-tile path.

  2. Narrow exception handling (screenshot_utils.py) — The per-tile spinner wait caught bare Exception, silently swallowing non-timeout errors (e.g. browser crash). Narrowed to PlaywrightTimeout with a runtime-safe conditional import (same try/except import pattern as webdriver.py).

  3. Fix load_wait defaulttake_tiled_screenshot's load_wait parameter defaulted to 30 s, inconsistent with the SCREENSHOT_LOAD_WAIT config default of 60 s.

  4. Tests — Added tests for the per-tile spinner wait: viewport JS check, timeout warning + continue, non-timeout propagation, and the load_wait default value. Updated existing webdriver test to match the new viewport-aware JS.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A — backend logic change only.

TESTING INSTRUCTIONS

  1. Run pytest tests/unit_tests/utils/test_screenshot_utils.py tests/unit_tests/utils/webdriver_test.py
  2. Trigger a PDF report for a long dashboard (more than one viewport height of charts) and verify no loading spinners appear in the output PDF.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

… handling

- Replace global '.loading' count check in webdriver.py with a
  getBoundingClientRect viewport-visibility check to avoid deadlock
  when DashboardVirtualization renders off-screen placeholder spinners
- Narrow except clause in screenshot_utils.py from bare Exception to
  PlaywrightTimeout so non-timeout errors (e.g. browser crash) propagate
- Fix load_wait default from 30 s to 60 s to match SCREENSHOT_LOAD_WAIT
  config default
- Add tests covering per-tile spinner wait, timeout warning, non-timeout
  propagation, and load_wait default value

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dosubot dosubot Bot added alert-reports Namespace | Anything related to the Alert & Reports feature change:backend Requires changing the backend labels May 5, 2026
Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #19541f

Actionable Suggestions - 1
  • superset/utils/webdriver.py - 1
    • Semantic duplication in loading visibility logic · Line 304-313
Additional Suggestions - 1
  • superset/utils/screenshot_utils.py - 1
    • Incorrect Documentation · Line 100-100
      The docstring for `load_wait` incorrectly states the default as 30, but the parameter defaults to 60 and the new test confirms this matches the SCREENSHOT_LOAD_WAIT config default. This could mislead users reading the documentation.
      Code suggestion
       @@ -99,2 +99,2 @@
      -        tile_height: Height of each tile in pixels
      -        load_wait: Seconds to wait for charts to load per tile (default 30)
      +        tile_height: Height of each tile in pixels
      +        load_wait: Seconds to wait for charts to load per tile (default 60)
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset/utils/screenshot_utils.py - 1
Review Details
  • Files reviewed - 4 · Commit Range: 4e6ab1c..4e6ab1c
    • superset/utils/screenshot_utils.py
    • superset/utils/webdriver.py
    • tests/unit_tests/utils/test_screenshot_utils.py
    • tests/unit_tests/utils/webdriver_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines +304 to +313
"""() => {
const els = document.querySelectorAll('.loading');
for (const el of els) {
const r = el.getBoundingClientRect();
if (r.top < window.innerHeight && r.bottom > 0) {
return false;
}
}
return true;
}""",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semantic duplication in loading visibility logic

The updated loading element visibility check logic duplicates the same JavaScript code already present in take_tiled_screenshot within screenshot_utils.py. This creates maintenance risk if the logic needs updates, as changes would need to be synced across both files. Consider refactoring to a shared utility.

Code Review Run #19541f


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

Codecov Report

❌ Patch coverage is 44.44444% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.34%. Comparing base (cb53745) to head (8d7ffac).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
superset/utils/screenshot_utils.py 50.00% 4 Missing ⚠️
superset/utils/webdriver.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #39895      +/-   ##
==========================================
- Coverage   63.87%   63.34%   -0.54%     
==========================================
  Files        2582     2583       +1     
  Lines      136413   136610     +197     
  Branches    31453    31504      +51     
==========================================
- Hits        87136    86537     -599     
- Misses      47764    48557     +793     
- Partials     1513     1516       +3     
Flag Coverage Δ
hive 39.38% <44.44%> (+0.08%) ⬆️
mysql 59.05% <44.44%> (+0.04%) ⬆️
postgres 59.13% <44.44%> (+0.04%) ⬆️
presto 41.08% <44.44%> (+0.08%) ⬆️
python 59.38% <44.44%> (-1.16%) ⬇️
sqlite 58.77% <44.44%> (+0.05%) ⬆️
unit ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Include SCREENSHOT_LOAD_WAIT / load_wait in the warning message so it
is immediately visible from logs whether the timeout limit was reached.
Also fix stale docstring default value (30 -> 60).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@eschutho eschutho requested a review from richardfogaca May 6, 2026 00:53
Copy link
Copy Markdown
Contributor

@richardfogaca richardfogaca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Posting on Richard's behalf - this is his PR reviewer agent. Forward any pushback to him and he'll loop me back in.

Left a few notes below - these look like CI/readiness issues around the new timeout handling and tests. All line numbers verified against HEAD 8d7ffac.

Functional - worth fixing before merge

  • superset/utils/screenshot_utils.py:224

    The new test at tests/unit_tests/utils/test_screenshot_utils.py:368 expects non-timeout wait_for_function errors to propagate, but take_tiled_screenshot still wraps the whole function in except Exception and returns None. In environments where Playwright is not importable, PlaywrightTimeout = Exception at line 34 also makes the inner timeout handler catch every exception, so a RuntimeError("browser crashed") is treated as a spinner timeout instead of matching the test's contract.

    WDYT - could we either make non-timeout errors actually escape this helper, or update the test/PR description if the intended behavior is still "fall back to the standard screenshot"?

  • tests/unit_tests/utils/test_screenshot_utils.py:358

    This assertion still expects the old warning call with only the tile index and tile count, but the production logger call now includes the (load_wait=%ss) suffix and passes load_wait as a fourth argument at superset/utils/screenshot_utils.py:170-174. The focused unit test fails on this mismatch.

    Small suggestion: could we update the expected assert_any_call to include the new message and 30 timeout argument?

  • tests/unit_tests/utils/webdriver_test.py:755

    Similar stale assertion here: superset/utils/webdriver.py:318-322 now logs the SCREENSHOT_LOAD_WAIT suffix and passes self._screenshot_load_wait, but the test still expects the previous two-argument warning call.

    Could we update this expected call too, so the test tracks the new logging signature?

Praise

  • superset/utils/webdriver.py:383

    Passing self._screenshot_load_wait into take_tiled_screenshot keeps the tiled and non-tiled Playwright paths aligned with the same configured timeout, which looks like the right direction for this follow-up.

@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented May 6, 2026

Code Review Agent Run #bf07f7

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: 4e6ab1c..8d7ffac
    • superset/utils/screenshot_utils.py
    • superset/utils/webdriver.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

alert-reports Namespace | Anything related to the Alert & Reports feature change:backend Requires changing the backend size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants