This is an automated email from the ASF dual-hosted git repository.

bbovenzi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 0f7f45f674c Fix XComs e2e filter tests: scope the filter input by 
testid (#72438)
0f7f45f674c is described below

commit 0f7f45f674cbd2575c365107f843d2872980760f
Author: Kunal <[email protected]>
AuthorDate: Fri Sep 4 22:11:30 2026 +0530

    Fix XComs e2e filter tests: scope the filter input by testid (#72438)
    
    * Fix XComs e2e filter tests: scope the filter input by testid
    
    xcoms.spec.ts's filter tests locate the active filter pill's input via
    page.locator("div").filter({ hasText: `${filterName}:` }), which
    matches any ancestor whose descendant text contains that string.
    #71554 restructured the filter bar's DOM so more than one ancestor now
    matches, and .first() no longer reliably picks the actual pill -
    getByRole("textbox") on it resolves to every textbox inside whichever
    div wins, throwing "resolved to 12 elements instead of 1".
    
    Give the actively-editing pill's input a stable data-testid
    (filter-pill-input) instead of relying on ancestor text matching, and
    scope XComsPage.applyFilter() to it directly. Only one pill is ever in
    edit mode at a time, so the testid alone is enough - no per-filter key
    plumbing needed.
    
    Added a FilterBar test that fails without the fix (verified locally by
    reverting the testid and confirming the new test - and only that
    test - breaks).
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
    Claude-Session: https://claude.ai/code/session_015kAvbZ6SeKgp6jbGcvpXSh
    
    * Add newsfragment
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
    Claude-Session: https://claude.ai/code/session_015kAvbZ6SeKgp6jbGcvpXSh
    
    * Revert "Add newsfragment"
    
    This reverts commit 06fd055afb8fa6f4f3c6b7ea31d5c0920ee850ed.
    
    ---------
    
    Co-authored-by: Claude <[email protected]>
    Co-authored-by: Kunal8954 <[email protected]>
---
 .../ui/src/components/FilterBar/FilterBar.test.tsx     | 18 ++++++++++++++++++
 .../components/FilterBar/filters/TextSearchFilter.tsx  |  1 +
 .../src/airflow/ui/tests/e2e/pages/XComsPage.ts        | 11 ++++++-----
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git 
a/airflow-core/src/airflow/ui/src/components/FilterBar/FilterBar.test.tsx 
b/airflow-core/src/airflow/ui/src/components/FilterBar/FilterBar.test.tsx
index 3b324a891e2..7b4e7326cfb 100644
--- a/airflow-core/src/airflow/ui/src/components/FilterBar/FilterBar.test.tsx
+++ b/airflow-core/src/airflow/ui/src/components/FilterBar/FilterBar.test.tsx
@@ -198,6 +198,24 @@ describe("FilterBar abandoned filters", () => {
   });
 });
 
+describe("FilterBar text filter input testid", () => {
+  it("exposes the actively-editing pill's input via a stable, unique testid", 
async () => {
+    render(<FilterBar configs={[textConfig]} onFiltersChange={vi.fn()} />, { 
wrapper });
+
+    fireEvent.click(screen.getByTestId("add-filter-button"));
+    fireEvent.click(await screen.findByTestId("add-filter-dag_id"));
+
+    // Regression guard for #72433: e2e tests locate this input via 
`filter-pill-input`
+    // rather than `page.locator("div").filter({ hasText })`, which matched 
any ancestor
+    // whose descendant text contained the filter label and broke once the 
filter bar's
+    // DOM was restructured. `getByTestId` throws if more than one match is 
found, so this
+    // also proves the testid stays unique while a pill is being edited.
+    const input = screen.getByTestId("filter-pill-input");
+
+    expect(input).toBe(screen.getByRole("textbox"));
+  });
+});
+
 describe("FilterBar keyboard handling", () => {
   it("leaves Enter to editors that use it to commit a value", async () => {
     render(<FilterBar configs={[multiSelectConfig]} onFiltersChange={vi.fn()} 
/>, { wrapper });
diff --git 
a/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx
 
b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx
index 045900f10e5..b0754174385 100644
--- 
a/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx
+++ 
b/airflow-core/src/airflow/ui/src/components/FilterBar/filters/TextSearchFilter.tsx
@@ -77,6 +77,7 @@ export const TextSearchFilter = ({ filter, onChange, onRemove 
}: FilterPluginPro
       renderInput={(props) => (
         <InputWithAddon
           {...props}
+          data-testid="filter-pill-input"
           endAddon={
             showAdvancedToggle ? (
               <AdvancedSearchToggle enabled={advanced.enabled} 
onToggle={advanced.onToggle} variant="addon" />
diff --git a/airflow-core/src/airflow/ui/tests/e2e/pages/XComsPage.ts 
b/airflow-core/src/airflow/ui/tests/e2e/pages/XComsPage.ts
index 88c9566ffde..30e5b8b2f8f 100644
--- a/airflow-core/src/airflow/ui/tests/e2e/pages/XComsPage.ts
+++ b/airflow-core/src/airflow/ui/tests/e2e/pages/XComsPage.ts
@@ -53,11 +53,12 @@ export class XComsPage extends BasePage {
 
     await filterOption.click();
 
-    const filterPill = this.page
-      .locator("div")
-      .filter({ hasText: `${filterName}:` })
-      .first();
-    const filterInput = filterPill.getByRole("textbox");
+    // The newly added pill enters edit mode immediately, and 
`filter-pill-input` is only
+    // rendered on the pill that is actively being edited — so this resolves 
to exactly one
+    // element. Previously this scoped through `page.locator("div").filter({ 
hasText: ... })`,
+    // which matches any ancestor whose descendant text contains 
"<filterName>:" and broke
+    // (matched 12 elements instead of 1) once #71554 restructured the filter 
bar's DOM.
+    const filterInput = this.page.getByTestId("filter-pill-input");
 
     await expect(filterInput).toBeVisible({ timeout: 30_000 });
     await filterInput.fill(value);

Reply via email to