haseebmalik18 commented on code in PR #61234:
URL: https://github.com/apache/airflow/pull/61234#discussion_r2785388085


##########
airflow-core/src/airflow/ui/tests/e2e/pages/DagRunsTabPage.ts:
##########
@@ -0,0 +1,294 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { expect, type Locator, type Page } from "@playwright/test";
+import { BasePage } from "tests/e2e/pages/BasePage";
+
+export class DagRunsTabPage extends BasePage {
+  public readonly markRunAsButton: Locator;
+  public readonly nextPageButton: Locator;
+  public readonly prevPageButton: Locator;
+  public readonly runsTable: Locator;
+  public readonly tableRows: Locator;
+  public readonly triggerButton: Locator;
+
+  private currentDagId?: string;
+  private currentLimit?: number;
+
+  public constructor(page: Page) {
+    super(page);
+    this.markRunAsButton = 
page.locator('[data-testid="mark-run-as-button"]').first();
+    this.nextPageButton = page.locator('[data-testid="next"]');
+    this.prevPageButton = page.locator('[data-testid="prev"]');
+    this.runsTable = page.locator('[data-testid="table-list"]');
+    this.tableRows = this.runsTable.locator("tbody tr");
+    this.triggerButton = page.locator('[data-testid="trigger-dag-button"]');
+  }
+
+  public async clickNextPage(): Promise<void> {
+    await this.waitForRunsTableToLoad();
+    const firstRunLink = 
this.tableRows.first().locator("a[href*='/runs/']").first();
+
+    await expect(firstRunLink).toBeVisible();
+    const firstRunId = await firstRunLink.textContent();
+
+    if (firstRunId === null || firstRunId === "") {
+      throw new Error("Could not get first run ID before pagination");
+    }
+
+    await this.nextPageButton.click();
+    await expect(this.tableRows.first()).not.toContainText(firstRunId, { 
timeout: 10_000 });
+    await this.ensureUrlParams();
+  }
+
+  public async clickPrevPage(): Promise<void> {
+    await this.waitForRunsTableToLoad();
+    const firstRunLink = 
this.tableRows.first().locator("a[href*='/runs/']").first();
+
+    await expect(firstRunLink).toBeVisible();
+    const firstRunId = await firstRunLink.textContent();
+
+    if (firstRunId === null || firstRunId === "") {
+      throw new Error("Could not get first run ID before pagination");
+    }
+
+    await this.prevPageButton.click();
+    await expect(this.tableRows.first()).not.toContainText(firstRunId, { 
timeout: 10_000 });
+    await this.ensureUrlParams();
+  }
+
+  public async clickRunAndVerifyDetails(): Promise<void> {
+    const firstRunLink = 
this.tableRows.first().locator("a[href*='/runs/']").first();
+
+    await expect(firstRunLink).toBeVisible({ timeout: 10_000 });
+    await firstRunLink.click();
+    await this.page.waitForURL(/.*\/dags\/.*\/runs\/[^/]+$/, { timeout: 15_000 
});
+    await expect(this.markRunAsButton).toBeVisible({ timeout: 10_000 });
+  }
+
+  public async clickRunsTab(): Promise<void> {
+    const runsTab = this.page.locator('a[href$="/runs"]');
+
+    await expect(runsTab).toBeVisible({ timeout: 10_000 });
+    await runsTab.click();
+    await this.page.waitForURL(/.*\/dags\/[^/]+\/runs/, { timeout: 15_000 });
+    await this.waitForRunsTableToLoad();
+  }
+
+  public async clickRunsTabWithPageSize(dagId: string, pageSize: number): 
Promise<void> {
+    this.currentDagId = dagId;
+    this.currentLimit = pageSize;
+
+    await this.navigateTo(`/dags/${dagId}/runs?offset=0&limit=${pageSize}`);
+    await this.page.waitForURL(/.*\/dags\/[^/]+\/runs.*offset=0&limit=/, {
+      timeout: 15_000,
+    });
+    await this.waitForRunsTableToLoad();
+  }
+
+  public async filterByState(state: string): Promise<void> {
+    const currentUrl = new URL(this.page.url());
+
+    currentUrl.searchParams.set("state", state.toLowerCase());
+    await this.navigateTo(currentUrl.pathname + currentUrl.search);
+    await this.page.waitForURL(/.*state=.*/, { timeout: 15_000 });
+    await this.waitForRunsTableToLoad();
+  }
+
+  public async getRowCount(): Promise<number> {
+    await this.waitForRunsTableToLoad();
+
+    return this.tableRows.count();
+  }
+
+  public async markRunAs(state: "failed" | "success"): Promise<void> {
+    const stateBadge = 
this.page.locator('[data-testid="state-badge"]').first();
+
+    await expect(stateBadge).toBeVisible({ timeout: 10_000 });
+    const currentState = await stateBadge.textContent();
+
+    if (currentState?.toLowerCase().includes(state)) {
+      return;
+    }
+
+    await expect(this.markRunAsButton).toBeVisible({ timeout: 10_000 });
+    await this.markRunAsButton.click();
+
+    const stateOption = 
this.page.locator(`[data-testid="mark-run-as-${state}"]`);

Review Comment:
   These already exist in the codebase. `MarkRunAsButton.tsx Line: 103` has 
`data-testid={`mark-run-as-${menuState}`}` which dynamically generates 
`mark-run-as-success` and `mark-run-as-failed`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to