feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import { describe, it, expect } from '@wdio/globals';
|
||||
import { MobileAlmanacPage } from '../pages/AlmanacPage';
|
||||
|
||||
describe('Android Almanac Tests', () => {
|
||||
let almanacPage: MobileAlmanacPage;
|
||||
|
||||
before(async () => {
|
||||
almanacPage = new MobileAlmanacPage(browser);
|
||||
await almanacPage.navigate();
|
||||
});
|
||||
|
||||
it('should display current date', async () => {
|
||||
const currentDate = await almanacPage.getCurrentDate();
|
||||
expect(currentDate).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display lunar date', async () => {
|
||||
const lunarDate = await almanacPage.getLunarDate();
|
||||
expect(lunarDate).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display gan zhi', async () => {
|
||||
const ganzhi = await almanacPage.getGanZhi();
|
||||
expect(ganzhi).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display zodiac', async () => {
|
||||
const zodiac = await almanacPage.getZodiac();
|
||||
expect(zodiac).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display solar term', async () => {
|
||||
const solarTerm = await almanacPage.getSolarTerm();
|
||||
expect(solarTerm).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display suitable activities', async () => {
|
||||
const suitable = await almanacPage.getSuitable();
|
||||
expect(suitable).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display unsuitable activities', async () => {
|
||||
const unsuitable = await almanacPage.getUnsuitable();
|
||||
expect(unsuitable).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display day info', async () => {
|
||||
const dayInfo = await almanacPage.getDayInfo();
|
||||
expect(dayInfo).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow date search', async () => {
|
||||
const date = '2026-02-11';
|
||||
await almanacPage.searchDate(date);
|
||||
const currentDate = await almanacPage.getCurrentDate();
|
||||
expect(currentDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should navigate to next day', async () => {
|
||||
const currentDateBefore = await almanacPage.getCurrentDate();
|
||||
await almanacPage.navigateToNextDay();
|
||||
const currentDateAfter = await almanacPage.getCurrentDate();
|
||||
expect(currentDateBefore).not.toBe(currentDateAfter);
|
||||
});
|
||||
|
||||
it('should navigate to previous day', async () => {
|
||||
const currentDateBefore = await almanacPage.getCurrentDate();
|
||||
await almanacPage.navigateToPreviousDay();
|
||||
const currentDateAfter = await almanacPage.getCurrentDate();
|
||||
expect(currentDateBefore).not.toBe(currentDateAfter);
|
||||
});
|
||||
|
||||
it('should display today indicator', async () => {
|
||||
const isToday = await almanacPage.isToday();
|
||||
expect(isToday).toBe(true);
|
||||
});
|
||||
|
||||
it('should display almanac details', async () => {
|
||||
const details = await almanacPage.getAlmanacDetails();
|
||||
expect(details).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow tap on date', async () => {
|
||||
const date = '2026-02-11';
|
||||
await almanacPage.tapDate(date);
|
||||
const currentDate = await almanacPage.getCurrentDate();
|
||||
expect(currentDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should allow long press on date', async () => {
|
||||
const date = '2026-02-11';
|
||||
await almanacPage.longPressDate(date);
|
||||
await browser.pause(1000);
|
||||
const currentDate = await almanacPage.getCurrentDate();
|
||||
expect(currentDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should allow swipe left to next day', async () => {
|
||||
const currentDateBefore = await almanacPage.getCurrentDate();
|
||||
await almanacPage.swipeLeft();
|
||||
await browser.pause(500);
|
||||
const currentDateAfter = await almanacPage.getCurrentDate();
|
||||
expect(currentDateBefore).not.toBe(currentDateAfter);
|
||||
});
|
||||
|
||||
it('should allow swipe right to previous day', async () => {
|
||||
const currentDateBefore = await almanacPage.getCurrentDate();
|
||||
await almanacPage.swipeRight();
|
||||
await browser.pause(500);
|
||||
const currentDateAfter = await almanacPage.getCurrentDate();
|
||||
expect(currentDateBefore).not.toBe(currentDateAfter);
|
||||
});
|
||||
|
||||
it('should allow share almanac', async () => {
|
||||
await almanacPage.shareAlmanac();
|
||||
await browser.pause(1000);
|
||||
const shareDialog = await browser.$('.share-dialog');
|
||||
const isVisible = await shareDialog.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow bookmark date', async () => {
|
||||
await almanacPage.bookmarkDate();
|
||||
await browser.pause(500);
|
||||
const isBookmarked = await almanacPage.isBookmarked();
|
||||
expect(isBookmarked).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow unbookmark date', async () => {
|
||||
await almanacPage.bookmarkDate();
|
||||
await browser.pause(500);
|
||||
const isBookmarked = await almanacPage.isBookmarked();
|
||||
expect(isBookmarked).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
import { describe, it, expect } from '@wdio/globals';
|
||||
import { MobileCalendarPage } from '../pages/CalendarPage';
|
||||
|
||||
describe('Android Calendar Tests', () => {
|
||||
let calendarPage: MobileCalendarPage;
|
||||
|
||||
before(async () => {
|
||||
calendarPage = new MobileCalendarPage(browser);
|
||||
await calendarPage.navigate();
|
||||
});
|
||||
|
||||
it('should display current date', async () => {
|
||||
const currentDate = await calendarPage.getCurrentDate();
|
||||
expect(currentDate).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow date selection', async () => {
|
||||
await calendarPage.selectDate('2026-02-11');
|
||||
const selectedDate = await calendarPage.getSelectedDate();
|
||||
expect(selectedDate).toContain('2026-02-11');
|
||||
});
|
||||
|
||||
it('should navigate to next month', async () => {
|
||||
const currentMonthBefore = await calendarPage.getCurrentMonth();
|
||||
await calendarPage.navigateToNextMonth();
|
||||
const currentMonthAfter = await calendarPage.getCurrentMonth();
|
||||
expect(currentMonthBefore).not.toBe(currentMonthAfter);
|
||||
});
|
||||
|
||||
it('should navigate to previous month', async () => {
|
||||
const currentMonthBefore = await calendarPage.getCurrentMonth();
|
||||
await calendarPage.navigateToPreviousMonth();
|
||||
const currentMonthAfter = await calendarPage.getCurrentMonth();
|
||||
expect(currentMonthBefore).not.toBe(currentMonthAfter);
|
||||
});
|
||||
|
||||
it('should display today indicator', async () => {
|
||||
const today = new Date();
|
||||
const todayDate = today.toISOString().split('T')[0];
|
||||
const isToday = await calendarPage.isToday(todayDate);
|
||||
expect(isToday).toBe(true);
|
||||
});
|
||||
|
||||
it('should display weekend indicators', async () => {
|
||||
const weekendDate = '2026-02-15';
|
||||
const isWeekend = await calendarPage.isWeekend(weekendDate);
|
||||
expect(isWeekend).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow tap on date', async () => {
|
||||
const date = '2026-02-11';
|
||||
await calendarPage.tapDate(date);
|
||||
const selectedDate = await calendarPage.getSelectedDate();
|
||||
expect(selectedDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should allow long press on date', async () => {
|
||||
const date = '2026-02-11';
|
||||
await calendarPage.longPressDate(date);
|
||||
await browser.pause(1000);
|
||||
const selectedDate = await calendarPage.getSelectedDate();
|
||||
expect(selectedDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should allow swipe left to next month', async () => {
|
||||
const currentMonthBefore = await calendarPage.getCurrentMonth();
|
||||
await calendarPage.swipeLeft();
|
||||
await browser.pause(500);
|
||||
const currentMonthAfter = await calendarPage.getCurrentMonth();
|
||||
expect(currentMonthBefore).not.toBe(currentMonthAfter);
|
||||
});
|
||||
|
||||
it('should allow swipe right to previous month', async () => {
|
||||
const currentMonthBefore = await calendarPage.getCurrentMonth();
|
||||
await calendarPage.swipeRight();
|
||||
await browser.pause(500);
|
||||
const currentMonthAfter = await calendarPage.getCurrentMonth();
|
||||
expect(currentMonthBefore).not.toBe(currentMonthAfter);
|
||||
});
|
||||
|
||||
it('should display calendar events', async () => {
|
||||
const events = await calendarPage.getCalendarEvents();
|
||||
expect(Array.isArray(events)).toBe(true);
|
||||
});
|
||||
|
||||
it('should display event indicators for dates with events', async () => {
|
||||
const dateWithEvent = '2026-02-11';
|
||||
const hasEvent = await calendarPage.hasEvent(dateWithEvent);
|
||||
expect(hasEvent).toBe(true);
|
||||
});
|
||||
|
||||
it('should display all dates in current month', async () => {
|
||||
const date = '2026-02-15';
|
||||
const isVisible = await calendarPage.isDateVisible(date);
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,211 @@
|
||||
import { describe, it, expect } from '@wdio/globals';
|
||||
import { MobileSearchPage } from '../pages/SearchPage';
|
||||
|
||||
describe('Android Search Tests', () => {
|
||||
let searchPage: MobileSearchPage;
|
||||
|
||||
before(async () => {
|
||||
searchPage = new MobileSearchPage(browser);
|
||||
await searchPage.navigate();
|
||||
});
|
||||
|
||||
it('should display search input', async () => {
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow search', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const hasResults = await searchPage.hasResults();
|
||||
expect(hasResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow clear search', async () => {
|
||||
await searchPage.search('test');
|
||||
await searchPage.clearSearch();
|
||||
const hasResults = await searchPage.hasResults();
|
||||
expect(hasResults).toBe(false);
|
||||
});
|
||||
|
||||
it('should display search results', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const results = await searchPage.getSearchResults();
|
||||
expect(Array.isArray(results)).toBe(true);
|
||||
expect(results.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should display result count', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const count = await searchPage.getResultCount();
|
||||
expect(count).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should display no results when no matches', async () => {
|
||||
const keyword = 'xyz123';
|
||||
await searchPage.search(keyword);
|
||||
const noResults = await searchPage.noResults();
|
||||
expect(noResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow tap on result', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.tapResult(0);
|
||||
await browser.pause(1000);
|
||||
const resultTitle = await searchPage.getResultTitle(0);
|
||||
expect(resultTitle).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow long press on result', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.longPressResult(0);
|
||||
await browser.pause(1000);
|
||||
const resultTitle = await searchPage.getResultTitle(0);
|
||||
expect(resultTitle).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display result title', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const title = await searchPage.getResultTitle(0);
|
||||
expect(title).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display result description', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const description = await searchPage.getResultDescription(0);
|
||||
expect(description).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display result date', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const date = await searchPage.getResultDate(0);
|
||||
expect(date).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow filter by type', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.filterByType('holiday');
|
||||
const results = await searchPage.getSearchResults();
|
||||
expect(Array.isArray(results)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow filter by date range', 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);
|
||||
});
|
||||
|
||||
it('should allow sort', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.sortBy('date');
|
||||
const currentSort = await searchPage.getCurrentSort();
|
||||
expect(currentSort).toContain('date');
|
||||
});
|
||||
|
||||
it('should display active filters', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.filterByType('holiday');
|
||||
const activeFilters = await searchPage.getActiveFilters();
|
||||
expect(Array.isArray(activeFilters)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow clear filters', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.filterByType('holiday');
|
||||
await searchPage.clearFilters();
|
||||
const activeFilters = await searchPage.getActiveFilters();
|
||||
expect(activeFilters.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should allow save search', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.saveSearch(keyword);
|
||||
const savedSearches = await searchPage.getSavedSearches();
|
||||
expect(savedSearches).toContain(keyword);
|
||||
});
|
||||
|
||||
it('should display saved searches', async () => {
|
||||
const savedSearches = await searchPage.getSavedSearches();
|
||||
expect(Array.isArray(savedSearches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow delete saved search', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.saveSearch(keyword);
|
||||
await searchPage.deleteSavedSearch(keyword);
|
||||
const savedSearches = await searchPage.getSavedSearches();
|
||||
expect(savedSearches).not.toContain(keyword);
|
||||
});
|
||||
|
||||
it('should display recent searches', async () => {
|
||||
const keyword = 'test';
|
||||
await searchPage.search(keyword);
|
||||
const recentSearches = await searchPage.getRecentSearches();
|
||||
expect(Array.isArray(recentSearches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow clear recent searches', async () => {
|
||||
await searchPage.clearRecentSearches();
|
||||
const recentSearches = await searchPage.getRecentSearches();
|
||||
expect(recentSearches.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should display search suggestions', async () => {
|
||||
const keyword = '春';
|
||||
const suggestions = await searchPage.getSearchSuggestions(keyword);
|
||||
expect(Array.isArray(suggestions)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow select suggestion', async () => {
|
||||
const keyword = '春';
|
||||
await searchPage.selectSuggestion(0);
|
||||
const hasResults = await searchPage.hasResults();
|
||||
expect(hasResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow swipe left', async () => {
|
||||
await searchPage.swipeLeft();
|
||||
await browser.pause(500);
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow swipe right', async () => {
|
||||
await searchPage.swipeRight();
|
||||
await browser.pause(500);
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow swipe up', async () => {
|
||||
await searchPage.swipeUp();
|
||||
await browser.pause(500);
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow swipe down', async () => {
|
||||
await searchPage.swipeDown();
|
||||
await browser.pause(500);
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,140 @@
|
||||
import { describe, it, expect } from '@wdio/globals';
|
||||
import { MobileUserPage } from '../pages/UserPage';
|
||||
|
||||
describe('Android User Tests', () => {
|
||||
let userPage: MobileUserPage;
|
||||
|
||||
before(async () => {
|
||||
userPage = new MobileUserPage(browser);
|
||||
await userPage.navigate();
|
||||
});
|
||||
|
||||
it('should display username', async () => {
|
||||
const username = await userPage.getUsername();
|
||||
expect(username).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display user avatar', async () => {
|
||||
const avatar = await userPage.getUserAvatar();
|
||||
expect(avatar).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should check login status', async () => {
|
||||
const isLoggedIn = await userPage.isLoggedIn();
|
||||
expect(typeof isLoggedIn).toBe('boolean');
|
||||
});
|
||||
|
||||
it('should allow login', 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);
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow logout', async () => {
|
||||
await userPage.logout();
|
||||
const isLoggedIn = await userPage.isLoggedIn();
|
||||
expect(isLoggedIn).toBe(false);
|
||||
});
|
||||
|
||||
it('should navigate to profile', async () => {
|
||||
await userPage.login('test-user', 'test-password');
|
||||
await userPage.navigateToProfile();
|
||||
const profile = await userPage.getProfile();
|
||||
expect(profile.username).toBe('test-user');
|
||||
});
|
||||
|
||||
it('should navigate to settings', async () => {
|
||||
await userPage.navigateToSettings();
|
||||
const settings = await userPage.getSettings();
|
||||
expect(settings.theme).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should navigate to history', async () => {
|
||||
await userPage.navigateToHistory();
|
||||
const history = await userPage.getHistory();
|
||||
expect(Array.isArray(history)).toBe(true);
|
||||
});
|
||||
|
||||
it('should navigate to favorites', async () => {
|
||||
await userPage.navigateToFavorites();
|
||||
const favorites = await userPage.getFavorites();
|
||||
expect(Array.isArray(favorites)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow profile update', async () => {
|
||||
await userPage.updateProfile({
|
||||
username: 'updated-user',
|
||||
email: 'updated@example.com',
|
||||
phone: '1234567890',
|
||||
});
|
||||
const profile = await userPage.getProfile();
|
||||
expect(profile.username).toBe('updated-user');
|
||||
});
|
||||
|
||||
it('should allow theme toggle', async () => {
|
||||
const themeBefore = await userPage.getCurrentTheme();
|
||||
await userPage.toggleTheme();
|
||||
const themeAfter = await userPage.getCurrentTheme();
|
||||
expect(themeBefore).not.toBe(themeAfter);
|
||||
});
|
||||
|
||||
it('should allow settings update', async () => {
|
||||
await userPage.updateSetting('theme', 'dark');
|
||||
const settings = await userPage.getSettings();
|
||||
expect(settings.theme).toContain('dark');
|
||||
});
|
||||
|
||||
it('should allow history clear', async () => {
|
||||
await userPage.clearHistory();
|
||||
const history = await userPage.getHistory();
|
||||
expect(history.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should allow favorite removal', 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);
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow tap on button', async () => {
|
||||
await userPage.navigate();
|
||||
await userPage.tapButton('profile-button');
|
||||
const profile = await userPage.getProfile();
|
||||
expect(profile.username).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow long press on button', async () => {
|
||||
await userPage.navigate();
|
||||
await userPage.longPressButton('settings-button');
|
||||
await browser.pause(1000);
|
||||
const settings = await userPage.getSettings();
|
||||
expect(settings.theme).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow swipe up', async () => {
|
||||
await userPage.navigate();
|
||||
await userPage.swipeUp();
|
||||
await browser.pause(500);
|
||||
const username = await userPage.getUsername();
|
||||
expect(username).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow swipe down', async () => {
|
||||
await userPage.navigate();
|
||||
await userPage.swipeDown();
|
||||
await browser.pause(500);
|
||||
const username = await userPage.getUsername();
|
||||
expect(username).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,135 @@
|
||||
import { describe, it, expect } from '@wdio/globals';
|
||||
import { MobileAlmanacPage } from '../pages/AlmanacPage';
|
||||
|
||||
describe('iOS Almanac Tests', () => {
|
||||
let almanacPage: MobileAlmanacPage;
|
||||
|
||||
before(async () => {
|
||||
almanacPage = new MobileAlmanacPage(browser);
|
||||
await almanacPage.navigate();
|
||||
});
|
||||
|
||||
it('should display current date', async () => {
|
||||
const currentDate = await almanacPage.getCurrentDate();
|
||||
expect(currentDate).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display lunar date', async () => {
|
||||
const lunarDate = await almanacPage.getLunarDate();
|
||||
expect(lunarDate).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display gan zhi', async () => {
|
||||
const ganzhi = await almanacPage.getGanZhi();
|
||||
expect(ganzhi).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display zodiac', async () => {
|
||||
const zodiac = await almanacPage.getZodiac();
|
||||
expect(zodiac).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display solar term', async () => {
|
||||
const solarTerm = await almanacPage.getSolarTerm();
|
||||
expect(solarTerm).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display suitable activities', async () => {
|
||||
const suitable = await almanacPage.getSuitable();
|
||||
expect(suitable).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display unsuitable activities', async () => {
|
||||
const unsuitable = await almanacPage.getUnsuitable();
|
||||
expect(unsuitable).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display day info', async () => {
|
||||
const dayInfo = await almanacPage.getDayInfo();
|
||||
expect(dayInfo).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow date search', async () => {
|
||||
const date = '2026-02-11';
|
||||
await almanacPage.searchDate(date);
|
||||
const currentDate = await almanacPage.getCurrentDate();
|
||||
expect(currentDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should navigate to next day', async () => {
|
||||
const currentDateBefore = await almanacPage.getCurrentDate();
|
||||
await almanacPage.navigateToNextDay();
|
||||
const currentDateAfter = await almanacPage.getCurrentDate();
|
||||
expect(currentDateBefore).not.toBe(currentDateAfter);
|
||||
});
|
||||
|
||||
it('should navigate to previous day', async () => {
|
||||
const currentDateBefore = await almanacPage.getCurrentDate();
|
||||
await almanacPage.navigateToPreviousDay();
|
||||
const currentDateAfter = await almanacPage.getCurrentDate();
|
||||
expect(currentDateBefore).not.toBe(currentDateAfter);
|
||||
});
|
||||
|
||||
it('should display today indicator', async () => {
|
||||
const isToday = await almanacPage.isToday();
|
||||
expect(isToday).toBe(true);
|
||||
});
|
||||
|
||||
it('should display almanac details', async () => {
|
||||
const details = await almanacPage.getAlmanacDetails();
|
||||
expect(details).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow tap on date', async () => {
|
||||
const date = '2026-02-11';
|
||||
await almanacPage.tapDate(date);
|
||||
const currentDate = await almanacPage.getCurrentDate();
|
||||
expect(currentDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should allow long press on date', async () => {
|
||||
const date = '2026-02-11';
|
||||
await almanacPage.longPressDate(date);
|
||||
await browser.pause(1000);
|
||||
const currentDate = await almanacPage.getCurrentDate();
|
||||
expect(currentDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should allow swipe left to next day', async () => {
|
||||
const currentDateBefore = await almanacPage.getCurrentDate();
|
||||
await almanacPage.swipeLeft();
|
||||
await browser.pause(500);
|
||||
const currentDateAfter = await almanacPage.getCurrentDate();
|
||||
expect(currentDateBefore).not.toBe(currentDateAfter);
|
||||
});
|
||||
|
||||
it('should allow swipe right to previous day', async () => {
|
||||
const currentDateBefore = await almanacPage.getCurrentDate();
|
||||
await almanacPage.swipeRight();
|
||||
await browser.pause(500);
|
||||
const currentDateAfter = await almanacPage.getCurrentDate();
|
||||
expect(currentDateBefore).not.toBe(currentDateAfter);
|
||||
});
|
||||
|
||||
it('should allow share almanac', async () => {
|
||||
await almanacPage.shareAlmanac();
|
||||
await browser.pause(1000);
|
||||
const shareDialog = await browser.$('.share-dialog');
|
||||
const isVisible = await shareDialog.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow bookmark date', async () => {
|
||||
await almanacPage.bookmarkDate();
|
||||
await browser.pause(500);
|
||||
const isBookmarked = await almanacPage.isBookmarked();
|
||||
expect(isBookmarked).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow unbookmark date', async () => {
|
||||
await almanacPage.bookmarkDate();
|
||||
await browser.pause(500);
|
||||
const isBookmarked = await almanacPage.isBookmarked();
|
||||
expect(isBookmarked).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
import { describe, it, expect } from '@wdio/globals';
|
||||
import { MobileCalendarPage } from '../pages/CalendarPage';
|
||||
|
||||
describe('iOS Calendar Tests', () => {
|
||||
let calendarPage: MobileCalendarPage;
|
||||
|
||||
before(async () => {
|
||||
calendarPage = new MobileCalendarPage(browser);
|
||||
await calendarPage.navigate();
|
||||
});
|
||||
|
||||
it('should display current date', async () => {
|
||||
const currentDate = await calendarPage.getCurrentDate();
|
||||
expect(currentDate).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow date selection', async () => {
|
||||
await calendarPage.selectDate('2026-02-11');
|
||||
const selectedDate = await calendarPage.getSelectedDate();
|
||||
expect(selectedDate).toContain('2026-02-11');
|
||||
});
|
||||
|
||||
it('should navigate to next month', async () => {
|
||||
const currentMonthBefore = await calendarPage.getCurrentMonth();
|
||||
await calendarPage.navigateToNextMonth();
|
||||
const currentMonthAfter = await calendarPage.getCurrentMonth();
|
||||
expect(currentMonthBefore).not.toBe(currentMonthAfter);
|
||||
});
|
||||
|
||||
it('should navigate to previous month', async () => {
|
||||
const currentMonthBefore = await calendarPage.getCurrentMonth();
|
||||
await calendarPage.navigateToPreviousMonth();
|
||||
const currentMonthAfter = await calendarPage.getCurrentMonth();
|
||||
expect(currentMonthBefore).not.toBe(currentMonthAfter);
|
||||
});
|
||||
|
||||
it('should display today indicator', async () => {
|
||||
const today = new Date();
|
||||
const todayDate = today.toISOString().split('T')[0];
|
||||
const isToday = await calendarPage.isToday(todayDate);
|
||||
expect(isToday).toBe(true);
|
||||
});
|
||||
|
||||
it('should display weekend indicators', async () => {
|
||||
const weekendDate = '2026-02-15';
|
||||
const isWeekend = await calendarPage.isWeekend(weekendDate);
|
||||
expect(isWeekend).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow tap on date', async () => {
|
||||
const date = '2026-02-11';
|
||||
await calendarPage.tapDate(date);
|
||||
const selectedDate = await calendarPage.getSelectedDate();
|
||||
expect(selectedDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should allow long press on date', async () => {
|
||||
const date = '2026-02-11';
|
||||
await calendarPage.longPressDate(date);
|
||||
await browser.pause(1000);
|
||||
const selectedDate = await calendarPage.getSelectedDate();
|
||||
expect(selectedDate).toContain(date);
|
||||
});
|
||||
|
||||
it('should allow swipe left to next month', async () => {
|
||||
const currentMonthBefore = await calendarPage.getCurrentMonth();
|
||||
await calendarPage.swipeLeft();
|
||||
await browser.pause(500);
|
||||
const currentMonthAfter = await calendarPage.getCurrentMonth();
|
||||
expect(currentMonthBefore).not.toBe(currentMonthAfter);
|
||||
});
|
||||
|
||||
it('should allow swipe right to previous month', async () => {
|
||||
const currentMonthBefore = await calendarPage.getCurrentMonth();
|
||||
await calendarPage.swipeRight();
|
||||
await browser.pause(500);
|
||||
const currentMonthAfter = await calendarPage.getCurrentMonth();
|
||||
expect(currentMonthBefore).not.toBe(currentMonthAfter);
|
||||
});
|
||||
|
||||
it('should display calendar events', async () => {
|
||||
const events = await calendarPage.getCalendarEvents();
|
||||
expect(Array.isArray(events)).toBe(true);
|
||||
});
|
||||
|
||||
it('should display event indicators for dates with events', async () => {
|
||||
const dateWithEvent = '2026-02-11';
|
||||
const hasEvent = await calendarPage.hasEvent(dateWithEvent);
|
||||
expect(hasEvent).toBe(true);
|
||||
});
|
||||
|
||||
it('should display all dates in current month', async () => {
|
||||
const date = '2026-02-15';
|
||||
const isVisible = await calendarPage.isDateVisible(date);
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,211 @@
|
||||
import { describe, it, expect } from '@wdio/globals';
|
||||
import { MobileSearchPage } from '../pages/SearchPage';
|
||||
|
||||
describe('iOS Search Tests', () => {
|
||||
let searchPage: MobileSearchPage;
|
||||
|
||||
before(async () => {
|
||||
searchPage = new MobileSearchPage(browser);
|
||||
await searchPage.navigate();
|
||||
});
|
||||
|
||||
it('should display search input', async () => {
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow search', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const hasResults = await searchPage.hasResults();
|
||||
expect(hasResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow clear search', async () => {
|
||||
await searchPage.search('test');
|
||||
await searchPage.clearSearch();
|
||||
const hasResults = await searchPage.hasResults();
|
||||
expect(hasResults).toBe(false);
|
||||
});
|
||||
|
||||
it('should display search results', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const results = await searchPage.getSearchResults();
|
||||
expect(Array.isArray(results)).toBe(true);
|
||||
expect(results.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should display result count', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const count = await searchPage.getResultCount();
|
||||
expect(count).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should display no results when no matches', async () => {
|
||||
const keyword = 'xyz123';
|
||||
await searchPage.search(keyword);
|
||||
const noResults = await searchPage.noResults();
|
||||
expect(noResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow tap on result', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.tapResult(0);
|
||||
await browser.pause(1000);
|
||||
const resultTitle = await searchPage.getResultTitle(0);
|
||||
expect(resultTitle).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow long press on result', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.longPressResult(0);
|
||||
await browser.pause(1000);
|
||||
const resultTitle = await searchPage.getResultTitle(0);
|
||||
expect(resultTitle).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display result title', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const title = await searchPage.getResultTitle(0);
|
||||
expect(title).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display result description', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const description = await searchPage.getResultDescription(0);
|
||||
expect(description).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display result date', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
const date = await searchPage.getResultDate(0);
|
||||
expect(date).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow filter by type', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.filterByType('holiday');
|
||||
const results = await searchPage.getSearchResults();
|
||||
expect(Array.isArray(results)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow filter by date range', 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);
|
||||
});
|
||||
|
||||
it('should allow sort', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.sortBy('date');
|
||||
const currentSort = await searchPage.getCurrentSort();
|
||||
expect(currentSort).toContain('date');
|
||||
});
|
||||
|
||||
it('should display active filters', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.filterByType('holiday');
|
||||
const activeFilters = await searchPage.getActiveFilters();
|
||||
expect(Array.isArray(activeFilters)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow clear filters', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.search(keyword);
|
||||
await searchPage.filterByType('holiday');
|
||||
await searchPage.clearFilters();
|
||||
const activeFilters = await searchPage.getActiveFilters();
|
||||
expect(activeFilters.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should allow save search', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.saveSearch(keyword);
|
||||
const savedSearches = await searchPage.getSavedSearches();
|
||||
expect(savedSearches).toContain(keyword);
|
||||
});
|
||||
|
||||
it('should display saved searches', async () => {
|
||||
const savedSearches = await searchPage.getSavedSearches();
|
||||
expect(Array.isArray(savedSearches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow delete saved search', async () => {
|
||||
const keyword = '春节';
|
||||
await searchPage.saveSearch(keyword);
|
||||
await searchPage.deleteSavedSearch(keyword);
|
||||
const savedSearches = await searchPage.getSavedSearches();
|
||||
expect(savedSearches).not.toContain(keyword);
|
||||
});
|
||||
|
||||
it('should display recent searches', async () => {
|
||||
const keyword = 'test';
|
||||
await searchPage.search(keyword);
|
||||
const recentSearches = await searchPage.getRecentSearches();
|
||||
expect(Array.isArray(recentSearches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow clear recent searches', async () => {
|
||||
await searchPage.clearRecentSearches();
|
||||
const recentSearches = await searchPage.getRecentSearches();
|
||||
expect(recentSearches.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should display search suggestions', async () => {
|
||||
const keyword = '春';
|
||||
const suggestions = await searchPage.getSearchSuggestions(keyword);
|
||||
expect(Array.isArray(suggestions)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow select suggestion', async () => {
|
||||
const keyword = '春';
|
||||
await searchPage.selectSuggestion(0);
|
||||
const hasResults = await searchPage.hasResults();
|
||||
expect(hasResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow swipe left', async () => {
|
||||
await searchPage.swipeLeft();
|
||||
await browser.pause(500);
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow swipe right', async () => {
|
||||
await searchPage.swipeRight();
|
||||
await browser.pause(500);
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow swipe up', async () => {
|
||||
await searchPage.swipeUp();
|
||||
await browser.pause(500);
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow swipe down', async () => {
|
||||
await searchPage.swipeDown();
|
||||
await browser.pause(500);
|
||||
const searchInput = await browser.$('.search-input input');
|
||||
const isVisible = await searchInput.isDisplayed();
|
||||
expect(isVisible).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,140 @@
|
||||
import { describe, it, expect } from '@wdio/globals';
|
||||
import { MobileUserPage } from '../pages/UserPage';
|
||||
|
||||
describe('iOS User Tests', () => {
|
||||
let userPage: MobileUserPage;
|
||||
|
||||
before(async () => {
|
||||
userPage = new MobileUserPage(browser);
|
||||
await userPage.navigate();
|
||||
});
|
||||
|
||||
it('should display username', async () => {
|
||||
const username = await userPage.getUsername();
|
||||
expect(username).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display user avatar', async () => {
|
||||
const avatar = await userPage.getUserAvatar();
|
||||
expect(avatar).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should check login status', async () => {
|
||||
const isLoggedIn = await userPage.isLoggedIn();
|
||||
expect(typeof isLoggedIn).toBe('boolean');
|
||||
});
|
||||
|
||||
it('should allow login', 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);
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow logout', async () => {
|
||||
await userPage.logout();
|
||||
const isLoggedIn = await userPage.isLoggedIn();
|
||||
expect(isLoggedIn).toBe(false);
|
||||
});
|
||||
|
||||
it('should navigate to profile', async () => {
|
||||
await userPage.login('test-user', 'test-password');
|
||||
await userPage.navigateToProfile();
|
||||
const profile = await userPage.getProfile();
|
||||
expect(profile.username).toBe('test-user');
|
||||
});
|
||||
|
||||
it('should navigate to settings', async () => {
|
||||
await userPage.navigateToSettings();
|
||||
const settings = await userPage.getSettings();
|
||||
expect(settings.theme).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should navigate to history', async () => {
|
||||
await userPage.navigateToHistory();
|
||||
const history = await userPage.getHistory();
|
||||
expect(Array.isArray(history)).toBe(true);
|
||||
});
|
||||
|
||||
it('should navigate to favorites', async () => {
|
||||
await userPage.navigateToFavorites();
|
||||
const favorites = await userPage.getFavorites();
|
||||
expect(Array.isArray(favorites)).toBe(true);
|
||||
});
|
||||
|
||||
it('should allow profile update', async () => {
|
||||
await userPage.updateProfile({
|
||||
username: 'updated-user',
|
||||
email: 'updated@example.com',
|
||||
phone: '1234567890',
|
||||
});
|
||||
const profile = await userPage.getProfile();
|
||||
expect(profile.username).toBe('updated-user');
|
||||
});
|
||||
|
||||
it('should allow theme toggle', async () => {
|
||||
const themeBefore = await userPage.getCurrentTheme();
|
||||
await userPage.toggleTheme();
|
||||
const themeAfter = await userPage.getCurrentTheme();
|
||||
expect(themeBefore).not.toBe(themeAfter);
|
||||
});
|
||||
|
||||
it('should allow settings update', async () => {
|
||||
await userPage.updateSetting('theme', 'dark');
|
||||
const settings = await userPage.getSettings();
|
||||
expect(settings.theme).toContain('dark');
|
||||
});
|
||||
|
||||
it('should allow history clear', async () => {
|
||||
await userPage.clearHistory();
|
||||
const history = await userPage.getHistory();
|
||||
expect(history.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should allow favorite removal', 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);
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow tap on button', async () => {
|
||||
await userPage.navigate();
|
||||
await userPage.tapButton('profile-button');
|
||||
const profile = await userPage.getProfile();
|
||||
expect(profile.username).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow long press on button', async () => {
|
||||
await userPage.navigate();
|
||||
await userPage.longPressButton('settings-button');
|
||||
await browser.pause(1000);
|
||||
const settings = await userPage.getSettings();
|
||||
expect(settings.theme).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow swipe up', async () => {
|
||||
await userPage.navigate();
|
||||
await userPage.swipeUp();
|
||||
await browser.pause(500);
|
||||
const username = await userPage.getUsername();
|
||||
expect(username).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow swipe down', async () => {
|
||||
await userPage.navigate();
|
||||
await userPage.swipeDown();
|
||||
await browser.pause(500);
|
||||
const username = await userPage.getUsername();
|
||||
expect(username).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,107 @@
|
||||
import { Page } from 'playwright';
|
||||
|
||||
export class MobileAlmanacPage {
|
||||
constructor(private page: Page) {}
|
||||
|
||||
async navigate() {
|
||||
await this.page.goto('http://localhost:8081/#/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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import { Page } from 'playwright';
|
||||
|
||||
export class MobileCalendarPage {
|
||||
constructor(private page: Page) {}
|
||||
|
||||
async navigate() {
|
||||
await this.page.goto('http://localhost:8081/#/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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
import { Page } from 'playwright';
|
||||
|
||||
export class MobileSearchPage {
|
||||
constructor(private page: Page) {}
|
||||
|
||||
async navigate() {
|
||||
await this.page.goto('http://localhost:8081/#/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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
import { Page } from 'playwright';
|
||||
|
||||
export class MobileUserPage {
|
||||
constructor(private page: Page) {}
|
||||
|
||||
async navigate() {
|
||||
await this.page.goto('http://localhost:8081/#/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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export { MobileCalendarPage } from './CalendarPage';
|
||||
export { MobileAlmanacPage } from './AlmanacPage';
|
||||
export { MobileUserPage } from './UserPage';
|
||||
export { MobileSearchPage } from './SearchPage';
|
||||
Reference in New Issue
Block a user