feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import { Page, Locator } from '@playwright/test';
|
||||
|
||||
export class AlmanacPage {
|
||||
readonly page: Page;
|
||||
readonly themeSwitch: Locator;
|
||||
readonly almanacCard: Locator;
|
||||
readonly suitableText: Locator;
|
||||
readonly avoidText: Locator;
|
||||
readonly navigationBar: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.themeSwitch = page.locator('[data-testid="theme-switch"], .theme-switch');
|
||||
this.almanacCard = page.locator('[data-testid="almanac-card"], .almanac-card');
|
||||
this.suitableText = page.locator('[data-testid="suitable"], .suitable');
|
||||
this.avoidText = page.locator('[data-testid="avoid"], .avoid');
|
||||
this.navigationBar = page.locator('.uni-tabbar, [class*="tabbar"]');
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/#/pages/almanac/index');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async switchTheme(themeId: string) {
|
||||
await this.themeSwitch.click();
|
||||
await this.page.locator(`[data-testid="theme-${themeId}"], [data-theme="${themeId}"]`).click();
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
async getCurrentTheme(): Promise<string | null> {
|
||||
return await this.page.evaluate(() => {
|
||||
const body = document.body;
|
||||
const style = getComputedStyle(body);
|
||||
return style.getPropertyValue('--theme-id') || null;
|
||||
});
|
||||
}
|
||||
|
||||
async isAlmanacVisible(): Promise<boolean> {
|
||||
return await this.almanacCard.isVisible().catch(() => false);
|
||||
}
|
||||
|
||||
async getSuitableText(): Promise<string | null> {
|
||||
return await this.suitableText.textContent().catch(() => null);
|
||||
}
|
||||
|
||||
async getAvoidText(): Promise<string | null> {
|
||||
return await this.avoidText.textContent().catch(() => null);
|
||||
}
|
||||
|
||||
async navigateToTab(tabName: string) {
|
||||
await this.navigationBar.locator(`text=${tabName}`).click();
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async takeScreenshot(path: string) {
|
||||
await this.page.screenshot({ path, fullPage: true });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Page, Locator } from '@playwright/test';
|
||||
|
||||
export class CalendarPage {
|
||||
readonly page: Page;
|
||||
readonly themeSwitch: Locator;
|
||||
readonly calendarGrid: Locator;
|
||||
readonly currentDate: Locator;
|
||||
readonly navigationBar: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.themeSwitch = page.locator('[data-testid="theme-switch"], .theme-switch');
|
||||
this.calendarGrid = page.locator('[data-testid="calendar-grid"], .calendar-grid');
|
||||
this.currentDate = page.locator('[data-testid="current-date"], .current-date');
|
||||
this.navigationBar = page.locator('.uni-tabbar, [class*="tabbar"]');
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/#/pages/calendar/index');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async switchTheme(themeId: string) {
|
||||
await this.themeSwitch.click();
|
||||
await this.page.locator(`[data-testid="theme-${themeId}"], [data-theme="${themeId}"]`).click();
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
async getCurrentTheme(): Promise<string | null> {
|
||||
return await this.page.evaluate(() => {
|
||||
const body = document.body;
|
||||
const style = getComputedStyle(body);
|
||||
return style.getPropertyValue('--theme-id') || null;
|
||||
});
|
||||
}
|
||||
|
||||
async isCalendarVisible(): Promise<boolean> {
|
||||
return await this.calendarGrid.isVisible().catch(() => false);
|
||||
}
|
||||
|
||||
async getCurrentDateText(): Promise<string | null> {
|
||||
return await this.currentDate.textContent().catch(() => null);
|
||||
}
|
||||
|
||||
async navigateToTab(tabName: string) {
|
||||
await this.navigationBar.locator(`text=${tabName}`).click();
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async takeScreenshot(path: string) {
|
||||
await this.page.screenshot({ path, fullPage: true });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { Page, Locator } from '@playwright/test';
|
||||
|
||||
export class SearchPage {
|
||||
readonly page: Page;
|
||||
readonly searchInput: Locator;
|
||||
readonly searchButton: Locator;
|
||||
readonly searchResults: Locator;
|
||||
readonly searchHistory: Locator;
|
||||
readonly navigationBar: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.searchInput = page.locator('[data-testid="search-input"], .search-input, input[type="search"]');
|
||||
this.searchButton = page.locator('[data-testid="search-button"], .search-button, button[type="submit"]');
|
||||
this.searchResults = page.locator('[data-testid="search-results"], .search-results');
|
||||
this.searchHistory = page.locator('[data-testid="search-history"], .search-history');
|
||||
this.navigationBar = page.locator('.uni-tabbar, [class*="tabbar"]');
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/#/pages/almanac-search/index');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async isSearchInputVisible(): Promise<boolean> {
|
||||
return await this.searchInput.isVisible().catch(() => false);
|
||||
}
|
||||
|
||||
async fillSearchInput(text: string) {
|
||||
await this.searchInput.fill(text);
|
||||
}
|
||||
|
||||
async clickSearchButton() {
|
||||
await this.searchButton.click();
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async getSearchResultsCount(): Promise<number> {
|
||||
return await this.searchResults.locator('[data-testid="search-result-card"], .search-result-card').count();
|
||||
}
|
||||
|
||||
async isSearchResultsVisible(): Promise<boolean> {
|
||||
return await this.searchResults.isVisible().catch(() => false);
|
||||
}
|
||||
|
||||
async isSearchHistoryVisible(): Promise<boolean> {
|
||||
return await this.searchHistory.isVisible().catch(() => false);
|
||||
}
|
||||
|
||||
async navigateToTab(tabName: string) {
|
||||
await this.navigationBar.locator(`text=${tabName}`).click();
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async takeScreenshot(path: string) {
|
||||
await this.page.screenshot({ path, fullPage: true });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Page, Locator } from '@playwright/test';
|
||||
|
||||
export class UserPage {
|
||||
readonly page: Page;
|
||||
readonly userInfoCard: Locator;
|
||||
readonly loginButton: Locator;
|
||||
readonly logoutButton: Locator;
|
||||
readonly navigationBar: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.userInfoCard = page.locator('[data-testid="user-info-card"], .user-info-card');
|
||||
this.loginButton = page.locator('[data-testid="login-button"], .login-button');
|
||||
this.logoutButton = page.locator('[data-testid="logout-button"], .logout-button');
|
||||
this.navigationBar = page.locator('.uni-tabbar, [class*="tabbar"]');
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/#/pages/user/index');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async isUserInfoVisible(): Promise<boolean> {
|
||||
return await this.userInfoCard.isVisible().catch(() => false);
|
||||
}
|
||||
|
||||
async isLoginButtonVisible(): Promise<boolean> {
|
||||
return await this.loginButton.isVisible().catch(() => false);
|
||||
}
|
||||
|
||||
async isLogoutButtonVisible(): Promise<boolean> {
|
||||
return await this.logoutButton.isVisible().catch(() => false);
|
||||
}
|
||||
|
||||
async clickLogin() {
|
||||
await this.loginButton.click();
|
||||
}
|
||||
|
||||
async clickLogout() {
|
||||
await this.logoutButton.click();
|
||||
}
|
||||
|
||||
async navigateToTab(tabName: string) {
|
||||
await this.navigationBar.locator(`text=${tabName}`).click();
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async takeScreenshot(path: string) {
|
||||
await this.page.screenshot({ path, fullPage: true });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export { CalendarPage } from './CalendarPage';
|
||||
export { AlmanacPage } from './AlmanacPage';
|
||||
export { UserPage } from './UserPage';
|
||||
export { SearchPage } from './SearchPage';
|
||||
Reference in New Issue
Block a user