fix: 修复移动端导航菜单选择器问题
feat: 为主导航菜单和页面区块添加ARIA属性 fix: 解决工作时间信息获取问题 perf: 优化页面滚动功能实现 fix: 修正联系页面标题显示问题 test: 运行完整测试套件验证修复效果 docs: 添加修复完成报告
This commit is contained in:
@@ -0,0 +1,554 @@
|
||||
# Critical Issues Fix Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Fix all critical and high-priority issues identified in the deployment readiness assessment to achieve 95%+ test pass rate and enable safe deployment.
|
||||
|
||||
**Architecture:** Fix mobile navigation issues, update page selectors, correct page titles, and improve scrolling functionality using Playwright E2E tests with TDD approach.
|
||||
|
||||
**Tech Stack:** Playwright, TypeScript, Next.js 16, React 19, Tailwind CSS 4
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Fix Mobile Navigation Menu Functionality
|
||||
|
||||
**Priority:** P0 (Critical)
|
||||
**Estimated Time:** 2-3 hours
|
||||
**Files:**
|
||||
- Modify: `e2e/src/pages/BasePage.ts`
|
||||
- Modify: `e2e/src/pages/HomePage.ts`
|
||||
- Modify: `src/components/layout/mobile-menu.tsx`
|
||||
- Test: `e2e/src/tests/smoke/navigation.smoke.spec.ts`
|
||||
|
||||
**Step 1: Analyze the mobile menu component structure**
|
||||
|
||||
Run: `cat src/components/layout/mobile-menu.tsx`
|
||||
|
||||
Expected: Identify the mobile menu button and menu container structure
|
||||
|
||||
**Step 2: Update BasePage mobile menu selectors**
|
||||
|
||||
```typescript
|
||||
// e2e/src/pages/BasePage.ts
|
||||
export class BasePage {
|
||||
readonly page: Page;
|
||||
readonly mobileMenuButton: Locator;
|
||||
readonly mobileMenu: Locator;
|
||||
readonly mobileMenuCloseButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.mobileMenuButton = page.getByRole('button', { name: /打开菜单|menu/i });
|
||||
this.mobileMenu = page.locator('[role="dialog"], [role="navigation"], .mobile-menu');
|
||||
this.mobileMenuCloseButton = page.getByRole('button', { name: /关闭|close/i });
|
||||
}
|
||||
|
||||
async openMobileMenu() {
|
||||
await this.mobileMenuButton.click();
|
||||
await this.mobileMenu.waitFor({ state: 'visible', timeout: 5000 });
|
||||
}
|
||||
|
||||
async closeMobileMenu() {
|
||||
if (await this.mobileMenu.isVisible()) {
|
||||
await this.mobileMenuCloseButton.click();
|
||||
await this.mobileMenu.waitFor({ state: 'hidden', timeout: 5000 });
|
||||
}
|
||||
}
|
||||
|
||||
async isMobileMenuOpen() {
|
||||
return await this.mobileMenu.isVisible();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3: Update HomePage to extend BasePage properly**
|
||||
|
||||
```typescript
|
||||
// e2e/src/pages/HomePage.ts
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export class HomePage extends BasePage {
|
||||
readonly navigation: Locator;
|
||||
readonly logo: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.navigation = page.locator('nav, [role="navigation"]');
|
||||
this.logo = page.getByRole('link', { name: /四川睿新致远|novalon/i });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: Run navigation smoke tests to verify fixes**
|
||||
|
||||
Run: `cd e2e && npm run test:smoke -- --grep "导航冒烟测试"`
|
||||
|
||||
Expected: See current failures for mobile menu tests
|
||||
|
||||
**Step 5: Fix mobile menu component if needed**
|
||||
|
||||
Check: `src/components/layout/mobile-menu.tsx`
|
||||
|
||||
Ensure the mobile menu has proper ARIA attributes:
|
||||
```tsx
|
||||
<button
|
||||
aria-label="打开菜单"
|
||||
aria-expanded={isOpen}
|
||||
onClick={toggleMenu}
|
||||
>
|
||||
{/* Menu icon */}
|
||||
</button>
|
||||
|
||||
{isOpen && (
|
||||
<nav
|
||||
role="navigation"
|
||||
aria-label="主导航"
|
||||
className="mobile-menu"
|
||||
>
|
||||
{/* Menu items */}
|
||||
<button
|
||||
aria-label="关闭菜单"
|
||||
onClick={toggleMenu}
|
||||
>
|
||||
{/* Close icon */}
|
||||
</button>
|
||||
</nav>
|
||||
)}
|
||||
```
|
||||
|
||||
**Step 6: Run navigation smoke tests again**
|
||||
|
||||
Run: `cd e2e && npm run test:smoke -- --grep "导航冒烟测试"`
|
||||
|
||||
Expected: Mobile menu tests should pass
|
||||
|
||||
**Step 7: Commit mobile menu fixes**
|
||||
|
||||
```bash
|
||||
git add e2e/src/pages/BasePage.ts e2e/src/pages/HomePage.ts src/components/layout/mobile-menu.tsx
|
||||
git commit -m "fix: resolve mobile navigation menu selector issues"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Fix Main Navigation Menu Display
|
||||
|
||||
**Priority:** P0 (Critical)
|
||||
**Estimated Time:** 1-2 hours
|
||||
**Files:**
|
||||
- Modify: `e2e/src/pages/HomePage.ts`
|
||||
- Modify: `e2e/src/tests/smoke/navigation.smoke.spec.ts`
|
||||
- Modify: `src/components/layout/header.tsx`
|
||||
|
||||
**Step 1: Update HomePage navigation selector to use Locator**
|
||||
|
||||
```typescript
|
||||
// e2e/src/pages/HomePage.ts
|
||||
export class HomePage extends BasePage {
|
||||
readonly navigation: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.navigation = page.locator('nav, [role="navigation"], .main-nav');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Update navigation smoke test to use proper Locator**
|
||||
|
||||
```typescript
|
||||
// e2e/src/tests/smoke/navigation.smoke.spec.ts
|
||||
test('应该显示主导航菜单', async ({ homePage }) => {
|
||||
const nav = homePage.page.locator('nav, [role="navigation"]');
|
||||
await expect(nav.first()).toBeVisible();
|
||||
});
|
||||
```
|
||||
|
||||
**Step 3: Ensure header component has proper semantic HTML**
|
||||
|
||||
Check: `src/components/layout/header.tsx`
|
||||
|
||||
```tsx
|
||||
<nav role="navigation" aria-label="主导航" className="main-nav">
|
||||
<ul>
|
||||
<li><a href="/services">服务</a></li>
|
||||
<li><a href="/products">产品</a></li>
|
||||
<li><a href="/cases">案例</a></li>
|
||||
<li><a href="/news">新闻</a></li>
|
||||
<li><a href="/about">关于我们</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
```
|
||||
|
||||
**Step 4: Run navigation tests**
|
||||
|
||||
Run: `cd e2e && npm run test:smoke -- --grep "应该显示主导航菜单"`
|
||||
|
||||
Expected: Test should pass
|
||||
|
||||
**Step 5: Commit navigation display fixes**
|
||||
|
||||
```bash
|
||||
git add e2e/src/pages/HomePage.ts e2e/src/tests/smoke/navigation.smoke.spec.ts src/components/layout/header.tsx
|
||||
git commit -m "fix: resolve main navigation menu display issues"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Fix Page Section Display Issues
|
||||
|
||||
**Priority:** P0 (Critical)
|
||||
**Estimated Time:** 2-3 hours
|
||||
**Files:**
|
||||
- Modify: `e2e/src/pages/HomePage.ts`
|
||||
- Modify: `e2e/src/tests/smoke/home-page.smoke.spec.ts`
|
||||
- Modify: `src/components/sections/*.tsx`
|
||||
|
||||
**Step 1: Add section locators to HomePage**
|
||||
|
||||
```typescript
|
||||
// e2e/src/pages/HomePage.ts
|
||||
export class HomePage extends BasePage {
|
||||
readonly heroSection: Locator;
|
||||
readonly servicesSection: Locator;
|
||||
readonly productsSection: Locator;
|
||||
readonly casesSection: Locator;
|
||||
readonly footer: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.heroSection = page.locator('section:has(h1), [role="region"]:has(h1)');
|
||||
this.servicesSection = page.getByRole('region', { name: /核心业务|服务/i });
|
||||
this.productsSection = page.getByRole('region', { name: /产品/i });
|
||||
this.casesSection = page.getByRole('region', { name: /案例/i });
|
||||
this.footer = page.locator('footer');
|
||||
}
|
||||
|
||||
async scrollToSection(section: Locator) {
|
||||
await section.scrollIntoViewIfNeeded();
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Update home page smoke tests to use section locators**
|
||||
|
||||
```typescript
|
||||
// e2e/src/tests/smoke/home-page.smoke.spec.ts
|
||||
test('应该显示所有主要区块', async ({ homePage }) => {
|
||||
await expect(homePage.heroSection).toBeVisible();
|
||||
await expect(homePage.servicesSection).toBeVisible();
|
||||
await expect(homePage.productsSection).toBeVisible();
|
||||
await expect(homePage.casesSection).toBeVisible();
|
||||
});
|
||||
|
||||
test('应该显示页脚', async ({ homePage }) => {
|
||||
await expect(homePage.footer).toBeVisible();
|
||||
});
|
||||
```
|
||||
|
||||
**Step 3: Ensure sections have proper ARIA roles**
|
||||
|
||||
Check each section component and add role if missing:
|
||||
```tsx
|
||||
<section role="region" aria-labelledby="services-heading">
|
||||
<h2 id="services-heading">我们的 核心业务</h2>
|
||||
{/* Section content */}
|
||||
</section>
|
||||
```
|
||||
|
||||
**Step 4: Run home page smoke tests**
|
||||
|
||||
Run: `cd e2e && npm run test:smoke -- --grep "首页冒烟测试"`
|
||||
|
||||
Expected: Section display tests should pass
|
||||
|
||||
**Step 5: Commit section display fixes**
|
||||
|
||||
```bash
|
||||
git add e2e/src/pages/HomePage.ts e2e/src/tests/smoke/home-page.smoke.spec.ts src/components/sections/
|
||||
git commit -m "fix: resolve page section display issues"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 4: Fix Work Hours Information Retrieval
|
||||
|
||||
**Priority:** P1 (High)
|
||||
**Estimated Time:** 30 minutes
|
||||
**Files:**
|
||||
- Modify: `e2e/src/pages/ContactPage.ts`
|
||||
- Modify: `src/app/(marketing)/contact/page.tsx`
|
||||
|
||||
**Step 1: Update ContactPage work hours selector**
|
||||
|
||||
```typescript
|
||||
// e2e/src/pages/ContactPage.ts
|
||||
export class ContactPage extends BasePage {
|
||||
async getWorkHours() {
|
||||
const workHoursItems = this.page.locator('[aria-label="工作时间"] + div, .work-hours > div');
|
||||
const count = await workHoursItems.count();
|
||||
const items = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const item = workHoursItems.nth(i);
|
||||
const day = await item.locator('div').first().textContent();
|
||||
const hours = await item.locator('div').nth(1).textContent();
|
||||
if (day && hours) {
|
||||
items.push({ day: day.trim(), hours: hours.trim() });
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Ensure contact page has proper work hours structure**
|
||||
|
||||
Check: `src/app/(marketing)/contact/page.tsx`
|
||||
|
||||
```tsx
|
||||
<div aria-label="工作时间" className="work-hours">
|
||||
<div>
|
||||
<div>周一至周五</div>
|
||||
<div>9:00 - 18:00</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Step 3: Run contact page smoke tests**
|
||||
|
||||
Run: `cd e2e && npm run test:smoke -- --grep "联系页面冒烟测试.*工作时间"`
|
||||
|
||||
Expected: Work hours tests should pass
|
||||
|
||||
**Step 4: Commit work hours fixes**
|
||||
|
||||
```bash
|
||||
git add e2e/src/pages/ContactPage.ts src/app/(marketing)/contact/page.tsx
|
||||
git commit -m "fix: resolve work hours information retrieval"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 5: Fix Page Scrolling Functionality
|
||||
|
||||
**Priority:** P1 (High)
|
||||
**Estimated Time:** 1-2 hours
|
||||
**Files:**
|
||||
- Modify: `e2e/src/pages/BasePage.ts`
|
||||
- Modify: `e2e/src/tests/smoke/navigation.smoke.spec.ts`
|
||||
- Modify: `e2e/src/tests/smoke/home-page.smoke.spec.ts`
|
||||
|
||||
**Step 1: Add robust scrolling methods to BasePage**
|
||||
|
||||
```typescript
|
||||
// e2e/src/pages/BasePage.ts
|
||||
async scrollToTop() {
|
||||
await this.page.evaluate(() => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
await this.page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
async scrollToBottom() {
|
||||
await this.page.evaluate(() => {
|
||||
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
|
||||
});
|
||||
await this.page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
async scrollToElement(selector: string) {
|
||||
const element = this.page.locator(selector);
|
||||
await element.scrollIntoViewIfNeeded({ timeout: 5000 });
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Update scrolling tests with better error handling**
|
||||
|
||||
```typescript
|
||||
// e2e/src/tests/smoke/navigation.smoke.spec.ts
|
||||
test('应该能够滚动到页面顶部', async ({ homePage }) => {
|
||||
await homePage.scrollToBottom();
|
||||
await homePage.scrollToTop();
|
||||
const scrollPosition = await homePage.page.evaluate(() => window.scrollY);
|
||||
expect(scrollPosition).toBeLessThan(100);
|
||||
});
|
||||
|
||||
test('应该能够滚动到页面底部', async ({ homePage }) => {
|
||||
await homePage.scrollToBottom();
|
||||
const scrollPosition = await homePage.page.evaluate(() => {
|
||||
return window.scrollY + window.innerHeight;
|
||||
});
|
||||
const pageHeight = await homePage.page.evaluate(() => document.body.scrollHeight);
|
||||
expect(scrollPosition).toBeGreaterThanOrEqual(pageHeight - 100);
|
||||
});
|
||||
```
|
||||
|
||||
**Step 3: Run scrolling tests**
|
||||
|
||||
Run: `cd e2e && npm run test:smoke -- --grep "滚动"`
|
||||
|
||||
Expected: Scrolling tests should pass
|
||||
|
||||
**Step 4: Commit scrolling fixes**
|
||||
|
||||
```bash
|
||||
git add e2e/src/pages/BasePage.ts e2e/src/tests/smoke/navigation.smoke.spec.ts e2e/src/tests/smoke/home-page.smoke.spec.ts
|
||||
git commit -m "fix: resolve page scrolling functionality issues"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 6: Fix Contact Page Title
|
||||
|
||||
**Priority:** P2 (Medium)
|
||||
**Estimated Time:** 10 minutes
|
||||
**Files:**
|
||||
- Modify: `src/app/(marketing)/contact/page.tsx`
|
||||
- Modify: `e2e/src/tests/smoke/contact-page.smoke.spec.ts`
|
||||
|
||||
**Step 1: Update contact page title**
|
||||
|
||||
```typescript
|
||||
// src/app/(marketing)/contact/page.tsx
|
||||
export const metadata = {
|
||||
title: '联系我们 - 四川睿新致远科技有限公司',
|
||||
description: '无论您有任何问题或合作意向,我们都很乐意与您交流',
|
||||
};
|
||||
```
|
||||
|
||||
**Step 2: Update page heading to match title**
|
||||
|
||||
```tsx
|
||||
// src/app/(marketing)/contact/page.tsx
|
||||
<h1>联系我们</h1>
|
||||
```
|
||||
|
||||
**Step 3: Update test to match actual title**
|
||||
|
||||
```typescript
|
||||
// e2e/src/tests/smoke/contact-page.smoke.spec.ts
|
||||
test('应该显示正确的页面标题', async ({ contactPage }) => {
|
||||
const title = await contactPage.page.title();
|
||||
expect(title).toBeTruthy();
|
||||
expect(title.length).toBeGreaterThan(0);
|
||||
expect(title).toContain('联系');
|
||||
});
|
||||
```
|
||||
|
||||
**Step 4: Run contact page title test**
|
||||
|
||||
Run: `cd e2e && npm run test:smoke -- --grep "应该显示正确的页面标题"`
|
||||
|
||||
Expected: Title test should pass
|
||||
|
||||
**Step 5: Commit title fixes**
|
||||
|
||||
```bash
|
||||
git add src/app/(marketing)/contact/page.tsx e2e/src/tests/smoke/contact-page.smoke.spec.ts
|
||||
git commit -m "fix: correct contact page title"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 7: Run Full Test Suite and Verify
|
||||
|
||||
**Priority:** P0 (Critical)
|
||||
**Estimated Time:** 45 minutes
|
||||
**Files:**
|
||||
- Test: All smoke tests
|
||||
|
||||
**Step 1: Run all smoke tests**
|
||||
|
||||
Run: `cd e2e && npm run test:smoke`
|
||||
|
||||
Expected: All smoke tests should pass with >95% pass rate
|
||||
|
||||
**Step 2: Generate test report**
|
||||
|
||||
Run: `cd e2e && npm run test:report`
|
||||
|
||||
Expected: HTML report generated
|
||||
|
||||
**Step 3: Check test results**
|
||||
|
||||
Run: `cd e2e && node analyze-results.js`
|
||||
|
||||
Expected: Pass rate should be >95%
|
||||
|
||||
**Step 4: If any tests fail, analyze and fix**
|
||||
|
||||
Run: `cd e2e && npx playwright show-report`
|
||||
|
||||
Expected: Identify any remaining failures and create additional fix tasks
|
||||
|
||||
**Step 5: Commit test results**
|
||||
|
||||
```bash
|
||||
git add e2e/test-results/ e2e/analyze-results.js
|
||||
git commit -m "test: verify all critical fixes with full test suite"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 8: Create Deployment Readiness Report
|
||||
|
||||
**Priority:** P0 (Critical)
|
||||
**Estimated Time:** 30 minutes
|
||||
**Files:**
|
||||
- Create: `docs/reports/2026-03-07-fixes-completion-report.md`
|
||||
|
||||
**Step 1: Generate completion report**
|
||||
|
||||
Create report with:
|
||||
- Summary of all fixes implemented
|
||||
- Before and after test results
|
||||
- Remaining issues (if any)
|
||||
- Deployment readiness status
|
||||
- Recommendations
|
||||
|
||||
**Step 2: Commit report**
|
||||
|
||||
```bash
|
||||
git add docs/reports/2026-03-07-fixes-completion-report.md
|
||||
git commit -m "docs: add fixes completion report"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
After completing all tasks, verify:
|
||||
|
||||
- [ ] All P0 issues fixed (mobile navigation, main navigation, page sections)
|
||||
- [ ] All P1 issues fixed (work hours, scrolling)
|
||||
- [ ] All P2 issues fixed (page title)
|
||||
- [ ] Smoke test pass rate >95%
|
||||
- [ ] No critical failures remaining
|
||||
- [ ] All changes committed with clear messages
|
||||
- [ ] Completion report generated
|
||||
|
||||
---
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If any fix introduces new issues:
|
||||
|
||||
1. Identify the problematic commit
|
||||
2. Revert the specific commit: `git revert <commit-hash>`
|
||||
3. Re-run tests to verify stability
|
||||
4. Document the issue for future investigation
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- Smoke test pass rate: >95%
|
||||
- Navigation tests: 100% pass
|
||||
- Home page tests: 100% pass
|
||||
- Contact page tests: 100% pass
|
||||
- Zero P0 or P1 issues remaining
|
||||
- Ready for deployment with confidence
|
||||
Reference in New Issue
Block a user