import { Page, Locator, expect } from '@playwright/test'; import { BasePage } from './BasePage'; export class HomePage extends BasePage { readonly url: string; readonly header: Locator; readonly logo: Locator; readonly navigation: Locator; readonly heroSection: Locator; readonly servicesSection: Locator; readonly productsSection: Locator; readonly casesSection: Locator; readonly aboutSection: Locator; readonly newsSection: Locator; readonly contactSection: Locator; readonly footer: Locator; readonly mobileMenuButton: Locator; readonly mobileMenu: Locator; constructor(page: Page) { super(page); this.url = '/'; this.header = page.locator('header'); this.logo = page.locator('header img[alt*="四川睿新致远"]'); this.navigation = page.locator('nav[role="navigation"]'); this.heroSection = page.locator('#home'); this.servicesSection = page.locator('#services'); this.productsSection = page.locator('#products'); this.casesSection = page.locator('#cases'); this.aboutSection = page.locator('#about'); this.newsSection = page.locator('#news'); this.contactSection = page.locator('#contact'); this.footer = page.locator('footer'); this.mobileMenuButton = page.locator('button[aria-label="打开菜单"]'); this.mobileMenu = page.locator('#mobile-menu-panel'); } async goto(): Promise { await this.navigate(this.url); await this.waitForLoadState('networkidle'); } async isLoaded(): Promise { try { await this.header.waitFor({ state: 'visible', timeout: 5000 }); await this.heroSection.waitFor({ state: 'visible', timeout: 5000 }); return true; } catch { return false; } } async waitForPageLoad(): Promise { await this.waitForLoadState('networkidle'); await this.header.waitFor({ state: 'visible' }); await this.heroSection.waitFor({ state: 'visible' }); } async getNavigationItems(): Promise { return await this.navigation.locator('a').all(); } async clickNavigationItem(label: string): Promise { await this.navigation.locator(`a:has-text("${label}")`).click(); } async openMobileMenu(): Promise { if (!(await this.mobileMenu.isVisible())) { await this.mobileMenuButton.click(); await this.mobileMenu.waitFor({ state: 'visible' }); } } async closeMobileMenu(): Promise { if (await this.mobileMenu.isVisible()) { await this.mobileMenuButton.click(); await this.mobileMenu.waitFor({ state: 'hidden' }); } } async scrollToSection(sectionId: string): Promise { const section = this.page.locator(`#${sectionId}`); await section.scrollIntoViewIfNeeded(); await this.page.waitForTimeout(500); } async isSectionVisible(sectionId: string): Promise { const section = this.page.locator(`#${sectionId}`); return await section.isVisible(); } async getSectionText(sectionId: string): Promise { const section = this.page.locator(`#${sectionId}`); return await section.textContent() || ''; } async clickContactButton(): Promise { await this.page.locator('a:has-text("立即咨询")').first().click(); } async isLogoVisible(): Promise { return await this.logo.isVisible(); } async getLogoAltText(): Promise { return await this.logo.getAttribute('alt'); } async isFooterVisible(): Promise { return await this.footer.isVisible(); } async getFooterText(): Promise { return await this.footer.textContent() || ''; } async waitForHeroSection(): Promise { await this.heroSection.waitFor({ state: 'visible' }); } async waitForServicesSection(): Promise { await this.scrollToSection('services'); await this.servicesSection.waitFor({ state: 'visible' }); } async waitForProductsSection(): Promise { await this.scrollToSection('products'); await this.productsSection.waitFor({ state: 'visible' }); } async waitForCasesSection(): Promise { await this.scrollToSection('cases'); await this.casesSection.waitFor({ state: 'visible' }); } async waitForAboutSection(): Promise { await this.scrollToSection('about'); await this.aboutSection.waitFor({ state: 'visible' }); } async waitForNewsSection(): Promise { await this.scrollToSection('news'); await this.newsSection.waitFor({ state: 'visible' }); } async waitForContactSection(): Promise { await this.scrollToSection('contact'); await this.contactSection.waitFor({ state: 'visible' }); } async scrollToBottom(): Promise { await this.page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); await this.page.waitForTimeout(500); } async scrollToTop(): Promise { await this.page.evaluate(() => window.scrollTo(0, 0)); await this.page.waitForTimeout(500); } async getActiveNavigationItem(): Promise { const activeItem = this.navigation.locator('a[aria-current="page"]'); if (await activeItem.count() > 0) { return await activeItem.textContent(); } return null; } async isNavigationItemActive(label: string): Promise { const item = this.navigation.locator(`a:has-text("${label}")`); const ariaCurrent = await item.getAttribute('aria-current'); return ariaCurrent === 'page'; } async getAllSectionIds(): Promise { return await this.page.evaluate(() => { const sections = document.querySelectorAll('section[id]'); return Array.from(sections).map(section => section.id); }); } async takeScreenshotOfSection(sectionId: string, filename: string): Promise { const section = this.page.locator(`#${sectionId}`); await section.screenshot({ path: `test-results/screenshots/${filename}` }); } async getHeroSectionTitle(): Promise { const title = this.heroSection.locator('h1, h2').first(); return await title.textContent() || ''; } async getServicesSectionTitle(): Promise { const title = this.servicesSection.locator('h2').first(); return await title.textContent() || ''; } async getProductsSectionTitle(): Promise { const title = this.productsSection.locator('h2').first(); return await title.textContent() || ''; } async getCasesSectionTitle(): Promise { const title = this.casesSection.locator('h2').first(); return await title.textContent() || ''; } async getAboutSectionTitle(): Promise { const title = this.aboutSection.locator('h2').first(); return await title.textContent() || ''; } async getNewsSectionTitle(): Promise { const title = this.newsSection.locator('h2').first(); return await title.textContent() || ''; } async getContactSectionTitle(): Promise { const title = this.contactSection.locator('h2').first(); return await title.textContent() || ''; } async isHeaderSticky(): Promise { const isSticky = await this.header.evaluate(el => { return window.getComputedStyle(el).position === 'fixed'; }); return isSticky; } async getHeaderBackgroundColor(): Promise { return await this.header.evaluate(el => { return window.getComputedStyle(el).backgroundColor; }); } async isHeaderScrolled(): Promise { const hasShadow = await this.header.evaluate(el => { return window.getComputedStyle(el).boxShadow !== 'none'; }); return hasShadow; } async getNavigationItemCount(): Promise { return await this.navigation.locator('a').count(); } async getAllNavigationLabels(): Promise { const items = await this.getNavigationItems(); const labels: string[] = []; for (const item of items) { const text = await item.textContent(); if (text) labels.push(text); } return labels; } }