This is an automated email from the ASF dual-hosted git repository.
potiuk 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 9d4f495a804 Fix flaky Firefox calendar-tab e2e tests: read run states
from the DOM (#67879)
9d4f495a804 is described below
commit 9d4f495a804e9a79015f1618665029d8a24e8edc
Author: Jarek Potiuk <[email protected]>
AuthorDate: Tue Jun 2 17:10:07 2026 +0200
Fix flaky Firefox calendar-tab e2e tests: read run states from the DOM
(#67879)
The Dag Calendar tab e2e tests read run states by hovering each cell to open
the tooltip. BasicTooltip opens on a mouseenter after a 500ms delay and
renders
through a portal, which synthetic pointer events do not open reliably in
headless Firefox — the three state-reading tests timed out there (chromium
was
unaffected), and a stepped real-pointer hover did not help either.
Expose the per-cell run states as a data-states attribute on the calendar
cell,
computed with the same view-mode-aware logic the tooltip uses, and read that
attribute in the tests instead of hovering. Reading a DOM attribute is
deterministic and backend-independent, so the tests pass on every browser.
---
.../ui/src/pages/Dag/Calendar/CalendarCell.tsx | 14 +++++++++++
.../airflow/ui/tests/e2e/pages/DagCalendarTab.ts | 28 ++++++++--------------
.../ui/tests/e2e/specs/dag-calendar-tab.spec.ts | 2 +-
3 files changed, 25 insertions(+), 19 deletions(-)
diff --git
a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
index a64ac790ea8..ea91e34309b 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
@@ -51,6 +51,18 @@ export const CalendarCell = ({
const hasData = Boolean(cellData && relevantCount > 0);
const hasTooltip = Boolean(cellData);
+ // States present in this cell, computed with the same view-mode-aware logic
the
+ // tooltip uses (see CalendarTooltip). Exposed as a `data-states` attribute
so e2e
+ // tests can read run states from the DOM instead of hovering — the tooltip
does
+ // not open reliably under synthetic pointer events in headless Firefox.
+ const runStates = cellData
+ ? Object.entries(cellData.counts)
+ .filter(
+ ([key, value]) => key !== "total" && value > 0 && (viewMode ===
"failed" ? key === "failed" : true),
+ )
+ .map(([key]) => key)
+ : [];
+
const isMixedState =
typeof backgroundColor === "object" && "planned" in backgroundColor &&
"actual" in backgroundColor;
@@ -60,6 +72,7 @@ export const CalendarCell = ({
borderRadius="2px"
cursor={hasData ? "pointer" : "default"}
data-has-data={hasData ? "true" : "false"}
+ data-states={runStates.join(" ")}
data-testid="calendar-cell"
data-view-mode={viewMode}
height="14px"
@@ -90,6 +103,7 @@ export const CalendarCell = ({
borderRadius="2px"
cursor={hasData ? "pointer" : "default"}
data-has-data={hasData ? "true" : "false"}
+ data-states={runStates.join(" ")}
data-testid="calendar-cell"
data-view-mode={viewMode}
height="14px"
diff --git a/airflow-core/src/airflow/ui/tests/e2e/pages/DagCalendarTab.ts
b/airflow-core/src/airflow/ui/tests/e2e/pages/DagCalendarTab.ts
index 77b6d465864..74e46a1802d 100644
--- a/airflow-core/src/airflow/ui/tests/e2e/pages/DagCalendarTab.ts
+++ b/airflow-core/src/airflow/ui/tests/e2e/pages/DagCalendarTab.ts
@@ -33,10 +33,6 @@ export class DagCalendarTab extends BasePage {
return this.page.getByTestId("calendar-cell");
}
- public get tooltip(): Locator {
- return this.page.getByTestId("calendar-tooltip");
- }
-
public constructor(page: Page) {
super(page);
@@ -92,22 +88,18 @@ export class DagCalendarTab extends BasePage {
const count = await this.activeCells.count();
const states: Array<string> = [];
+ // Read run states from the cell's `data-states` attribute rather than
hovering to
+ // read the tooltip. The tooltip (BasicTooltip) opens on a `mouseenter`
after a
+ // 500ms delay and renders through a portal; synthetic pointer events do
not open
+ // it reliably in headless Firefox, which made these tests flaky.
`data-states` is
+ // populated with the same view-mode-aware logic the tooltip uses (see
+ // CalendarCell), so the assertions are unchanged and now
backend-independent.
for (let i = 0; i < count; i++) {
- const cell = this.activeCells.nth(i);
+ const raw = (await this.activeCells.nth(i).getAttribute("data-states"))
?? "";
- // Firefox sometimes fails to trigger tooltips on hover.
- // Retry the hover + tooltip visibility check to handle this.
- let text = "";
-
- await expect(async () => {
- await cell.hover({ force: true });
- await expect(this.tooltip).toBeVisible({ timeout: 3000 });
- text = ((await this.tooltip.textContent()) ?? "").toLowerCase();
- }).toPass({ intervals: [1000], timeout: 20_000 });
-
- if (text.includes("success")) states.push("success");
- if (text.includes("failed")) states.push("failed");
- if (text.includes("running")) states.push("running");
+ for (const state of raw.split(" ").filter(Boolean)) {
+ states.push(state);
+ }
}
return states;
diff --git
a/airflow-core/src/airflow/ui/tests/e2e/specs/dag-calendar-tab.spec.ts
b/airflow-core/src/airflow/ui/tests/e2e/specs/dag-calendar-tab.spec.ts
index d05f4b9e9bc..771f7241f85 100644
--- a/airflow-core/src/airflow/ui/tests/e2e/specs/dag-calendar-tab.spec.ts
+++ b/airflow-core/src/airflow/ui/tests/e2e/specs/dag-calendar-tab.spec.ts
@@ -48,7 +48,7 @@ test.describe("Dag Calendar Tab", () => {
expect(states.length).toBeGreaterThanOrEqual(2);
});
- test("verify hover shows correct run states", async ({ dagCalendarTab }) => {
+ test("verify success and failed run states are detected", async ({
dagCalendarTab }) => {
await dagCalendarTab.switchToHourly();
const states = await dagCalendarTab.getManualRunStates();