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 717c0fb9e1e Fix 63573 task duration tooltip (#63639)
717c0fb9e1e is described below

commit 717c0fb9e1ede0ce3b60f08c5b74a7221cd73c09
Author: Subham <[email protected]>
AuthorDate: Wed Mar 18 23:41:23 2026 +0530

    Fix 63573 task duration tooltip (#63639)
    
    * Fix task duration tooltip showing stale duration for running tasks 
(#63573)
    
    * UI: fix TaskInstanceTooltip test typing
    
    Made-with: Cursor
    
    ---------
    
    Co-authored-by: Jarek Potiuk <[email protected]>
---
 .../ui/src/components/TaskInstanceTooltip.test.tsx | 59 +++++++++++++++++++++-
 .../ui/src/components/TaskInstanceTooltip.tsx      |  8 ++-
 2 files changed, 64 insertions(+), 3 deletions(-)

diff --git 
a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.test.tsx 
b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.test.tsx
index bd2758c8bce..51058868003 100644
--- a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.test.tsx
+++ b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.test.tsx
@@ -22,7 +22,7 @@ import "@testing-library/jest-dom";
 import { render, screen } from "@testing-library/react";
 import { describe, expect, it } from "vitest";
 
-import type { LightGridTaskInstanceSummary } from "openapi/requests/types.gen";
+import type { LightGridTaskInstanceSummary, TaskInstanceResponse } from 
"openapi/requests/types.gen";
 import { Wrapper } from "src/utils/Wrapper";
 
 import TaskInstanceTooltip from "./TaskInstanceTooltip";
@@ -60,10 +60,65 @@ describe("TaskInstanceTooltip", () => {
 
     expect(screen.getByText(/state/iu)).toBeInTheDocument();
     expect(screen.getByText(/startDate/iu)).toBeInTheDocument();
-    expect(screen.getByText(/endDate/iu)).toBeInTheDocument();
     expect(screen.getByText(/duration/iu)).toBeInTheDocument();
   });
 
+  it("calculates live duration for a running task instead of using stale 
duration", () => {
+    // We pass a stale duration of 50 seconds, but start date is 2 hours ago.
+    // The calculated duration should be ~2 hours, not 50 seconds.
+    const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 
1000).toISOString();
+    const taskInstance: TaskInstanceResponse = {
+      dag_display_name: "Test DAG",
+      dag_id: "test",
+      dag_run_id: "test",
+      dag_version: null,
+      duration: 50.0,
+      end_date: null,
+      executor: null,
+      executor_config: "{}",
+      hostname: null,
+      id: "test_my_task",
+      logical_date: null,
+      map_index: 0,
+      max_tries: 3,
+      note: null,
+      operator: "DummyOperator",
+      operator_name: "DummyOperator",
+      pid: null,
+      pool: "default_pool",
+      pool_slots: 1,
+      priority_weight: null,
+      queue: null,
+      queued_when: null,
+      rendered_fields: undefined,
+      rendered_map_index: null,
+      run_after: twoHoursAgo,
+      scheduled_when: null,
+      start_date: twoHoursAgo,
+      state: "running",
+      task_display_name: "My Task",
+      task_id: "my_task",
+      trigger: null,
+      triggerer_job: null,
+      try_number: 2,
+      unixname: null,
+    };
+
+    render(
+      <TaskInstanceTooltip open taskInstance={taskInstance}>
+        <span>trigger</span>
+      </TaskInstanceTooltip>,
+      { wrapper: Wrapper },
+    );
+
+    const durationText = 
screen.getByText(/duration/iu).parentElement?.textContent;
+
+    // The calculated duration should be around 2 hours (e.g., "02:00:00" or 
similar)
+    // It should definitely NOT be "00:00:50.000" which is what 
`renderDuration(50)` gives
+    expect(durationText).not.toContain("00:00:50");
+    expect(durationText).toContain("02:00:");
+  });
+
   it("shows only start date when max_end_date is null", () => {
     const taskInstance: LightGridTaskInstanceSummary = {
       child_states: null,
diff --git a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx 
b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
index a375252f420..8162c02a7c3 100644
--- a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
+++ b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
@@ -81,7 +81,13 @@ const TaskInstanceTooltip = ({ children, positioning, 
taskInstance, tooltip, ...
                     {translate("endDate")}: <Time 
datetime={taskInstance.end_date} />
                   </Text>
                   <Text>
-                    {translate("duration")}: 
{renderDuration(taskInstance.duration)}
+                    {translate("duration")}:{" "}
+                    {taskInstance.state === "running" || taskInstance.state 
=== "deferred"
+                      ? getDuration(
+                          taskInstance.start_date,
+                          taskInstance.end_date ?? new Date().toISOString(),
+                        )
+                      : renderDuration(taskInstance.duration)}
                   </Text>
                 </>
               ) : undefined}

Reply via email to