eschutho opened a new pull request, #42273:
URL: https://github.com/apache/superset/pull/42273

   ### Decisions made that were not in the instructions
   
   - **Exception type: `PlaywrightTimeout`.** No dedicated exception class 
exists for "capture failed, no more waiting to do" in this method. 
`PlaywrightTimeout` is already used three times in 
`WebDriverPlaywright.get_screenshot()` (element-wait, chart-container-wait, and 
both spinner-wait sites) as the established "log a WARNING, then raise so the 
report fails" pattern, and it's the one exception type in the enclosing `try` 
block that isn't swallowed — the sibling `except PlaywrightError:` handler at 
the bottom of the method logs via `logger.exception` and does *not* re-raise, 
so raising a `PlaywrightError` here would silently swallow the failure instead 
of propagating it. Reusing `PlaywrightTimeout` keeps this fix consistent with 
the existing local convention rather than introducing a new exception type.
   - **Test-level propagation check.** Verified (not part of the fix) that 
`PlaywrightTimeout` raised here already propagates cleanly through 
`BaseScreenshot.get_screenshot()` (`superset/utils/screenshots.py`, no 
swallowing `except`) into `BaseReportState._get_screenshots()` 
(`superset/commands/report/execute.py`), which wraps any `Exception` as 
`ReportScheduleScreenshotFailedError`, driving the report to 
`ReportState.ERROR`. The sibling per-tile-readiness-timeout fix 
(`take_tiled_screenshot()` in `screenshot_utils.py`) only tests up to the point 
the exception leaves the function under test, not the full chain to 
`ReportScheduleScreenshotFailedError` — this PR's tests follow that same 
convention and assert the raise happens at the 
`WebDriverPlaywright.get_screenshot()` boundary.
   
   ### SUMMARY
   
   `WebDriverPlaywright.get_screenshot()` fell back to `_get_screenshot()` — a 
raw `page.screenshot()`/`element.screenshot()` call with **zero** 
wait/readiness logic — whenever the tiled capture (`take_tiled_screenshot()`) 
returned a falsy result (`None` or `b""`). Unlike the tiled path itself or the 
non-tiled/standard branch in this same method, this fallback never waited for 
spinners to clear or charts to render, so it could silently deliver a 
screenshot of loading spinners or a blank dashboard in a report/thumbnail.
   
   This PR removes that fallback. When tiled capture fails for any reason, the 
method now logs a `WARNING` (a capture/rendering issue, not a system fault — 
matching the level already used for the other capture-failure paths in this 
method) and raises `PlaywrightTimeout`, which propagates to a clean report 
failure the same way the other timeout paths in this method already do.
   
   ### BEFORE/AFTER
   
   **Before:**
   ```python
   if not img:
       logger.warning("Tiled screenshot failed, falling back to standard 
screenshot")
       img = WebDriverPlaywright._get_screenshot(page, element, element_name)
   ```
   
   **After:**
   ```python
   if not img:
       logger.warning(
           "Tiled screenshot failed for url %s and no safe fallback "
           "exists; failing the report",
           url,
       )
       raise PlaywrightTimeout(f"Tiled screenshot failed for url {url}")
   ```
   
   ### TESTING INSTRUCTIONS
   
   - 
`tests/unit_tests/utils/webdriver_test.py::TestWebDriverPlaywrightFallback::test_tiled_screenshot_failure_raises_without_fallback`
 — `take_tiled_screenshot()` returns `None` → asserts `PlaywrightTimeout` is 
raised, `page.screenshot`/`element.screenshot` are never called, and the 
`WARNING` log fires with the expected message.
   - 
`tests/unit_tests/utils/webdriver_test.py::TestWebDriverPlaywrightAnimationWaitOrder::test_tiled_empty_bytes_raises_without_fallback`
 — same assertions for the `b""` (falsy-but-not-`None`) case.
   - Ran `pytest tests/unit_tests/utils/webdriver_test.py 
tests/unit_tests/utils/test_screenshot_utils.py` — 59 passed, 1 pre-existing 
failure unrelated to this change 
(`test_get_screenshot_handles_playwright_timeout` fails on `master` too, due to 
a `playwright` package version mismatch with the test's no-arg 
`PlaywrightTimeout()` construction).
   - Ran `pre-commit run --files superset/utils/webdriver.py 
tests/unit_tests/utils/webdriver_test.py` — all hooks pass (ruff, ruff-format, 
mypy, pylint).
   
   ### ADDITIONAL INFORMATION
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] Migration is atomic, supports rollback & is backwards-compatible
     - [ ] Confirm DB migration upgrade and downgrade tested
     - [ ] Runtime estimates and downtime expectations provided
   - [ ] Introduces new feature or API
   - [ ] Removes existing feature or API
   
   **Not changed (out of scope for this PR):**
   - `take_tiled_screenshot()` itself in `screenshot_utils.py`, and the 
tiling-routing decision (chart-count/height threshold) in `webdriver.py`.
   - The non-tiled/standard screenshot branch in 
`WebDriverPlaywright.get_screenshot()`.
   - The Selenium webdriver path (`WebDriverSelenium`).
   - Pixel-level/image-content blank-screenshot validation — not built as a 
backstop here.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to