import { Page, Locator, expect } from '@playwright/test'; /** * Page Object Model for Problem Detail page * URL: /pro/{id} */ export class ProblemPage { readonly page: Page; readonly problemTitle: Locator; readonly problemContent: Locator; readonly submitButton: Locator; readonly timeLimitText: Locator; readonly memoryLimitText: Locator; readonly subtaskInfo: Locator; constructor(page: Page) { this.page = page; // Problem detail elements this.problemTitle = page.locator('h1, h2').first(); this.problemContent = page.locator('#problem-content, .problem-content, iframe'); this.submitButton = page.locator('a:has-text("提交"), a:has-text("Submit"), button:has-text("提交"), button:has-text("Submit")'); this.timeLimitText = page.locator('text=/Time Limit|時間限制/'); this.memoryLimitText = page.locator('text=/Memory Limit|記憶體限制/'); this.subtaskInfo = page.locator('text=/Subtask|子任務/'); } /** * Navigate to a specific problem page */ async goto(problemId: number) { await this.page.goto(`/pro/${problemId}`); await this.page.waitForLoadState('networkidle'); } /** * Click the submit button to go to submission page */ async goToSubmit() { await this.submitButton.click(); await this.page.waitForLoadState('networkidle'); } /** * Verify we are on the problem page */ async verifyOnPage(problemId: number) { await expect(this.page).toHaveURL(new RegExp(`/pro/${problemId}`)); } /** * Check if problem has content loaded */ async verifyProblemLoaded() { // Wait for either the content div or iframe to be visible await expect( this.problemContent.or(this.page.locator('iframe')) ).toBeVisible({ timeout: 10000 }); } /** * Get problem limits information */ async getLimits() { const limits = { timeLimit: '', memoryLimit: '', }; if (await this.timeLimitText.isVisible()) { limits.timeLimit = await this.timeLimitText.textContent() || ''; } if (await this.memoryLimitText.isVisible()) { limits.memoryLimit = await this.memoryLimitText.textContent() || ''; } return limits; } }