feb646efe5
feat: 为主导航菜单和页面区块添加ARIA属性 fix: 解决工作时间信息获取问题 perf: 优化页面滚动功能实现 fix: 修正联系页面标题显示问题 test: 运行完整测试套件验证修复效果 docs: 添加修复完成报告
554 lines
14 KiB
Markdown
554 lines
14 KiB
Markdown
# 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 |