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