Skip to content

fix(reports): wait for ECharts animation after spinners clear in non-tiled screenshots#41428

Open
msyavuz wants to merge 1 commit into
masterfrom
msyavuz/fix/png-report-partial-echarts-render
Open

fix(reports): wait for ECharts animation after spinners clear in non-tiled screenshots#41428
msyavuz wants to merge 1 commit into
masterfrom
msyavuz/fix/png-report-partial-echarts-render

Conversation

@msyavuz

@msyavuz msyavuz commented Jun 25, 2026

Copy link
Copy Markdown
Member

SUMMARY

ECharts charts run a ~1s draw animation that only starts once data has loaded and the spinner clears. In WebDriverPlaywright.get_screenshot, the non-tiled (single chart / standard) path waits SCREENSHOT_SELENIUM_ANIMATION_WAIT before charts finish loading, then waits for .loading spinners to disappear, then screenshots immediately. For a slow-loading chart the animation wait is spent while the chart is still loading, so the moment the spinner clears the screenshot fires mid-animation, producing a partially-rendered chart.

This is the same root cause as #40694, which fixed only the tiled dashboard path (per-tile wait after the spinner clears). The non-tiled PNG path was never fixed — mix charts (bar + line, time-shift, multiple metrics) load slowest and are the most exposed, matching the customer report (3 of 53 reports affected → a timing race).

Fix: add the animation wait after the .loading spinner check in both non-tiled branches, gated on SCREENSHOT_SELENIUM_ANIMATION_WAIT > 0. Deployments already setting that value (e.g. =5) get it automatically; the default 0 is a no-op.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A — bug manifests as a partially-drawn chart captured mid-animation; fix lets the draw animation complete before capture.

TESTING INSTRUCTIONS

  1. Configure an instance with SCREENSHOT_SELENIUM_ANIMATION_WAIT=5.
  2. Build a mix chart (bar + line, time-shift, multiple metrics) and schedule a "Send as PNG" report with cache ignored.
  3. Trigger repeatedly — the chart should render fully every time, not cut off mid-series.

Unit test: pytest tests/unit_tests/utils/webdriver_test.py -k animation_wait_runs_after_spinners_clear

ADDITIONAL INFORMATION

  • No — backend-only timing fix.
  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

@dosubot dosubot Bot added alert-reports Namespace | Anything related to the Alert & Reports feature risk:hard-to-test The change will be hard to test viz:charts:echarts Related to Echarts labels Jun 25, 2026
@bito-code-review

bito-code-review Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #8949f7

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: 95f7589..95f7589
    • superset/utils/webdriver.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

@netlify

netlify Bot commented Jun 25, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 95f7589
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a3d58f0eafcff00081c8661
😎 Deploy Preview https://deploy-preview-41428--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.43%. Comparing base (fe2424e) to head (95f7589).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
superset/utils/webdriver.py 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41428      +/-   ##
==========================================
- Coverage   64.44%   64.43%   -0.01%     
==========================================
  Files        2655     2655              
  Lines      145491   145515      +24     
  Branches    33585    33589       +4     
==========================================
+ Hits        93762    93764       +2     
- Misses      50028    50047      +19     
- Partials     1701     1704       +3     
Flag Coverage Δ
hive 39.23% <0.00%> (-0.01%) ⬇️
mysql 57.99% <0.00%> (-0.02%) ⬇️
postgres 58.05% <0.00%> (-0.02%) ⬇️
presto 40.81% <0.00%> (-0.01%) ⬇️
python 59.49% <0.00%> (-0.02%) ⬇️
sqlite 57.71% <0.00%> (-0.02%) ⬇️
unit 100.00% <ø> (ø)

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

☔ View full report in Codecov by Harness.
📢 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.

Comment on lines +453 to +454
if selenium_animation_wait > 0:
page.wait_for_timeout(selenium_animation_wait * 1000)

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.

Suggestion: This adds a second animation delay in the non-tiled flow, but the method already performs an unconditional SCREENSHOT_SELENIUM_ANIMATION_WAIT earlier before branching. With non-zero config values, screenshots now wait twice (effectively 2x the configured delay), which can significantly slow report generation and cause avoidable timeout pressure. Move the existing pre-branch wait to the post-spinner location (instead of adding a second wait), so the delay runs once at the correct time. [performance]

Severity Level: Major ⚠️
- ⚠️ Non-tiled Playwright PNG reports wait double animation time.
- ⚠️ Report generation slower, increased timeout pressure in jobs.
Steps of Reproduction ✅
1. Trigger a screenshot via `Screenshot.get_screenshot()` in
`superset/utils/screenshots.py:212-218`, which instantiates a WebDriver (Playwright when
enabled) and calls `driver.get_screenshot(self.url, self.element, user)`.

2. In the Playwright implementation `WebDriverPlaywright.get_screenshot()` at
`superset/utils/webdriver.py:320-355`, the code reads `selenium_animation_wait =
app.config["SCREENSHOT_SELENIUM_ANIMATION_WAIT"]` and unconditionally executes
`page.wait_for_timeout(selenium_animation_wait * 1000)` (Grep output at lines 340-348).

3. For a non-tiled screenshot (either `tiled_enabled` False, or `tiled_enabled` True with
`use_tiled` False) the flow continues into the branches shown in the PR hunk at
`superset/utils/webdriver.py:434-455` and `465-485`, where after waiting for `.loading`
spinners to disappear, the new code at lines 453-454 and 483-484 conditionally executes
`page.wait_for_timeout(selenium_animation_wait * 1000)` again when
`selenium_animation_wait > 0`.

4. With `SCREENSHOT_SELENIUM_ANIMATION_WAIT` configured to a non-zero value (e.g. `5`), a
single non-tiled Playwright screenshot now incurs two separate animation waits (first
before charts finish loading, then again after spinners clear), doubling the intended
delay for every PNG report and increasing end-to-end report generation time and timeout
risk compared to the single delay prior to this PR.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset/utils/webdriver.py
**Line:** 453:454
**Comment:**
	*Performance: This adds a second animation delay in the non-tiled flow, but the method already performs an unconditional `SCREENSHOT_SELENIUM_ANIMATION_WAIT` earlier before branching. With non-zero config values, screenshots now wait twice (effectively 2x the configured delay), which can significantly slow report generation and cause avoidable timeout pressure. Move the existing pre-branch wait to the post-spinner location (instead of adding a second wait), so the delay runs once at the correct time.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@bito-code-review

Copy link
Copy Markdown
Contributor

The flagged issue is correct. The current implementation adds a second wait_for_timeout call in the non-tiled flow, which results in double the configured SCREENSHOT_SELENIUM_ANIMATION_WAIT delay. To resolve this, the initial unconditional wait should be removed, and the delay should be applied only once after the spinners have cleared.

To implement this, remove the early page.wait_for_timeout call (which occurs before branching) and ensure the wait only happens in the post-spinner location as added in this PR. Would you like me to fetch all other comments on this PR to validate and implement fixes for them as well?

superset/utils/webdriver.py

# Remove the early unconditional wait (typically found earlier in the method):
# page.wait_for_timeout(selenium_animation_wait * 1000)

# Keep the post-spinner wait as implemented in the PR:
if selenium_animation_wait > 0:
    page.wait_for_timeout(selenium_animation_wait * 1000)

@rusackas rusackas self-requested a review June 25, 2026 17:08
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 risk:hard-to-test The change will be hard to test size/M viz:charts:echarts Related to Echarts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant