fix: add navigation role attribute for better test selector

This commit is contained in:
张翔
2026-03-05 20:59:25 +08:00
parent 3c5d79f7e3
commit 2f6f6a6aca
3 changed files with 90 additions and 22 deletions
+63 -20
View File
@@ -6,7 +6,10 @@ export class HomePage extends BasePage {
readonly header: Locator;
readonly logo: Locator;
readonly navigation: Locator;
readonly desktopNavigation: Locator;
readonly mobileNavigation: Locator;
readonly mobileMenuButton: Locator;
readonly consultButton: Locator;
readonly heroSection: Locator;
readonly servicesSection: Locator;
readonly productsSection: Locator;
@@ -16,16 +19,16 @@ export class HomePage extends BasePage {
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.desktopNavigation = page.locator('[data-testid="desktop-navigation"]');
this.mobileNavigation = page.locator('[data-testid="mobile-navigation"]');
this.mobileMenuButton = page.locator('[data-testid="mobile-menu-button"]');
this.consultButton = page.locator('[data-testid="consult-button"]');
this.heroSection = page.locator('#home');
this.servicesSection = page.locator('#services');
this.productsSection = page.locator('#products');
@@ -34,9 +37,19 @@ export class HomePage extends BasePage {
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');
async getNavigationItemCount(): Promise<number> {
const isMobile = await this.mobileMenuButton.isVisible();
if (isMobile) {
await this.mobileMenuButton.click();
await this.mobileNavigation.waitFor({ state: 'visible' });
const count = await this.mobileNavigation.locator('a').count();
await this.mobileMenuButton.click();
return count;
} else {
return await this.desktopNavigation.locator('a').count();
}
}
async goto(): Promise<void> {
@@ -61,25 +74,37 @@ export class HomePage extends BasePage {
}
async getNavigationItems(): Promise<Locator[]> {
return await this.navigation.locator('a').all();
const isMobile = await this.mobileMenuButton.isVisible();
if (isMobile) {
await this.openMobileMenu();
return await this.mobileNavigation.locator('a').all();
} else {
return await this.desktopNavigation.locator('a').all();
}
}
async clickNavigationItem(label: string): Promise<void> {
await this.navigation.locator(`a:has-text("${label}")`).click();
const isMobile = await this.mobileMenuButton.isVisible();
if (isMobile) {
await this.openMobileMenu();
await this.mobileNavigation.locator(`a:has-text("${label}")`).click();
} else {
await this.desktopNavigation.locator(`a:has-text("${label}")`).click();
}
}
async openMobileMenu(): Promise<void> {
await this.mobileMenuButton.waitFor({ state: 'visible', timeout: 5000 });
if (!(await this.mobileMenu.isVisible())) {
if (!(await this.mobileNavigation.isVisible())) {
await this.mobileMenuButton.click();
await this.mobileMenu.waitFor({ state: 'visible', timeout: 5000 });
await this.mobileNavigation.waitFor({ state: 'visible', timeout: 5000 });
}
}
async closeMobileMenu(): Promise<void> {
if (await this.mobileMenu.isVisible()) {
if (await this.mobileNavigation.isVisible()) {
await this.mobileMenuButton.click();
await this.mobileMenu.waitFor({ state: 'hidden', timeout: 5000 });
await this.mobileNavigation.waitFor({ state: 'hidden', timeout: 5000 });
}
}
@@ -167,7 +192,14 @@ export class HomePage extends BasePage {
}
async getActiveNavigationItem(): Promise<string | null> {
const activeItem = this.navigation.locator('a[aria-current="page"]');
const isMobile = await this.mobileMenuButton.isVisible();
let activeItem;
if (isMobile) {
await this.openMobileMenu();
activeItem = this.mobileNavigation.locator('a[aria-current="page"]');
} else {
activeItem = this.desktopNavigation.locator('a[aria-current="page"]');
}
if (await activeItem.count() > 0) {
return await activeItem.textContent();
}
@@ -175,7 +207,14 @@ export class HomePage extends BasePage {
}
async isNavigationItemActive(label: string): Promise<boolean> {
const item = this.navigation.locator(`a:has-text("${label}")`);
const isMobile = await this.mobileMenuButton.isVisible();
let item;
if (isMobile) {
await this.openMobileMenu();
item = this.mobileNavigation.locator(`a:has-text("${label}")`);
} else {
item = this.desktopNavigation.locator(`a:has-text("${label}")`);
}
const ariaCurrent = await item.getAttribute('aria-current');
return ariaCurrent === 'page';
}
@@ -247,10 +286,6 @@ export class HomePage extends BasePage {
return hasShadow;
}
async getNavigationItemCount(): Promise<number> {
return await this.navigation.locator('a').count();
}
async getAllNavigationLabels(): Promise<string[]> {
const items = await this.getNavigationItems();
const labels: string[] = [];
@@ -368,10 +403,18 @@ export class HomePage extends BasePage {
await this.page.setViewportSize(viewport);
await this.waitForTimeout(500);
const isMobile = await this.mobileMenuButton.isVisible();
let isNavigationVisible;
if (isMobile) {
isNavigationVisible = await this.mobileMenuButton.isVisible();
} else {
isNavigationVisible = await this.desktopNavigation.isVisible();
}
return {
isHeaderVisible: await this.header.isVisible(),
isHeroVisible: await this.heroSection.isVisible(),
isNavigationVisible: await this.navigation.isVisible(),
isNavigationVisible,
isFooterVisible: await this.footer.isVisible(),
};
}
+23 -1
View File
@@ -26,11 +26,33 @@ test.describe('首页冒烟测试 @smoke', () => {
});
test('应该显示主导航菜单', async ({ homePage }) => {
await expect(homePage.navigation).toBeVisible();
const isMobile = await homePage.mobileMenuButton.isVisible();
if (isMobile) {
await expect(homePage.mobileMenuButton).toBeVisible();
} else {
await expect(homePage.desktopNavigation).toBeVisible();
}
const navItems = await homePage.getNavigationItemCount();
expect(navItems).toBeGreaterThan(0);
});
test('移动端应该显示导航菜单按钮', async ({ homePage, page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await expect(homePage.mobileMenuButton).toBeVisible();
});
test('应该显示立即咨询按钮', async ({ homePage }) => {
const isMobile = await homePage.mobileMenuButton.isVisible();
if (isMobile) {
await homePage.mobileMenuButton.click();
await expect(homePage.mobileNavigation).toBeVisible();
const consultButton = homePage.mobileNavigation.locator('a[href="/contact"]').first();
await expect(consultButton).toBeVisible();
} else {
await expect(homePage.consultButton).toBeVisible();
}
});
test('应该显示所有主要区块', async ({ homePage }) => {
await expect(homePage.heroSection).toBeVisible();
await homePage.scrollToSection('services');