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

choo121600 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 c588c665afc Fix e2e flaky in AssetDetailPage and ConnectionsPage tests 
(#65494)
c588c665afc is described below

commit c588c665afc3d23f97322f0b4da0b917968d7d26
Author: Yeonguk Choo <[email protected]>
AuthorDate: Wed Apr 22 13:21:40 2026 +0900

    Fix e2e flaky in AssetDetailPage and ConnectionsPage tests (#65494)
---
 .../airflow/ui/tests/e2e/pages/AssetDetailPage.ts  |  7 ++++++
 .../airflow/ui/tests/e2e/pages/ConnectionsPage.ts  | 27 +++++++++++-----------
 .../src/airflow/ui/tests/e2e/specs/asset.spec.ts   |  2 +-
 .../airflow/ui/tests/e2e/specs/connections.spec.ts |  2 +-
 4 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/airflow-core/src/airflow/ui/tests/e2e/pages/AssetDetailPage.ts 
b/airflow-core/src/airflow/ui/tests/e2e/pages/AssetDetailPage.ts
index ecd414fd6ef..33402a9dcde 100644
--- a/airflow-core/src/airflow/ui/tests/e2e/pages/AssetDetailPage.ts
+++ b/airflow-core/src/airflow/ui/tests/e2e/pages/AssetDetailPage.ts
@@ -30,7 +30,13 @@ export class AssetDetailPage extends BasePage {
   }
 
   public async clickOnAsset(name: string): Promise<void> {
+    const responsePromise = this.page.waitForResponse(
+      (res) => /\/api\/v2\/assets\/\d+(\?|$)/.test(res.url()) && res.ok(),
+      { timeout: 15_000 },
+    );
+
     await this.page.getByRole("link", { exact: true, name }).click();
+    await responsePromise;
   }
 
   public getHeading(name: string): Locator {
@@ -64,6 +70,7 @@ export class AssetDetailPage extends BasePage {
     const button = statContainer.getByRole("button").first();
 
     await expect(button).toBeVisible();
+    await expect(button).toBeEnabled();
     await expect(button).toHaveText(/^[1-9]/);
 
     const text = await button.textContent();
diff --git a/airflow-core/src/airflow/ui/tests/e2e/pages/ConnectionsPage.ts 
b/airflow-core/src/airflow/ui/tests/e2e/pages/ConnectionsPage.ts
index b5920db3eb8..20fbecb6d5a 100644
--- a/airflow-core/src/airflow/ui/tests/e2e/pages/ConnectionsPage.ts
+++ b/airflow-core/src/airflow/ui/tests/e2e/pages/ConnectionsPage.ts
@@ -147,11 +147,12 @@ export class ConnectionsPage extends BasePage {
     await expect(deleteButton).toBeVisible({ timeout: 10_000 });
     await expect(deleteButton).toBeEnabled({ timeout: 5000 });
 
-    await expect(async () => {
-      await deleteButton.click({ timeout: 5000 });
-      await expect(this.confirmDeleteButton).toBeVisible({ timeout: 5000 });
-    }).toPass({ intervals: [2000], timeout: 30_000 });
+    // Extended timeout: on resource-constrained CI runners, WebKit can take
+    // longer than the default 10s to release the previous dialog's backdrop
+    // pointer-events after close.
+    await deleteButton.click({ timeout: 30_000 });
 
+    await expect(this.confirmDeleteButton).toBeVisible({ timeout: 10_000 });
     await expect(this.confirmDeleteButton).toBeEnabled({ timeout: 5000 });
     await this.confirmDeleteButton.click();
 
@@ -304,17 +305,17 @@ export class ConnectionsPage extends BasePage {
   public async saveConnection(): Promise<void> {
     await expect(this.saveButton).toBeVisible({ timeout: 10_000 });
     await expect(this.saveButton).toBeEnabled({ timeout: 5000 });
-    await this.saveButton.click();
 
-    await Promise.race([
-      this.page.waitForURL("**/connections", { timeout: 10_000 }),
-      this.successAlert.waitFor({ state: "visible", timeout: 30_000 }),
-    ]);
+    const responsePromise = this.page.waitForResponse(
+      (response) =>
+        /\/api\/v2\/connections(\/[^/]+)?(\?|$)/.test(response.url()) &&
+        ["PATCH", "POST"].includes(response.request().method()) &&
+        response.ok(),
+      { timeout: 15_000 },
+    );
 
-    // Ensure the dialog is fully closed before proceeding.
-    // Ark UI may leave the backdrop element in the DOM with 
data-state="closed",
-    // but it is non-interactive (pointer-events: none) and does not block 
clicks.
-    await expect(this.connectionForm).toBeHidden({ timeout: 10_000 });
+    await this.saveButton.click();
+    await responsePromise;
   }
 
   public async searchConnections(searchTerm: string): Promise<void> {
diff --git a/airflow-core/src/airflow/ui/tests/e2e/specs/asset.spec.ts 
b/airflow-core/src/airflow/ui/tests/e2e/specs/asset.spec.ts
index d40cee8a0b3..f1f11eed513 100644
--- a/airflow-core/src/airflow/ui/tests/e2e/specs/asset.spec.ts
+++ b/airflow-core/src/airflow/ui/tests/e2e/specs/asset.spec.ts
@@ -71,7 +71,7 @@ test.describe("Assets Page", () => {
       .toBe(true);
   });
 
-  test.fixme("verify asset details and dependencies", async ({ assetDetailPage 
}) => {
+  test("verify asset details and dependencies", async ({ assetDetailPage }) => 
{
     const assetName = testConfig.asset.name;
 
     await assetDetailPage.goto();
diff --git a/airflow-core/src/airflow/ui/tests/e2e/specs/connections.spec.ts 
b/airflow-core/src/airflow/ui/tests/e2e/specs/connections.spec.ts
index 510a49316d6..131cb3a5d59 100644
--- a/airflow-core/src/airflow/ui/tests/e2e/specs/connections.spec.ts
+++ b/airflow-core/src/airflow/ui/tests/e2e/specs/connections.spec.ts
@@ -191,7 +191,7 @@ test.describe("Connections Page - CRUD Operations", () => {
     expect(stillExists).toBeTruthy();
   });
 
-  test.fixme("should delete a connection", async () => {
+  test("should delete a connection", async () => {
     test.setTimeout(120_000);
 
     // Create a temporary connection for deletion test

Reply via email to