feat(admin): 添加用户管理相关文件

添加用户管理视图、API和状态管理文件
This commit is contained in:
张翔
2026-03-28 14:37:29 +08:00
commit 08ea5fbe98
1643 changed files with 255646 additions and 0 deletions
@@ -0,0 +1,150 @@
import { test, expect } from '@playwright/test';
import { MiniProgramAlmanacPage } from '../pages/AlmanacPage';
test.describe('小程序黄历测试', () => {
let almanacPage: MiniProgramAlmanacPage;
test.beforeEach(async ({ page }) => {
almanacPage = new MiniProgramAlmanacPage(page);
await almanacPage.navigate();
});
test('应该显示当前日期', async () => {
const currentDate = await almanacPage.getCurrentDate();
expect(currentDate).toBeTruthy();
});
test('应该显示农历日期', async () => {
const lunarDate = await almanacPage.getLunarDate();
expect(lunarDate).toBeTruthy();
});
test('应该显示干支', async () => {
const ganzhi = await almanacPage.getGanZhi();
expect(ganzhi).toBeTruthy();
});
test('应该显示生肖', async () => {
const zodiac = await almanacPage.getZodiac();
expect(zodiac).toBeTruthy();
});
test('应该显示节气', async () => {
const solarTerm = await almanacPage.getSolarTerm();
expect(solarTerm).toBeTruthy();
});
test('应该显示宜', async () => {
const suitable = await almanacPage.getSuitable();
expect(suitable).toBeTruthy();
});
test('应该显示忌', async () => {
const unsuitable = await almanacPage.getUnsuitable();
expect(unsuitable).toBeTruthy();
});
test('应该显示日期信息', async () => {
const dayInfo = await almanacPage.getDayInfo();
expect(dayInfo).toBeTruthy();
});
test('应该允许日期搜索', async () => {
const date = '2026-02-11';
await almanacPage.searchDate(date);
const currentDate = await almanacPage.getCurrentDate();
expect(currentDate).toContain(date);
});
test('应该能够导航到下一天', async () => {
const currentDateBefore = await almanacPage.getCurrentDate();
await almanacPage.navigateToNextDay();
const currentDateAfter = await almanacPage.getCurrentDate();
expect(currentDateBefore).not.toBe(currentDateAfter);
});
test('应该能够导航到上一天', async () => {
const currentDateBefore = await almanacPage.getCurrentDate();
await almanacPage.navigateToPreviousDay();
const currentDateAfter = await almanacPage.getCurrentDate();
expect(currentDateBefore).not.toBe(currentDateAfter);
});
test('应该显示今天指示器', async () => {
const isToday = await almanacPage.isToday();
expect(isToday).toBe(true);
});
test('应该显示黄历详情', async () => {
const details = await almanacPage.getAlmanacDetails();
expect(details).toBeTruthy();
});
test('应该允许点击日期', async () => {
const date = '2026-02-11';
await almanacPage.tapDate(date);
const currentDate = await almanacPage.getCurrentDate();
expect(currentDate).toContain(date);
});
test('应该允许长按日期', async ({ page }) => {
const date = '2026-02-11';
await almanacPage.longPressDate(date);
await page.waitForTimeout(1000);
const currentDate = await almanacPage.getCurrentDate();
expect(currentDate).toContain(date);
});
test('应该允许左滑到下一天', async ({ page }) => {
const currentDateBefore = await almanacPage.getCurrentDate();
await almanacPage.swipeLeft();
await page.waitForTimeout(500);
const currentDateAfter = await almanacPage.getCurrentDate();
expect(currentDateBefore).not.toBe(currentDateAfter);
});
test('应该允许右滑到上一天', async ({ page }) => {
const currentDateBefore = await almanacPage.getCurrentDate();
await almanacPage.swipeRight();
await page.waitForTimeout(500);
const currentDateAfter = await almanacPage.getCurrentDate();
expect(currentDateBefore).not.toBe(currentDateAfter);
});
test('应该允许分享黄历', async () => {
await almanacPage.shareAlmanac();
await page.waitForTimeout(1000);
const shareDialog = await page.$('.share-dialog');
const isVisible = await shareDialog?.isVisible();
expect(isVisible).toBe(true);
});
test('应该允许收藏日期', async () => {
await almanacPage.bookmarkDate();
await page.waitForTimeout(500);
const isBookmarked = await almanacPage.isBookmarked();
expect(isBookmarked).toBe(true);
});
test('应该允许取消收藏日期', async () => {
await almanacPage.bookmarkDate();
await page.waitForTimeout(500);
const isBookmarked = await almanacPage.isBookmarked();
expect(isBookmarked).toBe(false);
});
test('应该显示农历日历', async () => {
const lunarCalendar = await almanacPage.getLunarCalendar();
expect(lunarCalendar).toBeTruthy();
});
test('应该显示节日', async () => {
const festivals = await almanacPage.getFestivals();
expect(Array.isArray(festivals)).toBe(true);
});
test('应该显示有节日的节日指示器', async () => {
const hasFestival = await almanacPage.hasFestival();
expect(typeof hasFestival).toBe('boolean');
});
});
@@ -0,0 +1,114 @@
import { test, expect } from '@playwright/test';
import { MiniProgramCalendarPage } from '../pages/CalendarPage';
test.describe('小程序日历测试', () => {
let calendarPage: MiniProgramCalendarPage;
test.beforeEach(async ({ page }) => {
calendarPage = new MiniProgramCalendarPage(page);
await calendarPage.navigate();
});
test('应该显示当前日期', async () => {
const currentDate = await calendarPage.getCurrentDate();
expect(currentDate).toBeTruthy();
});
test('应该允许选择日期', async () => {
await calendarPage.selectDate('2026-02-11');
const selectedDate = await calendarPage.getSelectedDate();
expect(selectedDate).toContain('2026-02-11');
});
test('应该能够导航到下个月', async () => {
const currentMonthBefore = await calendarPage.getCurrentMonth();
await calendarPage.navigateToNextMonth();
const currentMonthAfter = await calendarPage.getCurrentMonth();
expect(currentMonthBefore).not.toBe(currentMonthAfter);
});
test('应该能够导航到上个月', async () => {
const currentMonthBefore = await calendarPage.getCurrentMonth();
await calendarPage.navigateToPreviousMonth();
const currentMonthAfter = await calendarPage.getCurrentMonth();
expect(currentMonthBefore).not.toBe(currentMonthAfter);
});
test('应该显示今天指示器', async () => {
const today = new Date();
const todayDate = today.toISOString().split('T')[0];
const isToday = await calendarPage.isToday(todayDate);
expect(isToday).toBe(true);
});
test('应该显示周末指示器', async () => {
const weekendDate = '2026-02-15';
const isWeekend = await calendarPage.isWeekend(weekendDate);
expect(isWeekend).toBe(true);
});
test('应该允许点击日期', async () => {
const date = '2026-02-11';
await calendarPage.tapDate(date);
const selectedDate = await calendarPage.getSelectedDate();
expect(selectedDate).toContain(date);
});
test('应该允许长按日期', async ({ page }) => {
const date = '2026-02-11';
await calendarPage.longPressDate(date);
await page.waitForTimeout(1000);
const selectedDate = await calendarPage.getSelectedDate();
expect(selectedDate).toContain(date);
});
test('应该允许左滑到下个月', async ({ page }) => {
const currentMonthBefore = await calendarPage.getCurrentMonth();
await calendarPage.swipeLeft();
await page.waitForTimeout(500);
const currentMonthAfter = await calendarPage.getCurrentMonth();
expect(currentMonthBefore).not.toBe(currentMonthAfter);
});
test('应该允许右滑到上个月', async ({ page }) => {
const currentMonthBefore = await calendarPage.getCurrentMonth();
await calendarPage.swipeRight();
await page.waitForTimeout(500);
const currentMonthAfter = await calendarPage.getCurrentMonth();
expect(currentMonthBefore).not.toBe(currentMonthAfter);
});
test('应该显示日历事件', async () => {
const events = await calendarPage.getCalendarEvents();
expect(Array.isArray(events)).toBe(true);
});
test('应该显示有事件日期的事件指示器', async () => {
const dateWithEvent = '2026-02-11';
const hasEvent = await calendarPage.hasEvent(dateWithEvent);
expect(hasEvent).toBe(true);
});
test('应该显示当前月份的所有日期', async () => {
const date = '2026-02-15';
const isVisible = await calendarPage.isDateVisible(date);
expect(isVisible).toBe(true);
});
test('应该显示月份视图', async () => {
const monthView = await calendarPage.getMonthView();
expect(monthView).toBeTruthy();
});
test('应该显示星期几', async () => {
const weekDays = await calendarPage.getWeekDays();
expect(Array.isArray(weekDays)).toBe(true);
expect(weekDays.length).toBe(7);
});
test('应该显示月份中的所有日期', async () => {
const dates = await calendarPage.getDatesInMonth();
expect(Array.isArray(dates)).toBe(true);
expect(dates.length).toBeGreaterThan(0);
});
});
@@ -0,0 +1,122 @@
import { Page } from 'playwright';
export class MiniProgramAlmanacPage {
constructor(private page: Page) {}
async navigate() {
await this.page.goto('http://localhost:9527/#/pages/almanac/index');
await this.page.waitForLoadState('networkidle');
}
async getCurrentDate() {
const currentDate = await this.page.locator('.current-date').textContent();
return currentDate || '';
}
async getLunarDate() {
const lunarDate = await this.page.locator('.lunar-date').textContent();
return lunarDate || '';
}
async getGanZhi() {
const ganzhi = await this.page.locator('.ganzhi').textContent();
return ganzhi || '';
}
async getZodiac() {
const zodiac = await this.page.locator('.zodiac').textContent();
return zodiac || '';
}
async getSolarTerm() {
const solarTerm = await this.page.locator('.solar-term').textContent();
return solarTerm || '';
}
async getSuitable() {
const suitable = await this.page.locator('.suitable').textContent();
return suitable || '';
}
async getUnsuitable() {
const unsuitable = await this.page.locator('.unsuitable').textContent();
return unsuitable || '';
}
async getDayInfo() {
const dayInfo = await this.page.locator('.day-info').textContent();
return dayInfo || '';
}
async searchDate(date: string) {
await this.page.fill('.date-search input', date);
await this.page.click('.date-search button');
await this.page.waitForLoadState('networkidle');
}
async navigateToNextDay() {
await this.page.click('.next-day');
}
async navigateToPreviousDay() {
await this.page.click('.previous-day');
}
async isToday() {
const todayIndicator = this.page.locator('.today-indicator');
return await todayIndicator.isVisible();
}
async getAlmanacDetails() {
const details = await this.page.locator('.almanac-details').textContent();
return details || '';
}
async tapDate(date: string) {
await this.page.tap(`[data-date="${date}"]`);
}
async longPressDate(date: string) {
const element = this.page.locator(`[data-date="${date}"]`);
await element.tap();
await this.page.waitForTimeout(500);
}
async swipeLeft() {
await this.page.touchscreen.tap(0, 0);
await this.page.touchscreen.tap(100, 0);
}
async swipeRight() {
await this.page.touchscreen.tap(100, 0);
await this.page.touchscreen.tap(0, 0);
}
async shareAlmanac() {
await this.page.click('.share-button');
}
async bookmarkDate() {
await this.page.click('.bookmark-button');
}
async isBookmarked() {
const bookmarked = this.page.locator('.bookmarked');
return await bookmarked.isVisible();
}
async getLunarCalendar() {
const lunarCalendar = await this.page.locator('.lunar-calendar').textContent();
return lunarCalendar || '';
}
async getFestivals() {
const festivals = await this.page.locator('.festivals').allTextContents();
return festivals;
}
async hasFestival() {
const festivalIndicator = this.page.locator('.festival-indicator');
return await festivalIndicator.isVisible();
}
}
@@ -0,0 +1,97 @@
import { Page } from 'playwright';
export class MiniProgramCalendarPage {
constructor(private page: Page) {}
async navigate() {
await this.page.goto('http://localhost:9527/#/pages/calendar/index');
await this.page.waitForLoadState('networkidle');
}
async getCurrentDate() {
const currentDate = await this.page.locator('.current-date').textContent();
return currentDate || '';
}
async selectDate(date: string) {
await this.page.click(`[data-date="${date}"]`);
}
async getSelectedDate() {
const selectedDate = await this.page.locator('.selected-date').textContent();
return selectedDate || '';
}
async navigateToNextMonth() {
await this.page.click('.next-month');
}
async navigateToPreviousMonth() {
await this.page.click('.previous-month');
}
async getCurrentMonth() {
const currentMonth = await this.page.locator('.current-month').textContent();
return currentMonth || '';
}
async isDateVisible(date: string) {
const dateElement = this.page.locator(`[data-date="${date}"]`);
return await dateElement.isVisible();
}
async isToday(date: string) {
const todayElement = this.page.locator(`[data-date="${date}"].today`);
return await todayElement.isVisible();
}
async isWeekend(date: string) {
const weekendElement = this.page.locator(`[data-date="${date}"].weekend`);
return await weekendElement.isVisible();
}
async getCalendarEvents() {
const events = await this.page.locator('.calendar-event').allTextContents();
return events;
}
async hasEvent(date: string) {
const eventIndicator = this.page.locator(`[data-date="${date}"] .event-indicator`);
return await eventIndicator.isVisible();
}
async tapDate(date: string) {
await this.page.tap(`[data-date="${date}"]`);
}
async longPressDate(date: string) {
const element = this.page.locator(`[data-date="${date}"]`);
await element.tap();
await this.page.waitForTimeout(500);
}
async swipeLeft() {
await this.page.touchscreen.tap(0, 0);
await this.page.touchscreen.tap(100, 0);
}
async swipeRight() {
await this.page.touchscreen.tap(100, 0);
await this.page.touchscreen.tap(0, 0);
}
async getMonthView() {
const monthView = await this.page.locator('.calendar-month').textContent();
return monthView || '';
}
async getWeekDays() {
const weekDays = await this.page.locator('.week-day').allTextContents();
return weekDays;
}
async getDatesInMonth() {
const dates = await this.page.locator('.calendar-date').allTextContents();
return dates;
}
}
@@ -0,0 +1,178 @@
import { Page } from 'playwright';
export class MiniProgramSearchPage {
constructor(private page: Page) {}
async navigate() {
await this.page.goto('http://localhost:9527/#/pages/search/index');
await this.page.waitForLoadState('networkidle');
}
async search(keyword: string) {
await this.page.fill('.search-input input', keyword);
await this.page.click('.search-button');
await this.page.waitForLoadState('networkidle');
}
async clearSearch() {
await this.page.click('.clear-button');
await this.page.waitForLoadState('networkidle');
}
async getSearchResults() {
const results = await this.page.locator('.search-result').allTextContents();
return results;
}
async getResultCount() {
const count = await this.page.locator('.search-result').count();
return count;
}
async hasResults() {
const count = await this.getResultCount();
return count > 0;
}
async noResults() {
const noResults = this.page.locator('.no-results');
return await noResults.isVisible();
}
async tapResult(index: number) {
await this.page.tap(`.search-result:nth-child(${index + 1})`);
}
async longPressResult(index: number) {
const element = this.page.locator(`.search-result:nth-child(${index + 1})`);
await element.tap();
await this.page.waitForTimeout(500);
}
async getResultTitle(index: number) {
const title = await this.page.locator(`.search-result:nth-child(${index + 1}) .result-title`).textContent();
return title || '';
}
async getResultDescription(index: number) {
const description = await this.page.locator(`.search-result:nth-child(${index + 1}) .result-description`).textContent();
return description || '';
}
async getResultDate(index: number) {
const date = await this.page.locator(`.search-result:nth-child(${index + 1}) .result-date`).textContent();
return date || '';
}
async filterByType(type: string) {
await this.page.click(`.filter-type[data-type="${type}"]`);
await this.page.waitForLoadState('networkidle');
}
async filterByDate(startDate: string, endDate: string) {
await this.page.click('.filter-date');
await this.page.fill('.filter-start-date input', startDate);
await this.page.fill('.filter-end-date input', endDate);
await this.page.click('.apply-filter');
await this.page.waitForLoadState('networkidle');
}
async sortBy(sortType: string) {
await this.page.click('.sort-button');
await this.page.click(`.sort-option[data-sort="${sortType}"]`);
await this.page.waitForLoadState('networkidle');
}
async getCurrentSort() {
const currentSort = await this.page.locator('.current-sort').textContent();
return currentSort || '';
}
async getActiveFilters() {
const activeFilters = await this.page.locator('.active-filter').allTextContents();
return activeFilters;
}
async clearFilters() {
await this.page.click('.clear-filters');
await this.page.waitForLoadState('networkidle');
}
async saveSearch(keyword: string) {
await this.search(keyword);
await this.page.click('.save-search-button');
await this.page.waitForLoadState('networkidle');
}
async getSavedSearches() {
const savedSearches = await this.page.locator('.saved-search').allTextContents();
return savedSearches;
}
async deleteSavedSearch(keyword: string) {
await this.page.click(`.saved-search[data-keyword="${keyword}"] .delete-button`);
await this.page.waitForLoadState('networkidle');
}
async getRecentSearches() {
const recentSearches = await this.page.locator('.recent-search').allTextContents();
return recentSearches;
}
async clearRecentSearches() {
await this.page.click('.clear-recent');
await this.page.waitForLoadState('networkidle');
}
async getSearchSuggestions(keyword: string) {
await this.page.fill('.search-input input', keyword);
await this.page.waitForTimeout(500);
const suggestions = await this.page.locator('.search-suggestion').allTextContents();
return suggestions;
}
async selectSuggestion(index: number) {
await this.page.tap(`.search-suggestion:nth-child(${index + 1})`);
await this.page.waitForLoadState('networkidle');
}
async swipeLeft() {
await this.page.touchscreen.tap(0, 0);
await this.page.touchscreen.tap(100, 0);
}
async swipeRight() {
await this.page.touchscreen.tap(100, 0);
await this.page.touchscreen.tap(0, 0);
}
async swipeUp() {
await this.page.touchscreen.tap(0, 100);
await this.page.touchscreen.tap(0, 0);
}
async swipeDown() {
await this.page.touchscreen.tap(0, 0);
await this.page.touchscreen.tap(0, 100);
}
async getSearchHistory() {
const searchHistory = await this.page.locator('.search-history').allTextContents();
return searchHistory;
}
async clearSearchHistory() {
await this.page.click('.clear-search-history');
await this.page.waitForLoadState('networkidle');
}
async getHotSearches() {
const hotSearches = await this.page.locator('.hot-search').allTextContents();
return hotSearches;
}
async tapHotSearch(index: number) {
await this.page.tap(`.hot-search:nth-child(${index + 1})`);
await this.page.waitForLoadState('networkidle');
}
}
@@ -0,0 +1,162 @@
import { Page } from 'playwright';
export class MiniProgramUserPage {
constructor(private page: Page) {}
async navigate() {
await this.page.goto('http://localhost:9527/#/pages/user/index');
await this.page.waitForLoadState('networkidle');
}
async getUsername() {
const username = await this.page.locator('.username').textContent();
return username || '';
}
async getUserAvatar() {
const avatar = await this.page.locator('.user-avatar');
return await avatar.getAttribute('src');
}
async isLoggedIn() {
const loginButton = this.page.locator('.login-button');
return !(await loginButton.isVisible());
}
async login(username: string, password: string) {
await this.page.fill('.login-username input', username);
await this.page.fill('.login-password input', password);
await this.page.click('.login-button');
await this.page.waitForLoadState('networkidle');
}
async logout() {
await this.page.click('.logout-button');
await this.page.waitForLoadState('networkidle');
}
async navigateToProfile() {
await this.page.click('.profile-button');
await this.page.waitForLoadState('networkidle');
}
async navigateToSettings() {
await this.page.click('.settings-button');
await this.page.waitForLoadState('networkidle');
}
async navigateToHistory() {
await this.page.click('.history-button');
await this.page.waitForLoadState('networkidle');
}
async navigateToFavorites() {
await this.page.click('.favorites-button');
await this.page.waitForLoadState('networkidle');
}
async updateProfile(data: { username?: string; email?: string; phone?: string }) {
await this.navigateToProfile();
if (data.username) {
await this.page.fill('.profile-username input', data.username);
}
if (data.email) {
await this.page.fill('.profile-email input', data.email);
}
if (data.phone) {
await this.page.fill('.profile-phone input', data.phone);
}
await this.page.click('.save-button');
await this.page.waitForLoadState('networkidle');
}
async getProfile() {
const profile = {
username: await this.page.locator('.profile-username').textContent() || '',
email: await this.page.locator('.profile-email').textContent() || '',
phone: await this.page.locator('.profile-phone').textContent() || '',
};
return profile;
}
async toggleTheme() {
await this.page.click('.theme-toggle');
await this.page.waitForTimeout(500);
}
async getCurrentTheme() {
const theme = await this.page.locator('.current-theme').textContent();
return theme || '';
}
async getSettings() {
const settings = {
theme: await this.page.locator('.setting-theme').textContent() || '',
language: await this.page.locator('.setting-language').textContent() || '',
notifications: await this.page.locator('.setting-notifications').textContent() || '',
};
return settings;
}
async updateSetting(key: string, value: string) {
await this.navigateToSettings();
await this.page.click(`.setting-${key}`);
await this.page.click(`[data-value="${value}"]`);
await this.page.click('.save-button');
await this.page.waitForLoadState('networkidle');
}
async getHistory() {
const historyItems = await this.page.locator('.history-item').allTextContents();
return historyItems;
}
async clearHistory() {
await this.navigateToHistory();
await this.page.click('.clear-history-button');
await this.page.waitForLoadState('networkidle');
}
async getFavorites() {
const favorites = await this.page.locator('.favorite-item').allTextContents();
return favorites;
}
async removeFavorite(id: string) {
await this.navigateToFavorites();
await this.page.click(`[data-favorite-id="${id}"] .remove-button`);
await this.page.waitForLoadState('networkidle');
}
async tapButton(buttonClass: string) {
await this.page.tap(`.${buttonClass}`);
}
async longPressButton(buttonClass: string) {
const element = this.page.locator(`.${buttonClass}`);
await element.tap();
await this.page.waitForTimeout(500);
}
async swipeUp() {
await this.page.touchscreen.tap(0, 100);
await this.page.touchscreen.tap(0, 0);
}
async swipeDown() {
await this.page.touchscreen.tap(0, 0);
await this.page.touchscreen.tap(0, 100);
}
async getUserInfo() {
const userInfo = await this.page.locator('.user-info').textContent();
return userInfo || '';
}
async getNavigationItems() {
const navItems = await this.page.locator('.nav-item').allTextContents();
return navItems;
}
}
@@ -0,0 +1,4 @@
export { MiniProgramCalendarPage } from './CalendarPage';
export { MiniProgramAlmanacPage } from './AlmanacPage';
export { MiniProgramUserPage } from './UserPage';
export { MiniProgramSearchPage } from './SearchPage';
@@ -0,0 +1,35 @@
const { spawn } = require('child_process');
const path = require('path');
const PLAYWRIGHT_CONFIG = path.join(__dirname, '../../playwright.miniprogram.config.ts');
function runTests() {
console.log('Starting mini program tests...');
console.log(`Using Playwright config: ${PLAYWRIGHT_CONFIG}`);
const playwright = spawn('npx', ['playwright', 'test', '--config', PLAYWRIGHT_CONFIG], {
stdio: 'inherit',
shell: true,
});
playwright.on('close', (code) => {
if (code === 0) {
console.log('Mini program tests passed!');
process.exit(0);
} else {
console.error(`Mini program tests failed with code ${code}`);
process.exit(code);
}
});
playwright.on('error', (error) => {
console.error('Failed to start Playwright:', error);
process.exit(1);
});
}
if (require.main === module) {
runTests();
}
module.exports = { runTests };
@@ -0,0 +1,234 @@
import { test, expect } from '@playwright/test';
import { MiniProgramSearchPage } from '../pages/SearchPage';
test.describe('小程序搜索测试', () => {
let searchPage: MiniProgramSearchPage;
test.beforeEach(async ({ page }) => {
searchPage = new MiniProgramSearchPage(page);
await searchPage.navigate();
});
test('应该显示搜索输入框', async () => {
const searchInput = await page.$('.search-input input');
const isVisible = await searchInput?.isVisible();
expect(isVisible).toBe(true);
});
test('应该允许搜索', async () => {
const keyword = '春节';
await searchPage.search(keyword);
const hasResults = await searchPage.hasResults();
expect(hasResults).toBe(true);
});
test('应该允许清除搜索', async () => {
await searchPage.search('test');
await searchPage.clearSearch();
const hasResults = await searchPage.hasResults();
expect(hasResults).toBe(false);
});
test('应该显示搜索结果', async () => {
const keyword = '春节';
await searchPage.search(keyword);
const results = await searchPage.getSearchResults();
expect(Array.isArray(results)).toBe(true);
expect(results.length).toBeGreaterThan(0);
});
test('应该显示结果数量', async () => {
const keyword = '春节';
await searchPage.search(keyword);
const count = await searchPage.getResultCount();
expect(count).toBeGreaterThan(0);
});
test('应该显示无结果提示', async () => {
const keyword = 'xyz123';
await searchPage.search(keyword);
const noResults = await searchPage.noResults();
expect(noResults).toBe(true);
});
test('应该允许点击结果', async () => {
const keyword = '春节';
await searchPage.search(keyword);
await searchPage.tapResult(0);
await page.waitForTimeout(1000);
const resultTitle = await searchPage.getResultTitle(0);
expect(resultTitle).toBeTruthy();
});
test('应该允许长按结果', async () => {
const keyword = '春节';
await searchPage.search(keyword);
await searchPage.longPressResult(0);
await page.waitForTimeout(1000);
const resultTitle = await searchPage.getResultTitle(0);
expect(resultTitle).toBeTruthy();
});
test('应该显示结果标题', async () => {
const keyword = '春节';
await searchPage.search(keyword);
const title = await searchPage.getResultTitle(0);
expect(title).toBeTruthy();
});
test('应该显示结果描述', async () => {
const keyword = '春节';
await searchPage.search(keyword);
const description = await searchPage.getResultDescription(0);
expect(description).toBeTruthy();
});
test('应该显示结果日期', async () => {
const keyword = '春节';
await searchPage.search(keyword);
const date = await searchPage.getResultDate(0);
expect(date).toBeTruthy();
});
test('应该允许按类型筛选', async () => {
const keyword = '春节';
await searchPage.search(keyword);
await searchPage.filterByType('holiday');
const results = await searchPage.getSearchResults();
expect(Array.isArray(results)).toBe(true);
});
test('应该允许按日期范围筛选', async () => {
const startDate = '2026-01-01';
const endDate = '2026-12-31';
await searchPage.filterByDate(startDate, endDate);
const results = await searchPage.getSearchResults();
expect(Array.isArray(results)).toBe(true);
});
test('应该允许排序', async () => {
const keyword = '春节';
await searchPage.search(keyword);
await searchPage.sortBy('date');
const currentSort = await searchPage.getCurrentSort();
expect(currentSort).toContain('date');
});
test('应该显示活动筛选器', async () => {
const keyword = '春节';
await searchPage.search(keyword);
await searchPage.filterByType('holiday');
const activeFilters = await searchPage.getActiveFilters();
expect(Array.isArray(activeFilters)).toBe(true);
});
test('应该允许清除筛选器', async () => {
const keyword = '春节';
await searchPage.search(keyword);
await searchPage.filterByType('holiday');
await searchPage.clearFilters();
const activeFilters = await searchPage.getActiveFilters();
expect(activeFilters.length).toBe(0);
});
test('应该允许保存搜索', async () => {
const keyword = '春节';
await searchPage.saveSearch(keyword);
const savedSearches = await searchPage.getSavedSearches();
expect(savedSearches).toContain(keyword);
});
test('应该显示保存的搜索', async () => {
const savedSearches = await searchPage.getSavedSearches();
expect(Array.isArray(savedSearches)).toBe(true);
});
test('应该允许删除保存的搜索', async () => {
const keyword = '春节';
await searchPage.saveSearch(keyword);
await searchPage.deleteSavedSearch(keyword);
const savedSearches = await searchPage.getSavedSearches();
expect(savedSearches).not.toContain(keyword);
});
test('应该显示最近搜索', async () => {
const keyword = 'test';
await searchPage.search(keyword);
const recentSearches = await searchPage.getRecentSearches();
expect(Array.isArray(recentSearches)).toBe(true);
});
test('应该允许清除最近搜索', async () => {
await searchPage.clearRecentSearches();
const recentSearches = await searchPage.getRecentSearches();
expect(recentSearches.length).toBe(0);
});
test('应该显示搜索建议', async () => {
const keyword = '春';
const suggestions = await searchPage.getSearchSuggestions(keyword);
expect(Array.isArray(suggestions)).toBe(true);
});
test('应该允许选择建议', async () => {
const keyword = '春';
await searchPage.selectSuggestion(0);
const hasResults = await searchPage.hasResults();
expect(hasResults).toBe(true);
});
test('应该允许左滑', async ({ page }) => {
await searchPage.swipeLeft();
await page.waitForTimeout(500);
const searchInput = await page.$('.search-input input');
const isVisible = await searchInput?.isVisible();
expect(isVisible).toBe(true);
});
test('应该允许右滑', async ({ page }) => {
await searchPage.swipeRight();
await page.waitForTimeout(500);
const searchInput = await page.$('.search-input input');
const isVisible = await searchInput?.isVisible();
expect(isVisible).toBe(true);
});
test('应该允许上滑', async ({ page }) => {
await searchPage.swipeUp();
await page.waitForTimeout(500);
const searchInput = await page.$('.search-input input');
const isVisible = await searchInput?.isVisible();
expect(isVisible).toBe(true);
});
test('应该允许下滑', async ({ page }) => {
await searchPage.swipeDown();
await page.waitForTimeout(500);
const searchInput = await page.$('.search-input input');
const isVisible = await searchInput?.isVisible();
expect(isVisible).toBe(true);
});
test('应该显示搜索历史', async () => {
const searchHistory = await searchPage.getSearchHistory();
expect(Array.isArray(searchHistory)).toBe(true);
});
test('应该允许清除搜索历史', async () => {
await searchPage.clearSearchHistory();
const searchHistory = await searchPage.getSearchHistory();
expect(searchHistory.length).toBe(0);
});
test('应该显示热门搜索', async () => {
const hotSearches = await searchPage.getHotSearches();
expect(Array.isArray(hotSearches)).toBe(true);
});
test('应该允许点击热门搜索', async () => {
await searchPage.tapHotSearch(0);
await page.waitForTimeout(500);
const hasResults = await searchPage.hasResults();
expect(hasResults).toBe(true);
});
});
@@ -0,0 +1,150 @@
import { test, expect } from '@playwright/test';
import { MiniProgramUserPage } from '../pages/UserPage';
test.describe('小程序用户测试', () => {
let userPage: MiniProgramUserPage;
test.beforeEach(async ({ page }) => {
userPage = new MiniProgramUserPage(page);
await userPage.navigate();
});
test('应该显示用户名', async () => {
const username = await userPage.getUsername();
expect(username).toBeTruthy();
});
test('应该显示用户头像', async () => {
const avatar = await userPage.getUserAvatar();
expect(avatar).toBeTruthy();
});
test('应该检查登录状态', async () => {
const isLoggedIn = await userPage.isLoggedIn();
expect(typeof isLoggedIn).toBe('boolean');
});
test('应该允许登录', async () => {
await userPage.navigate();
const isLoggedInBefore = await userPage.isLoggedIn();
if (!isLoggedInBefore) {
await userPage.login('test-user', 'test-password');
const isLoggedInAfter = await userPage.isLoggedIn();
expect(isLoggedInAfter).toBe(true);
}
});
test('应该允许登出', async () => {
await userPage.logout();
const isLoggedIn = await userPage.isLoggedIn();
expect(isLoggedIn).toBe(false);
});
test('应该能够导航到个人资料', async () => {
await userPage.login('test-user', 'test-password');
await userPage.navigateToProfile();
const profile = await userPage.getProfile();
expect(profile.username).toBe('test-user');
});
test('应该能够导航到设置', async () => {
await userPage.navigateToSettings();
const settings = await userPage.getSettings();
expect(settings.theme).toBeTruthy();
});
test('应该能够导航到历史记录', async () => {
await userPage.navigateToHistory();
const history = await userPage.getHistory();
expect(Array.isArray(history)).toBe(true);
});
test('应该能够导航到收藏', async () => {
await userPage.navigateToFavorites();
const favorites = await userPage.getFavorites();
expect(Array.isArray(favorites)).toBe(true);
});
test('应该允许更新个人资料', async () => {
await userPage.updateProfile({
username: 'updated-user',
email: 'updated@example.com',
phone: '1234567890',
});
const profile = await userPage.getProfile();
expect(profile.username).toBe('updated-user');
});
test('应该允许切换主题', async () => {
const themeBefore = await userPage.getCurrentTheme();
await userPage.toggleTheme();
const themeAfter = await userPage.getCurrentTheme();
expect(themeBefore).not.toBe(themeAfter);
});
test('应该允许更新设置', async () => {
await userPage.updateSetting('theme', 'dark');
const settings = await userPage.getSettings();
expect(settings.theme).toContain('dark');
});
test('应该允许清除历史记录', async () => {
await userPage.clearHistory();
const history = await userPage.getHistory();
expect(history.length).toBe(0);
});
test('应该允许移除收藏', async () => {
await userPage.navigateToFavorites();
const favoritesBefore = await userPage.getFavorites();
if (favoritesBefore.length > 0) {
const firstFavoriteId = '1';
await userPage.removeFavorite(firstFavoriteId);
const favoritesAfter = await userPage.getFavorites();
expect(favoritesAfter.length).toBe(favoritesBefore.length - 1);
}
});
test('应该允许点击按钮', async () => {
await userPage.navigate();
await userPage.tapButton('profile-button');
const profile = await userPage.getProfile();
expect(profile.username).toBeTruthy();
});
test('应该允许长按按钮', async ({ page }) => {
await userPage.navigate();
await userPage.longPressButton('settings-button');
await page.waitForTimeout(1000);
const settings = await userPage.getSettings();
expect(settings.theme).toBeTruthy();
});
test('应该允许上滑', async ({ page }) => {
await userPage.navigate();
await userPage.swipeUp();
await page.waitForTimeout(500);
const username = await userPage.getUsername();
expect(username).toBeTruthy();
});
test('应该允许下滑', async ({ page }) => {
await userPage.navigate();
await userPage.swipeDown();
await page.waitForTimeout(500);
const username = await userPage.getUsername();
expect(username).toBeTruthy();
});
test('应该显示用户信息', async () => {
const userInfo = await userPage.getUserInfo();
expect(userInfo).toBeTruthy();
});
test('应该显示导航项', async () => {
const navItems = await userPage.getNavigationItems();
expect(Array.isArray(navItems)).toBe(true);
});
});