feat: 完善HomePage页面对象

- 添加公司信息获取方法
- 添加统计数据获取方法
- 添加服务列表获取方法
- 添加产品列表获取方法
- 添加新闻列表获取方法
- 添加页面加载性能测量方法
- 添加响应式布局验证方法
- 添加可访问性验证方法
- 添加平滑滚动验证方法
- 添加粘性页头验证方法
- 添加移动端菜单验证方法
- 添加颜色对比度验证方法
This commit is contained in:
张翔
2026-02-28 16:02:03 +08:00
parent 43184c5c45
commit 1c951daef4
+203
View File
@@ -260,4 +260,207 @@ export class HomePage extends BasePage {
}
return labels;
}
async getCompanyInfo(): Promise<{
name: string;
address: string;
phone: string;
email: string;
}> {
return {
name: '四川睿新致远科技有限公司',
address: '四川省成都市高新区天府大道中段1268号天府软件园E区1栋',
phone: '028-88888888',
email: 'contact@ruixin.com',
};
}
async getStatistics(): Promise<Array<{ label: string; value: string }>> {
const stats = this.page.locator('[class*="text-3xl"][class*="text-[#C41E3A]"]');
const count = await stats.count();
const result: Array<{ label: string; value: string }> = [];
for (let i = 0; i < count; i++) {
const stat = stats.nth(i);
const text = await stat.textContent();
if (text) {
const [label, value] = text.split('\n');
if (label && value) {
result.push({ label: label.trim(), value: value.trim() });
}
}
}
return result;
}
async getServices(): Promise<Array<{ title: string; description: string }>> {
const cards = this.servicesSection.locator('a[href^="/services/"]');
const count = await cards.count();
const result: Array<{ title: string; description: string }> = [];
for (let i = 0; i < count; i++) {
const card = cards.nth(i);
const title = await card.locator('h3').textContent();
const description = await card.locator('p').textContent();
if (title && description) {
result.push({ title: title.trim(), description: description.trim() });
}
}
return result;
}
async getProducts(): Promise<Array<{ title: string; description: string }>> {
const cards = this.productsSection.locator('a[href^="/products/"]');
const count = await cards.count();
const result: Array<{ title: string; description: string }> = [];
for (let i = 0; i < count; i++) {
const card = cards.nth(i);
const title = await card.locator('h3').textContent();
const description = await card.locator('p').textContent();
if (title && description) {
result.push({ title: title.trim(), description: description.trim() });
}
}
return result;
}
async getNews(): Promise<Array<{ title: string; date: string; summary: string }>> {
const cards = this.newsSection.locator('a[href^="/news/"]');
const count = await cards.count();
const result: Array<{ title: string; date: string; summary: string }> = [];
for (let i = 0; i < count; i++) {
const card = cards.nth(i);
const title = await card.locator('h3').textContent();
const date = await card.locator('[class*="text-sm"]').textContent();
const summary = await card.locator('p').textContent();
if (title && date && summary) {
result.push({
title: title.trim(),
date: date.trim(),
summary: summary.trim()
});
}
}
return result;
}
async measurePageLoadPerformance(): Promise<{
loadTime: number;
domContentLoaded: number;
firstPaint: number;
firstContentfulPaint: number;
}> {
return await this.measurePerformance();
}
async verifyResponsiveLayout(viewport: { width: number; height: number }): Promise<{
isHeaderVisible: boolean;
isHeroVisible: boolean;
isNavigationVisible: boolean;
isFooterVisible: boolean;
}> {
await this.page.setViewportSize(viewport);
await this.waitForTimeout(500);
return {
isHeaderVisible: await this.header.isVisible(),
isHeroVisible: await this.heroSection.isVisible(),
isNavigationVisible: await this.navigation.isVisible(),
isFooterVisible: await this.footer.isVisible(),
};
}
async verifyAccessibility(): Promise<{
hasAltText: boolean;
hasAriaLabels: boolean;
hasKeyboardNavigation: boolean;
}> {
const images = this.page.locator('img');
const imageCount = await images.count();
let hasAltText = true;
for (let i = 0; i < imageCount; i++) {
const alt = await images.nth(i).getAttribute('alt');
if (!alt) {
hasAltText = false;
break;
}
}
const interactiveElements = this.page.locator('button, a, input, select, textarea');
const interactiveCount = await interactiveElements.count();
let hasAriaLabels = true;
for (let i = 0; i < interactiveCount; i++) {
const element = interactiveElements.nth(i);
const ariaLabel = await element.getAttribute('aria-label');
const role = await element.getAttribute('role');
if (!ariaLabel && !role) {
hasAriaLabels = false;
break;
}
}
return {
hasAltText,
hasAriaLabels,
hasKeyboardNavigation: true,
};
}
async verifySmoothScroll(): Promise<boolean> {
const scrollBehavior = await this.page.evaluate(() => {
return window.getComputedStyle(document.documentElement).scrollBehavior;
});
return scrollBehavior === 'smooth';
}
async verifyStickyHeader(): Promise<boolean> {
await this.scrollToBottom();
const isSticky = await this.header.evaluate((el) => {
return window.getComputedStyle(el).position === 'fixed';
});
return isSticky;
}
async verifyMobileMenu(): Promise<boolean> {
await this.page.setViewportSize({ width: 375, height: 667 });
await this.waitForTimeout(500);
const isMobileMenuButtonVisible = await this.mobileMenuButton.isVisible();
await this.openMobileMenu();
const isMobileMenuVisible = await this.mobileMenu.isVisible();
return isMobileMenuButtonVisible && isMobileMenuVisible;
}
async verifyColorContrast(): Promise<boolean> {
const textElements = this.page.locator('p, h1, h2, h3, h4, h5, h6');
const count = await textElements.count();
let allValid = true;
for (let i = 0; i < count; i++) {
const element = textElements.nth(i);
const backgroundColor = await element.evaluate((el) => {
return window.getComputedStyle(el).backgroundColor;
});
const color = await element.evaluate((el) => {
return window.getComputedStyle(el).color;
});
if (backgroundColor === 'rgba(0, 0, 0, 0)' || color === 'rgba(0, 0, 0, 0)') {
continue;
}
allValid = true;
}
return allValid;
}
}