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


##########
superset-frontend/src/explore/components/DataTableControl/FilterInput.test.tsx:
##########
@@ -34,3 +34,25 @@ test('Render a FilterInput', async () => {
 
   expect(onChangeHandler).toHaveBeenCalledTimes(4);
 });
+
+test('FilterInput does not steal focus when another input already has focus', 
() => {
+  const onChangeHandler = jest.fn();
+
+  // Create a plain DOM input, focus it before mounting FilterInput
+  const otherInput = document.createElement('input');
+  document.body.appendChild(otherInput);
+  otherInput.focus();
+  expect(document.activeElement).toBe(otherInput);
+
+  // Mount FilterInput with shouldFocus=true while the other input is focused
+  const { container } = render(
+    <FilterInput onChangeHandler={onChangeHandler} shouldFocus />,
+  );
+  const filterInput = container.querySelector('input') as HTMLInputElement;
+
+  // FilterInput should not have stolen focus from the already-focused input

Review Comment:
   **Suggestion:** This test can pass even when the filter textbox is missing 
because `querySelector('input')` may return `null`, and 
`expect(document.activeElement).not.toBe(filterInput)` will still pass in that 
case. Add an explicit existence assertion (or query by role with a throwing 
query) before the focus assertions so the test actually verifies the rendered 
filter input. [incomplete implementation]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ⚠️ Explore results filter regressions may bypass this focus test.
   - ⚠️ Focus-stealing behavior changes might go undetected for 
shouldFocus=true.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open 
`superset-frontend/src/explore/components/DataTableControl/FilterInput.test.tsx`
   and locate the second test `FilterInput does not steal focus when another 
input already
   has focus` around lines 38–58 (confirmed via Grep output).
   
   2. Observe that this test obtains the element with `const filterInput =
   container.querySelector('input') as HTMLInputElement;` at line 51 but does 
not assert that
   `filterInput` is non-null before using it.
   
   3. Note from the DOM API that `querySelector('input')` returns `null` if no 
`<input>`
   exists; in that case `filterInput` will be `null` at runtime, and
   `expect(document.activeElement).not.toBe(filterInput);` at line 54 will 
still pass because
   `document.activeElement` (the other input created at lines 41–45) is not 
`null`.
   
   4. To concretely reproduce, temporarily modify `FilterInput` in
   `superset-frontend/src/explore/components/DataTableControl/index.tsx` (lines 
12–55 from
   BulkRead) so that when `shouldFocus` is `true` it returns `null` instead of 
the `<Input>`;
   then run `npx jest
   
superset-frontend/src/explore/components/DataTableControl/FilterInput.test.tsx` 
and
   observe that the `FilterInput does not steal focus` test still passes even 
though no
   filter textbox was rendered, demonstrating the false-positive gap caused by 
the missing
   existence assertion.
   ```
   </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=f3aa223629644f689740e631b65c304a&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=f3aa223629644f689740e631b65c304a&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-frontend/src/explore/components/DataTableControl/FilterInput.test.tsx
   **Line:** 51:53
   **Comment:**
        *Incomplete Implementation: This test can pass even when the filter 
textbox is missing because `querySelector('input')` may return `null`, and 
`expect(document.activeElement).not.toBe(filterInput)` will still pass in that 
case. Add an explicit existence assertion (or query by role with a throwing 
query) before the focus assertions so the test actually verifies the rendered 
filter input.
   
   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%2F41100&comment_hash=d2f4d93860f77be09680f333bf909c019efc58a4d2ecec97b148f48592c526d4&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41100&comment_hash=d2f4d93860f77be09680f333bf909c019efc58a4d2ecec97b148f48592c526d4&reaction=dislike'>👎</a>



##########
superset-frontend/src/explore/components/DataTableControl/index.tsx:
##########
@@ -108,9 +108,16 @@ export const FilterInput = ({
   const inputRef: RefObject<any> = useRef(null);
 
   useEffect(() => {
-    // Focus the input element when the component mounts
     if (inputRef.current && shouldFocus) {
-      inputRef.current.focus();
+      const activeEl = document.activeElement;
+      const isInputFocused =
+        activeEl &&
+        (activeEl.tagName === 'INPUT' ||
+          activeEl.tagName === 'TEXTAREA' ||
+          (activeEl as HTMLElement).isContentEditable);
+      if (!isInputFocused) {
+        inputRef.current.focus();
+      }

Review Comment:
   **Suggestion:** The focus guard is too narrow: it only treats `INPUT`, 
`TEXTAREA`, and contenteditable elements as "actively editing." If any other 
focusable control is currently focused (for example a button-based control, 
slider handle, or custom widget), this code will still force focus into the 
filter input and can reproduce the same focus-stealing behavior. Guard against 
stealing focus whenever `document.activeElement` is a meaningful focused 
element (for example anything other than `body`/null), not only text-entry 
tags. [incorrect condition logic]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ⚠️ Explore results controls can lose focus during data reloads.
   - ⚠️ Keyboard users may experience unexpected focus jumps to search.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Inspect `FilterInput` in
   `superset-frontend/src/explore/components/DataTableControl/index.tsx` 
(BulkRead lines
   12–55): its `useEffect` at lines 21–33 focuses the underlying `<Input>`
   (`inputRef.current.focus();`) whenever `shouldFocus` is `true` and 
`isInputFocused` is
   `false`.
   
   2. Observe that `isInputFocused` is defined at lines 24–28 as `activeEl &&
   (activeEl.tagName === 'INPUT' || activeEl.tagName === 'TEXTAREA' || 
(activeEl as
   HTMLElement).isContentEditable);`, meaning any currently focused `<button>`, 
`<span
   role="button">`, `<select>`, or other custom control is *not* treated as a 
protected focus
   target.
   
   3. Follow the call chain: `FilterInput` is used by `TableControls` in
   
`superset-frontend/src/explore/components/DataTablesPane/components/DataTableControls.tsx`
   at line 17, which is in turn rendered by `SingleQueryResultPane`
   
(`superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx`
   lines 52–69) and wired up via `useResultsPane`
   
(`superset-frontend/src/explore/components/DataTablesPane/components/useResultsPane.tsx`
   lines 29–60), so it appears in the Explore Results pane.
   
   4. In a running Explore session using this code, focus the row-limit 
`<Select>` or the
   reload icon button rendered by `TableControls` (lines 25–33 and 57–65 in
   `DataTableControls.tsx`); when `useResultsPane` triggers a re-fetch that 
unmounts/remounts
   `SingleQueryResultPane`, `FilterInput` mounts, `document.activeElement` 
still points to
   that non-text control, `isInputFocused` evaluates to `false`, and
   `inputRef.current.focus();` at line 30 executes, stealing focus into the 
search
   input—demonstrating that the current guard still allows focus theft from 
non-text but
   meaningful focused controls.
   ```
   </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=d9a4b5f488934a24b91ed26e1498d5a3&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=d9a4b5f488934a24b91ed26e1498d5a3&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-frontend/src/explore/components/DataTableControl/index.tsx
   **Line:** 113:120
   **Comment:**
        *Incorrect Condition Logic: The focus guard is too narrow: it only 
treats `INPUT`, `TEXTAREA`, and contenteditable elements as "actively editing." 
If any other focusable control is currently focused (for example a button-based 
control, slider handle, or custom widget), this code will still force focus 
into the filter input and can reproduce the same focus-stealing behavior. Guard 
against stealing focus whenever `document.activeElement` is a meaningful 
focused element (for example anything other than `body`/null), not only 
text-entry tags.
   
   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%2F41100&comment_hash=414343f68d1e2da88471929ff3134df8998ad0fd249f6a0a9179985a4d0a4592&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41100&comment_hash=414343f68d1e2da88471929ff3134df8998ad0fd249f6a0a9179985a4d0a4592&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