mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 02:51:12 -05:00
101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
/**
|
|
* Moderation Queue Page Object Model
|
|
*
|
|
* Encapsulates interactions with the moderation queue.
|
|
*/
|
|
|
|
import { Page, expect } from '@playwright/test';
|
|
|
|
export class ModerationQueuePage {
|
|
constructor(private page: Page) {}
|
|
|
|
async goto() {
|
|
await this.page.goto('/moderation/queue');
|
|
await this.page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
async claimSubmission(index: number = 0) {
|
|
const claimButtons = this.page.locator('button:has-text("Claim")');
|
|
await claimButtons.nth(index).click();
|
|
|
|
// Wait for lock to be acquired
|
|
await expect(this.page.getByText(/claimed by you/i)).toBeVisible({ timeout: 5000 });
|
|
}
|
|
|
|
async approveSubmission(reason?: string) {
|
|
// Click approve button
|
|
await this.page.click('button:has-text("Approve")');
|
|
|
|
// Fill optional reason if provided
|
|
if (reason) {
|
|
await this.page.fill('textarea[placeholder*="reason"]', reason);
|
|
}
|
|
|
|
// Confirm in dialog
|
|
await this.page.click('button:has-text("Confirm")');
|
|
|
|
// Wait for success toast
|
|
await expect(this.page.getByText(/approved/i)).toBeVisible({ timeout: 10000 });
|
|
}
|
|
|
|
async rejectSubmission(reason: string) {
|
|
// Click reject button
|
|
await this.page.click('button:has-text("Reject")');
|
|
|
|
// Fill required reason
|
|
await this.page.fill('textarea[placeholder*="reason"]', reason);
|
|
|
|
// Confirm in dialog
|
|
await this.page.click('button:has-text("Confirm")');
|
|
|
|
// Wait for success toast
|
|
await expect(this.page.getByText(/rejected/i)).toBeVisible({ timeout: 10000 });
|
|
}
|
|
|
|
async extendLock() {
|
|
await this.page.click('button:has-text("Extend")');
|
|
await expect(this.page.getByText(/extended/i)).toBeVisible({ timeout: 5000 });
|
|
}
|
|
|
|
async releaseLock() {
|
|
await this.page.click('button:has-text("Release")');
|
|
await expect(this.page.getByText(/released/i)).toBeVisible({ timeout: 5000 });
|
|
}
|
|
|
|
async filterByType(type: string) {
|
|
await this.page.selectOption('select[name="entity_type"]', type);
|
|
await this.page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
async filterByStatus(status: string) {
|
|
await this.page.selectOption('select[name="status"]', status);
|
|
await this.page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
async searchBySubmitter(name: string) {
|
|
await this.page.fill('input[placeholder*="submitter"]', name);
|
|
await this.page.waitForTimeout(500); // Debounce
|
|
await this.page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
async expectSubmissionVisible(submissionName: string) {
|
|
await expect(this.page.getByText(submissionName)).toBeVisible();
|
|
}
|
|
|
|
async expectSubmissionNotVisible(submissionName: string) {
|
|
await expect(this.page.getByText(submissionName)).not.toBeVisible();
|
|
}
|
|
|
|
async expectLockTimer() {
|
|
// Check that lock timer is visible (e.g., "14:59 remaining")
|
|
await expect(this.page.locator('[data-testid="lock-timer"]').or(
|
|
this.page.getByText(/\d{1,2}:\d{2}.*remaining/i)
|
|
)).toBeVisible();
|
|
}
|
|
|
|
async expectLockWarning() {
|
|
// Warning should appear at 2 minutes remaining
|
|
await expect(this.page.getByText(/lock.*expir/i)).toBeVisible();
|
|
}
|
|
}
|