codeant-ai-for-open-source[bot] commented on code in PR #42118:
URL: https://github.com/apache/superset/pull/42118#discussion_r3599301065


##########
tests/unit_tests/utils/test_screenshot_utils.py:
##########
@@ -397,3 +398,106 @@ def test_animation_wait_default_is_zero(self):
 
         sig = inspect.signature(take_tiled_screenshot)
         assert sig.parameters["animation_wait"].default == 0
+
+
+class TestTileWaitBudget:
+    @pytest.fixture
+    def mock_page(self):

Review Comment:
   **Suggestion:** Add explicit parameter and return type annotations to this 
fixture method signature. [custom_rule]
   
   **Severity Level:** Minor ๐Ÿงน
   <details>
   <summary><b>Why it matters? โญ </b></summary>
   
   The new fixture method omits both parameter and return type annotations, 
which violates the Python type-hints rule for newly added code.
   </details>
   <details>
   <summary><b>Rule source ๐Ÿ“– </b></summary>
   
   .cursor/rules/dev-standard.mdc (line 28)
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=7b38d85cc459435fb20d574556994ca5&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=7b38d85cc459435fb20d574556994ca5&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent ๐Ÿค– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** tests/unit_tests/utils/test_screenshot_utils.py
   **Line:** 405:405
   **Comment:**
        *Custom Rule: Add explicit parameter and return type annotations to 
this fixture method signature.
   
   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
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=809943a70e337a20fbfc77808b8ffea53f6a9596232755f9a521be90ced6ef62&reaction=like'>๐Ÿ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=809943a70e337a20fbfc77808b8ffea53f6a9596232755f9a521be90ced6ef62&reaction=dislike'>๐Ÿ‘Ž</a>



##########
superset/utils/screenshot_utils.py:
##########
@@ -28,6 +29,35 @@
 # Time to wait after scrolling for content to settle and load (in milliseconds)
 SCROLL_SETTLE_TIMEOUT_MS = 1000
 
+# Total wall-clock budget, in seconds, for the entire tiled-screenshot
+# operation (element lookup plus all per-tile spinner/animation waits
+# combined). Each tile's wait is capped at whatever remains of this budget
+# so a slow dashboard degrades gracefully instead of running past the
+# Celery task time limit and getting SIGKILLed mid-capture.
+#
+# This is a conservative fixed constant rather than a value derived from
+# Celery's configured task time limit at runtime, because that limit isn't
+# reliably reachable from here: superset/tasks/scheduler.py sets it
+# per-report-schedule via `apply_async(time_limit=..., soft_time_limit=...)`
+# only when a schedule defines `working_timeout`
+# (ALERT_REPORTS_WORKING_TIME_OUT_KILL); there is no static config value
+# that always reflects the limit actually enforced, and this function can
+# also run outside of a Celery task entirely (e.g. synchronous thumbnail
+# generation).
+#
+# Production has observed a Celery hard task_time_limit of 1740s (29 min)
+# for report execution (2026-07-13 incident: a tiled screenshot was killed
+# mid-capture with SoftTimeLimitExceeded). This budget leaves a 300s margin
+# under that ceiling for the rest of the pipeline that runs after tiling
+# completes: combining tiles into one image, building the PDF, and
+# uploading/delivering the notification.
+TILED_SCREENSHOT_TOTAL_WAIT_BUDGET_SECONDS = 1440  # 1740s limit - 300s margin

Review Comment:
   **Suggestion:** Add an explicit type annotation to this new module-level 
constant (for example, annotate it as an integer) to satisfy the type-hint 
requirement for relevant variables. [custom_rule]
   
   **Severity Level:** Minor ๐Ÿงน
   <details>
   <summary><b>Why it matters? โญ </b></summary>
   
   This is a new module-level constant introduced without a type annotation, 
and the custom rule requires type hints for relevant variables that can be 
annotated. An `int` annotation would satisfy the rule.
   </details>
   <details>
   <summary><b>Rule source ๐Ÿ“– </b></summary>
   
   .cursor/rules/dev-standard.mdc (line 28)
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=968703c5289f4b0a8e831cc1c71991bc&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=968703c5289f4b0a8e831cc1c71991bc&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent ๐Ÿค– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/utils/screenshot_utils.py
   **Line:** 54:54
   **Comment:**
        *Custom Rule: Add an explicit type annotation to this new module-level 
constant (for example, annotate it as an integer) to satisfy the type-hint 
requirement for relevant variables.
   
   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
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=da7aaf4f7698a094c3f4e87e27fd64b35811c2a91914d43f3602e3b8034acc10&reaction=like'>๐Ÿ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=da7aaf4f7698a094c3f4e87e27fd64b35811c2a91914d43f3602e3b8034acc10&reaction=dislike'>๐Ÿ‘Ž</a>



##########
tests/unit_tests/utils/test_screenshot_utils.py:
##########
@@ -397,3 +398,106 @@ def test_animation_wait_default_is_zero(self):
 
         sig = inspect.signature(take_tiled_screenshot)
         assert sig.parameters["animation_wait"].default == 0
+
+
+class TestTileWaitBudget:
+    @pytest.fixture
+    def mock_page(self):
+        """Create a mock Playwright page object for a 3-tile (5000px) 
dashboard."""
+        page = MagicMock()
+        element = MagicMock()
+        page.locator.return_value = element
+        page.evaluate.return_value = {
+            "height": 5000,
+            "top": 100,
+            "left": 50,
+            "width": 800,
+        }
+        page.screenshot.return_value = b"fake_screenshot_data"
+        return page
+
+    def test_per_tile_wait_shrinks_as_budget_depletes(self, mock_page, 
monkeypatch):

Review Comment:
   **Suggestion:** Add type annotations for all parameters and an explicit 
return type on this new test method. [custom_rule]
   
   **Severity Level:** Minor ๐Ÿงน
   <details>
   <summary><b>Why it matters? โญ </b></summary>
   
   The added test method has unannotated parameters and no return type 
annotation, so it matches the type-hints violation rule.
   </details>
   <details>
   <summary><b>Rule source ๐Ÿ“– </b></summary>
   
   .cursor/rules/dev-standard.mdc (line 28)
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=f20f628fd0114eca86e2609f05bd71c8&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=f20f628fd0114eca86e2609f05bd71c8&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent ๐Ÿค– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** tests/unit_tests/utils/test_screenshot_utils.py
   **Line:** 419:419
   **Comment:**
        *Custom Rule: Add type annotations for all parameters and an explicit 
return type on this new test method.
   
   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
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=a9f2206e01e67d3c1c64a79a1454d100716b66a8ea0dc3208814eeebc6f008a1&reaction=like'>๐Ÿ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=a9f2206e01e67d3c1c64a79a1454d100716b66a8ea0dc3208814eeebc6f008a1&reaction=dislike'>๐Ÿ‘Ž</a>



##########
tests/unit_tests/utils/test_screenshot_utils.py:
##########
@@ -397,3 +398,106 @@ def test_animation_wait_default_is_zero(self):
 
         sig = inspect.signature(take_tiled_screenshot)
         assert sig.parameters["animation_wait"].default == 0
+
+
+class TestTileWaitBudget:
+    @pytest.fixture
+    def mock_page(self):
+        """Create a mock Playwright page object for a 3-tile (5000px) 
dashboard."""
+        page = MagicMock()
+        element = MagicMock()
+        page.locator.return_value = element
+        page.evaluate.return_value = {
+            "height": 5000,
+            "top": 100,
+            "left": 50,
+            "width": 800,
+        }
+        page.screenshot.return_value = b"fake_screenshot_data"
+        return page
+
+    def test_per_tile_wait_shrinks_as_budget_depletes(self, mock_page, 
monkeypatch):
+        """Each tile's spinner-wait timeout is capped at the remaining 
budget."""
+        monkeypatch.setattr(
+            
"superset.utils.screenshot_utils.TILED_SCREENSHOT_TOTAL_WAIT_BUDGET_SECONDS",  
# noqa: E501
+            1000,
+        )
+        # monotonic() is called once for start_time, then once per tile to
+        # compute elapsed/remaining budget before that tile's spinner wait.
+        monotonic_values = iter([0, 0, 950, 990])
+        with patch(
+            "superset.utils.screenshot_utils.time.monotonic",
+            side_effect=lambda: next(monotonic_values),
+        ):
+            with 
patch("superset.utils.screenshot_utils.combine_screenshot_tiles"):
+                result = take_tiled_screenshot(
+                    mock_page, "dashboard", tile_height=2000, load_wait=100
+                )
+
+        assert result is not None
+        timeouts = [
+            call[1]["timeout"] for call in 
mock_page.wait_for_function.call_args_list
+        ]
+        # remaining budget: 1000, 50, 10 seconds -> capped timeouts shrink
+        assert timeouts == [100 * 1000, 50 * 1000, 10 * 1000]
+        assert timeouts == sorted(timeouts, reverse=True)
+
+    def test_budget_exhausted_raises_and_stops_capturing(self, mock_page, 
monkeypatch):
+        """Exhausting the budget aborts cleanly instead of capturing 
unchecked."""
+        monkeypatch.setattr(
+            
"superset.utils.screenshot_utils.TILED_SCREENSHOT_TOTAL_WAIT_BUDGET_SECONDS",  
# noqa: E501
+            1000,
+        )
+        # start_time=0, tile 0 check: elapsed=0 (proceeds and captures),
+        # tile 1 check: elapsed=1000 -> remaining=0 -> raise before capturing.
+        monotonic_values = iter([0, 0, 1000])
+        with patch(
+            "superset.utils.screenshot_utils.time.monotonic",
+            side_effect=lambda: next(monotonic_values),
+        ):
+            with patch(
+                "superset.utils.screenshot_utils.combine_screenshot_tiles"
+            ) as mock_combine:
+                with patch("superset.utils.screenshot_utils.logger") as 
mock_logger:
+                    with pytest.raises(TiledScreenshotBudgetExceededError):
+                        take_tiled_screenshot(
+                            mock_page, "dashboard", tile_height=2000, 
load_wait=100
+                        )
+
+        # Only the first tile was captured before the budget ran out.
+        assert mock_page.screenshot.call_count == 1
+        # Tiles were never combined -- the function raised before that point.
+        mock_combine.assert_not_called()
+
+        mock_logger.error.assert_called_once()
+        error_args = mock_logger.error.call_args[0]
+        assert "budget exhausted" in error_args[0]
+        # tiles captured, tiles total, elapsed seconds, budget seconds
+        assert error_args[1] == 1
+        assert error_args[2] == 3
+        assert error_args[3] == 1000
+        assert error_args[4] == 1000
+
+    def test_fast_dashboard_matches_default_behavior(self, mock_page):

Review Comment:
   **Suggestion:** Add parameter and return type annotations to this test 
method declaration. [custom_rule]
   
   **Severity Level:** Minor ๐Ÿงน
   <details>
   <summary><b>Why it matters? โญ </b></summary>
   
   This new test method omits type hints for its argument and return value, so 
the suggestion correctly identifies a type-hints violation.
   </details>
   <details>
   <summary><b>Rule source ๐Ÿ“– </b></summary>
   
   .cursor/rules/dev-standard.mdc (line 28)
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=6de36cb75c8447d7b86ccff9fe4602ac&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=6de36cb75c8447d7b86ccff9fe4602ac&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent ๐Ÿค– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** tests/unit_tests/utils/test_screenshot_utils.py
   **Line:** 481:481
   **Comment:**
        *Custom Rule: Add parameter and return type annotations to this test 
method declaration.
   
   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
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=57588b945dc2632369429cf0ff516110c40c922e4d36f1ae8add364cf23ca0fa&reaction=like'>๐Ÿ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=57588b945dc2632369429cf0ff516110c40c922e4d36f1ae8add364cf23ca0fa&reaction=dislike'>๐Ÿ‘Ž</a>



##########
tests/unit_tests/utils/test_screenshot_utils.py:
##########
@@ -397,3 +398,106 @@ def test_animation_wait_default_is_zero(self):
 
         sig = inspect.signature(take_tiled_screenshot)
         assert sig.parameters["animation_wait"].default == 0
+
+
+class TestTileWaitBudget:
+    @pytest.fixture
+    def mock_page(self):
+        """Create a mock Playwright page object for a 3-tile (5000px) 
dashboard."""
+        page = MagicMock()
+        element = MagicMock()
+        page.locator.return_value = element
+        page.evaluate.return_value = {
+            "height": 5000,
+            "top": 100,
+            "left": 50,
+            "width": 800,
+        }
+        page.screenshot.return_value = b"fake_screenshot_data"
+        return page
+
+    def test_per_tile_wait_shrinks_as_budget_depletes(self, mock_page, 
monkeypatch):
+        """Each tile's spinner-wait timeout is capped at the remaining 
budget."""
+        monkeypatch.setattr(
+            
"superset.utils.screenshot_utils.TILED_SCREENSHOT_TOTAL_WAIT_BUDGET_SECONDS",  
# noqa: E501
+            1000,
+        )
+        # monotonic() is called once for start_time, then once per tile to
+        # compute elapsed/remaining budget before that tile's spinner wait.
+        monotonic_values = iter([0, 0, 950, 990])
+        with patch(
+            "superset.utils.screenshot_utils.time.monotonic",
+            side_effect=lambda: next(monotonic_values),
+        ):
+            with 
patch("superset.utils.screenshot_utils.combine_screenshot_tiles"):
+                result = take_tiled_screenshot(
+                    mock_page, "dashboard", tile_height=2000, load_wait=100
+                )
+
+        assert result is not None
+        timeouts = [
+            call[1]["timeout"] for call in 
mock_page.wait_for_function.call_args_list
+        ]
+        # remaining budget: 1000, 50, 10 seconds -> capped timeouts shrink
+        assert timeouts == [100 * 1000, 50 * 1000, 10 * 1000]
+        assert timeouts == sorted(timeouts, reverse=True)
+
+    def test_budget_exhausted_raises_and_stops_capturing(self, mock_page, 
monkeypatch):

Review Comment:
   **Suggestion:** Add type hints to this method signature, including fixture 
argument types and a return type. [custom_rule]
   
   **Severity Level:** Minor ๐Ÿงน
   <details>
   <summary><b>Why it matters? โญ </b></summary>
   
   This newly added test method is missing type annotations on its parameters 
and return type, which is a real violation of the type-hints rule.
   </details>
   <details>
   <summary><b>Rule source ๐Ÿ“– </b></summary>
   
   .cursor/rules/dev-standard.mdc (line 28)
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=8dae0036fa864eefb48dfb6676e4a31a&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=8dae0036fa864eefb48dfb6676e4a31a&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent ๐Ÿค– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** tests/unit_tests/utils/test_screenshot_utils.py
   **Line:** 445:445
   **Comment:**
        *Custom Rule: Add type hints to this method signature, including 
fixture argument types and a return type.
   
   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
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=3de3388727e50825725e25aae3d21fbf3211ccdd9c76403f22557ff14ef7c776&reaction=like'>๐Ÿ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42118&comment_hash=3de3388727e50825725e25aae3d21fbf3211ccdd9c76403f22557ff14ef7c776&reaction=dislike'>๐Ÿ‘Ž</a>



-- 
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