Files
TOJE2E/pages/ChallengeListPage.ts
ChenKaiLiuG e139daa410 Initialize
2026-01-29 11:48:45 +08:00

91 lines
2.5 KiB
TypeScript

import { Page, Locator, expect } from '@playwright/test';
/**
* Page Object Model for Challenge List page
* URL: /chal
*/
export class ChallengeListPage {
readonly page: Page;
readonly challengeRows: Locator;
readonly accountFilter: Locator;
readonly problemFilter: Locator;
readonly stateFilter: Locator;
readonly compilerFilter: Locator;
constructor(page: Page) {
this.page = page;
// Challenge list elements
this.challengeRows = page.locator('tr[data-challenge-id], .challenge-row, tbody tr');
// Filter elements
this.accountFilter = page.locator('input[name="account"], #account-filter');
this.problemFilter = page.locator('input[name="problem"], #problem-filter');
this.stateFilter = page.locator('select[name="state"], #state-filter');
this.compilerFilter = page.locator('select[name="compiler"], #compiler-filter');
}
/**
* Navigate to the challenge list page
*/
async goto() {
await this.page.goto('/chal');
await this.page.waitForLoadState('networkidle');
}
/**
* Get the latest challenge ID from the list
*/
async getLatestChallengeId(): Promise<number | null> {
// Look for challenge links in the format /chal/{id}
const firstChallengeLink = this.page.locator('a[href^="/chal/"]').first();
if (await firstChallengeLink.count() === 0) {
return null;
}
const href = await firstChallengeLink.getAttribute('href');
if (!href) return null;
const match = href.match(/\/chal\/(\d+)/);
return match ? parseInt(match[1]) : null;
}
/**
* Click on a challenge to view details
*/
async clickChallenge(challengeId: number) {
await this.page.click(`a[href="/chal/${challengeId}"]`);
await this.page.waitForLoadState('networkidle');
}
/**
* Filter challenges by account ID
*/
async filterByAccount(accountId: number) {
if (await this.accountFilter.isVisible()) {
await this.accountFilter.fill(accountId.toString());
await this.page.keyboard.press('Enter');
await this.page.waitForLoadState('networkidle');
}
}
/**
* Filter challenges by problem ID
*/
async filterByProblem(problemId: number) {
if (await this.problemFilter.isVisible()) {
await this.problemFilter.fill(problemId.toString());
await this.page.keyboard.press('Enter');
await this.page.waitForLoadState('networkidle');
}
}
/**
* Verify we are on the challenge list page
*/
async verifyOnPage() {
await expect(this.page).toHaveURL(/\/chal/);
}
}