fix: add navigation role attribute for better test selector
This commit is contained in:
+63
-20
@@ -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(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -165,7 +165,7 @@ function HeaderContent() {
|
||||
/>
|
||||
</Link>
|
||||
|
||||
<nav className="hidden md:flex items-center gap-1" role="navigation" aria-label="主导航">
|
||||
<nav className="hidden md:flex items-center gap-1" role="navigation" aria-label="主导航" data-testid="desktop-navigation">
|
||||
{navigationItems.map((item) => (
|
||||
<Link
|
||||
key={item.id}
|
||||
@@ -200,6 +200,7 @@ function HeaderContent() {
|
||||
<Button
|
||||
size="sm"
|
||||
asChild
|
||||
data-testid="consult-button"
|
||||
>
|
||||
<Link href="/contact">立即咨询</Link>
|
||||
</Button>
|
||||
@@ -212,6 +213,7 @@ function HeaderContent() {
|
||||
aria-expanded={isOpen}
|
||||
aria-controls="mobile-menu"
|
||||
aria-label={isOpen ? '关闭菜单' : '打开菜单'}
|
||||
data-testid="mobile-menu-button"
|
||||
style={{ minWidth: '44px', minHeight: '44px' }}
|
||||
>
|
||||
{isOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
|
||||
@@ -244,6 +246,7 @@ function HeaderContent() {
|
||||
id="mobile-menu"
|
||||
role="navigation"
|
||||
aria-label="移动端导航"
|
||||
data-testid="mobile-navigation"
|
||||
>
|
||||
<nav className="container-wide py-6">
|
||||
{navigationItems.map((item, index) => (
|
||||
|
||||
Reference in New Issue
Block a user