import { Page, Locator, expect } from '@playwright/test'; export class DashboardPage { readonly page: Page; readonly pageTitle: Locator; readonly activeUsersCard: Locator; readonly systemMessagesCard: Locator; readonly onlineUsersCard: Locator; readonly userManagementCard: Locator; readonly systemSettingsCard: Locator; constructor(page: Page) { this.page = page; this.pageTitle = page.getByRole('heading', { name: '仪表盘' }); this.activeUsersCard = page.getByText('活跃用户'); this.systemMessagesCard = page.getByText('系统消息'); this.onlineUsersCard = page.getByText('在线用户'); this.userManagementCard = page.getByText('用户管理'); this.systemSettingsCard = page.getByText('系统设置'); } async expectToBeVisible(options?: { timeout?: number }) { await expect(this.pageTitle).toBeVisible(options); await expect(this.activeUsersCard).toBeVisible(options); await expect(this.systemMessagesCard).toBeVisible(options); await expect(this.onlineUsersCard).toBeVisible(options); } async navigateToUserManagement() { // 检查是否为移动端,需要先打开菜单 const isMobile = (this.page.viewportSize()?.width || 0) < 768; if (isMobile) { // 移动端需要先点击菜单按钮 - 使用测试ID const menuButton = this.page.getByTestId('mobile-menu-button'); await expect(menuButton).toBeVisible({ timeout: 10000 }); await menuButton.click({ timeout: 15000 }); await this.page.waitForTimeout(1000); // 等待菜单完全展开 } // 移动端需要点击侧边栏菜单项,而不是快捷操作卡片 const userManagementCard = isMobile ? this.page.getByRole('button', { name: '用户管理' }).first() : this.page.locator('text=用户管理').first(); await expect(userManagementCard).toBeVisible({ timeout: 10000 }); await userManagementCard.click({ timeout: 10000 }); await this.page.waitForLoadState('networkidle'); } async navigateToSystemSettings() { // 检查是否为移动端,需要先打开菜单 const isMobile = (this.page.viewportSize()?.width || 0) < 768; if (isMobile) { // 移动端需要先点击菜单按钮 - 使用测试ID const menuButton = this.page.getByTestId('mobile-menu-button'); await expect(menuButton).toBeVisible({ timeout: 10000 }); await menuButton.click({ timeout: 15000 }); await this.page.waitForTimeout(1000); // 等待菜单完全展开 } // 使用更具体的定位器来避免重复元素问题 const systemSettingsCard = this.page.locator('text=系统设置').first(); await systemSettingsCard.click({ timeout: 10000 }); await this.page.waitForLoadState('networkidle'); } async getActiveUsersCount(): Promise { // 使用更可靠的定位器来获取活跃用户统计数字 const countElement = this.page.locator('text=活跃用户').locator('xpath=following::div[contains(@class, "text-2xl")][1]'); await expect(countElement).toBeVisible({ timeout: 10000 }); return await countElement.textContent() || ''; } async getSystemMessagesCount(): Promise { // 使用更可靠的定位器来获取系统消息统计数字 const countElement = this.page.locator('text=系统消息').locator('xpath=following::div[contains(@class, "text-2xl")][1]'); await expect(countElement).toBeVisible({ timeout: 10000 }); return await countElement.textContent() || ''; } async logout() { // 先点击用户头像/用户名打开下拉菜单 const userMenuButton = this.page.getByRole('button', { name: 'admin' }); await userMenuButton.click(); // 然后查找并点击登出按钮 const logoutButton = this.page.getByRole('menuitem', { name: /登出|退出|Logout|Sign out/i }); await logoutButton.click(); await this.page.waitForLoadState('networkidle'); } clone(newPage: Page): DashboardPage { return new DashboardPage(newPage); } }